java – 解析时DateTimeFormatter的覆盖区如何工作?

在解析时,我对DateTimeFormatter的withZone方法的行为感到困惑.根据它的文件:

When parsing, there are two distinct cases to consider. If a zone has been parsed directly from the text, perhaps because DateTimeFormatterBuilder.appendZoneId() was used, then this override zone has no effect. If no zone has been parsed, then this override zone will be included in the result of the parse where it can be used to build instants and date-times.

基于此以及DateTimeFormatter.ISO_DATE_TIME解析时区的事实,我希望通过以下两个测试.

@Test
public void testNoZoneInInput() {
    final ZonedDateTime expected = ZonedDateTime.of(2017, 2, 2, 9, 0, 0, 0, ZoneId.of("UTC"));
    final ZonedDateTime actual = ZonedDateTime.parse("2017-02-02T10:00:00", DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneId.of("UTC+1")));
    Assert.assertTrue("Expected " + expected + ", got " + actual + " instead.", expected.isEqual(actual));
}

@Test
public void testWithZoneInInput() {
    final ZonedDateTime expected = ZonedDateTime.of(2017, 2, 2, 9, 0, 0, 0, ZoneId.of("UTC"));
    final ZonedDateTime actual = ZonedDateTime.parse("2017-02-02T09:00:00Z", DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneId.of("UTC+1")));
    Assert.assertTrue("Expected " + expected + ", got " + actual + " instead.", expected.isEqual(actual));
}

但前者确实如此,后者则不然:

java.lang.AssertionError: Expected 2017-02-02T09:00Z[UTC], got 2017-02-02T09:00+01:00[UTC+01:00] instead.

因此,无论是否在输入中找到时区,似乎都使用覆盖区域.我发现在this answer中简要提到了类似的行为,当时它表明它可能是JDK中的一个错误,但是我没有在OpenJDK的bug跟踪器上找到相应的票据.它实际上是一个错误,还是我对这个文档的理解不正确?

更新
我用java版本1.8.0_121测试了这个.

最佳答案 这确实是一个错误,只有JDK-8033662,而不是
JDK-8177021.据报道,所有Java 8版本的断言都会失败(我确认它失败了1.8.0_172,最近的一台ATM),但是传递Java 9.

点赞