java.time.ZonedDateTime.parse和iso8601?

为什么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");

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

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...