From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Mar 2026 08:45:07 +0000 (+0200) Subject: gh-145731: Fix negative timestamp during DST on Windows (GH-145728) X-Git-Tag: v3.15.0a7~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=170d85a37deb77a1711ab86288a33fda5c0a381a;p=thirdparty%2FPython%2Fcpython.git gh-145731: Fix negative timestamp during DST on Windows (GH-145728) --- 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 index 000000000000..676a68e5a912 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst @@ -0,0 +1 @@ +Fix negative timestamp during DST on Windows. Patch by Hugo van Kemenade. diff --git a/Python/pytime.c b/Python/pytime.c index 2b1488911ef9..399ff59ad01a 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -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 */