Java's "Week Based Year" DateTimeFormatter
Investigating the true behaviour of the "YYYY" formatter pattern.
- Cateogory: <Coding>
I stumbled upon this tweet the other day:
PSA: TIS THE SEASON TO CHECK YOUR FORMATTERS, PEOPLE— Giuliana Taylor (@NmVAson) December 20, 2019
TIL that Java's DateTimeFormatter pattern "YYYY" gives you the week-based-year, (by default, ISO-8601 standard) the year of the Thursday of that week.
12/29/2019 formats to 2019
12/30/2019 formats to 2020
This surprised me a bit and wanted to check it out for myself. I often use the DateTimeFormatter and, not really thinking too much about it, construct them with a pattern of the form
YYYY-MM-dd. I always expect it to just format the year as the year that was passed to it, not go of and work out the year by some other means.
Let’s see what actually happens. Here are two uses of the DateTimeFormatter with that pattern I usually use:
The first date formatted results in:
The second date formatted results in:
Uh-oh! That could cause all kinds of problems.
It turns out “Y” part of the pattern will format a date’s year as week-based-year. That is the year in which the Thursday of the week falls in. As is the case this very week, beginning 30/12/2019, the Thursday of this week is 02/01/2020. Therfore passing any date for this week into that DateTimeFormatter with result in a formatted date in the year 2020.
This is to some extent documented in the Java docs for DateTimeFormatter, but could be easily missed or overlooked.
What I should be using to achieve my expected behaviour of returning a result with the specific year of the single date passed to the formatter is a pattern with the lowercase “y” eg. “yyyy-MM-dd”:
The first date formatted now results in:
The second date formatted now results in: