【问题标题】:Is DateTimeFormatter Operating System Dependent?DateTimeFormatter 操作系统是否依赖?
【发布时间】:2021-12-31 15:47:30
【问题描述】:

以下代码:

Locale locale = new java.util.Locale("en", "AU");
DateTimeFormatter fmt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(locale);
ZonedDateTime zdt = ZonedDateTime.parse("2021-11-19T14:13:12Z");
return fmt.format(zdt);

根据操作系统给我不同的结果:

OS Format Java
Windows 19 Nov. 2021, 2:13:12 pm 1.8.0_312
macOS 19 Nov 2021, 2:13:12 pm 1.8.0_312
Linux/Ubuntu 19/11/2021, 2:13:12 PM 1.8.0_292

这是预期的吗?我的单元测试在不同的上下文中都失败了,这对我来说似乎很意外

【问题讨论】:

  • 我看不到测试在哪里实际使用了创建的Locale locale = new java.util.Locale("en", "AU");。你的意思是写...withLocale(locale); 而不是.withLocale(context.getLocale());
  • FormatStyle.SHORT 也不同:windows & OSX 19/11/21, 2:13 pm, Linux 19/11/21 2:13 PM
  • 哦,是的,忘记简化了,谢谢 - 更新
  • 所以... Mac 和 Windows 产生相同的结果,并且使用来自具有相同语言环境的 samve 供应商的相同版本。 Linux 不是。您能否尝试设置区域设置并将安装设置为与 linux 机器相同的版本和相同的供应商?
  • 问题:我们(您和我们)如何确保您显示的代码实际上代表了正在运行的代码?您在转录时已经犯了至少 2 个错误 - 一次是为了省略输出的时间部分,一次是因为您没有使用 Locale 实例。我们如何确定您的真实测试没有运行与您在此处显示的不同的东西?您似乎很可能在没有意识到的情况下在每台机器上使用了不同的语言环境。

标签: java time formatting datetimeformatter


【解决方案1】:

Java 8:对操作系统没有预期的依赖

Java 运行时引擎从 Java 的早期版本开始就内置了语言环境数据。来自 Unicode Common Locale Data Repository CLDR 的 Java 8 数据也包含在 Java 中,但默认的 Java 自己的数据仍然是首选。

使用格式化程序格式化日期和时间的结果预计取决于三个或四个因素:

  1. 在语言环境中。
  2. 关于语言环境数据的提供者。 Java 最多可以从四个来源获取其语言环境数据:JRE 自己的数据、CLDR、已安装的服务提供者(可以说是您自己)和主机操作系统。使用哪些以及优先级由java.locale.providers 系统属性控制。
  3. 关于来自所选提供商的语言环境数据的版本。
  4. 如果HOST 语言环境数据提供程序显然在操作系统上。

Java 8 中,默认使用 JRE 自己的语言环境数据作为第一优先级,任何已配置的服务提供者第二。在任何情况下都不是主机操作系统。所以不设置系统属性java.locale.providers相当于设置为JRE,SPI。这反过来又不会对操作系统产生任何依赖。

Java 9 中,默认值已更改为等同于 CLDR,COMPAT,其中 COMPATJRE 的新名称。这反过来仍然不会对操作系统产生任何依赖。

为什么你观察到不同的结果?

假设您依赖于默认的语言环境数据提供者 JRE 和 SPI,并且您没有添加自己的服务提供者 (SPI),那么您的不同结果肯定是由 Java 语言环境数据的不同版本造成的。显然,他们将语言环境数据从 Java 1.8.0_292 更新为 1.8.0_312。

Windows 和 Mac 都运行 1.8.0_312 的细微差别,Nov 后面的点,然后呢?虽然我希望他们为不同操作系统的 Java 安装程序提供相同版本的语言环境数据,但我能想到的解释是,在这种情况下他们可能没有。

更多观察结果

我也运行了一些你的代码。下表包括您的观察和我的观察。在所有运行中,我已将 java.locale.providers 设置为 JRE,SPI 以在 Java 9 及更高版本上获得 Java 8 行为。

Java Format OS Tester
1.8.0_121 19/11/2021, 2:13:12 PM MacOS Me
1.8.0_271 19/11/2021, 2:13:12 PM Windows Me
1.8.0_292 19/11/2021, 2:13:12 PM Ubuntu You
1.8.0_312 19 Nov. 2021, 2:13:12 pm Windows You
1.8.0_312 19 Nov 2021, 2:13:12 pm MacOS You
9.0.4 19 Nov 2021, 2:13:12 pm MacOS Me
15.0.1 19/11/2021 2:13:12 PM Windows Me

最后一个结果很有趣,点的结果也很有趣。

链接

【讨论】:

  • 是的,至少大部分与版本相关
猜你喜欢
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
相关资源
最近更新 更多