如何使用 UTC 偏移量转换字符串

How to convert string with UTC offset

我的日期是

In [1]: a = "Sun 10 May 2015 13:34:36 -0700"

当我尝试使用 strptime 转换它时,出现错误。

In [3]: datetime.strptime(a, "%a %d %b %Y %H:%M:%S %Z"
   ...: )
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-973ef1c6daca> in <module>()
----> 1 datetime.strptime(a, "%a %d %b %Y %H:%M:%S %Z"
      2 )
/usr/lib/python2.7/_strptime.pyc in _strptime(data_string, format)
    323     if not found:
    324         raise ValueError("time data %r does not match format %r" %
--> 325                          (data_string, format))
    326     if len(data_string) != found.end():
    327         raise ValueError("unconverted data remains: %s" %
ValueError: time data 'Sun 10 May 2015 13:34:36 -0700' does not match format '%a %d %b %Y %H:%M:%S %Z'
In [6]: datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-e4870e34edda> in <module>()
----> 1 datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
/usr/lib/python2.7/_strptime.pyc in _strptime(data_string, format)
    315                 del err
    316                 raise ValueError("'%s' is a bad directive in format '%s'" %
--> 317                                     (bad_directive, format))
    318             # IndexError only occurs when the format string is "%"
    319             except IndexError:
ValueError: 'z' is a bad directive in format '%a %d %b %Y %H:%M:%S %z'

根据文档,正确的格式是 %z,但我可能遗漏了某些部分。

根据您为 python 文档提供的 link,我发现您使用的是 Python 2.7

似乎strptime 并不总是支持%z。 Python 似乎只是调用 C 函数,strptime 在您的平台上不支持 %z

注意:Python 3.2 开始它将始终有效。

我正在使用 Python 3.4,它工作正常

>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")

更新 使用 dateutil

$ pip install python-dateutil

from dateutil import parser
parsed_date = parser.parse(date)

>>> parsed_date
datetime.datetime(2015, 3, 14, 18, 43, 19)

您的格式字符串是正确的并且在 Python 3.3:

中工作正常
>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
datetime.datetime(2015, 5, 10, 13, 34, 36, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))

它确实给出了 Python 2.7 中的错误。

不同于strftime()是调用libc函数实现的,strptime()是在Python库中实现的。 Here you can see that the version used in Python 2.7 doesn’t support the z format. On the other hand here 是 Python 3.3 的版本,支持它(我认为这是在 3.2 左右添加的)。

所以,基本上,您有两个选择:

  1. 使用一些能够处理 z.
  2. 的外部库
  3. 自己实现(例如,从字符串中剥离时区,将第一部分提供给 strptime() 并手动解析第二部分)。查看 Python 库中的操作方法可能会有所帮助。

我试图将其解析为 return 一个“感知”对象,但它有点复杂。

>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> time, tz = a.rsplit(' ', 1)
>>> d = datetime.strptime(time, '%a %d %b %Y %H:%M:%S')
datetime.datetime(2015, 5, 10, 13, 34, 36)

现在我必须调用 d.replace(tzinfo=…tz…) 来替换时区,但问题是我无法获得 tzinfo 的实例,因为仅知道与 UTC 的偏移量不足以识别一个时区。

在 Python 3.2 中有一个特殊的 timezone class,它是 tzinfo 的子class,表示由 just 定义的“假”时区它的偏移量。所以有两种方法可以继续:

  1. 从 Python 3 向后移植(基本上是复制和粘贴)timezone class 并在您的解析器中使用它。
  2. Return一个“幼稚”的对象:

    >>> d + timedelta(hours=int(tz[1:]) * (1 if tz.startswith('-') else -1))
    datetime.datetime(2015, 6, 8, 17, 34, 36)
    

即使在 Python 2.7 中,您也可以仅使用 stdlib 解析输入格式:

>>> from datetime import datetime
>>> from email.utils import mktime_tz, parsedate_tz
>>> mktime_tz(parsedate_tz("Sun 10 May 2015 13:34:36 -0700"))
1431290076
>>> datetime.utcfromtimestamp(_)
datetime.datetime(2015, 5, 10, 20, 34, 36)

结果是一个表示 UTC 时间的原始日期时间对象。

Python: parsing date with timezone from an email 中查看其他解决方案和获取感知日期时间对象的方法。