Found this issues working with timestamp conversions where the .timestamp()
seem to compensate for time offset even though I created the datetime object with utcnow()
method. So what is the reason for the utcnow()
method if it actually fails when converting to timestamp later on?
def test_timestamp_issues():
now = datetime.now()
utc_now = datetime.utcnow()
utc_now_with_tz = datetime.now(timezone.utc)
print(f"Now: {now} -- As Timestamp: {now.timestamp()}")
print(f"Utc Now: {utc_now} -- As TimeStamp: {utc_now.timestamp()} "
f"with builtin: {datetime.timestamp(utc_now)}, with setting timezone hard: "
f"{utc_now.replace(tzinfo=timezone.utc).timestamp()}")
print(f"Utc Now: {utc_now_with_tz} -- As TimeStamp: {utc_now_with_tz.timestamp()} "
f"with builtin: {datetime.timestamp(utc_now_with_tz)}, with setting timezone hard: "
f"{utc_now_with_tz.replace(tzinfo=timezone.utc).timestamp()}")
Output:
Now: 2022-04-25 09:12:16.881608 -- As Timestamp: 1650870736.881608
Utc Now: 2022-04-25 07:12:16.881613 -- As TimeStamp: 1650863536.881613 with builtin: 1650863536.881613, with setting timezone hard: 1650870736.881613
Utc Now: 2022-04-25 07:12:16.881753 00:00 -- As TimeStamp: 1650870736.881753 with builtin: 1650870736.881753, with setting timezone hard: 1650870736.881753
The expected timestamp here should be 1650870736.881608 but for some reason converting the utcnow() gives 2 hours backward again.
So for some reason I get another 2 hours withdrawal when taking timestamp of a utcnow()
created datetime object. I am currently running a macbook m1 pro, with Timezone Norway ( 1, 2 atm with daylight), and python 3.9.12
So can this be the arm architecture messing up things or is it just not recommended to use the utcnow()
and then convert to timestamp?
CodePudding user response:
The answer to your question is managing timezones (TZ). When you create a datetime
instance with now()
or utcnow()
, it does not store info about TZ. And, according to python docs for utcnow()
(bolding by author):
Return the current UTC date and time, with
tzinfo
None.This is like
now()
, but returns the current UTC date and time, as a naivedatetime
object. An aware current UTC datetime can be obtained by callingdatetime.now(timezone.utc)
. See alsonow()
.Warning: Because naive
datetime
objects are treated by many datetime 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)
.
This means that, although you received time for UTC TZ with utcnow()
, since no TZ info is stored (naive datetime
object), python thinks of it as a local time. And, when converting it to timestamp, will add/subtract time difference once again. Proof for this weird behaviour may be found in python docs for timestamp()
method:
Naive
datetime
instances are assumed to represent local time
The reason actually is the one, you stated in the title of the question, not the ARM architecture