解析日期时 %y 指令究竟是如何解释的?

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

在阅读 关于解析 %m/%d/%y 形式的日期时,我意识到我不知道 %y 指令的实际工作原理。

docs 声明如下:

Year without century as a zero-padded decimal number.

但是它使用的是哪个世纪?如果我使用 %y 来解析年份 01,结果是 1901 年还是 2001 年?如果我在 100 年后重新 运行 相同的代码,结果会是 2101 吗?


作为实验,我编写了一些代码来解析从 0 到 99 的所有数字并显示结果:

for year in range(100):
    date = '6/1/{:>02}'.format(year)
    dt = datetime.strptime(date, "%m/%d/%y")
    print(year, dt.date())

结果令人惊讶:

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

为什么突然从2068跳到1969?这种行为是否记录在任何地方? %y 的正式规范是什么?

来自 time 文档,强调我的:

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.

strptime 大概是 C 的 strptime.

的基本包装

strptimethe POSIX specification states:

%y The year within century. When a century is not otherwise specified, values in the range [69,99] shall refer to years 1969 to 1999 inclusive, and values in the range [00,68] shall refer to years 2000 to 2068 inclusive; leading zeros shall be permitted but shall not be required.

Note: It is expected that in a future version of IEEE Std 1003.1-2001 the default century inferred from a 2-digit year will change. (This would apply to all commands accepting a 2-digit year as input.)

您可以阅读 strptime 的 CPython 实现 here, and in particular at lines 384-392 有一点很有趣:

    if group_key == 'y':
        year = int(found_dict['y'])
        # Open Group specification for strptime() states that a %y
        #value in the range of [00, 68] is in the century 2000, while
        #[69,99] is in the century 1900
        if year <= 68:
            year += 2000
        else:
            year += 1900

手册中也解释了此行为 ot time:

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.