This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Calculate timestamp is wrong in datetime.datetime
Type: behavior Stage: resolved
Components: Extension Modules Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: belopolsky, dh4931, lemburg, p-ganssle, serhiy.storchaka, xtreak
Priority: normal Keywords:

Created on 2020-07-17 09:20 by dh4931, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg373805 - (view) Author: (dh4931) Date: 2020-07-17 09:20
like so
datetime.datetime(1986, 5, 4, 7, 13, 22).timestamp() - datetime.datetime(1986, 5, 4, 0, 0, 0).timestamp()
the result is 22402.0, the result is wrong.
but on May 2nd
datetime.datetime(1986, 5, 2, 7, 13, 22).timestamp() - datetime.datetime(1986, 5, 2, 0, 0, 0).timestamp()
the result is 26002.0, the result is true
msg373808 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2020-07-17 09:52
I cannot reproduce the report on 3.8 and master. Both of the instances return 26002 which is 7 hours, 13 minutes and 22 seconds. Can you please attach a script that I can run to reproduce the difference?

python3
Python 3.8.0 (v3.8.0:fa919fdf25, Oct 14 2019, 10:23:27)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> datetime.datetime(1986, 5, 4, 7, 13, 22).timestamp() - datetime.datetime(1986, 5, 4, 0, 0, 0).timestamp()
26002.0
>>> datetime.datetime(1986, 5, 2, 7, 13, 22).timestamp() - datetime.datetime(1986, 5, 2, 0, 0, 0).timestamp()
26002.0
msg373818 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-07-17 11:03
It depends on timezone. I guess there was a switch to daylight saving time at that time and place.
msg373830 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2020-07-17 12:16
Serhiy, you are right. I wrote below script that could explain the difference.

# ../backups/bpo41321.py
import datetime
import zoneinfo

for tz in zoneinfo.available_timezones():
    diff = datetime.datetime(1986, 5, 4, 7, 13, 22, tzinfo=zoneinfo.ZoneInfo(tz)).timestamp() - datetime.datetime(1986, 5, 4, 0, 0, 0, tzinfo=zoneinfo.ZoneInfo(tz)).timestamp()
    if diff != 26002:
        print(diff, tz)

for tz in zoneinfo.available_timezones():
    diff = datetime.datetime(1986, 5, 2, 7, 13, 22, tzinfo=zoneinfo.ZoneInfo(tz)).timestamp() - datetime.datetime(1986, 5, 2, 0, 0, 0, tzinfo=zoneinfo.ZoneInfo(tz)).timestamp()
    if diff != 26002:
        print("Diff using second day", diff, tz)

$ ./python ../backups/bpo41321.py
22402.0 Asia/Harbin
22402.0 Asia/Shanghai
22402.0 PRC
22402.0 Asia/Chongqing
22402.0 Asia/Chungking
msg374016 - (view) Author: Paul Ganssle (p-ganssle) * (Python committer) Date: 2020-07-20 17:09
Hi dh4931 — this is the expected result, assuming that the offsets changed between those two dates in your system local time.

The .timestamp() method returns an epoch time, which is the number of seconds since 1970-01-01T00:00:00 UTC, and so it is inherently timezone-aware. In Python 3, naïve datetimes went from being "unitless datetimes" to representing "local datetimes", and in certain situations (like calling `.timestamp()`), your system's time zone is used.

If you want something that gives the number of seconds that has elapsed between two naïve datetimes on the calendar and ignoring any daylight saving time transitions, subtract them directly to get a timedelta, then divide the result by a timedelta representing 1 second, like so:

    >>> (datetime.datetime(1986, 5, 4, 7, 13, 22) - datetime.datetime(1986, 5, 4, 0, 0, 0)) / datetime.timedelta(seconds=1)
    26002.0


    >>> (datetime.datetime(1986, 5, 2, 7, 13, 22) - datetime.datetime(1986, 5, 2, 0, 0, 0)) / datetime.timedelta(seconds=1)
    26002.0
History
Date User Action Args
2022-04-11 14:59:33adminsetgithub: 85493
2020-07-20 20:00:24SilentGhostsetstatus: open -> closed
2020-07-20 17:09:04p-gansslesettype: behavior
resolution: not a bug
messages: + msg374016
stage: resolved
2020-07-17 12:16:23xtreaksetmessages: + msg373830
2020-07-17 11:03:24serhiy.storchakasetnosy: + belopolsky, serhiy.storchaka, lemburg, p-ganssle
messages: + msg373818
2020-07-17 09:52:25xtreaksetnosy: + xtreak
messages: + msg373808
2020-07-17 09:20:57dh4931create