Reputation: 21
When I print the unix epoch, with something like time.time()
it seems to print the timestamp in my local timezone. Especially from what converters like: https://www.epochconverter.com tell me.
Does anyone know how I can print the UNIX Epoch/timestamp but actually in UTC time? Thank you so much.
Upvotes: 1
Views: 3690
Reputation: 522081
There's no such thing as "UTC UNIX Epoch time". There's UNIX Epoch time, period. It's the same all over the world. It is timezone independent. As long as your computer's clock is set correctly, time.time()
will give you the correct UNIX epoch time. datetime.datetime.now().timestamp()
will give you the same UNIX Epoch time. You don't need to convert anything and there's nothing to convert.
Now, to address the comment by Deepak, which I think is important:
I do get different responses for
datetime.now()
vsdatetime.utcnow()
corresponding to my local time vs UTC. Accordingly, the seconds elapsed has a difference of 19800s (+5:30 for my time zone) for me.
This is a known pitfall with datetime.utcnow
and is in fact addressed in the manual:
Warning: Because naive
datetime
objects are treated by manydatetime
methods as local times, it is preferred to use aware datetimes to represent times in UTC. As such, the recommended way to create an object representing the current time in UTC is by callingdatetime.now(timezone.utc)
.
To unpack this a bit:
When you call datetime.now()
, it returns you a naïve datetime
object (meaning it has no tzinfo
timezone attached) for your current local time:
>>> datetime.now()
datetime.datetime(2021, 4, 16, 9, 50, 3, 571235)
The time represents my current wall clock time, but it does not know what timezone it's in. So this timestamp could really represent about two dozen different absolute timestamps on this planet, depending on what timezone you take it as.
When using this object's timestamp()
method to convert it to an absolute UNIX timestamp, some timezone must be assumed. Python will assume your computer's local timezone for the conversion. Which is fine for datetime.now()
, because this timestamp was created with my local time anyway:
>>> datetime.now().timestamp()
1618559403.571235
This is the correct UNIX timestamp at the time of writing. Not "for my local timezone", but globally. At the time of writing, it's 1618559403
everywhere in the world.
Now, if you use datetime.utcnow()
, it will give you a naïve timestamp for the current UTC time:
>>> datetime.utcnow()
datetime.datetime(2021, 4, 16, 7, 50, 3, 571235)
Note how it's off by 2 hours from the previous datetime.now()
, which is fine, because that's the current local time in the UTC timezone. But since this timestamp is still naïve, when converting it to a UNIX timestamp, Python must assume some timezone, and will assume my local timezone. So it's giving me the UNIX timestamp for 7:50:03 of my local time:
>>> datetime.utcnow().timestamp()
1618552203.571235
Which is not the current UNIX time. It's off by two hours. It's the UNIX time of two hours ago.
If we'd do this properly, by creating an aware timestamp and taking its UNIX time, we'd get the correct UNIX time:
>>> datetime.now(timezone.utc)
datetime.datetime(2021, 4, 16, 7, 50, 3, 571235, tzinfo=datetime.timezone.utc)
>>> datetime.now(timezone.utc).timestamp()
1618559403.571235
Note how the human readable time is the same as we got for datetime.utcnow()
, but the UNIX timestamp is correctly the one we got for datetime.now().timestamp()
. Which is also the same as we'd get for time.time()
:
>>> from time import time
>>> time()
1618559403.571235
When pasting this into https://www.epochconverter.com, which you reference:
GMT: Friday, 16 April 2021 07:50:03.571
Your time zone: Friday, 16 April 2021 09:50:03.571 GMT+02:00 DST
Which is correct. In UTC/GMT, this UNIX timestamp represents 7:50am, and in my local timezone it's 9:50am.
If we take the incorrect naïve datetime.utcnow()
timestamp 1618552203.571235
, the result is:
GMT: Friday, 16 April 2021 05:50:03.571
Your time zone: Friday, 16 April 2021 07:50:03.571 GMT+02:00 DST
Which is incorrect. That was 2 hours ago, not now.
Upvotes: 3