Locale-independent year, week, and date format
I want to print Instant
in a locale-independent way, with ISO set to the first day of the week (Monday) and the minimum number of days of the week (4).
My current setup is:
private String print(Instant i) {
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("YYYY-ww")
.withZone(UTC);
return formatter.format(i);
}
@Test
public void test() {
System.out.format("First day of week : %s%n",
WeekFields.of(Locale.getDefault()).getFirstDayOfWeek());
System.out.format("Min days in 1st week : %s%n",
WeekFields.of(Locale.getDefault()).getMinimalDaysInFirstWeek());
Instant instant = Instant.parse("1998-12-31T00:00:00Z");
System.out.println(print(instant));
}
For the system locale “en_US”, test print:
First day of week : SUNDAY
Min days in 1st week : 1
1999-01
For the system locale “de_DE”, test printing:
First day of week : MONDAY
Min days in 1st week : 4
1998-53
The “de_DE” locale is consistent with the ISO settings, and I know I can set the formatter to
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("YYYY-ww")
.withZone(UTC)
.withLocale(Locale.GERMANY);
But can I do this without specifying binds to any locale for a particular country? I found java.time.temporal.WeekFields#ISO
:
public static final WeekFields ISO = new WeekFields(DayOfWeek.MONDAY, 4);
This is what I want, but I don’t know how to use it with DateTimeFormatter
.
Solution
You can use the corresponding fields for java.time.format.DateTimeFormatterBuilder
and WeekFields.ISO
- week-based-year(i.e. equivalent of
Y
pattern ) - week-of-week-based-year(i.e. equivalent of
w
pattern)
The code is:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
append week year
.appendValue(WeekFields.ISO.weekBasedYear(), 4)
separator
.appendLiteral('-')
append week of week year field
.appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2)
create formatter
.toFormatter().withZone(ZoneOffset.UTC);
Instead of creating a new instance of WeekFields
(using WeekFields.of(locale)
), just use WeekFields.ISO
System.out.format("First day of week : %s%n", WeekFields.ISO.getFirstDayOfWeek());
System.out.format("Min days in 1st week : %s%n", WeekFields.ISO.getMinimalDaysInFirstWeek());
Instant instant = Instant.parse("1998-12-31T00:00:00Z");
System.out.println(formatter.format(instant));
The output is:
First day of week : MONDAY
Min days in 1st week : 4
1998-53
Even if I change the locale of the formatter :
formatter = formatter.withLocale(Locale.GERMANY);
Or:
formatter = formatter.withLocale(Locale.ENGLISH);
The output remains unchanged.