Java日期解析具有微秒或纳秒精度 [英] Java date parsing with microsecond or nanosecond accuracy

查看:5225
本文介绍了Java日期解析具有微秒或纳秒精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 SimpleDateFormat类文档 Java 在日期模式中不支持超过毫秒的时间粒度。

According to the SimpleDateFormat class documentation, Java does not support time granularity above milliseconds in its date patterns.

所以,日期字符串


  • 2015-05-09 00:10:23.999750900 //最后9位数字表示纳秒数

通过模式解析时


  • yyyy-MM-dd HH:mm :ss.SSSSSSSSS // 9''符号

实际上解释之后的整数。符号为(近10亿!)毫秒而不是纳秒,导致日期

actually interprets the whole number after the . symbol as (nearly 1 billion!) milliseconds and not as nanoseconds, resulting in the date


  • 2015-05-20 21:52:53 UTC

ie超过11天。令人惊讶的是,使用较少数量的 S 符号仍然会导致所有9位数被解析(而不是,例如, .SSS最左边的3位数)。

i.e. over 11 days ahead. Surprisingly, using a smaller number of S symbols still results in all 9 digits being parsed (instead of, say, the leftmost 3 for .SSS).

有两种方法可以正确处理此问题:

There are 2 ways to handle this issue correctly:


  • 使用字符串预处理

  • 使用自定义SimpleDateFormat实现

是否有任何通过向标准 SimpleDateFormat 实现提供模式来获得正确解决方案的其他方法,无需任何其他代码修改或字符串操作?

Would there be any other way for getting a correct solution by just supplying a pattern to the standard SimpleDateFormat implementation, without any other code modifications or string manipulation?

推荐答案

tl; dr



tl;dr

LocalDateTime.parse(                 // With resolution of nanoseconds, represent the idea of a date and time somewhere, unspecified. Does *not* represent a moment, is *not* a point on the timeline. To determine an actual moment, place this date+time into context of a time zone (apply a `ZoneId` to get a `ZonedDateTime`). 
    "2015-05-09 00:10:23.999750900"  // A `String` nearly in standard ISO 8601 format.
    .replace( " " , "T" )            // Replace SPACE in middle with `T` to comply with ISO 8601 standard format.
)                                    // Returns a `LocalDateTime` object.



Nope



不,你不能使用SimpleDateFormat可以处理纳秒

但是你的前提是......

But your premise that…


Java不支持时间粒度毫秒

...从 Java 8 ,9,10及更高版本 java.time 类内置。并不是Java 6和Java 7也是如此,因为大多数 java.time 功能已反向移植

…is no longer true as of Java 8, 9, 10 and later with java.time classes built-in. And not really true of Java 6 and Java 7 either, as most of the java.time functionality is back-ported.

SimpleDateFormat ,以及相关的 java.util.Date / .Calendar 类现已过时找到新的 java.time 包在Java 8中(教程)。

SimpleDateFormat, and the related java.util.Date/.Calendar classes are now outmoded by the new java.time package found in Java 8 (Tutorial).

新的java.time类支持纳秒决议。该支持包括解析和生成九位数的小数秒。例如,当您使用 java.time.format DateTimeFormatter API时, S 模式字母表示秒的一小部分而不是毫秒,它可以处理纳秒值。

The new java.time classes support nanosecond resolution. That support includes parsing and generating nine digits of fractional second. For example, when you use the java.time.format DateTimeFormatter API, the S pattern letter denotes a "fraction of the second" rather than "milliseconds", and it can cope with nanosecond values.

例如, Instant 类代表 UTC 。它的 toString 方法使用标准 String 对象/ wiki / ISO_8601rel =noreferrer> ISO 8601 格式。结尾的 Z 表示UTC,发音为Zulu。

As an example, the Instant class represents a moment in UTC. Its toString method generates a String object using the standard ISO 8601 format. The Z on the end means UTC, pronounced "Zulu".

