我有以下代码可在Oracle JDK 10上完美运行

public static void main(String[] args) {
    final var localTime = LocalTime.parse("8:00AM", DateTimeFormatter.ofPattern("h:mma"));
    System.out.println("Local time is " + localTime);
}

它输出以下内容...
Local time is 08:00

当我在OpenJDK 12上运行相同的代码时,我得到了...
Exception in thread "main" java.time.format.DateTimeParseException: Text '8:00AM' could not be parsed at index 4
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2049)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1951)
    at java.base/java.time.LocalTime.parse(LocalTime.java:463)
    at com.virtualenergyservices.portal.backend.bootstrap.FacilitiesImporter.main(FacilitiesImporter.java:909)

有人有什么想法吗?

最佳答案

JDK 11已更新为使用CLDR v33(请参阅发行说明:Updated Locale Data to Unicode CLDR v33)。与CLDR和更早版本中的默认JRE语言环境数据相比,JDK8有很多更改,这会导致在解析某些与语言环境相关的字段时抛出异常,这些字段与以前的JDK版本一起使用时效果很好。

测试用例中的代码不起作用,因为对于en_CA语言环境,对于CLDR v33来说,dayperiod看起来像a.m./p.m.。因此,这里有两个选择:

  • 更新代码以使用CLDR指定的格式,如下所示:
    public static void main(String[] args) {
        Locale.setDefault(new Locale("en", "CA"));
        final var localTime = LocalTime.parse("8:00a.m.", DateTimeFormatter.ofPattern("h:mma"));
        System.out.println("Local time is " + localTime);
    }
    
  • 使用兼容性开关-Djava.locale.providers=COMPAT,它支持与JRE捆绑在一起的语言环境数据,该数据在JDK8和更早版本中是默认设置。使用上述选项运行时,"8:00AM"将使用JDK12正确解析。
  • 08-24 17:31