java - WeekFields 在 JVM 8 和 JVM 10 上的不同行为
问题描述
我在这里有非常简单的程序:
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:我实际上在github上找到了改变行为的提交->这里我很好奇为什么会改变。
解决方案
这样的星期字段是高度本地化的,因此依赖于底层 JVM 的本地化资源,这些资源可以从一个版本更改为另一个版本。
我认为 JVM10 更正确,因为Locale.GERMAN
它没有提到任何国家,所以 Java 简单地假设为美国(将这个国家作为世界标准处理有些问题,但 Java 也是如此)。
你应该更好地使用 Locale.GERMANY
. 该国家确实确实将星期一用作一周的第一天(与美国从星期日开始用作后备相比,GERMAN
后者只是一种语言而不是国家/地区。
更新——我对 CLDR 数据的研究:
后备国家/地区“001”(= 全球)的当前 CLDR 数据列表周定义(星期一为一周的第一天,1 = 日历年第一周的最少天数)。令人惊讶的是,这与美国的定义不同(星期日,1)。我认为,甲骨文只是做了自己的事情。就个人而言,我同意@Holger 的观点,并希望 ISO-8601 作为后备(星期一,4)。
但是,您可以通过设置以下系统属性(未测试)来恢复 JVM-10 机器上的 Java-8 行为:
java.locale.providers=COMPAT,CLDR,SPI
推荐阅读
- selenium - 当我使用 Maven 运行 selenium 测试时,我在 org/apache/poi/xssf/usermodel/XSSFWorkbook 中出现错误
- anylogic - 如何在 Anylogic 中实现机器学习模型
- swift - 在 SwiftUI 中自动调整 NavigationView 的大小
- javascript - 当我将 setTimeout 的结果分配给变量时,即使我不调用我的变量,setTimeout 中的函数如何运行?
- node.js - UnhandledPromiseRejectionWarning: TypeError: Channel credentials must be a ChannelCredentials object in GCP Batch publishing
- javascript - Pug 增加数字 'inside' 数组名
- python - 时间数据 '09-01-2014 00:01' 与格式 '%m/%d/%Y %H:%M:%S' 不匹配(匹配)
- javascript - 反应如何根据多个键过滤地图功能
- reactjs - 如何将十进制字符 (.) 更改为 (,)
- azure - 物联网工业无云架构