6

Suppose I have the following datetime object:

>>> dt
datetime.datetime(2015, 5, 13, 18, 5, 55, 320000, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))

I can print that object in ISO 8601 format like so:

>>> dt.isoformat()
'2015-05-13T18:05:55.320000-07:00'

Under Python 3.4, I can parse the string of an ISO 8601 string if I remove the colon in the time zone:

>>> import re
>>> ts='2015-05-13T18:05:55.320-07:00'
>>> tf="%Y-%m-%dT%H:%M:%S.%f%z"
>>> tsm=re.sub(r'([+-]\d+):(\d+)$', r'\1\2', '2015-05-13T18:05:55.320-07:00')
>>> tsm
'2015-05-13T18:05:55.320-0700'
>>> datetime.datetime.strptime(tsm, tf)
datetime.datetime(2015, 5, 13, 18, 5, 55, 320000, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))

Under Python 2.7, the situation is worse since the %z does not seem to work as documented:

>>> tsm='2015-05-13T18:05:55.320-0700'
>>> tf="%Y-%m-%dT%H:%M:%S.%f%z"
>>> datetime.datetime.strptime(tsm, tf)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/2.7.9/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-%dT%H:%M:%S.%f%z'

Note that is the same format string that does work under Python 3.4.

Question: Other than using dateutil (which works great), is there a reasonable way to parse a ISO 8601 date string with datetime.strptime or something else in the standard library?

  • 1
    I believe that the docs are (mostly) correct here. If you look at the footnotes, it implies that `%z` really only works for aware objects. `datetime.datetime.strptime` creates objects -- They aren't aware already so it can be expected to fail. If you look at the docs for python 3.4, you can see the "new in version 3.2" note where it says that using `%z` in strptime starts to create aware objects instead (which is what you're seeing). – mgilson May 15 '15 at 20:14
  • @mgilson: So it is a chicken / egg thing prior to Python 3.2? It only works for an aware object; `datetime.datetime.strptime` creates objects by default that are not aware prior to 3.2; ergo -- it cannot work on Python earlier than 3.2? Hmmm. Your reasoning is sound, but the conclusion is frustrating. –  May 15 '15 at 20:19
  • Yep -- And that frustration is probably the reason they fixed it in python3.2. It's a shame they didn't backport to python2.7 though. – mgilson May 15 '15 at 20:24
  • Did you look at these answers? http://stackoverflow.com/questions/969285/how-do-i-translate-a-iso-8601-datetime-string-into-a-python-datetime-object – Brent Washburne May 15 '15 at 20:27
  • http://stackoverflow.com/questions/2609259/converting-string-to-datetime-object-in-python – mgilson May 15 '15 at 20:28
  • [Issue 8601](http://bugs.python.org/issue6641) – dawg May 15 '15 at 22:57
  • @dawg -- i'm not sure that issue is actually correct here ... It seems to be associated with version 3.2 (which is the revision where they started making %z work with strptime). – mgilson May 15 '15 at 22:59
  • I can reopen if you wish... – dawg May 15 '15 at 23:04
  • @dawg ? Not sure I understand. This question is about python2.7 -- The issue you linked is a bug in python3.2 so I think it's not necessarily the same thing... Unless I don't understand the version tag on python issues (which is entirely possible). – mgilson May 15 '15 at 23:05

0 Answers0