Java 11 上的 DateTimeParseException 但适用于 Java 10
DateTimeParseException on Java 11 but works on Java 10
下面的测试用例在Java10下完美运行:
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)
怎么回事?
UPDATE:将 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)
。
DateTimeFormatter.RFC_1123_DATE_TIME
您的日期时间字符串在 RFC 822/RFC 1123 format. Instead of building your own formatter use the built-in 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);
输出为:
Result: 2018-09-29T20:49:02Z
根据 RFC 规范的要求,此 RFC 1123 格式化程序始终使用英文。我什至尝试将我的默认语言环境设置为 Locale.CANADA_FRENCH
,代码仍然有效。
你的代码出了什么问题?
In Java 11 Java 期望星期几和月份的缩写在 Locale.CANADA
中用点书写:Sat.
和 Sep.
而不是 Sat
和 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 上打印没有点:
Sample: Sun, 30 Sep 2018 10:39:28 EDT
在 Java 11 build 11+28:
Sample: Sun., 30 Sep. 2018 10:50:29 EDT
所以我认为该行为与您链接到的错误报告无关。
链接
下面的测试用例在Java10下完美运行:
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)
怎么回事?
UPDATE:将 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)
。
DateTimeFormatter.RFC_1123_DATE_TIME
您的日期时间字符串在 RFC 822/RFC 1123 format. Instead of building your own formatter use the built-in 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);
输出为:
Result: 2018-09-29T20:49:02Z
根据 RFC 规范的要求,此 RFC 1123 格式化程序始终使用英文。我什至尝试将我的默认语言环境设置为 Locale.CANADA_FRENCH
,代码仍然有效。
你的代码出了什么问题?
In Java 11 Java 期望星期几和月份的缩写在 Locale.CANADA
中用点书写:Sat.
和 Sep.
而不是 Sat
和 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 上打印没有点:
Sample: Sun, 30 Sep 2018 10:39:28 EDT
在 Java 11 build 11+28:
Sample: Sun., 30 Sep. 2018 10:50:29 EDT
所以我认为该行为与您链接到的错误报告无关。