The end of the year is rolling around and it’s time to remind everyone about that
yyyy works the way you think it does and
YYYY does not. Here’s a quick example to start:
Just because you test a format quickly with the current date and get back the result you expect, does not mean you’ve constructed your date format correctly.
Speaking of which, BJ Homer points out that you can just use “y”, as “yyyy” pads to 4 digits which doesn’t usually matter but isn’t always needed. Olivier Halligon adds, further, that not all calendars use 4 digit years. “For example the Japanese start a new era every time the emperor changes, resetting to year 1 in that era; we’re currently in year Heisei 30.”
To quote The Dave™: “Nooooooo…. Please use “y”, not “yyyy”. “yyyy” zero-pads years that aren’t four digits, and there are multiple calendars w/ 2 or 3-digits years (Japanese, Chinese, Republic of China). “y” is the natural length of the year: “30” for Japanese cal, “2018” for Gregorian, etc”
What you’re actually seeing with “Dec 24, 2017” is the first day of the last full week of the preceding year. It doesn’t matter what numbers you plug into the month (“MM”) or day (“dd”). The presence of
YYYY in the date format without its expected supporting information reduces to “start of year, go back one week, report the first day”. (I’ll explain this more in just a little bit.)
Here are some examples, which you can check from the command line using the
As Apple’s 2014-era date formatting guide points out:
A common mistake is to use
yyyyspecifies the calendar year whereas
YYYYspecifies the year (of “Week of Year”), used in the ISO year-week calendar. In most cases,
YYYYyield the same number, however they may be different. Typically you should use the calendar year.
Unicode.org’s Unicode Technical Standard #35, Date Format Patterns goes into a little more depth:
[“Y” is] Year (in “Week of Year” based calendars). This year designation is used in ISO year-week calendar as defined by ISO 8601, but can be used in non-Gregorian based calendar systems where week date processing is desired. May not always be the same value as calendar year.
ISO 8601 uses a 4-digit year (
YYYY) for “week of year” calendars from 0000 to 9999. If you’re into trivia, the years before 1583 are technically excluded except by special agreement between sending and receiving parties.
Anyway, if you’re going to use
YYYY formats, you’ll want to use additional format elements that support “week of year” date construction. For example, consider the calendar for this upcoming January, which starts on Tuesday the 1st:
January 2019 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
This year, January first can be considered as the first week of 2019 or the 53rd week of 2018, as the weeks overlap in the middle. Using
e (the numeric day of the week) and
ww (the ordinal week to count from), you can represent both dates correctly using the oddball
YYYY formatting token.
Here are examples that use the week-of-year approach counting from both 2018 and 2019:
As you can see from this, when you use
YYYY and do not supply an ordinal week or day, they both default to zero, which is why you get the behavior of the zeroth week (that is, the week before the first week) on the zeroth day (also, the first day of that week) for that calendar year, which is the week before the first week that overlaps the stated year. This explains the results of all those otherwise random late-December dates from earlier.
ISO 8601 should be updated in a few months, with a release somewhere around February.
- ISO/FDIS 8601-1 Preview and Store Expected publication date 2019-02
- ISO/FDIS 8601-2 Preview and Store Expected publication date 2019-02
From what I can tell, the first part revises the current standard and the second expands it. The only freely accessible human-viewable material I could find were the five-page TOC previews for 8601-1 and 8601-2.
(Hat tip: Thanks, Robin Malhotra)