I have really simple program here:
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)));
}
But it behaves differently on JVM 8 and JVM 10. The problem seems to be implementation of WeekFields.of(Locale.GERMAN).weekOfYear()
.
On JVM 10 I get following results:
JVM 10
2022-04-10
WeekOfYear[WeekFields[SUNDAY,1]]
2021-12-19
2021-12-13
whereas on JVM 8:
JVM 8
2022-04-10
WeekOfYear[WeekFields[MONDAY,4]]
2022-01-02
2021-12-27
Why is this happening? Am I doing something, that could potentially cause undefined behavior? Or is this change in behavior somewhere specified?
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)
EDIT:
JVM 9
has same behavior as JVM 8
and JVM 11
behaves like JVM 10
EDIT 2: I actually found the commit which changed the behavior -> here on github and I'm curious why this was changed.
Such week fields are highly localized, and hence dependent on the localized resources of the underlying JVM which can change from one release to another.
I think JVM10 is more correct because Locale.GERMAN
does not refer to any country so Java simple assumes US (somehow questionable to handle this country as world standard, but so is Java).
You should better use Locale.GERMANY
. That country indeed does use Monday as first day of week (in contrast to US starting on Sunday which is used as fallback for GERMAN
which is just a language and not a country.
The current CLDR data list for the fallback country/territory "001" (= worldwide) the week definitions (Monday as first day of week and 1 = minimal days of first week in calendar year). Astonishingly, this is different from US-definition (Sunday, 1). I think, Oracle has just done its own thing. Personally, I agree with @Holger and rather expect ISO-8601 as fallback (Monday, 4).
However, you might be able to restore the Java-8-behaviour on your JVM-10-machine by setting following system property (not tested):
java.locale.providers=COMPAT,CLDR,SPI