diff -r 1c486516b39e Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c Thu Dec 29 23:57:31 2016 -0700 +++ b/Modules/_datetimemodule.c Fri Dec 30 06:05:47 2016 -0500 @@ -4251,6 +4251,7 @@ PyObject *tzinfo) { struct tm tm; + time_t fold_detection_time; int year, month, day, hour, minute, second, fold = 0; if (f(timet, &tm) != 0) @@ -4274,13 +4275,32 @@ result_seconds = utc_to_seconds(year, month, day, hour, minute, second); - /* Probe max_fold_seconds to detect a fold. */ - probe_seconds = local(epoch + timet - max_fold_seconds); + fold_detection_time = epoch + timet - max_fold_seconds; +#ifdef MS_WINDOWS + /* On Windows, passing a negative value to local results + * in an OSError because localtime_s on Windows does + * not support negative timestamps. Unfortunately this + * means that fold detection for time values between + * 0 and max_fold_seconds will result in an identical + * error since we subtract max_fold_seconds to detect a + * fold. However, since we know there haven't been any + * folds in the interval [0, max_fold_seconds) in any + * timezone, we can hackily just truncate negative values + * on Windows. */ + if (fold_detection_time - epoch < 0) + fold_detection_time = epoch; +#endif + probe_seconds = local(fold_detection_time); if (probe_seconds == -1) return NULL; transition = result_seconds - probe_seconds - max_fold_seconds; if (transition < 0) { - probe_seconds = local(epoch + timet + transition); + fold_detection_time = epoch + timet + transition; +#ifdef MS_WINDOWS + if (fold_detection_time - epoch < 0) + fold_detection_time = epoch + 1; +#endif + probe_seconds = local(fold_detection_time); if (probe_seconds == -1) return NULL; if (probe_seconds == result_seconds)