我有以下测试。
@Test
void withoutColon_fails() {
ZonedDateTime.parse("2019-01-24T12:10:58.036820+0400");
}
@Test
void withColon_ok() {
ZonedDateTime.parse("2019-01-24T12:10:58.036820+04:00");
}
我试图解析的日期时间之间的唯一区别是,在第一种情况下,时区指定的小时和分钟之间没有冒号,而在第二种情况下,有一个冒号。
首先他们失败了:
java.time.format.DateTimeParseException: Text '2019-01-24T12:10:58.036820+0400' could not be parsed, unparsed text found at index 29
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2049)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:598)
at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:583)
根据 javadoc,parse()
, through DateTimeFormatter.ISO_ZONED_DATE_TIME
, 最终使用DateTimeFormatter.ISO_OFFSET_DATE_TIME
, 反过来,我们可以读到它是
ISO 日期时间格式化程序,用于格式化或解析带有偏移量的日期时间,例如“2011-12-03T10:15:30+01:00”。
进一步遵循 javadoc 链接,我们得到ZoneOffset.getId()
它接受的内容:
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)
因此,根据 javadocs,冒号始终是强制性的。
但是,根据https://en.wikipedia.org/wiki/ISO_8601,
UTC 偏移以与上面的“Z”相同的方式附加到时间,格式为 ±[hh]:[mm]、±[hh][mm] 或 ±[hh]。
因此,根据标准,冒号不是强制性的,Java 似乎并不完全支持该标准。
问题是:为什么?遗漏是故意的吗,这有充分的理由吗?
这在 Java 8 和 Java 11 中都以这种方式工作。