While reading this question about parsing dates of the form %m/%d/%y
, I realized that I don't know how the %y
directive actually works.
The docs state the following:
Year without century as a zero-padded decimal number.
But which century does it use? If I use %y
to parse the year 01
, will that result in 1901 or 2001? If I re-run the same code in 100 years, will it result in 2101?
As an experiment, I wrote some code that parses all numbers from 0 to 99 and displays the results:
for year in range(100):
date = '6/1/{:>02}'.format(year)
dt = datetime.strptime(date, "%m/%d/%y")
print(year, dt.date())
The results were surprising:
0 2000-06-01
1 2001-06-01
2 2002-06-01
...
67 2067-06-01
68 2068-06-01
69 1969-06-01 # <- wut
70 1970-06-01
71 1971-06-01
...
98 1998-06-01
99 1999-06-01
Why does it suddenly jump from 2068 to 1969? Is this behavior documented anywhere? What's the formal specification for %y
?
From the time
docs, emphasis mine:
Year 2000 (Y2K) issues: Python depends on the platform’s C library, which generally doesn’t have year 2000 issues, since all dates and times are represented internally as seconds since the epoch. Function
strptime()
can parse 2-digit years when given%y
format code. When 2-digit years are parsed, they are converted according to the POSIX and ISO C standards: values 69–99 are mapped to 1969–1999, and values 0–68 are mapped to 2000–2068.