I am trying to convert ISO to datetime
using the code below:
dt = datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00", "%Y-%m-%dT%H:%M:%S.%f%z")
and I'm getting the error below:
'z' is a bad directive in format '%Y-%m-%dT%H:%M:%S.%f%z'
What is the best way to convert an ISO string of above the format to a datetime
object? I'm using Python version 2.7.6.
This string is converted into an ISO format string by using the . strftime() method. Here as we know that ISO format is YYYY-MM-DD so we convert it into this format by using the following format code- “%Y-%m-%dT%H:%M:%S. %f%z”.
strptime is short for "parse time" where strftime is for "formatting time". That is, strptime is the opposite of strftime though they use, conveniently, the same formatting specification.
We can convert a string to datetime using strptime() function. This function is available in datetime and time modules to parse a string to datetime and time objects respectively.
Welcome to Python datetime! Dealing with dates and times is necessarily complex, and Python doesn't come fully with batteries included in this case. You can't use %z
in strptime
because Python has no classes to represent timezones (you are supposed to implement your own, or better yet include some other libraries).
You want to use pytz
and python-dateutil
. For more details see here:
Python strptime() and timezones?
I have had a similar problem parsing commit dates from the output of git log --date=iso8601
which actually isn't the ISO8601 format (hence the addition of --date=iso8601-strict
in a later version).
>>> import datetime, sys >>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00", "%Y-%m-%dT%H:%M:%S.%f%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-%dT%H:%M:%S.%f%z' >>> sys.version '2.7.10 (default, Feb 7 2017, 00:08:15) \n[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]'
If python 2 does not support %z
because of the underlying strptime()
implementation, then a possible way to fix your issue is to migrate to python 3. But it didn't work for me:
>>> import datetime, sys >>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00", "%Y-%m-%dT%H:%M:%S.%f%z") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_strptime.py", line 565, in _strptime_datetime tt, fraction = _strptime(data_string, format) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_strptime.py", line 362, in _strptime (data_string, format)) ValueError: time data '2013-07-23T15:10:59.342107+01:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z' >>> sys.version '3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) \n[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]'
The problem is because is not strictly ISO8601 (note how there was a :
in the timezone info).
>>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+0100", "%Y-%m-%dT%H:%M:%S.%f%z") datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=datetime.timezone(datetime.timedelta(0, 3600)))
Since I am using django
I can leverage the utilities there.
https://github.com/django/django/blob/master/django/utils/dateparse.py
>>> from django.utils.dateparse import parse_datetime >>> parse_datetime('2013-07-23T15:10:59.342107+01:00') datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100)
Instead of strptime
you could use your own regular expression.
Please note that django does use pytz
under the hood for things like the utc
singleton.
If you want a quick and dirty solution, you can use something similar to django
without all the requirements.
https://gist.github.com/dnozay/3cd554a818ed768bff804bc04484905d
>>> from datetime_z import parse_datetime >>> parse_datetime("2013-07-23T15:10:59.342107+01:00") datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100)
Please note: YMMV, there is no support.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With