Is DateTimeFormatter Operating System Dependent?

Viewed 103

The following code:

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);

gives me different results depending on operating system:

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

is this expected? My unit tests fail in different contexts, and it seems rather unexpected to me

1 Answers

Java 8: no expected dependency on operating system

The Java Runtime engine has had locale data built-in since early versions of Java. From Java 8 data from Unicode Common Locale Data Repository, CLDR, are also included with Java, but default Java’s own data are still preferred.

The result from formatting date and time using your formatter is expected to depend on three or four factors:

  1. On locale.
  2. On the provider of the locale data. Java can get its locale data from up to four sources: the JRE’s own data, CLDR, an installed service provider (so yourself, so to speak) and the host operating system. Which ones are used and with what priority is controlled by the java.locale.providers system property.
  3. On the versions of the locale data from the selected providers.
  4. In case of the HOST locale data provider obviously on the operating system.

In Java 8 the default is to use the JRE’s own locale data as first priorioty and any configured service provider second. Not the host operating system in any case. So not setting the system property java.locale.providers is equivalent to setting it to JRE,SPI. Which in turn does not incur any dependency on the operating system.

In Java 9 the default was changed to be equivalent to CLDR,COMPAT where COMPAT is the new name for JRE. Which in turn still does not incur any dependency on the operating system.

Why did you observe different results?

Assuming that you are relying on the default locale data providers, JRE and SPI, and that you have not added your own service provider (SPI), your different results must be caused by different versions of Java’s locale data. So apparently they updated the locale data from Java 1.8.0_292 to 1.8.0_312.

The slight difference between Windows and Mac both running 1.8.0_312, the dot after Nov, then? While I would have expected them to ship the same version of the locale data with Java installers for different operating systems, the explanation that I can think of is that in this case they may not have.

More observed results

I did some runs of your code too. The following table includes your observations and mine. In all runs I have set java.locale.providers to JRE,SPI to get Java 8 behaviour on Java 9 and later too.

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

The last result is funny, as is your result with the dot.

Links

Related