除了当前时区之外,输入中不支持%Z
的任何内容。只有time.tzname
元组中的字符串加上'UTC'
和'GMT'
才会被识别:
>>> from datetime import datetime
>>> import time
>>> time.tzname
('GMT', 'BST')
>>> sample = 'Sun, 28 Oct 2018 07:33:13 -0400 (EDT)'
>>> datetime.strptime(sample.replace('EDT', time.tzname[0]), '%a, %d %b %Y %H:%M:%S %z (%Z)')
datetime.datetime(2018, 10, 28, 7, 33, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000), 'GMT'))
>>> datetime.strptime(sample.replace('EDT', time.tzname[1]), '%a, %d %b %Y %H:%M:%S %z (%Z)')
datetime.datetime(2018, 10, 28, 7, 33, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000), 'BST'))
即使您在输入中使用了“已知”的时区名称,除非还有一个时区偏移量(
%z
),否则该名称将被忽略;使用
%z
偏移量仅用于设置从
%z
偏移量构建的{{link1:
datetime.timezone()
实例}}的
name
参数。
不幸的是,这种行为并没有得到明确记录,请参阅Python问题{{link2:#22377}}和{{link3:#22426}}。文档似乎暗示EST
应该是%Z
可解析的可接受值,但文档的这部分仅显示 datetime.strftime()
字符串输出,而不是可接受的datetime.strptime()
字符串输入。
由于您在字符串中还具有相对于UTC的偏移量(-0400
部分),因此只需将时区名称从输入中删除,并且不要尝试解析它:
>>> datetime.strptime(sample.rpartition(' ')[0], '%a, %d %b %Y %H:%M:%S %z')
datetime.datetime(2018, 10, 28, 7, 33, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))
我在这里使用了
str.rpartition()
来删除从最后一个空格开始的所有内容,但是最好根据您的输入类型来确定如何最好地在应用程序中删除时区名称部分。没有它,
(%Z)
部分是不需要的,您将得到一个正确的
datetime
对象。
在调试
datetime.strptime()
问题时,您需要将问题进行“分隔”。您可以对输入和模板部分进行二分,以查看问题所在,或者逐个尝试不同的组件。可能是单个指令引起了问题,也可能是多个,因此我通常会一步一步地删除指令,直到找到有效的一个。
对于那些对datetime.strptime()
的工作细节感兴趣的人,您可以使用调试器进入调用,因为实现使用纯Python模块。对于datetime.strptime()
,入口点是_strptime._strptime_datetime()
,而%Z
参数匹配模式是由这个小循环生成的,其中self.locale_time.timezone
是一个包含3个字母字符串的frozensets的2值元组,它是通过LocaleTime.__calc_timezone()
方法设置的。
(UTC)
。EDT 是一个有效的区域吗? - Jean-François Fabre('(?P<a>mon|tue|wed|thu|fri|sat|sun),\\s+(?P<d>3[0-1]|[1-2]\\d|0[1-9]|[1-9]| ' '[1-9])\\s+(?P<b>jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\\s+(?P<Y>\\d\\d\\d\\d)\\s+(?P<H>2[0-3]|[0-1]\\d|\\d):(?P<M>[0-5]\\d|\\d):(?P<S>6[0-1]|[0-5]\\d|\\d)\\s+(?P<z>[+-]\\d\\d[0-5]\\d)\\s+\\((?P<Z>paris\\,\\ ' 'madrid\\ \\(heure\\ d\\\x92\\ét\\é\\)|paris\\,\\ madrid|utc|gmt)\\)')
它取决于当前的时区。 - Jean-François Fabre