Search code examples
pythondatetimestrptime

How exactly is the %y directive interpreted when parsing dates?


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?


Solution

  • 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.