4

以下测试用例在 Java 10 下完美运行:

import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;

class Test
{
    public static void main (String[] args) throws java.lang.Exception
    {
        DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder().
          appendPattern("EEE, dd MMM yyyy HH:mm:ss zzz").
          toFormatter();
        Instant result = dateFormatter.parse("Sat, 29 Sep 2018 20:49:02 GMT", Instant::from);
        System.out.println("Result: " + result);
    }
}

但在 Java 11 下我得到:

Exception in thread "main" java.time.format.DateTimeParseException: Text 'Sat, 29 Sep 2018 20:49:02 GMT' could not be parsed at index 0
        at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
        at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
        at Test.main(Test.java:13)

这是怎么回事?

更新:替换toFormatter()toFormatter(Locale.US)修复问题。我猜这个问题与https://bugs.openjdk.java.net/browse/JDK-8206980有关。此问题在 Java 11 build 23 中标记为已修复,但我正在运行

openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

这个版本不应该修复吗?

UPDATE2:如果您无法重现问题,请尝试替换toFormatter()toFormatter(Locale.CANADA).

4

1 回答 1

8

DateTimeFormatter.RFC_1123_DATE_TIME

您的日期时间字符串采用RFC 822 / RFC 1123格式。不要构建自己的格式化程序,而是使用内置的DateTimeFormatter.RFC_1123_DATE_TIME

    Instant result = DateTimeFormatter.RFC_1123_DATE_TIME
            .parse("Sat, 29 Sep 2018 20:49:02 GMT", Instant::from);
    System.out.println("Result: " + result);

输出是:

结果:2018-09-29T20:49:02Z

根据 RFC 规范的要求,此 RFC 1123 格式化程序始终为英文。我什至尝试将我的默认语言环境设置为Locale.CANADA_FRENCH,并且代码仍然有效。

你的代码出了什么问题?

在 Java 11 中,Java 期望星期几和月份的缩写在Locale.CANADA:Sat.Sep.而不是Satand中用点书写Sep。在 Java 10 中,它们应该没有点,所以在这里解析有效。差异可能在于 CLDR 数据的不同版本,在任何提到的 Java 版本中都很难被视为错误。由于 Java 9 CLDR 一直是 Java 中的默认语言环境数据——包括不同语言环境中的日期和月份缩写形式。

演示:使用您的格式化程序,但修改它以使用Locale.CANADA您所说的:

    DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder().
            appendPattern("EEE, dd MMM yyyy HH:mm:ss zzz").
            toFormatter(Locale.CANADA);
    System.out.println("Sample: " + ZonedDateTime.now(ZoneId.of("America/Toronto"))
            .format(dateFormatter));

在 Java 10.0.2 上运行,这不打印任何点:

示例:2018 年 9 月 30 日星期日 10:39:28 EDT

在 Java 11 构建 11+28 上:

样品:2018 年 9 月 30 日星期日 10:50:29 EDT

因此,我认为该行为与您链接到的错误报告无关。

链接

于 2018-09-30T08:26:30.850 回答