diff options
Diffstat (limited to 'gl/mktime.c')
| -rw-r--r-- | gl/mktime.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/gl/mktime.c b/gl/mktime.c index ae721c72..7dc9d67e 100644 --- a/gl/mktime.c +++ b/gl/mktime.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert a 'struct tm' to a time_t value. | 1 | /* Convert a 'struct tm' to a time_t value. |
| 2 | Copyright (C) 1993-2021 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-2022 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Paul Eggert <eggert@twinsun.com>. | 4 | Contributed by Paul Eggert <eggert@twinsun.com>. |
| 5 | 5 | ||
| @@ -429,8 +429,13 @@ __mktime_internal (struct tm *tp, | |||
| 429 | time with the right value, and use its UTC offset. | 429 | time with the right value, and use its UTC offset. |
| 430 | 430 | ||
| 431 | Heuristic: probe the adjacent timestamps in both directions, | 431 | Heuristic: probe the adjacent timestamps in both directions, |
| 432 | looking for the desired isdst. This should work for all real | 432 | looking for the desired isdst. If none is found within a |
| 433 | time zone histories in the tz database. */ | 433 | reasonable duration bound, assume a one-hour DST difference. |
| 434 | This should work for all real time zone histories in the tz | ||
| 435 | database. */ | ||
| 436 | |||
| 437 | /* +1 if we wanted standard time but got DST, -1 if the reverse. */ | ||
| 438 | int dst_difference = (isdst == 0) - (tm.tm_isdst == 0); | ||
| 434 | 439 | ||
| 435 | /* Distance between probes when looking for a DST boundary. In | 440 | /* Distance between probes when looking for a DST boundary. In |
| 436 | tzdata2003a, the shortest period of DST is 601200 seconds | 441 | tzdata2003a, the shortest period of DST is 601200 seconds |
| @@ -441,12 +446,14 @@ __mktime_internal (struct tm *tp, | |||
| 441 | periods when probing. */ | 446 | periods when probing. */ |
| 442 | int stride = 601200; | 447 | int stride = 601200; |
| 443 | 448 | ||
| 444 | /* The longest period of DST in tzdata2003a is 536454000 seconds | 449 | /* In TZDB 2021e, the longest period of DST (or of non-DST), in |
| 445 | (e.g., America/Jujuy starting 1946-10-01 01:00). The longest | 450 | which the DST (or adjacent DST) difference is not one hour, |
| 446 | period of non-DST is much longer, but it makes no real sense | 451 | is 457243209 seconds: e.g., America/Cambridge_Bay with leap |
| 447 | to search for more than a year of non-DST, so use the DST | 452 | seconds, starting 1965-10-31 00:00 in a switch from |
| 448 | max. */ | 453 | double-daylight time (-05) to standard time (-07), and |
| 449 | int duration_max = 536454000; | 454 | continuing to 1980-04-27 02:00 in a switch from standard time |
| 455 | (-07) to daylight time (-06). */ | ||
| 456 | int duration_max = 457243209; | ||
| 450 | 457 | ||
| 451 | /* Search in both directions, so the maximum distance is half | 458 | /* Search in both directions, so the maximum distance is half |
| 452 | the duration; add the stride to avoid off-by-1 problems. */ | 459 | the duration; add the stride to avoid off-by-1 problems. */ |
| @@ -483,6 +490,11 @@ __mktime_internal (struct tm *tp, | |||
| 483 | } | 490 | } |
| 484 | } | 491 | } |
| 485 | 492 | ||
| 493 | /* No unusual DST offset was found nearby. Assume one-hour DST. */ | ||
| 494 | t += 60 * 60 * dst_difference; | ||
| 495 | if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm)) | ||
| 496 | goto offset_found; | ||
| 497 | |||
| 486 | __set_errno (EOVERFLOW); | 498 | __set_errno (EOVERFLOW); |
| 487 | return -1; | 499 | return -1; |
| 488 | } | 500 | } |
