Reputation: 41
In Java 8 java.time package, using LocalDate
with DateTimeFormatter.ISO_WEEK_DATE
:
LocalDate date = LocalDate.of(2015, 12, 28);
date.format(DateTimeFormatter.ISO_WEEK_DATE).equals("2015-W53-1");
as expected, but
date.format(DateTimeFormatter.ofPattern("YYYY'-W'ww'-'e")).equals("2016-W01-2");
That is a full week later! Why? What incantation would make my custom pattern work the same as the built-in pattern?
Upvotes: 4
Views: 181
Reputation: 11
Similar question answered here: Inconsistent `w` symbol formatting from joda time to java.time
Seems like the issue is with Locale as Basil mentioned.
Upvotes: 1
Reputation: 338624
Here is the implementation for DateTimeFormatter.ISO_WEEK_DATE
. The source uses a Builder (DateTimeFormatterBuilder
) rather than a coded String.
From this OpenJDK source code for Java 8 which appears to be current development version after Java 8 Update 72 (I'm not fluent with the OpenJDK site).
public static final DateTimeFormatter ISO_WEEK_DATE;
static {
ISO_WEEK_DATE = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendValue(IsoFields.WEEK_BASED_YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral("-W")
.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_WEEK, 1)
.optionalStart()
.appendOffsetId()
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
}
I do not know the exact nature of the problem, but I suspect it is the definition of the first day of week. The ISO standard says Monday starts the week. It seems .appendValue(DAY_OF_WEEK, 1)
line in code above is making that a fact though I do not know why that would be necessary as the IsoChronology
is specified in the last line above.
Anyways, the problem is certainly contained within Locale
. Here is an example showing the Germany locale generates 2015-W53-1
while the United States locale generates: 2016-W01-2
.
LocalDate localDate = LocalDate.of ( 2015 , 12 , 28 );
String builtIn = localDate.format ( DateTimeFormatter.ISO_WEEK_DATE ); // 2015-W53-1
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "YYYY'-W'ww'-'e" );
formatter = formatter.withLocale ( Locale.GERMANY ); // 2015-W53-1
String custom = localDate.format ( formatter );
System.out.println ( "formatter.locale: " + formatter.getLocale () + " | localDate: " + localDate + " | builtIn: " + builtIn + " | custom: " + custom );
formatter = formatter.withLocale ( Locale.US ); // 2016-W01-2
custom = localDate.format ( formatter );
System.out.println ( "formatter.locale: " + formatter.getLocale () + " | localDate: " + localDate + " | builtIn: " + builtIn + " | custom: " + custom );
formatter.locale: de_DE | localDate: 2015-12-28 | builtIn: 2015-W53-1 | custom: 2015-W53-1
formatter.locale: en_US | localDate: 2015-12-28 | builtIn: 2015-W53-1 | custom: 2016-W01-2
Upvotes: 2