xappppp
xappppp

Reputation: 491

why datetime.now() and datetime.utcnow() return different timestamp

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

Answers (1)

FObersteiner
FObersteiner

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

Related Questions