Reputation: 491
I'm working with datetime and find it difficult to understand how timestamp() works, I (in east coast) want to transform the datetime into timestamp, but I found following difference. Can anyone shed somelight how each of the two code works, are they suppose to act differently (roughly a difference of four hours)?
import datetime
datetime.datetime.utcnow().timestamp()
#1590436949.187297
datetime.datetime.now(tz=datetime.timezone.utc).timestamp()
#1590422553.042119
Upvotes: 5
Views: 5062
Reputation: 25564
The timestamp()
method returns a POSIX timestamp / seconds since the epoch (1970-01-01) which always refers to UTC.
The Problem: if you call the timestamp()
method on a naïve datetime object, Python will assume that the datetime object holds local time.
Although the utcnow()
in datetime.datetime.utcnow()
might suggest otherwise, it gives you a naïve datetime object. That is, it does not "know" it's in UTC. Therefore, if you call the timestamp()
method, Python assumes that the datetime object passed to the function is local time and calculates the timestamp as such. It is then not what you would get from time.time()
.
On the other hand, in datetime.datetime.now(tz=datetime.timezone.utc).timestamp()
, you pass a timezone-aware datetime object to timestamp()
. That is correct in the sense that it gives you time.time()
.
Illustration:
import datetime
import time
import dateutil
localtzname = time.tzname[time.daylight]
# naive:
dt_now = datetime.datetime.now()
# timezone-aware:
dt_now_loc = datetime.datetime.now(dateutil.tz.gettz(localtzname))
dt_now_utc = datetime.datetime.now(tz=datetime.timezone.utc)
# reference:
ts = time.time()
print(dt_now.timestamp())
# 1590424623.226529
print(dt_now_loc.timestamp())
# 1590424623.226529
print(dt_now_utc.timestamp())
# 1590424623.226529
print(ts)
# 1590424623.2265291
As you can see, even though dt_now
is naïve, Python returns the same timestamp as you get from the localized dt_now_loc
or from time.time()
.
In summary, datetime.datetime.utcnow().timestamp()
can be pretty misleading and I would recommend avoiding it.
Upvotes: 5