System.out.println(
DateTimeFormatter.ofPattern("YYYY-ww").withZone(ZoneOffset.UTC).format(Instant.parse("2022-05-10T00:00:00.00Z"))
);
System.out.println(
DateTimeFormatter.ofPattern("YYYY-ww").withZone(ZoneOffset.UTC).format(Instant.parse("2022-05-17T00:00:00.00Z"))
);
Why this pattern YYYY-ww
resolves differently on Ubuntu and Mac:
Ubuntu: (default locale en_US, my computer)
2022-20
2022-21
Mac: (default locale en_GB)
2022-19
2022-20
EDIT
System.out.println(
DateTimeFormatter.ofPattern("YYYY-ww").withLocale(Locale.UK).withZone(ZoneOffset.UTC).format(Instant.parse("2022-05-10T00:00:00.00Z"))
);
System.out.println(
DateTimeFormatter.ofPattern("YYYY-ww").withLocale(Locale.UK).withZone(ZoneOffset.UTC).format(Instant.parse("2022-05-17T00:00:00.00Z"))
);
returns:
2022-19
2022-20
Still, the question is why pattern ww
is Locale specific? I don't see that in documentation for https://docs.oracle.com/javase/8/docs/api/java/time/temporal/WeekFields.html
or https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
CodePudding user response:
In the US locale, the first week of the year can have one to seven days, whereas in the UK, the first week of the year needs to have at least 4 days.
WeekFields.of(Locale.UK).getMinimalDaysInFirstWeek() // 4
WeekFields.of(Locale.US).getMinimalDaysInFirstWeek() // 1
Also, a US week starts on a Sunday, whereas a UK week starts on a Monday.
This means that for the US, the first week of 2022 is the single Saturday of 2022-01-01, and 2022-01-02 is the start of the second week. On the other hand, for the UK, the first week of 2022 starts from 2022-01-03, since the first two days of the year don't form a week. And this is where that extra week for the US machine came about.
When creating a DateTimeFormatter
using ofPattern
, the default formatting locale of the machine is used:
The formatter will use the default FORMAT locale. This can be changed using
withLocale(Locale)
on the returned formatter
Hence the difference.
I suppose you want ISO weeks here, and not want anything to do with locales. One way to do this is to construct a DateTimeFormatter
using IsoFields
:
var dtf = new DateTimeFormatterBuilder()
. appendValue(IsoFields.WEEK_BASED_YEAR, 4)
.appendLiteral('-')
.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
.toFormatter().withZone(ZoneOffset.UTC);
System.out.println(
dtf.format(Instant.parse("2022-05-10T00:00:00.00Z"))
);
System.out.println(
dtf.format(Instant.parse("2022-05-17T00:00:00.00Z"))
);