Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Fix calculation of epoch that is not taking into account the timezone #45

Merged
merged 1 commit into from
Oct 28, 2021

Conversation

c00kiemon5ter
Copy link
Member

The problem is that datetime(1970, 1, 1) does not include a timezone component and it is assumed to be a local date.

>>> import datetime
>>> bad = datetime.datetime(1970, 1, 1)
>>> bad
datetime.datetime(1970, 1, 1, 0, 0)
>>> bad.astimezone(datetime.timezone.utc)
datetime.datetime(1969, 12, 31, 22, 0, tzinfo=datetime.timezone.utc)

The reason for this is because my localtime is not UTC, but "Europe/Athens".
If my timezone was UTC, then this would look as expected:

$ cat /etc/timezone 
UTC

$ python3
>>> import datetime
>>> happens_to_be_correct = datetime.datetime(1970, 1, 1)
>>> happens_to_be_correct
datetime.datetime(1970, 1, 1, 0, 0)
>>> happens_to_be_correct.astimezone(datetime.timezone.utc)
datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)

The right thing to do is to have an explicit timezone component on the date object

>>> better = datetime.datetime(1970, 1, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=datetime.timezone.utc)
>>> better
datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
>>> better.astimezone(datetime.timezone.utc)
datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)

Calculations against that object would yield correct results.


However, it is not needed to do such a calculation "by hand", as the standard library provides the tools to convert a datetime object to a timestamp

>>> import datetime
>>> better = datetime.datetime(1970, 1, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=datetime.timezone.utc)
>>> better.timestamp()
0.0
>>> dt = datetime.datetime.utcnow()
>>> dt
datetime.datetime(2021, 10, 27, 19, 5, 50, 776761)
>>> dt.timestamp()
1635350750.776761

So, instead of calculating the timestamp by creating a delta between two dates (which must be on the same timezone) and converting the result to seconds, we can just get the timestamp by calling .timestamp() on the datetime object. The timestamp will be relative to the datetime object timezone, which we must ensure is always on UTC.

Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
@rohe rohe merged commit cf687d7 into develop Oct 28, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants