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

时间:2015-05-11 05:21:59

标签: python datetime strptime

我的日期为

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,但我可能会遗漏某些部分。

3 个答案:

答案 0 :(得分:3)

从您为python doc提供的链接中,我发现您使用的是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)

答案 1 :(得分:2)

您的格式字符串是正确的,并且在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中给出了错误。

与通过调用libc函数实现的strftime()不同,strptime()在Python库中实现。 Here您可以看到Python 2.7中使用的版本不支持z格式。另一方面,here是Python 3.3的版本,支持它(我认为这是在3.2附近添加的)。

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

  1. 使用一些能够处理z
  2. 的外部库
  3. 自己实现(例如,从字符串中剥离时区,将第一部分提供给strptime()并手动解析第二部分)。看看如何在Python库中完成这项工作可能会有所帮助。
  4. 我试图解析它以返回一个“识别”对象,但它有点复杂。

    >>> 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类,它是tzinfo的子类,表示由其偏移定义的“假”时区。所以有两种方法可以继续:

    1. Backport(基本上,复制并粘贴)来自Python 3的timezone类,并在解析器中使用它。
    2. 返回一个“天真”的对象:

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

答案 2 :(得分:1)

即使在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中获取有效日期时间对象的方法。