2

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

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)

经过艰苦的错误搜索,我意识到第一个字符串没有按预期解析。代码给出:

2021-01-01 01:02:00
2021-01-01 12:10:00

我明白发生了什么:永远不会到达异常块。相反,“2021010112”的倒数第二个字符被解释为小时数字,最后一个字符被解释为分钟数字。

这是应该的行为吗?日期时间文档清楚地指出 %H 表示一个零填充的十进制数以及 %M。

我没有得到它还是文档只是误导?为什么 try-block 不会引发 ValueError?

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

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

4

3 回答 3

1

用于从dictlen获取字符串长度和时间格式。

前任:

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.")
于 2021-01-11T12:26:54.863 回答
1

也许最简单的方法是在需要时对您的日期时间字符串进行零填充:

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)

这里 fstringf'{date_str:0<12}'用于使用 12 的字段宽度对字符串的末尾进行零填充。这也允许解析可能根本没有时间分量的较短字符串:

>>> 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'
于 2021-01-11T13:12:57.180 回答
0

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

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

于 2021-01-11T12:10:03.870 回答