DateTimeParseException on Java 11 but works on Java 10

非 Y 不嫁゛ 提交于 2021-02-09 02:50:10

问题


The following testcase runs perfectly under 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);
    }
}

but under Java 11 I get:

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)

What's going on?

UPDATE: Replacing toFormatter() with toFormatter(Locale.US) fixes the problem. I am guessing this issue is related to https://bugs.openjdk.java.net/browse/JDK-8206980. This issue is marked as fixed in Java 11 build 23 but I am running

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)

Shouldn't this be fixed in this version?

UPDATE2: If you are unable to reproduce the problem, try replacing toFormatter() with toFormatter(Locale.CANADA).


回答1:


DateTimeFormatter.RFC_1123_DATE_TIME

Your date-time string is in 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);

Output is:

Result: 2018-09-29T20:49:02Z

This RFC 1123 formatter is always in English, as required by the RFC specification. I even tried setting my default locale to Locale.CANADA_FRENCH, and the code still worked.

What went wrong in your code?

In Java 11 Java expects that the abbreviations for day of week and for month are written with a dot in Locale.CANADA: Sat. and Sep. rather than Sat and Sep. In Java 10 they are expected without dots, so here parsing works. The difference probably lies in different versions of CLDR data and can hardly be considered a bug in any of the mentioned Java versions. Since Java 9 CLDR has been the default locale data in Java — including what day and month abbreviations look like in different locales.

Demonstration: Using your formatter, but modifying it to use Locale.CANADA as you said:

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

Running on Java 10.0.2 this printed no dots:

Sample: Sun, 30 Sep 2018 10:39:28 EDT

And on Java 11 build 11+28:

Sample: Sun., 30 Sep. 2018 10:50:29 EDT

So I believe that the behaviour has nothing to do with the bug report you linked to.

Links

  • DateTimeFormatter.RFC_1123_DATE_TIME documentation
  • CLDR - Unicode Common Locale Data Repository home page
  • JDK Bug System: DateTimeFormatter throws parsing a valid string depending on the locale


来源:https://stackoverflow.com/questions/52572726/datetimeparseexception-on-java-11-but-works-on-java-10

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!