instant.toString()  // Generate a `String` representing this moment, using standard ISO 8601 format.




2013-08-20T12:34:56.123456789Z

2013-08-20T12:34:56.123456789Z

请注意,捕获Java 8中的当前时刻仅限于毫秒分辨率。 java.time 类可以保持一个以纳秒为单位的值,但只能用毫秒来确定当前时间。此限制是由于 Clock 的实现。在Java 9及更高版本中,新的 Clock 实现可以以更精细的分辨率获取当前时刻,具体取决于主机硬件和操作系统的限制,通常微秒

Note that capturing the current moment in Java 8 is limited to millisecond resolution. The java.time classes can hold a value in nanoseconds, but can only determine the current time with milliseconds. This limitation is due to the implementation of Clock. In Java 9 and later, a new Clock implementation can grab the current moment in finer resolution, depending on the limits of your host hardware and operating system, usually microseconds in my experience.

Instant instant = Instant.now() ;  // Capture the current moment. May be in milliseconds or microseconds rather than the maximum resolution of nanoseconds.



LocalDateTime



您的示例输入字符串 2015-05-09 00:10:23.999750900 缺少时区指示符或UTC的偏移量。这意味着它代表片刻,时间轴上的一个点。相反,它代表潜在时刻,范围约为26-27小时,即全球时区范围。

LocalDateTime

Your example input string of 2015-05-09 00:10:23.999750900 lacks an indicator of time zone or offset-from-UTC. That means it does not represent a moment, is not a point on the timeline. Instead, it represents potential moments along a range of about 26-27 hours, the range of time zones around the globe.

Pares输入为 LocalDateTime 对象。首先,用 T 替换中间的SPACE,以符合ISO 8601格式,在解析/生成字符串时默认使用。所以不需要指定格式化模式。

Pares such an input as a LocalDateTime object. First, replace the SPACE in the middle with a T to comply with ISO 8601 format, used by default when parsing/generating strings. So no need to specify a formatting pattern.

LocalDateTime ldt = 
        LocalDateTime.parse( 
            "2015-05-09 00:10:23.999750900".replace( " " , "T" )  // Replace SPACE in middle with `T` to comply with ISO 8601 standard format.
        ) 
;



java.sql.Timestamp



java.sql.Timestamp 类也处理纳秒分辨率,但是处于一种尴尬的方式。通常最好在java.time类中完成你的工作。从JDBC 4.2及更高版本开始,无需再次使用 Timestamp

myPreparedStatement.setObject( … , instant ) ;

并且检索。

Instant instant = myResultSet.getObject( … , Instant.class ) ;

如果使用较旧的4.2之前的JDBC驱动程序,则可以使用 toInstant 来自 方法在java.sql.Timestamp和java.time之间来回传递。

If using an older pre-4.2 JDBC driver, you can use toInstant and from methods to go back and forth between java.sql.Timestamp and java.time.

java.time 框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如 java.util.Date 日历 ,& SimpleDateFormat

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time 项目,现在位于维护模式,建议迁移到 java.time 课程。

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle教程 。并搜索Stack Overflow以获取许多示例和解释。规范是 JSR 310

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

您可以直接与数据库交换 java.time 对象。使用符合 JDBC驱动程序 jeps / 170rel =noreferrer> JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql。* 类。

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

从哪里获取java.time班?

Where to obtain the java.time classes?


  • Java SE 8 Java SE 9 Java SE 10 以及稍后


    • 内置。

    • 带有捆绑实现的标准Java API的一部分。

    • Java 9添加了一些小功能和修复。

    • Java SE 8, Java SE 9, Java SE 10, and later
      • Built-in.
      • Part of the standard Java API with a bundled implementation.
      • Java 9 adds some minor features and fixes.
      • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
      • Later versions of Android bundle implementations of the java.time classes.
      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

      ThreeTen-Extra 项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的课程,例如 间隔 YearWeek YearQuarter 更多

      这篇关于Java日期解析具有微秒或纳秒精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