4

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

Gili
  • 86,244
  • 97
  • 390
  • 689
  • I tested your code [using JDK 11 downloaded from Oracle's web site](https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html) and it worked fine for me. I am using Windows 10, and downloaded the _zip_ file rather than the _exe_ file. – skomisa Sep 30 '18 at 07:09
  • Are both tests run on the same computer? What is Java’s default locale? Is it the same for your Java 10 and your Java 11? – Ole V.V. Sep 30 '18 at 08:16
  • @skomisa The default locale is CANADA. If you pass `Locale.CANADA` into the `toFormatter()` you should see the problem. – Gili Sep 30 '18 at 08:25
  • @Gili Yes I now see the problem, and the `DateTimeParseException` occurs even if I use **-source 10** under JDK 11. The code runs fine using JDK 10. – skomisa Sep 30 '18 at 15:26

1 Answers1

8

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

Community
  • 1
  • 1
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 1
    If I replace `toFormatter()` with `toFormatter(Locale.CANADA)` and run under Java 10 and 11 I see the code running under Java 10 but failing under Java 11. – Gili Sep 30 '18 at 08:28
  • 1
    I believe your answer/comments contain a typo. You wrote RFC 1134 but in the code the enum is for RFC 1123. The number is different. – Gili Sep 30 '18 at 08:31
  • Even more than once, @Gili. Corrected. Thank you for pointing it out. – Ole V.V. Sep 30 '18 at 10:00
  • Just to confirm that using `RFC_1123_DATE_TIME` also fixes the issue for me. – skomisa Sep 30 '18 at 15:48
  • 1
    Oracle came to the same conclusion: https://bugs.openjdk.java.net/browse/JDK-8211321. Thank you. – Gili Oct 02 '18 at 04:42