Skip to content

Commit 170d85a

Browse files
authored
gh-145731: Fix negative timestamp during DST on Windows (GH-145728)
1 parent 66eafc9 commit 170d85a

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix negative timestamp during DST on Windows. Patch by Hugo van Kemenade.

Python/pytime.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -320,23 +320,27 @@ _PyTime_windows_filetime(time_t timer, struct tm *tm, int is_local)
320320
ft.dwLowDateTime = (DWORD)(ticks); // cast to DWORD truncates to low 32 bits
321321
ft.dwHighDateTime = (DWORD)(ticks >> 32);
322322

323-
/* Convert FILETIME to SYSTEMTIME */
323+
/* Convert FILETIME to SYSTEMTIME (UTC) */
324+
SYSTEMTIME st_utc;
325+
if (!FileTimeToSystemTime(&ft, &st_utc)) {
326+
PyErr_SetFromWindowsErr(0);
327+
return -1;
328+
}
329+
324330
SYSTEMTIME st_result;
325331
if (is_local) {
326-
/* Convert to local time */
327-
FILETIME ft_local;
328-
if (!FileTimeToLocalFileTime(&ft, &ft_local) ||
329-
!FileTimeToSystemTime(&ft_local, &st_result)) {
332+
/* Convert UTC SYSTEMTIME to local SYSTEMTIME.
333+
* We use SystemTimeToTzSpecificLocalTime instead of
334+
* FileTimeToLocalFileTime because the latter always applies the
335+
* _current_ DST bias, whereas the former applies the correct
336+
* DST rules for the date being converted (gh-80620). */
337+
if (!SystemTimeToTzSpecificLocalTime(NULL, &st_utc, &st_result)) {
330338
PyErr_SetFromWindowsErr(0);
331339
return -1;
332340
}
333341
}
334342
else {
335-
/* Convert to UTC */
336-
if (!FileTimeToSystemTime(&ft, &st_result)) {
337-
PyErr_SetFromWindowsErr(0);
338-
return -1;
339-
}
343+
st_result = st_utc;
340344
}
341345

342346
/* Convert SYSTEMTIME to struct tm */

0 commit comments

Comments
 (0)