无法将缺少偏移冒号的字符串解析为Java 8日期的ISO 8601格式。
无法将缺少偏移冒号的字符串解析为Java 8日期的ISO 8601格式。
我对Java 8的日期格式/解析功能感到有些沮丧。我试图查找Jackson配置和DateTimeFormatter来解析\"2018-02-13T10:20:12.120+0000\"字符串到任何Java 8日期,但没有找到。\n下面是一个使用java.util.Date的示例,它运行正常:\nDate date = new SimpleDateFormat(\"yyyy-MM-dd\'T\'hh:mm:ss.SSSZZZ\")\n .parse(\"2018-02-13T10:20:12.120+0000\");\n同样的格式在新的日期时间API中不起作用:\nZonedDateTime dateTime = ZonedDateTime.parse(\"2018-02-13T10:20:12.120+0000\",\n DateTimeFormatter.ofPattern(\"yyyy-MM-dd\'T\'hh:mm:ss.SSSZZZ\"));\n我们应该能够以适合前端用户界面应用程序的任何格式来格式化/解析日期。也许我误解或者犯了一些错误,但我认为java.util.Date提供了更多的格式灵活性和更容易使用。
在使用Java 8的日期类解析ISO 8601格式日期字符串时,可能会遇到"Cannot parse String in ISO 8601 format, lacking colon in offset, to Java 8 Date"这个错误。下面我们来分析一下这个问题出现的原因以及解决方法。
问题的原因是在ISO 8601格式的日期字符串中,时区偏移量的表示方式可能没有使用冒号。例如,"+0000"表示零时区,而"+00:00"表示同样的零时区。
解决这个问题的方法是使用DateTimeFormatter类来指定日期字符串的格式,然后使用LocalDate类的parse()方法来解析日期字符串。
下面是一个示例代码,演示了如何解决这个问题:
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSX" ); LocalDate from = LocalDate.parse("2018-02-13T10:20:12.120+0000", f);
在上面的代码中,我们使用DateTimeFormatter的ofPattern()方法来指定日期字符串的格式,其中"uuuu-MM-dd'T'HH:mm:ss.SSSX"表示ISO 8601格式的日期字符串。然后,我们使用LocalDate的parse()方法来解析日期字符串,得到一个LocalDate对象。
通过使用DateTimeFormatter类来指定日期字符串的格式,我们可以解决"Cannot parse String in ISO 8601 format, lacking colon in offset, to Java 8 Date"这个问题。
使用Java 8的日期类解析ISO 8601格式日期字符串时,可能会遇到"Cannot parse String in ISO 8601 format, lacking colon in offset, to Java 8 Date"这个错误。这个错误的原因是日期字符串中的时区偏移量没有使用冒号。解决这个问题的方法是使用DateTimeFormatter类来指定日期字符串的格式,然后使用LocalDate类的parse()方法来解析日期字符串。通过这种方式,我们可以成功解析ISO 8601格式的日期字符串。
问题的出现原因是时间格式的错误,解决方法是使用OffsetDateTime类型并使用正确的时间格式。
在给定的内容中,解决方法是使用OffsetDateTime类型和DateTimeFormatter的ofPattern方法来解决问题。具体的解决方法如下:
OffsetDateTime odt = OffsetDateTime.parse( "2018-02-13T10:20:12.120+0000" , DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSZZZ" ) )
然后,内容详细地解释了问题的原因:
a) 12小时制和24小时制的问题,正确的应该使用"H"来表示24小时制。
b) 零时区的表示形式的问题,正确的应该使用"ZZZ"来表示零时区。
c) 输入不符合ISO-8601标准,因此不是Java中的bug。ISO-8601规定输入要么完全使用基本格式,要么完全使用扩展格式。
最后,内容提到了相关的JDK问题和ISO-8601规范的细节,对于理解问题非常有帮助。虽然这可能不是严格意义上的JDK bug,但如果JDK在这方面更加宽容并且自动处理正确的事情,会更好一些。
无法解析ISO 8601格式的字符串,偏移量缺少冒号,导致Java 8日期出现问题。出现这个问题的原因是Java 8中存在一个bug,该bug导致无法解析省略小时和分钟之间的冒号的偏移量。解决方法有两种:一种是通过操作输入字符串来插入冒号,另一种是定义和传递一个格式化模式。具体的解决方法如下:
在bug修复之前的解决方法:
OffsetDateTime.parse( "2018-02-13T10:20:12.120+0000" , DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSX" ) )
在bug修复之后的解决方法:
OffsetDateTime.parse( "2018-02-13T10:20:12.120+0000" )
问题的出现原因是使用了错误的类。避免使用旧的遗留类(如Date、Calendar和SimpleDateFormat),而是使用java.time包中的类。使用的ZonedDateTime类是不错的,它是java.time的一部分,但它适用于完整的时区。而你的输入字符串只有一个偏移量。对于只有偏移量而不是时区的情况,应该使用OffsetDateTime类。输入字符串符合ISO 8601标准,java.time类在解析/生成字符串时默认使用标准格式,因此不需要指定格式化模式。
解决方法之一是通过操作输入字符串来插入冒号:
String input = "2018-02-13T10:20:12.120+0000".replace( "+0000" , "+00:00" ); OffsetDateTime odt = OffsetDateTime.parse( input );
解决方法之二是定义并传递一个格式化模式:
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 );
如果想要始终使用UTC进行操作,可以提取一个Instant对象:
Instant instant = odt.toInstant();
如果想要查看某个区域的墙钟时间,请应用时区:
ZoneId z = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = odt.atZoneSameInstant( z );
以上是解决这个问题的方法。在Java 8中,使用java.time包中的类来处理日期和时间是更好的选择,避免使用旧的遗留类。关于java.time的更多信息,请参考Oracle的官方教程和Stack Overflow上的许多示例和解释。