在 en_GB 区域设置的 Java 17 中,September 的缩写形式“Sep”不再解析

ste*_*n35 27 java date

这适用于 Java 11,但不适用于 Java 17

DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM dd, yyyy")
    .withLocale(Locale.UK);
format.parse("Sep 29, 1988");
Run Code Online (Sandbox Code Playgroud)

Java 17 堆栈跟踪:

Exception in thread "main" java.time.format.DateTimeParseException: Text 'Sep 29, 1988' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1880)
Run Code Online (Sandbox Code Playgroud)

我的Java版本:

openjdk version "17" 2021-09-14 LTS
OpenJDK Runtime Environment Zulu17.28+13-CA (build 17+35-LTS)
OpenJDK 64-Bit Server VM Zulu17.28+13-CA (build 17+35-LTS, mixed mode, sharing)
Run Code Online (Sandbox Code Playgroud)

发生了什么变化?

Mic*_*ael 33

似乎在 en_GB 语言环境中,九月的缩写形式现在是“Sept”,而不是“Sep”。所有其他月份都是与 en_US 中相同的 3 个字母缩写。有点道理。作为一个英国人,“Sep”对我来说看起来不对。

这是票证:https ://bugs.openjdk.java.net/browse/JDK-8251317

这不是 JDK 作者有意识的决定。Java中默认使用的语言环境数据来自Common Locale Data Repository (CLDR) ,这是Unicode Consortium的一个项目。较新版本的 Java 附带较新版本的 CLDR。因此,您有时可能会看到区域设置行为发生变化。因此,您遇到的更改是一个功能,而不是一个错误。

你的只是众多小调整之一。

以下是 PR 中为您带来的具体更改: https://github.com/openjdk/jdk/pull/1279/files#diff-97210acd6f77c4f4979c43445d60ba1c369f058230e41177dceca697800b1fa2R116

  • @steven35:一致性的问题是,如果我们重视一致性高于一切,则语言环境永远无法改善。基本上,无论您使用哪个库,在没有非常精确的规范(往往使用数字)的情况下解析自由格式的文本日期都是一件冒险的事情。 (3认同)
  • @Michael如果数据以正常格式保存,则不需要更新 (3认同)
  • @steven35你说你想要一致性,但与语言环境相关的东西正在不断发展。货币、国家、语言等等都是流动的。保持数据静态可能会使其在“Java 版本之间”保持一致,但它会变得与现实不一致。他们需要在某个时候更新它。 (2认同)
  • 同意 @9ilsdx9rvj0lo 的观点——例如,我不希望格式 `uuuu-MM-dd'T'HH:mm:ss` 暂时改变。 (2认同)
  • @Holger 谁说这种格式是为了持久化?它是从 HTML 页面而不是数据库解析的。您知道日期并不总是以 ISO 格式显示吗? (2认同)
  • @Holger 假设 OP 在英国,我们使用“Sept”,而他们试图抓取的源网站是美国,他们使用“Sep”。在这种情况下,错误在于它们依赖于默认区域设置进行解析,而该默认区域设置与源区域设置不匹配。我在那条评论中所说的是,因为语言是流动的,所以你当然不能指望这样的解决方案永远有效。但像抓取网站这样的任务并不是你应该“永远”期望永远有效的解决方案。它们“本质上”是脆弱的。这并不会使它们无效。有时抓取网站是你能做的最好的事情 (2认同)