I expect these two formatters to be equivalent:
DateTimeFormatter fromBuilder = new DateTimeFormatterBuilder()
.appendValue(IsoFields.WEEK_BASED_YEAR, 4)
.appendLiteral('-')
.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
.toFormatter();
DateTimeFormatter fromPattern = DateTimeFormatter.ofPattern("YYYY-ww");
But they do not give the same result:
LocalDate date = LocalDate.of(2017, 1, 1);
System.out.printf("from builder: %s%n", fromBuilder.format(date)); // prints 'from builder: 2016-52'
System.out.printf("from pattern: %s%n", fromPattern.format(date)); // prints 'from pattern: 2017-01'
What am I missing?
The
Yandwpatterns correspond to a localized version of week-fields, using the JVM's default locale (java.util.Locale). The second formatter is equivalent to:As this is locale dependent, it can or can't work like
IsoFields. TheWeekFieldscreated above will have a different behaviour depending on the JVM's default locale.IsoFields, on the other hand, follows ISO-8601 definition to define the week-based fields, as described in the javadoc:As
2017-01-01is a Sunday, it corresponds to the last line above: week 1 starts on January 2nd 2017, so January 1st 2017 is still in the last week of 2016.You can check how your
WeekFieldsinstance differs fromIsoFieldsby calling the methodsgetFirstDayOfWeek()andgetMinimalDaysInFirstWeek()- which are used to calculate the values of the respecitive week-based fields:In the JVM I'm using, the default locale is
pt_BR, and theWeekFieldscreated has the first day-of-week as Sunday, and minimal days in first week as1. Check yours and you'll see that it also differs fromIsoFields.You can check ISO's definition by using the constant
WeekFields.ISO:getFirstDayOfWeek()returns Monday andgetMinimalDaysInFirstWeek()returns4.Also, remind that there's a small difference between
IsoFieldsandWeekFields.ISO. Quoting JodaStephen's comment in this thread: