【问题标题】:Why date parsing using DateTimeFormatter gives different result depending on Java version为什么使用 DateTimeFormatter 进行日期解析会根据 Java 版本给出不同的结果
【发布时间】:2021-11-26 13:44:51
【问题描述】:

相同的日期解析代码显示不同的结果,具体取决于我使用的是 Java 8 还是 Java 11。

这里是重现问题的代码示例:

    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);
}

在 java 8 上,输出为 -3600。

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

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

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

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()”)。 所以我想第一个格式化程序有问题,Java 11 上的默认行为有助于它在 Java 11 上按预期工作,但在 Java 8 上没有? 此外,我明确表示我的目标是让它在 Java 8 上运行。

【问题讨论】:

  • 请看这个stackoverflow.com/questions/58010818/…我相信它是同样的问题。
  • @Codeburned 你确定这是本地化问题吗?预期产量与法国时间无关。预计日期时间格式化程序从字符串中的字符 Z 解析时区,而不是从传递给 withZone 的参数解析时区。似乎发生的事情是格式化程序使用withZone 中的时区而不是文本中的时区。
  • @Codeburned 这对我来说似乎不是完全相同的问题,但也许我想念一些东西。解决方法似乎也不适用于我的情况
  • 我在我的 Java 8 上重现了不正确的结果。

标签: java date java-8 java-11 datetimeformatter


【解决方案1】:

已知错误

这是 Java 8 中的一个已知错误。Parsing with DateTimeFormatter.withZone does not behave as described in javadocs

有趣的是,我链接到的 Java 错误系统中的错误报告没有提到修复版本。不过,它确实提到了该错误不在 JDK 9-ea 中:

要重现该问题,请运行随附的测试用例。它在JDK上失败 8u121 但在 JDK 9-ea 中通过。

【讨论】:

    猜你喜欢
    • 2018-07-17
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多