3
>>> datetime.strptime('2014-02-13 11:55:00 -0800', '%Y-%m-%d %H:%M:%S %z')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 317, in _strptime
    (bad_directive, format))
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'

I understand that it's not supported, but don't know why. Seems it's not hard to support that. And 'Offset from UTC' is not as ambiguous as timezone abbreviation.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
wanghq
  • 1,336
  • 9
  • 17
  • Duplicate: http://stackoverflow.com/questions/1101508/how-to-parse-dates-with-0400-timezone-string-in-python – Ian Stevens May 29 '14 at 18:43
  • @IanStevens: that says nothing about *why*. – Martijn Pieters May 29 '14 at 18:43
  • There's some speculation under a comment in that link. The linked mailing list archive, https://mail.python.org/pipermail/python-bugs-list/2003-November/021063.html, suggests it's a feature of libc: "it's not a Python bug but a bug in the platform libc." Whether or not that's still true, I don't know. – Ian Stevens May 29 '14 at 18:48
  • That's a bug report about `time.strptime()` though. The reliance on the libc parser has long since been replaced by a [pure-Python implementation](http://hg.python.org/cpython/file/90dab7696e89/Lib/_strptime.py) used by both the `time.strptime()` and `datetime.datetime.strptime()` functions. – Martijn Pieters May 29 '14 at 23:26

2 Answers2

5

Until Python 3.2, Python's datetime module had no timezone() object. It supported 3rd-party libraries providing timezones by providing a datetime.tzinfo() abstract base class, but no timezone object was included. Without a timezone object, no support for parsing timezone offsets either.

As of Python 3.2, z is supported, because that version (and up) added a datetime.timezone() type:

>>> import datetime
>>> datetime.datetime.strptime('2014-02-13 11:55:00 -0800', '%Y-%m-%d %H:%M:%S %z')
datetime.datetime(2014, 2, 13, 11, 55, tzinfo=datetime.timezone(datetime.timedelta(-1, 57600)))
>>> _.tzinfo
datetime.timezone(datetime.timedelta(-1, 57600))
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

Here is a fix for python 2.7

Instead of using:

datetime.strptime(t,'%Y-%m-%dT%H:%M %z')

use the timedelta to account for the timezone, like this:

from datetime import datetime,timedelta
def dt_parse(t):
    ret = datetime.strptime(t[0:16],'%Y-%m-%dT%H:%M')
    if t[18]=='+':
        ret+=timedelta(hours=int(t[19:22]),minutes=int(t[23:]))
    elif t[18]=='-':
        ret-=timedelta(hours=int(t[19:22]),minutes=int(t[23:]))
    return ret
Uri Goren
  • 13,386
  • 6
  • 58
  • 110