我不确定为什么'200011'用'%Y%m'解析为'%Y%m'为'%Y%m'失败的'200013'和'%Y%m'为'200011'的格式? %d'成功。见代码:
>>> datetime.datetime.strptime('200013', '%Y%m')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../lib/python3.5/_strptime.py", line 510, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File ".../lib/python3.5/_strptime.py", line 346, in _strptime
data_string[found.end():])
ValueError: unconverted data remains: 3
>>> datetime.datetime.strptime('200011', '%Y%m')
datetime.datetime(2000, 11, 1, 0, 0)
>>> datetime.datetime.strptime('200011', '%Y%m%d')
datetime.datetime(2000, 1, 1, 0, 0)
任何想法发生了什么?
答案 0 :(得分:3)
TL; DR:Python文档忽略了零填充月是可选的。
>>> from datetime import datetime
>>> pattern = '%Y%m'
>>> datetime.strptime('20161', pattern).strftime(pattern)
'201601' # Note an extra "0" has appeared
strptime
和strftime
的时间格式来自C标准库。这里的Python文档有点缺乏一些重要的细节,Python文档中的relevant section只是说:
%m月份为零填充十进制数。
但是也提到了
支持的全套格式代码因平台而异,因为Python调用平台C库的strftime()函数,并且平台变体很常见。
这里导致令人惊讶的结果的行为,即前导零的处理,更好地记录在C:
%Y 全年{4};应允许前导零,但不应要求。在任何前导零之前允许使用前导'+'或' - '字符,但不需要。
%米 月份号[01,12];应允许前导零,但不得要求。
%d 每月的某一天[01,31];应允许前导零,但不得要求。
强调我的。来源here。
因此,在知道前导零可能存在或不存在的情况下,所有提到的案例都被正确解释:
datetime.strptime('200013', '%Y%m') # Can not parse
由于13不是有效月份,因此解析强制取1是省略前导零的月份。然后你得到ValueError
,因为解析器不知道如何处理额外的数据“3”。
datetime.datetime.strptime('200011', '%Y%m') # Parses to 1st Nov
解析器将11月(11)作为月份。 Day只是默认为1.这里的月份不可能是1月份,因为这会使这种模式的额外数据无法计算 - 剩下的会有一个额外的“1”剩余。因此,解析器必须贪婪并且在本月消耗'11'。
datetime.datetime.strptime('200011', '%Y%m%d') # Parses to 1st Jan
在这里,我们看到模式%Y%m
和%Y%m%d
可以成功解析'200011'。如果您使用%Y%m%d
模式进行解析,那么您将被迫将月份视为1月(1),否则没有剩余数据填充%d
。请注意,%d
的前导零也是可选的。
答案 1 :(得分:2)
整数13没有相应的月份,因此在3
被解析为月份之后,您必须添加一个说明符来解析1
:
>>> datetime.datetime.strptime('200013', '%Y%m%d')
datetime.datetime(2000, 1, 3, 0, 0)
'200011'
有效,因为11
对应11月,可以安全地解析为月份,而未指定时则默认为1。
答案 2 :(得分:0)
实施例: 月,日,小时和分钟缺失,因此这些设置为默认值:
datetime.datetime.strptime('2000','%Y') datetime.datetime(2000,1,1,0,0)
月,小时和分钟设置为默认值:
datetime.datetime.strptime('200012','%Y%d') datetime.datetime(2000,1,12,0,0)
在你的例子中,它寻找一个月作为第二个参数,但没有'13'月 - datetime.datetime.strptime('200013','%Y%m')
但是当你说,datetime.datetime.strptime('200013','%Y%m%d')时,它会查找年份:2000,月,因为13无效,它需要1个月, 3日当天
最后,在这种情况下:datetime.datetime.strptime('200011','%Y%m'),它查找年份,2000年有效年份,查找月份,11月份是有效月份。现在休息被设置为默认值(就像我在最顶部给出的例子一样)。
注意以下命令,默认为月份,并将13作为有效日期。
datetime.datetime.strptime('200013','%Y%d') datetime.datetime(2000,1,13,0,0)