Java date parsing with microsecond or nanosecond accuracy
根据SimpleDateFormat类文档,
因此,日期字符串
- 2015-05-09 00:10:23.999750900 //最后9位数字表示纳秒
通过模式解析时
- yyyy-MM-dd HH:mm:ss.SSSSSSSSS // 9个'S'符号
实际上将
- 2015-05-20 21:52:53 UTC
即提前11天以上。令人惊讶的是,使用更少的
有两种方法可以正确处理此问题:
- 使用字符串预处理
- 使用自定义的SimpleDateFormat实现
是否可以通过仅向标准
TL;博士
1 2 3 4 | 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. |
不
不,您不能使用SimpleDateFormat来处理纳秒。
但是你的前提是……
Java does not support time granularity above milliseconds in its date patterns
Ok.
…从Java 8、9、10及更高版本开始,内置Java.time类不再适用。 Java 6和Java 7也并非如此,因为大多数java.time功能都是反向移植的。
java.time
新的java.time类支持纳秒分辨率。该支持包括解析并生成9位数的小数秒。例如,当您使用
<5233>
例如,
1 | instant.toString() // Generate a `String` representing this moment, using standard ISO 8601 format. |
2013-08-20T12:34:56.123456789Z
Ok.
请注意,在Java 8中捕获当前时刻仅限于毫秒分辨率。 java.time类可以保存一个以纳秒为单位的值,但是只能以毫秒为单位确定当前时间。此限制归因于
1 | Instant instant = Instant.now() ; // Capture the current moment. May be in milliseconds or microseconds rather than the maximum resolution of nanoseconds. |
您的示例输入字符串
将此类输入解析为
1 2 3 4 5 | 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. ) ; |
1 | myPreparedStatement.setObject( … , instant ) ; |
和检索。
1 | Instant instant = myResultSet.getObject( … , Instant.class ) ; |
JDBC规范未强制支持
1 2 | OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ; myPreparedStatement.setObject( … , odt ) ; |
和检索。
1 | Instant instant = myResultSet.getObject( … , OffsetDateTime.class ).toInstant() ; |
如果使用旧版4.2之前的JDBC驱动程序,则可以使用
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧旧式日期时间类,例如
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如
好。