当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并得到相同的错误。即使将TZ(这是我的计算机的EDT)的值也可以,尽管将America/New_York设置为/etc/localtime也不起作用。

如何可靠地解析此类时间戳?

解决方法

我建议将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”,但不会产生已知的datetime对象。同样,dateutil的解析器比标准库的datetime.strptime做得更好。