首页 > 解决方案 > 当 TZ 在环境中时,Python 时间解析失败

问题描述

以下简单脚本:

from datetime import datetime as DT

ts  = 'Mon Aug 17 12:49:28 EDT 2020'
fmt = '%a %b %d %H:%M:%S %Z %Y'
dts = DT.strptime(ts, fmt)
print(dts)

正常工作,当我简单地用它调用 Python 时:

% python3.7 t.py
2020-08-17 12:49:28

但是,如果我向环境添加不同的时区,脚本将失败:

% env TZ=UTC python3.7 t.py
Traceback (most recent call last):
  File "t.py", line 5, in <module>
    dts = DT.strptime(ts, fmt)
  File "/opt/lib/python3.7/_strptime.py", line 577, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/opt/lib/python3.7/_strptime.py", line 359, in _strptime
    (data_string, format))
ValueError: time data 'Mon Aug 17 12:49:28 EDT 2020' does not match format '%a %b %d %H:%M:%S %Z %Y'

我尝试了早期的 Python 版本——2.7 和 3.6——并得到了同样的错误。即使设置TZtoEDT也不起作用,尽管America/New_York(这是我的计算机的/etc/localtime)的值似乎还可以。

如何可靠地解析这样的时间戳?

标签: pythondatetimedatetime-formatpython-datetime

解决方案


我建议使用dateutil带有时区映射字典的 parser.parse:

import dateutil
ts = 'Mon Aug 17 12:49:28 EDT 2020'

# add more time zone names / abbreviations as key-value pairs here:
tzmapping = {'EDT': dateutil.tz.gettz('US/Eastern')}

dt = dateutil.parser.parse(ts, tzinfos=tzmapping)

print(dt)
print(repr(dt))
# 2020-08-17 12:49:28-04:00
# datetime.datetime(2020, 8, 17, 12, 49, 28, tzinfo=tzfile('US/Eastern'))

时区名称缩写本质上是模棱两可的,不会被%Z. UTC 和 GMT 除外 - 但是,也要小心!%Z接受例如文字“UTC”,但它不会产生可识别的日期时间对象。同样,dateutil 的解析器比标准库的 datetime.strptime 做得更好。


推荐阅读