commit f6d4c1ac648c4ff8baad94500df0bb13108a4f79 Author: Paul Eggert Date: Thu Sep 8 20:08:32 2022 -0500 REVERT: mktime: improve heuristic for ca-1986 Indiana DST This patch syncs mktime.c from Gnulib, fixing a problem reported by Mark Krenz , and it should fix BZ#29035 too. * time/mktime.c (__mktime_internal): Be more generous about accepting arguments with the wrong value of tm_isdst, by falling back to a one-hour DST difference if we find no nearby DST that is unusual. This fixes a problem where "1986-04-28 00:00 EDT" was rejected when TZ="America/Indianapolis" because the nearest DST timestamp occurred in 1970, a temporal distance too great for the old heuristic. This also also narrows the search a bit, which is a minor performance win. (cherry picked from commit 83859e1115269cf56d21669361d4ddbe2687831c) diff --git b/time/mktime.c a/time/mktime.c index e9a6006710..494c89bf54 100644 --- b/time/mktime.c +++ a/time/mktime.c @@ -429,13 +429,8 @@ __mktime_internal (struct tm *tp, time with the right value, and use its UTC offset. Heuristic: probe the adjacent timestamps in both directions, - looking for the desired isdst. If none is found within a - reasonable duration bound, assume a one-hour DST difference. - This should work for all real time zone histories in the tz - database. */ - - /* +1 if we wanted standard time but got DST, -1 if the reverse. */ - int dst_difference = (isdst == 0) - (tm.tm_isdst == 0); + looking for the desired isdst. This should work for all real + time zone histories in the tz database. */ /* Distance between probes when looking for a DST boundary. In tzdata2003a, the shortest period of DST is 601200 seconds @@ -446,14 +441,12 @@ __mktime_internal (struct tm *tp, periods when probing. */ int stride = 601200; - /* In TZDB 2021e, the longest period of DST (or of non-DST), in - which the DST (or adjacent DST) difference is not one hour, - is 457243209 seconds: e.g., America/Cambridge_Bay with leap - seconds, starting 1965-10-31 00:00 in a switch from - double-daylight time (-05) to standard time (-07), and - continuing to 1980-04-27 02:00 in a switch from standard time - (-07) to daylight time (-06). */ - int duration_max = 457243209; + /* The longest period of DST in tzdata2003a is 536454000 seconds + (e.g., America/Jujuy starting 1946-10-01 01:00). The longest + period of non-DST is much longer, but it makes no real sense + to search for more than a year of non-DST, so use the DST + max. */ + int duration_max = 536454000; /* Search in both directions, so the maximum distance is half the duration; add the stride to avoid off-by-1 problems. */ @@ -490,11 +483,6 @@ __mktime_internal (struct tm *tp, } } - /* No unusual DST offset was found nearby. Assume one-hour DST. */ - t += 60 * 60 * dst_difference; - if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm)) - goto offset_found; - __set_errno (EOVERFLOW); return -1; }