17

I have tried some code in Java 8 (1.8.0_77) and Java 9 (Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode))

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("eee", Locale.GERMAN);
DayOfWeek mo = dtf.parse("Mo", DayOfWeek::from);
System.out.println("mo = " + mo);

I am not too familiar with details of those classes, but in Java 8 this works, printing:

mo = MONDAY

In Java 9, however it fails

Exception in thread "main" java.time.format.DateTimeParseException: Text 'Mo' could not be parsed at index 0 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1988) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1890) at day.main(day.java:10)

Any ideas, is this reproducible?

so, when formating: using this code:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("eee", Locale.GERMAN);
String format = dtf.format(DayOfWeek.MONDAY);
System.out.println("format = " + format);

jdk1.8.0-77:

format = Mo

jdk-9 (build 9+181)

format = Mo.

Cœur
  • 37,241
  • 25
  • 195
  • 267
user140547
  • 7,750
  • 3
  • 28
  • 80
  • 2
    https://ideone.com/6t60j1 Are you sure about java-8? –  Sep 15 '17 at 17:27
  • well I used 1.8.0_77. is it possible to use this version on this site? – user140547 Sep 15 '17 at 17:29
  • Ideone is providing some version you have no control over it. (and the service is already really nice IMHO) –  Sep 15 '17 at 17:30
  • 2
    @Tom You have misinterpreted the javadoc. "eee" is text abbreviation in format style (not stand-alone like "ccc"). – Meno Hochschild Sep 15 '17 at 17:38
  • @MenoHochschild Ok then. Thanks for the heads-up. – Tom Sep 15 '17 at 17:40
  • 2
    I can acknowledge that OPs code works on Java 8 (1.8.0_131). – Tom Sep 15 '17 at 17:41
  • @RC I'm using JDK 1.8.0_144 and it works. Didn't test with JDK 9, though. –  Sep 15 '17 at 17:43
  • 1
    Have you tried your first code with "Mo." in Java 9? Does that work? If yes, then it looks like the abbreviation has been changed? – Tom Sep 15 '17 at 17:43
  • 2
    @Tom: yes with "Mo." it works in JDK 9. Anyway, this seems to be a breaking change then. Well or maybe there is some standard which rules that "Mo." is the correct version so that was changed... – user140547 Sep 15 '17 at 17:46

2 Answers2

15

This seems to be there in due to the current implementation of CLDR date-time-patterns with the implementation of JEP - 252 which states that

Use locale data from the Unicode Consortium's Common Locale Data Repository (CLDR) by default.

Localized patterns for the formatting and translation of display strings, such as the locale name, may be different in some locales.

To enable behavior compatible with JDK 8, set the system property java.locale.providers to a value with COMPAT ahead of CLDR.


And to second the data part of it, the international components for Unicode in German locale which has the following relevant information can justify that the behavior is intentional -

enter image description here

Edit/Note: As linked in the comments, the migration guide states a similar warning for such implementations -

If your application starts successfully, look carefully at your tests and ensure that the behavior is the same as on JDK 8. For example, a few early adopters have noticed that their dates and currencies are formatted differently. See Use CLDR Locale Data by Default.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • 3
    From https://docs.oracle.com/javase/9/migrate/toc.htm#JSMIG-GUID-AFD3BDEC-99FC-4F3C-946F-A1CD2D05B74B "If your application starts successfully, look carefully at your tests and ensure that the behavior is the same as on JDK 8. For example, a few early adopters have noticed that their dates and currencies are formatted differently. See Use CLDR Locale Data by Default." – Mani Oct 07 '17 at 06:38
9

The abbreviatiions "Mo", "Di" etc. without dot have not disappeared in CLDR but are accessible via standalone-mode. You should change your pattern using the standalone format symbol "c" instead of "e":

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ccc", Locale.GERMAN);
DayOfWeek mo = dtf.parse("Mo", DayOfWeek::from);

Indeed, I consider the change of underlying data as breaking backwards compatibility (concrete as behavioural break).

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
  • 7
    The transition to using CDLR locale data by default is indeed a disruptive change. JDK 8 includes the CDLR locale data so you can run with `-Djava.locale.providers=CLDR` to identify any issues in advance of moving to JDK 9. – Alan Bateman Sep 16 '17 at 07:10