为什么 python 的 datetime.datetime.strptime('201412', '%Y%m%d') 不引发 ValueError?

Why does python's datetime.datetime.strptime('201412', '%Y%m%d') not raise a ValueError?

在我给出的格式中,日期 2014-01-02 将由“20140102”表示。这是使用标准 strptime 正确解析的:

>>> datetime.datetime.strptime("20140102", "%Y%m%d")
datetime.datetime(2014, 1, 2, 0, 0)

在此格式中,“201412”不是有效日期。 docs 表示“%m”指令是 "Month as a zero-padded decimal number." 它给出了示例“01, 02, ..., 12”。 days 指令“%d”也应该用零填充。

基于此,我预计“201412”将是这种格式的无效输入,因此会引发 ValueError。相反,它被解释为 2014-01-02:

>>> datetime.datetime.strptime("201412", "%Y%m%d")
datetime.datetime(2014, 1, 2, 0, 0)

问题是:有没有办法指定"no seriously zero-padded only"?还是我在这种情况下误解了术语 "zero-padded"?

请注意,问题不是关于如何解析这种格式的日期,而是关于理解 strptime 的行为。

如果您在此处查看正则表达式是如何为 %m https://github.com/python/cpython/blob/2d264235f6e066611b412f7c2e1603866e0f7f1b/Lib/_strptime.py#L204

定义的

'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])"

您可以看到您可以将 10-12、01-09 或 1-9 作为可接受的月份。

根据 Python 跟踪器上的相关 issue,例子是这样的(对这个问题做了一些修改,但是概念是完全一样的):

>>> datetime.datetime.strptime('20141110', '%Y%m%d').isoformat()
'2014-11-10T00:00:00'
>>> datetime.datetime.strptime('20141110', '%Y%m%d%H%M').isoformat()
'2014-01-01T01:00:00'

以上行为被确定为 不是 this comment which states that they conform to the OpenGroup strptime standard 所解释的错误,它指定 "leading zeros are permitted but not required.".

我想解决方法是使用正则表达式或在传入 strptime.

之前检查字符串的长度是否为 8

这很棘手,但听起来 strptime 只是试图尽可能接近地匹配字符串。 Python 的 strptime 与 C 的 strptime 相同,文档说填充是可选的:

is the month number [1,12]; leading zeros are permitted but not required.

http://pubs.opengroup.org/onlinepubs/7908799/xsh/strptime.html