加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java.time.ZonedDateTime.parse和iso8601?

发布时间:2020-12-15 03:08:31 所属栏目:Java 来源:网络整理
导读:为什么JDK8 DateTime库似乎无法解析有效的iso8601日期时间strings?它窒息的时区偏移表示为“01”而不是“01:00” 这有效: java.time.ZonedDateTime.parse("2015-08-18T00:00+01:00") 这会抛出一个解析异常: java.time.ZonedDateTime.parse("2015-08-18T00
为什么JDK8 DateTime库似乎无法解析有效的iso8601日期时间strings?它窒息的时区偏移表示为“01”而不是“01:00”

这有效:

java.time.ZonedDateTime.parse("2015-08-18T00:00+01:00")

这会抛出一个解析异常:

java.time.ZonedDateTime.parse("2015-08-18T00:00+01")

来自iso8601维基百科页面:

The offset from UTC is appended to the time in the same way that ‘Z’
was above,in the form ±[hh]:[mm],±[hh][mm],or ±[hh]. So if the time
being described is one hour ahead of UTC (such as the time in Berlin
during the winter),the zone designator would be “+01:00”,“+0100”,or
simply “+01”.

编辑:这看起来像JDK中的实际合法错误.

https://bugs.openjdk.java.net/browse/JDK-8032051

哇,经过多年测试新的日期时间后,我认为他们会抓住一些如此明显的东西.我还认为JDK作者类型非常严格,可以使用更好的自动化测试套件.

更新:这在当前的jdk-9版本中完全修复.我刚刚确认了.上面显示的完全相同的解析命令在当前的jdk-8构建中失败,并且在jdk-9中完美地工作.

附录:FWIW,基于ISO-8601的RFC 3339,不允许这个简写.您必须在时区偏移中指定分钟.

解决方法

你 use这个默认格式化程序: ISO_OFFSET_DATE_TIME(因为解析2015-08-18T00:00 01:00).

在文档中:

This returns an immutable formatter capable of formatting and parsing the ISO-8601 extended offset date-time format. […]

The offset ID. If the offset has seconds then they will be handled even though this is not part of the ISO-8601 standard. Parsing is case insensitive.

It’s(您只使用此默认格式化程序):

The ID is minor variation to the standard ISO-8601 formatted string
for the offset. There are three formats:

  • Z – for UTC (ISO-8601)
  • +hh:mm or -hh:mm – if the seconds are zero (ISO-8601)
  • +hh:mm:ss or -hh:mm:ss – if the seconds are non-zero (not ISO-8601)
    (don’t +hh like ISO-8601).

似乎java.time(JDK 8)并没有完全实现ISO-8601.

这个:

java.time.ZonedDateTime.parse("2015-08-18T00:00+01:00"); // works

对应(大致来自源JDK):

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
DateTimeFormatter formatter = builder
        .parseCaseInsensitive()
        .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
        .appendOffsetId()
        .toFormatter();

java.time.ZonedDateTime.parse("2015-08-18T00:00+01:00",formatter); // it's same

您可以使用DateTimeFormatterBuilder创建自己的DataTimeFormatter.

DateTimeFormatterBuilder builder2 = new DateTimeFormatterBuilder();
DateTimeFormatter formatter2 = builder2.parseCaseInsensitive()
        .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
        .appendPattern("X") // eg.:
        .toFormatter();

java.time.ZonedDateTime.parse("2015-08-18T00:00+01",formatter2); // here you set +01

而不是appendOffsetId()使用appendPattern(String pattern)并设置’X’或’x’.

现在,您可以使用数据时间2015-08-18T00:00 01.

或者……使用默认的ISO_OFFSET_DATE_TIME并添加后缀:00.

java.time.ZonedDateTime.parse("2015-08-18T00:00+01" + ":00");

但这最后是糟糕的解决方案.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读