How to parse datetime that ends with `Z`?
Question:
I have the following datetime string s
:
2017-10-18T04:46:53.553472514Z
I parese it like that:
t = datetime.strptime(s, '%Y-%m-%dT%H:%M:%SZ')
how to fix ValueError: time data '2017-10-18T04:46:53.553472514Z'
does not match format '%Y-%m-%dT%H:%M:%SZ'
Answers:
I think you should use dateutil.parser module
In [23]: s = "2017-10-18T04:46:53.553472514Z"
In [24]: import dateutil.parser as p
In [25]: p.parse(s)
Out[25]: datetime.datetime(2017, 10, 18, 4, 46, 53, 553472, tzinfo=tzutc())
In theory,
t = datetime.strptime(s, '%Y-%m-%dT%H:%M:%S.%fZ')
would be the correct format string as you have fractions of second as well. BUT they would then need to be microseconds. Yours are probably nanoseconds, as %f
only takes maximum of 6 digits.
So you need to do something like this:
t = datetime.datetime.strptime(s.split(".")[0], '%Y-%m-%dT%H:%M:%S')
t = t + datetime.timedelta(microseconds=int(s.split(".")[1][:-1])/1000)
print (t)
This works but it converts nanoseconds to microseconds. If this is not ok, then you need to do something else.
datetime
is another Python built-in module that is completely superseded by a better extra module: arrow
.
You can just do:
import arrow
dt = arrow.get('2017-10-18T04:46:53.553472514Z').datetime
Your date string being in standardized ISO format, it will be parsed without even giving a format string. The parsed df
will be:
datetime.datetime(2017, 10, 18, 4, 46, 53, 553472, tzinfo=tzutc())
Or keep the Arrow
object in case you want to keep the extra precision
I like the mx.DateTime module.
import mx.DateTime as dt
dt.DateTimeFrom('2017-10-18T04:46:53.553472514Z')
As @FObersteiner pointed out, %z
parses Z
as well as ±HHMM[SS[.ffffff]]
style of timezone encoding.
This information is hidden in the technical detail #6. :-/
Previous incorrect answer:
To answer the original question: there’s no way to parse "Z" as the timezone using only the standard library.~
Here’s some discussion on that: https://bugs.python.org/issue35829
I have the following datetime string s
:
2017-10-18T04:46:53.553472514Z
I parese it like that:
t = datetime.strptime(s, '%Y-%m-%dT%H:%M:%SZ')
how to fix ValueError: time data '2017-10-18T04:46:53.553472514Z'
does not match format '%Y-%m-%dT%H:%M:%SZ'
I think you should use dateutil.parser module
In [23]: s = "2017-10-18T04:46:53.553472514Z"
In [24]: import dateutil.parser as p
In [25]: p.parse(s)
Out[25]: datetime.datetime(2017, 10, 18, 4, 46, 53, 553472, tzinfo=tzutc())
In theory,
t = datetime.strptime(s, '%Y-%m-%dT%H:%M:%S.%fZ')
would be the correct format string as you have fractions of second as well. BUT they would then need to be microseconds. Yours are probably nanoseconds, as %f
only takes maximum of 6 digits.
So you need to do something like this:
t = datetime.datetime.strptime(s.split(".")[0], '%Y-%m-%dT%H:%M:%S')
t = t + datetime.timedelta(microseconds=int(s.split(".")[1][:-1])/1000)
print (t)
This works but it converts nanoseconds to microseconds. If this is not ok, then you need to do something else.
datetime
is another Python built-in module that is completely superseded by a better extra module: arrow
.
You can just do:
import arrow
dt = arrow.get('2017-10-18T04:46:53.553472514Z').datetime
Your date string being in standardized ISO format, it will be parsed without even giving a format string. The parsed df
will be:
datetime.datetime(2017, 10, 18, 4, 46, 53, 553472, tzinfo=tzutc())
Or keep the Arrow
object in case you want to keep the extra precision
I like the mx.DateTime module.
import mx.DateTime as dt
dt.DateTimeFrom('2017-10-18T04:46:53.553472514Z')
As @FObersteiner pointed out, %z
parses Z
as well as ±HHMM[SS[.ffffff]]
style of timezone encoding.
This information is hidden in the technical detail #6. :-/
Previous incorrect answer:
To answer the original question: there’s no way to parse "Z" as the timezone using only the standard library.~
Here’s some discussion on that: https://bugs.python.org/issue35829