Python中显式指定格式时如何解析时间字符串中的Z?
解析带Z的ISO时间字符串(显式指定格式)
在Python 3.11中,datetime.fromisoformat可以直接将时间字符串中的Z解析为UTC时区:
import datetime as dt dt.datetime.fromisoformat('2020-01-01T03:04:05Z') # 输出:datetime.datetime(2020, 1, 1, 3, 4, 5, tzinfo=datetime.timezone.utc)
但如果想要显式指定格式来解析,直接使用%Z格式符会触发报错:
dt.datetime.strptime('2020-01-01T03:04:05Z', '%Y-%m-%dT%H:%M:%S%Z')
完整报错信息:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[16], line 1 ----> 1 dt.datetime.strptime('2020-01-01T03:04:05Z', '%Y-%m-%dT%H:%M:%S%Z') File /usr/lib/python3.11/_strptime.py:568, in _strptime_datetime(cls, data_string, format) 565 def _strptime_datetime(cls, data_string, format="%a %b %d %H:%M:%S %Y"): 566 """Return a class cls instance based on the input string and the 567 format string.""" --> 568 tt, fraction, gmtoff_fraction = _strptime(data_string, format) 569 tzname, gmtoff = tt[-2:] 570 args = tt[:6] + (fraction,) File /usr/lib/python3.11/_strptime.py:349, in _strptime(data_string, format) 347 found = format_regex.match(data_string) 348 if not found: --> 349 raise ValueError("time data %r does not match format %r" % 350 (data_string, format)) 351 if len(data_string) != found.end(): 352 raise ValueError("unconverted data remains: %s" % 353 data_string[found.end():]) ValueError: time data '2020-01-01T03:04:05Z' does not match format '%Y-%m-%dT%H:%M:%S%Z'
如果将格式写为%Y-%m-%dT%H:%M:%SZ,虽然能成功解析,但不会把Z识别为时区信息:
dt.datetime.strptime('2020-01-01T03:04:05Z', '%Y-%m-%dT%H:%M:%SZ') # 输出:datetime.datetime(2020, 1, 1, 3, 4, 5)
可行的解决方法
- 方法1:解析后手动添加UTC时区
先按不含时区的格式解析,再通过replace方法为结果添加UTC时区:
dt_obj = dt.datetime.strptime('2020-01-01T03:04:05Z', '%Y-%m-%dT%H:%M:%SZ') dt_obj_with_tz = dt_obj.replace(tzinfo=dt.timezone.utc) # 输出:datetime.datetime(2020, 1, 1, 3, 4, 5, tzinfo=datetime.timezone.utc)
- 方法2:替换Z为+0000后用%z解析
%z格式符支持解析±HHMM形式的时区偏移,因此可以先将字符串中的Z替换为+0000,再用对应格式解析:
time_str = '2020-01-01T03:04:05Z' dt.datetime.strptime(time_str.replace('Z', '+0000'), '%Y-%m-%dT%H:%M:%S%z') # 输出:datetime.datetime(2020, 1, 1, 3, 4, 5, tzinfo=datetime.timezone.utc)
- 方法3:直接使用fromisoformat(推荐)
如果不需要强制显式指定格式,Python 3.11+的fromisoformat已经原生支持解析带Z的ISO时间字符串,是最简洁高效的方式,正如开头示例。
内容的提问来源于stack exchange,提问作者ignoring_gravity
相关产品推荐
相关产品推荐

