JDK dateformatter 在德语语言环境中解析 DayOfWeek,java8 对比 java9

JDK dateformatter parsing DayOfWeek in German locale, java8 vs java9

我已经在 Java 8 (1.8.0_77) 和 Java 9 (Java HotSpot(TM) 64 位服务器 VM(构建9+181,混合模式))

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

我不太熟悉那些 类 的细节,但在 Java 8 中可以工作,打印:

mo = MONDAY

在 Java 9 中,但是它失败了

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)

任何想法,这是可重现的吗?

所以,格式化的时候: 使用此代码:

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(内部版本 9+181)

format = Mo.

这似乎在 due to the current implementation of CLDR date-time-patterns with the implementation of JEP - 252 中,它指出

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.


并且附上它的数据部分,具有以下相关信息的international components for Unicode in German locale可以证明该行为是故意的 -

Edit/Note:正如评论中所链接的那样,migration guide 对此类实现提出了类似的警告-

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.

不带点的缩写 "Mo"、"Di" 等在 CLDR 中并未消失,但可以通过独立模式访问。 您应该使用独立格式符号 "c" 而不是 "e":

来更改您的模式
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ccc", Locale.GERMAN);
DayOfWeek mo = dtf.parse("Mo", DayOfWeek::from);

的确,我认为底层数据的变化是对向后兼容性的破坏(具体是行为上的破坏)。