I am getting two different results in seconds when I parse the following time string:
Method 1:
from datetime import datetime
int(datetime.strptime('2015-03-25T19:46:23.286966Z', '%Y-%m-%dT%H:%M:%S.%fZ').timestamp())
yields 1427309183
Method 2:
from dateutil.parser import parse
int(parse('2015-03-25T19:46:23.286966Z').timestamp())
yields 1427312783
It seems that method 1 ignores the TZ vs method do (I run it from a UTC+1 tz).
Question: Why do these two methods yield different second timestamps? Can someone please explain what's going on under the hood and how to best handle such situations.
My goal is to convert the string to seconds in unix epoch time (i.e. utc).
If you take a look at the repr
of your intermediate result (the datetime objects), you notice a difference:
from datetime import datetime
from dateutil.parser import parse
print(repr(datetime.strptime('2015-03-25T19:46:23.286966Z', '%Y-%m-%dT%H:%M:%S.%fZ')))
# datetime.datetime(2015, 3, 25, 19, 46, 23, 286966)
print(repr(parse('2015-03-25T19:46:23.286966Z')))
# datetime.datetime(2015, 3, 25, 19, 46, 23, 286966, tzinfo=tzutc())
The first one is naive, no tzinfo set since you use a literal Z
in the parsing directive. The second one is aware; tzinfo is set to UTC since dateutil's parser recognizes the Z
to signal UTC. That makes for the difference in the timestamp, since Python treats naive datetime as local time - thus the difference of 1 hour, which is your local time's UTC offset.
You can correctly parse like
print(repr(datetime.fromisoformat('2015-03-25T19:46:23.286966Z'.replace('Z', '+00:00'))))
# datetime.datetime(2015, 3, 25, 19, 46, 23, 286966, tzinfo=datetime.timezone.utc)
see also here.
Or less convenient (imho), with strptime
:
print(repr(datetime.strptime('2015-03-25T19:46:23.286966Z', '%Y-%m-%dT%H:%M:%S.%f%z')))
# datetime.datetime(2015, 3, 25, 19, 46, 23, 286966, tzinfo=datetime.timezone.utc)