Iso to Datetime Object: 'Z' Is a Bad Directive

Python Datetime Strptime Error: '-' is a bad directive in format '%-m-%-d-%y %-H:%M:%S'

%-* -- to skip padding -- is a GNU libc extension. It's not part of POSIX strftime, and thus not guaranteed to be portable to systems where your time-formatting calls aren't eventually backed by GNU's strftime C library function.

The Python datetime module documentation explicitly specifies the format strings it supports, and this extension is not given. Thus, while this is supported in GNU date and GNU strftime(), it isn't available in Python datetime.

How do I translate an ISO 8601 datetime string into a Python datetime object?

I prefer using the dateutil library for timezone handling and generally solid date parsing. If you were to get an ISO 8601 string like: 2010-05-08T23:41:54.000Z you'd have a fun time parsing that with strptime, especially if you didn't know up front whether or not the timezone was included. pyiso8601 has a couple of issues (check their tracker) that I ran into during my usage and it hasn't been updated in a few years. dateutil, by contrast, has been active and worked for me:

from dateutil import parser
yourdate = parser.parse(datestring)

Python3 parsing datetime in format 2018-01-14T23:55:27.337Z

Try doing this.

datetime.strptime('2018-01-14T23:55:27.337Z', '%Y-%m-%dT%H:%M:%S.%fZ')

Take note at the second argument. It's '%Y-%m-%dT%H:%M:%S.%fZ' and not '%Y-%m-%dT%H:%M:%S.%3N%Z'. You are getting a bad directive value error because %3 is not a directive.

In case you need it, here's the documentation for strptime().

How to convert this date string into a datetime date object?

%Z is the wrong directive here.

Try this

datetime.strptime('2013-11-05T20:24:51+0000', '%Y-%m-%dT%H:%M:%S+%f')

More here

Demo:

>>> from datetime import datetime
>>> datetime.strptime('2013-11-05T20:24:51+0000', '%Y-%m-%dT%H:%M:%S%Z')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data '2013-11-05T20:24:51+0000' does not match format '%Y-%m-%dT%H:%M:%S%Z'
>>> datetime.strptime('2013-11-05T20:24:51+0000', '%Y-%m-%dT%H:%M:%S+%f')
datetime.datetime(2013, 11, 5, 20, 24, 51)

Convert timestamps with offset to datetime obj using strptime

The Python 2 strptime() function indeed does not support the %z format for timezones (because the underlying time.strptime() function doesn't support it). You have two options:

  • Ignore the timezone when parsing with strptime:

    time_obj = datetime.datetime.strptime(time_str[:19], '%Y-%m-%dT%H:%M:%S')
  • use the dateutil module, it's parse function does deal with timezones:

    from dateutil.parser import parse
    time_obj = parse(time_str)

Quick demo on the command prompt:

>>> from dateutil.parser import parse
>>> parse("2012-07-24T23:14:29-07:00")
datetime.datetime(2012, 7, 24, 23, 14, 29, tzinfo=tzoffset(None, -25200))

You could also upgrade to Python 3.2 or newer, where timezone support has been improved to the point that %z would work, provided you remove the last : from the input, and the - from before the %z:

>>> import datetime
>>> time_str = "2012-07-24T23:14:29-07:00"
>>> datetime.datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S%z')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python3.4/_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '2012-07-24T23:14:29-07:00' does not match format '%Y-%m-%dT%H:%M:%S%z'
>>> ''.join(time_str.rsplit(':', 1))
'2012-07-24T23:14:29-0700'
>>> datetime.datetime.strptime(''.join(time_str.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S%z')
datetime.datetime(2012, 7, 24, 23, 14, 29, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))


Related Topics



Leave a reply



Submit