Python 3.x 零填充格式的python datetime strTime的意外行为

Python 3.x 零填充格式的python datetime strTime的意外行为,python-3.x,datetime,format,strptime,zero-padding,Python 3.x,Datetime,Format,Strptime,Zero Padding,我有一个以不同格式表示日期时间的字符串列表。即: list_date_str = ['2021010112', '202101011210'] 第一个应翻译为2021-01-01 12:00,第二个应翻译为2021-01-01 12:10。 我不假思索地写了这段话: import datetime as dt for date_str in list_date_str: try: date = dt.datetime.strptime(date_str, '%Y%m%

我有一个以不同格式表示日期时间的字符串列表。即:

list_date_str = ['2021010112', '202101011210']
第一个应翻译为2021-01-01 12:00,第二个应翻译为2021-01-01 12:10。 我不假思索地写了这段话:

import datetime as dt

for date_str in list_date_str:
    try:
        date = dt.datetime.strptime(date_str, '%Y%m%d%H%M')
    except ValueError:
        date = dt.datetime.strptime(date_str, '%Y%m%d%H') 
    print(date)
经过一番艰苦的bug搜索,我意识到第一个字符串没有按预期进行解析。该守则规定:

2021-01-01 01:02:00
2021-01-01 12:10:00
我确实理解正在发生的事情:除非永远无法到达障碍。相反,倒数第二个字符“2021010112”被解释为小时数字,最后一个字符被解释为分钟数字

这是假定的行为吗?表中明确指出%H表示零填充十进制数以及%M

是我不明白,还是医生只是在误导我?为什么try块不引发ValueError

有没有一种方便而有力的方法来解决这个问题?我知道在这种特殊情况下,可以通过交换try-and-expect块来修复代码。但这不是正确的方法


PS:这个问题也适用于pd.to_datetime。

我怀疑文档更准确地反映了字符串格式,而不是字符串解析


在您的情况下,实际的问题是您的数据格式不一致。我不会依赖解析尝试来确定应该用什么格式进行解析。相反,您应该显式地检查字符串的长度,以决定要使用什么格式来解析它。这还允许您优雅地处理这里描述的两种情况以外的情况。

使用
len
从dict获取字符串长度和时间格式

Ex:

import datetime
list_date_str = ['2021010112', '202101011210']

frmt = {10: '%Y%m%d%H', 12: '%Y%m%d%H%M'}
for date_str in list_date_str:
    try:
        print(datetime.datetime.strptime(date_str, frmt.get(len(date_str))))
    except:
        raise Exception("Date Format Not Found.")

也许最简单的方法是在需要时将日期时间字符串归零:

list_date_str = ['2021010112', '202101011210']

for date_str in list_date_str:
    try:
        date = dt.datetime.strptime(f'{date_str:0<12}', '%Y%m%d%H%M')
    except ValueError:
        print(f'Failed to convert {date_str!r}')
        continue 
    print(date)
list\u date\u str=['2021010112','202101011210']
对于列表中的日期列表:
尝试:

date=dt.datetime.strtime(f'{date_str:0这很优雅:)不要求数字是零填充的-我认为这在文档中有点不清楚。干净、健壮并且比我最初的尝试更通用
>>> list_date_str = ['2021010112', '202101011210', 'baddate', '20210101', '2021']
>>> for date_str in list_date_str:
...     try:
...         date = dt.datetime.strptime(f'{date_str:0<12}', '%Y%m%d%H%M')
...     except ValueError:
...         print(f'Failed to convert {date_str!r}')
...         continue 
...     print(date)
... 
2021-01-01 12:00:00
2021-01-01 12:10:00
Failed to convert 'baddate'
2021-01-01 00:00:00
Failed to convert '2021'