]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-145731: Fix negative timestamp during DST on Windows (GH-145728)
authorHugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Tue, 10 Mar 2026 08:45:07 +0000 (10:45 +0200)
committerGitHub <noreply@github.com>
Tue, 10 Mar 2026 08:45:07 +0000 (09:45 +0100)
Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst [new file with mode: 0644]
Python/pytime.c

diff --git a/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst b/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst
new file mode 100644 (file)
index 0000000..676a68e
--- /dev/null
@@ -0,0 +1 @@
+Fix negative timestamp during DST on Windows. Patch by Hugo van Kemenade.
index 2b1488911ef97b1e1bad8b2a286a4d7c233d6071..399ff59ad01ab6940af4fa31b185d855e1942ac8 100644 (file)
@@ -320,23 +320,27 @@ _PyTime_windows_filetime(time_t timer, struct tm *tm, int is_local)
     ft.dwLowDateTime = (DWORD)(ticks); // cast to DWORD truncates to low 32 bits
     ft.dwHighDateTime = (DWORD)(ticks >> 32);
 
-    /* Convert FILETIME to SYSTEMTIME */
+    /* Convert FILETIME to SYSTEMTIME (UTC) */
+    SYSTEMTIME st_utc;
+    if (!FileTimeToSystemTime(&ft, &st_utc)) {
+        PyErr_SetFromWindowsErr(0);
+        return -1;
+    }
+
     SYSTEMTIME st_result;
     if (is_local) {
-        /* Convert to local time */
-        FILETIME ft_local;
-        if (!FileTimeToLocalFileTime(&ft, &ft_local) ||
-            !FileTimeToSystemTime(&ft_local, &st_result)) {
+        /* Convert UTC SYSTEMTIME to local SYSTEMTIME.
+         * We use SystemTimeToTzSpecificLocalTime instead of
+         * FileTimeToLocalFileTime because the latter always applies the
+         * _current_ DST bias, whereas the former applies the correct
+         * DST rules for the date being converted (gh-80620). */
+        if (!SystemTimeToTzSpecificLocalTime(NULL, &st_utc, &st_result)) {
             PyErr_SetFromWindowsErr(0);
             return -1;
         }
     }
     else {
-        /* Convert to UTC */
-        if (!FileTimeToSystemTime(&ft, &st_result)) {
-            PyErr_SetFromWindowsErr(0);
-            return -1;
-        }
+        st_result = st_utc;
     }
 
     /* Convert SYSTEMTIME to struct tm */