3

可能重复:
Python strptime() 和时区?

'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'

也许我遗漏了一些东西,但谁能发现为什么这不能正确验证?

4

4 回答 4

2

strptime()函数不能很好地处理%Z时区解析。仅真正支持 UTC 和 GMT,当前值为time.tzname. 请参阅strptime文档

%Z指令的支持基于其中包含的值tzname以及是否daylight为真。因此,它是特定于平台的,除了识别始终已知的 UTC 和 GMT(并且被认为是非夏令时时区)。

删除EST输入的%Z部分和格式字符串的部分可以使事情正常进行:

>>> import time
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM EST', '%A, %B %d, %Y %I:%M:%S %p %Z')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 454, in _strptime_time
    return _strptime(data_string, format)[0]
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 325, in _strptime
    (data_string, format))
ValueError: time data 'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM', '%A, %B %d, %Y %I:%M:%S %p')
time.struct_time(tm_year=2012, tm_mon=12, tm_mday=22, tm_hour=13, tm_min=22, tm_sec=24, tm_wday=5, tm_yday=357, tm_isdst=-1)

或将时区替换ESTGMT

>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM GMT', '%A, %B %d, %Y %I:%M:%S %p %Z')
time.struct_time(tm_year=2012, tm_mon=12, tm_mday=22, tm_hour=13, tm_min=22, tm_sec=24, tm_wday=5, tm_yday=357, tm_isdst=0)

要解析时区不是time.tzname,GMT或的字符串UTC,请使用不同的日期解析库。该dateutil具有出色的parse功能,可以正确处理时区:

>>> from dateutil.parser import parse
>>> parse('Saturday, December 22, 2012 1:22:24 PM EST', tzinfos={'EST': -18000})
datetime.datetime(2012, 12, 22, 13, 22, 24, tzinfo=tzoffset(u'EST', -18000))

使用时,dateutil.parser.parse()您必须为您的格式提供自己的时区偏移量

于 2012-12-28T10:02:53.893 回答
1

正如@root 所建议的那样, dateutil.parser 是解析日期的可靠方法,但只是为了澄清这里的问题

我刚刚看到 _strptime.py 中的代码,似乎支持的时区是

["utc", "gmt", time.tzname[0].lower()]

如果当前语言环境时区支持夏令时,它会追加

time.tzname[0].lower()到上面的列表。

因此,在使用 strptime 时,请确保您解析日期的时区支持源时区

这是供参考的代码

def __calc_timezone(self):
    # Set self.timezone by using time.tzname.
    # Do not worry about possibility of time.tzname[0] == timetzname[1]
    # and time.daylight; handle that in strptime .
    try:
        time.tzset()
    except AttributeError:
        pass
    no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()])
    if time.daylight:
        has_saving = frozenset([time.tzname[1].lower()])
    else:
        has_saving = frozenset()
    self.timezone = (no_saving, has_saving)
于 2012-12-28T10:09:31.507 回答
1

您可以使用dateutil为自己省去很多麻烦。

In [1]: from dateutil import parser

In [2]: parser.parse('Saturday, December 22, 2012 1:22:24 PM EST')
Out[2]: datetime.datetime(2012, 12, 22, 13, 22, 24)

至于 eumiro 指出的歧义,您可以添加一个tzinfo论点:

In [3]: parser.parse('Saturday, December 22, 2012 1:22:24 PM EST',tzinfos={'EST':-5*3600})
Out[3]: datetime.datetime(2012, 12, 22, 13, 22, 24, tzinfo=tzoffset('EST', -18000))
于 2012-12-28T09:40:50.263 回答
0

您的语言环境时区很可能是空的,例如%Z评估为'' 您可以通过以下方式进行测试:

>>> fmt = '%A, %B %d, %Y %I:%M:%S %p %Z'
>>> datetime.strptime(datetime.strftime(datetime.now(), fmt), fmt)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 325, in _strptime
    (data_string, format))
ValueError: time data 'Friday, December 28, 2012 11:34:35 AM ' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'
于 2012-12-28T09:37:01.533 回答