Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTimeParseException on Java 11 but works on Java 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).

like image 414
Gili Avatar asked Jan 27 '23 09:01

Gili


1 Answers

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
like image 157
Ole V.V. Avatar answered Feb 05 '23 02:02

Ole V.V.