java - WeekFields 在 JVM 8 和 JVM 10 上的不同行为

标签 java java-8 jvm java-10 localdate

我这里有非常简单的程序:

 public static void main(String[] args) {
        LocalDate year = LocalDate.ofYearDay(2022, 100);
        System.out.println(year);

        System.out.println(WeekFields.of(Locale.GERMAN).weekOfYear());

        System.out.println(year.with(WeekFields.of(Locale.GERMAN).weekOfYear(), 0));
        System.out.println(year.with(WeekFields.of(Locale.GERMAN).weekOfYear(), 0).with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)));
    }

但它在 JVM 8 和 JVM 10 上的行为不同。问题似乎是 WeekFields.of(Locale.GERMAN).weekOfYear() 的实现。

在 JVM 10 上,我得到以下结果:

JVM 10

2022-04-10
WeekOfYear[WeekFields[SUNDAY,1]]
2021-12-19
2021-12-13

而在 JVM 8 上:

JVM 8

2022-04-10
WeekOfYear[WeekFields[MONDAY,4]]
2022-01-02
2021-12-27

为什么会这样?我在做什么,可能会导致未定义的行为吗?或者这种行为变化是否在某处指定?

JVM10:

$ java -version
openjdk version "10.0.2" 2018-07-17
OpenJDK Runtime Environment (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)
OpenJDK 64-Bit Server VM (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4, mixed mode)

JVM8

$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.18.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

编辑: JVM 9 的行为与 JVM 8 相同,JVM 11 的行为与 JVM 10

相同

编辑 2: 我实际上找到了改变行为的提交 -> here on github我很好奇为什么会这样。

最佳答案

这样的星期字段是高度本地化的,因此依赖于底层 JVM 的本地化资源,这些资源可以从一个版本更改为另一个版本。

我认为 JVM10 更正确,因为 Locale.GERMAN 没有指代任何国家,因此 Java 简单假设美国(将这个国家作为世界标准处理有点问题,但 Java 也是如此)。

你最好使用 Locale.GERMANY。该国家/地区确实使用星期一作为一周的第一天(与美国从星期日开始作为对比,后者用作 GERMAN 的后备,它只是一种语言,而不是一个国家/地区。

更新——我对 CLDR 数据的研究:

current CLDR data列出后备国家/地区“001”(= 全局)周定义(星期一作为一周的第一天,1 = 日历年第一周的最少天数)。令人惊讶的是,这与美国的定义不同(星期日,1 日)。我认为,甲骨文只是做了自己的事情。就我个人而言,我同意@Holger 的观点,并希望 ISO-8601 作为后备(星期一,4)。

但是,您可以通过以下设置在 JVM-10 机器上恢复 Java-8 行为 system property (未测试):

java.locale.providers=COMPAT,CLDR,SPI

关于java - WeekFields 在 JVM 8 和 JVM 10 上的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55139324/

相关文章:

java - 截断大对象图的设计模式

java - Kafka SaslAuthenticationException 在 SASL_SSL 协议(protocol)的临时基础上发生

java - 如何在 java 中随机播放 FilteredList?

java - JMeter中使用多线程测试时无法解决 "Uncaught Exception java.lang.OutOfMemoryError: unable to create new native thread"

java - Activiti中查询任务开始和结束日期

java - 输入字符串 : "15,7" 的 NumberFormatException

java - 从图像中获取手写文本

java - 使用 Java 11 的独立 Nashorn 在 eval 时抛出 java.lang.StackOverflowError

android - 我已经为我的应用程序使用了三个库,gradle调试花费了很多时间

java - JVM PC 计数器和堆栈空间如何与 JIT 配合使用?