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

时间:2016-09-16 04:56:19

标签: python datetime strptime

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

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

采用这种格式," 201412"将成为有效日期。 docs表示"%m"指令是"月份为零填充十进制数。"它给出了例子" 01,02,...,12"。日期指令"%d"也应该是零填充。

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

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

问题是:有没有办法指定"没有严重的零填充"?或者我误解了这个术语"零填充"在这种情况下?

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

3 个答案:

答案 0 :(得分:6)

如果你看一下如何为%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视为可接受的月份。

答案 1 :(得分:6)

根据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解释的错误,该错误表明它们符合OpenGroup strptime standard,该documentation指定“允许前导零但不允许需要“。

我想解决方法是使用正则表达式或在传入strptime之前检查字符串的长度是否为8。

答案 2 :(得分:1)

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

  

是月份数[1,12];允许但不是前导零   必需的。

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