Cannot parse String in ISO 8601 format, lacking colon in offset, to Java 8 Date
我对java 8日期格式/解析功能有点沮丧。 我试图找到Jackson配置和
这是
1 2 | Date date = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZZZ") .parse("2018-02-13T10:20:12.120+0000"); |
相同的格式不适用于新的日期时间api
1 2 | ZonedDateTime dateTime = ZonedDateTime.parse("2018-02-13T10:20:12.120+0000", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'hh:mm:ss.SSSZZZ")); |
我们应该能够以适合FE UI应用程序的任何格式格式化/解析日期。 也许我误解或错误的东西,但我认为
TL;博士
直到bug被修复:
1 2 3 4 | OffsetDateTime.parse( "2018-02-13T10:20:12.120+0000" , DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX" ) ) |
当错误修复时:
1 | OffsetDateTime.parse("2018-02-13T10:20:12.120+0000" ) |
细节
您使用的是错误的类。
避免麻烦的旧遗留类,如
您使用的
仅对于偏移而不是时区,请使用
您的输入字符串符合ISO 8601标准。在解析/生成字符串时,java.time类默认使用标准格式。因此无需指定格式化模式。
1 | OffsetDateTime odt = OffsetDateTime.parse("2018-02-13T10:20:12.120+0000" ); |
那应该是有效的。遗憾的是,Java 8中存在一个错误(至少通过Java 8 Update 121),该类无法解析在小时和分钟之间省略冒号的偏移量。因此,虫咬了
hack:操纵输入字符串以插入冒号。
1 2 | String input ="2018-02-13T10:20:12.120+0000".replace("+0000" ,"+00:00" ); OffsetDateTime odt = OffsetDateTime.parse( input ); |
更强大的解决方法是在
1 2 3 | String input ="2018-02-13T10:20:12.120+0000" ; DateTimeFormatter f = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX" ); OffsetDateTime odt = OffsetDateTime.parse( input , f ); |
odt.toString(): 2018-02-13T10:20:12.120Z
顺便说一句,这里有一个提示:我发现使用许多协议和库,如果你的偏移总是有冒号,你的生活会更容易,总是有小时和分钟(即使分钟为零),并且总是使用填充零(
对于通过
如果要使用始终为UTC(并且应该)的值,请提取
1 | Instant instant = odt.toInstant(); |
如果您想通过某个区域的挂钟时间镜头查看该时刻,请应用时区。
1 2 | ZoneId z = ZoneId.of("America/Montreal" ); ZonedDateTime zdt = odt.atZoneSameInstant( z ); |
请参阅IdeOne.com上的此代码。
在许多问题的答案中,所有这些都已被多次涵盖。请在发布前彻底搜索Stack Overflow。你会发现很多甚至数百个例子。
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要
从哪里获取java.time类?
-
Java SE 8,Java SE 9,Java SE 10及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小功能和修复。
-
Java SE 6和Java SE 7
- 许多java.time功能都被反向移植到Java 6& 7在ThreeTen-Backport。
-
Android的
- 更高版本的Android捆绑java.time类的实现。
- 对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP ....
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的类,例如