提问者:小点点

为什么日期解析使用DateTimeFor物质给出不同的结果取决于Java版本


相同的日期解析代码显示不同的结果,这取决于我使用的是Java8还是Java11。

以下是重现问题的代码示例:

    public static void main(String[] args) {

    DateTimeFormatterBuilder dfBuilder = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-M-d")
            .optionalStart()
            .optionalStart().appendLiteral(' ').optionalEnd()
            .optionalStart().appendLiteral('T').optionalEnd()
            .appendValue(ChronoField.HOUR_OF_DAY)
            .optionalStart()
            .appendLiteral(':')
            .appendValue(ChronoField.MINUTE_OF_HOUR)
            .optionalStart()
            .appendLiteral(':')
            .appendValue(ChronoField.SECOND_OF_MINUTE)
            .optionalStart()
            .appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, true)
            .optionalEnd()
            .optionalEnd()
            .optionalEnd()
            .appendPattern("[XXXXX][XXXX][XXX][XX][X]")
            .optionalEnd();
    DateTimeFormatter df = dfBuilder.toFormatter(Locale.FRANCE).withZone(ZoneId.of("Europe/Paris"));

    TemporalAccessor temporalAccessor = df.parse("1970-01-01T00:00:00.00Z");
    Instant instantTime = Instant.from(temporalAccessor);
    long epochTimestamp = instantTime.getEpochSecond();
    System.out.println(epochTimestamp);
}

在java8上,输出为-3600。

而在Java11上,输出为0(这是我期望的值)。

从我的分析来看,起源是使用“withZone()”方法,如果我删除它,它将按预期工作于包含区域数据的日期。

但同时,这种行为在所有DateTimeFor物质上并不相同:例如,如果我使用此格式化程序:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd HH:mm:ss")
                .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true)
                .optionalStart()
                .appendZoneId()
                .optionalEnd()
                .toFormatter()
                .withZone(ZoneId.of("Europe/Paris"));

在日期中出现的情况下,zoneId被很好地考虑在内(尽管调用了“withZone()”)。所以我认为第一个格式化程序有问题,Java11上的默认行为有助于它在Java11上按预期工作,而不是在Java8上?我还精确地说,我的目标是让它在Java8上工作。


共1个答案

匿名用户

这是Java8中的一个已知bug。使用DateTimeFormat. withZone进行解析的行为与javadocs中描述的不同。

有趣的是,我链接到的JavaBugs System中的bug报告没有提到修复版本。它确实提到bug不在JDK9-ea中,尽管:

要重现该问题,请运行附加的测试用例。它在JDK8u121上失败,但传入JDK9-ea。