在 Java 17 中解析带有两位小数的时间时出错,但在 Java 8 中成功

问题描述 投票:0回答:1

以下代码片段在 Java 8 中运行没有错误。但是,当我在 Java 17 中运行相同的代码时,它失败了。

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

public class Main2 {
    public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH[:mm[:ss[.SSS]]]X");
        OffsetDateTime offSetDateTime = OffsetDateTime.parse("2021-10-09T08:59:00.00Z", formatter);
        System.out.println(offSetDateTime);
    }
}

在 Java 17 上运行时的输出:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-10-09T08:59:00.00Z' could not be parsed at index 19
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954)
    at java.base/java.time.OffsetDateTime.parse(OffsetDateTime.java:404)
    at Main2.main(Main2.java:9)

但是,如果我针对 Java 8 运行相同的代码,则会给出以下结果:

2021-10-09T08:59Z

如果我将测试数据从

"2021-10-09T08:59:00.00Z"
更改为
"2021-10-09T08:59:00.000Z"
,它可以在 Java 17 中运行。知道 Java 17 中的哪些更改导致它失败吗?

java java-8 java-time java-17
1个回答
0
投票

此行为似乎是由 JDK-8230136 的修复引起的。

JDK-8230136 是秒分数字段不检查其最小宽度的问题。如果您在

appendFraction(NANO_OF_SECOND, 3, 3, false)
中输入
DateTimeFormatterBuilder
,则该字段将接受 1、2 或 3 位数字。

DateTimeFormatter
在底层使用
DateTimeFormatterBuilder
,因此它也会受到影响。模式中的
SSS
最终会导致像
appendFraction(NANO_OF_SECOND, 3, 3, false)
上的
DateTimeFormatterBuilder
那样的调用。

如果您需要旧的行为,您可以致电

appendFraction
并提供您自己的最小位数。

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("yyy-MM-dd'T'HH")
        .optionalStart()
        .appendPattern(":mm")
        .optionalStart()
        .appendPattern(":ss")
        .optionalStart()
        .appendFraction(ChronoField.NANO_OF_SECOND, 1, 3, true)
        .optionalEnd()
        .optionalEnd()
        .optionalEnd()
        .appendPattern("X")
        .toFormatter();
© www.soinside.com 2019 - 2024. All rights reserved.