1 /* Convert a 'struct tm' to a time_t value. 2 Copyright (C) 1993-2023 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 Contributed by Paul Eggert <eggert@twinsun.com>. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, see 18 <https://www.gnu.org/licenses/>. */ 19 20 /* The following macros influence what gets defined when this file is compiled: 21 22 Macro/expression Which gnulib module This compilation unit 23 should define 24 25 _LIBC (glibc proper) mktime 26 27 NEED_MKTIME_WORKING mktime rpl_mktime 28 || NEED_MKTIME_WINDOWS 29 30 NEED_MKTIME_INTERNAL mktime-internal mktime_internal 31 */ 32 33 #ifndef _LIBC 34 # include <libc-config.h> 35 #endif 36 37 /* Assume that leap seconds are possible, unless told otherwise. 38 If the host has a 'zic' command with a '-L leapsecondfilename' option, 39 then it supports leap seconds; otherwise it probably doesn't. */ 40 #ifndef LEAP_SECONDS_POSSIBLE 41 # define LEAP_SECONDS_POSSIBLE 1 42 #endif 43 44 #include <time.h> 45 46 #include <errno.h> 47 #include <limits.h> 48 #include <stdbool.h> 49 #include <stdckdint.h> 50 #include <stdlib.h> 51 #include <string.h> 52 53 #include <intprops.h> 54 #include <verify.h> 55 56 #ifndef NEED_MKTIME_INTERNAL 57 # define NEED_MKTIME_INTERNAL 0 58 #endif 59 #ifndef NEED_MKTIME_WINDOWS 60 # define NEED_MKTIME_WINDOWS 0 61 #endif 62 #ifndef NEED_MKTIME_WORKING 63 # define NEED_MKTIME_WORKING 0 64 #endif 65 66 #include "mktime-internal.h" 67 68 #if !defined _LIBC && (NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS) 69 static void 70 my_tzset (void) 71 { 72 # if NEED_MKTIME_WINDOWS 73 /* Rectify the value of the environment variable TZ. 74 There are four possible kinds of such values: 75 - Traditional US time zone names, e.g. "PST8PDT". Syntax: see 76 <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/tzset> 77 - Time zone names based on geography, that contain one or more 78 slashes, e.g. "Europe/Moscow". 79 - Time zone names based on geography, without slashes, e.g. 80 "Singapore". 81 - Time zone names that contain explicit DST rules. Syntax: see 82 <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03> 83 The Microsoft CRT understands only the first kind. It produces incorrect 84 results if the value of TZ is of the other kinds. 85 But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value 86 of the second kind for most geographies, or of the first kind in a few 87 other geographies. If it is of the second kind, neutralize it. For the 88 Microsoft CRT, an absent or empty TZ means the time zone that the user 89 has set in the Windows Control Panel. 90 If the value of TZ is of the third or fourth kind -- Cygwin programs 91 understand these syntaxes as well --, it does not matter whether we 92 neutralize it or not, since these values occur only when a Cygwin user 93 has set TZ explicitly; this case is 1. rare and 2. under the user's 94 responsibility. */ 95 const char *tz = getenv ("TZ"); 96 if (tz != NULL && strchr (tz, '/') != NULL) 97 _putenv ("TZ="); 98 # else 99 tzset (); 100 # endif 101 } 102 # undef __tzset 103 # define __tzset() my_tzset () 104 #endif 105 106 #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL 107 108 /* A signed type that can represent an integer number of years 109 multiplied by four times the number of seconds in a year. It is 110 needed when converting a tm_year value times the number of seconds 111 in a year. The factor of four comes because these products need 112 to be subtracted from each other, and sometimes with an offset 113 added to them, and then with another timestamp added, without 114 worrying about overflow. 115 116 Much of the code uses long_int to represent __time64_t values, to 117 lessen the hassle of dealing with platforms where __time64_t is 118 unsigned, and because long_int should suffice to represent all 119 __time64_t values that mktime can generate even on platforms where 120 __time64_t is wider than the int components of struct tm. */ 121 122 #if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60 123 typedef long int long_int; 124 #else 125 typedef long long int long_int; 126 #endif 127 verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60); 128 129 /* Shift A right by B bits portably, by dividing A by 2**B and 130 truncating towards minus infinity. B should be in the range 0 <= B 131 <= LONG_INT_BITS - 2, where LONG_INT_BITS is the number of useful 132 bits in a long_int. LONG_INT_BITS is at least 32. 133 134 ISO C99 says that A >> B is implementation-defined if A < 0. Some 135 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift 136 right in the usual way when A < 0, so SHR falls back on division if 137 ordinary A >> B doesn't seem to be the usual signed shift. */ 138 139 static long_int 140 shr (long_int a, int b) 141 { 142 long_int one = 1; 143 return (-one >> 1 == -1 144 ? a >> b 145 : (a + (a < 0)) / (one << b) - (a < 0)); 146 } 147 148 /* Bounds for the intersection of __time64_t and long_int. */ 149 150 static long_int const mktime_min 151 = ((TYPE_SIGNED (__time64_t) 152 && TYPE_MINIMUM (__time64_t) < TYPE_MINIMUM (long_int)) 153 ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (__time64_t)); 154 static long_int const mktime_max 155 = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t) 156 ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t)); 157 158 #define EPOCH_YEAR 1970 159 #define TM_YEAR_BASE 1900 160 verify (TM_YEAR_BASE % 100 == 0); 161 162 /* Is YEAR + TM_YEAR_BASE a leap year? */ 163 static bool 164 leapyear (long_int year) 165 { 166 /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. 167 Also, work even if YEAR is negative. */ 168 return 169 ((year & 3) == 0 170 && (year % 100 != 0 171 || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3))); 172 } 173 174 /* How many days come before each month (0-12). */ 175 #ifndef _LIBC 176 static 177 #endif 178 const unsigned short int __mon_yday[2][13] = 179 { 180 /* Normal years. */ 181 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 182 /* Leap years. */ 183 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 184 }; 185 186 187 /* Do the values A and B differ according to the rules for tm_isdst? 188 A and B differ if one is zero and the other positive. */ 189 static bool 190 isdst_differ (int a, int b) 191 { 192 return (!a != !b) && (0 <= a) && (0 <= b); 193 } 194 195 /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) - 196 (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks 197 were not adjusted between the timestamps. 198 199 The YEAR values uses the same numbering as TP->tm_year. Values 200 need not be in the usual range. However, YEAR1 - YEAR0 must not 201 overflow even when multiplied by three times the number of seconds 202 in a year, and likewise for YDAY1 - YDAY0 and three times the 203 number of seconds in a day. */ 204 205 static long_int 206 ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, 207 int year0, int yday0, int hour0, int min0, int sec0) 208 { 209 verify (-1 / 2 == 0); 210 211 /* Compute intervening leap days correctly even if year is negative. 212 Take care to avoid integer overflow here. */ 213 int a4 = shr (year1, 2) + shr (TM_YEAR_BASE, 2) - ! (year1 & 3); 214 int b4 = shr (year0, 2) + shr (TM_YEAR_BASE, 2) - ! (year0 & 3); 215 int a100 = (a4 + (a4 < 0)) / 25 - (a4 < 0); 216 int b100 = (b4 + (b4 < 0)) / 25 - (b4 < 0); 217 int a400 = shr (a100, 2); 218 int b400 = shr (b100, 2); 219 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); 220 221 /* Compute the desired time without overflowing. */ 222 long_int years = year1 - year0; 223 long_int days = 365 * years + yday1 - yday0 + intervening_leap_days; 224 long_int hours = 24 * days + hour1 - hour0; 225 long_int minutes = 60 * hours + min1 - min0; 226 long_int seconds = 60 * minutes + sec1 - sec0; 227 return seconds; 228 } 229 230 /* Return the average of A and B, even if A + B would overflow. 231 Round toward positive infinity. */ 232 static long_int 233 long_int_avg (long_int a, long_int b) 234 { 235 return shr (a, 1) + shr (b, 1) + ((a | b) & 1); 236 } 237 238 /* Return a long_int value corresponding to (YEAR-YDAY HOUR:MIN:SEC) 239 minus *TP seconds, assuming no clock adjustments occurred between 240 the two timestamps. 241 242 YEAR and YDAY must not be so large that multiplying them by three times the 243 number of seconds in a year (or day, respectively) would overflow long_int. 244 *TP should be in the usual range. */ 245 static long_int 246 tm_diff (long_int year, long_int yday, int hour, int min, int sec, 247 struct tm const *tp) 248 { 249 return ydhms_diff (year, yday, hour, min, sec, 250 tp->tm_year, tp->tm_yday, 251 tp->tm_hour, tp->tm_min, tp->tm_sec); 252 } 253 254 /* Use CONVERT to convert T to a struct tm value in *TM. T must be in 255 range for __time64_t. Return TM if successful, NULL (setting errno) on 256 failure. */ 257 static struct tm * 258 convert_time (struct tm *(*convert) (const __time64_t *, struct tm *), 259 long_int t, struct tm *tm) 260 { 261 __time64_t x = t; 262 return convert (&x, tm); 263 } 264 265 /* Use CONVERT to convert *T to a broken down time in *TP. 266 If *T is out of range for conversion, adjust it so that 267 it is the nearest in-range value and then convert that. 268 A value is in range if it fits in both __time64_t and long_int. 269 Return TP on success, NULL (setting errno) on failure. */ 270 static struct tm * 271 ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *), 272 long_int *t, struct tm *tp) 273 { 274 long_int t1 = (*t < mktime_min ? mktime_min 275 : *t <= mktime_max ? *t : mktime_max); 276 struct tm *r = convert_time (convert, t1, tp); 277 if (r) 278 { 279 *t = t1; 280 return r; 281 } 282 if (errno != EOVERFLOW) 283 return NULL; 284 285 long_int bad = t1; 286 long_int ok = 0; 287 struct tm oktm; oktm.tm_sec = -1; 288 289 /* BAD is a known out-of-range value, and OK is a known in-range one. 290 Use binary search to narrow the range between BAD and OK until 291 they differ by 1. */ 292 while (true) 293 { 294 long_int mid = long_int_avg (ok, bad); 295 if (mid == ok || mid == bad) 296 break; 297 if (convert_time (convert, mid, tp)) 298 ok = mid, oktm = *tp; 299 else if (errno != EOVERFLOW) 300 return NULL; 301 else 302 bad = mid; 303 } 304 305 if (oktm.tm_sec < 0) 306 return NULL; 307 *t = ok; 308 *tp = oktm; 309 return tp; 310 } 311 312 313 /* Convert *TP to a __time64_t value, inverting 314 the monotonic and mostly-unit-linear conversion function CONVERT. 315 Use *OFFSET to keep track of a guess at the offset of the result, 316 compared to what the result would be for UTC without leap seconds. 317 If *OFFSET's guess is correct, only one CONVERT call is needed. 318 If successful, set *TP to the canonicalized struct tm; 319 otherwise leave *TP alone, return ((time_t) -1) and set errno. 320 This function is external because it is used also by timegm.c. */ 321 __time64_t 322 __mktime_internal (struct tm *tp, 323 struct tm *(*convert) (const __time64_t *, struct tm *), 324 mktime_offset_t *offset) 325 { 326 struct tm tm; 327 328 /* The maximum number of probes (calls to CONVERT) should be enough 329 to handle any combinations of time zone rule changes, solar time, 330 leap seconds, and oscillations around a spring-forward gap. 331 POSIX.1 prohibits leap seconds, but some hosts have them anyway. */ 332 int remaining_probes = 6; 333 334 /* Time requested. Copy it in case CONVERT modifies *TP; this can 335 occur if TP is localtime's returned value and CONVERT is localtime. */ 336 int sec = tp->tm_sec; 337 int min = tp->tm_min; 338 int hour = tp->tm_hour; 339 int mday = tp->tm_mday; 340 int mon = tp->tm_mon; 341 int year_requested = tp->tm_year; 342 int isdst = tp->tm_isdst; 343 344 /* 1 if the previous probe was DST. */ 345 int dst2 = 0; 346 347 /* Ensure that mon is in range, and set year accordingly. */ 348 int mon_remainder = mon % 12; 349 int negative_mon_remainder = mon_remainder < 0; 350 int mon_years = mon / 12 - negative_mon_remainder; 351 long_int lyear_requested = year_requested; 352 long_int year = lyear_requested + mon_years; 353 354 /* The other values need not be in range: 355 the remaining code handles overflows correctly. */ 356 357 /* Calculate day of year from year, month, and day of month. 358 The result need not be in range. */ 359 int mon_yday = ((__mon_yday[leapyear (year)] 360 [mon_remainder + 12 * negative_mon_remainder]) 361 - 1); 362 long_int lmday = mday; 363 long_int yday = mon_yday + lmday; 364 365 mktime_offset_t off = *offset; 366 int negative_offset_guess; 367 368 int sec_requested = sec; 369 370 if (LEAP_SECONDS_POSSIBLE) 371 { 372 /* Handle out-of-range seconds specially, 373 since ydhms_diff assumes every minute has 60 seconds. */ 374 if (sec < 0) 375 sec = 0; 376 if (59 < sec) 377 sec = 59; 378 } 379 380 /* Invert CONVERT by probing. First assume the same offset as last 381 time. */ 382 383 ckd_sub (&negative_offset_guess, 0, off); 384 long_int t0 = ydhms_diff (year, yday, hour, min, sec, 385 EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, 386 negative_offset_guess); 387 long_int t = t0, t1 = t0, t2 = t0; 388 389 /* Repeatedly use the error to improve the guess. */ 390 391 while (true) 392 { 393 if (! ranged_convert (convert, &t, &tm)) 394 return -1; 395 long_int dt = tm_diff (year, yday, hour, min, sec, &tm); 396 if (dt == 0) 397 break; 398 399 if (t == t1 && t != t2 400 && (tm.tm_isdst < 0 401 || (isdst < 0 402 ? dst2 <= (tm.tm_isdst != 0) 403 : (isdst != 0) != (tm.tm_isdst != 0)))) 404 /* We can't possibly find a match, as we are oscillating 405 between two values. The requested time probably falls 406 within a spring-forward gap of size DT. Follow the common 407 practice in this case, which is to return a time that is DT 408 away from the requested time, preferring a time whose 409 tm_isdst differs from the requested value. (If no tm_isdst 410 was requested and only one of the two values has a nonzero 411 tm_isdst, prefer that value.) In practice, this is more 412 useful than returning -1. */ 413 goto offset_found; 414 415 remaining_probes--; 416 if (remaining_probes == 0) 417 { 418 __set_errno (EOVERFLOW); 419 return -1; 420 } 421 422 t1 = t2, t2 = t, t += dt, dst2 = tm.tm_isdst != 0; 423 } 424 425 /* We have a match. Check whether tm.tm_isdst has the requested 426 value, if any. */ 427 if (isdst_differ (isdst, tm.tm_isdst)) 428 { 429 /* tm.tm_isdst has the wrong value. Look for a neighboring 430 time with the right value, and use its UTC offset. 431 432 Heuristic: probe the adjacent timestamps in both directions, 433 looking for the desired isdst. If none is found within a 434 reasonable duration bound, assume a one-hour DST difference. 435 This should work for all real time zone histories in the tz 436 database. */ 437 438 /* +1 if we wanted standard time but got DST, -1 if the reverse. */ 439 int dst_difference = (isdst == 0) - (tm.tm_isdst == 0); 440 441 /* Distance between probes when looking for a DST boundary. In 442 tzdata2003a, the shortest period of DST is 601200 seconds 443 (e.g., America/Recife starting 2000-10-08 01:00), and the 444 shortest period of non-DST surrounded by DST is 694800 445 seconds (Africa/Tunis starting 1943-04-17 01:00). Use the 446 minimum of these two values, so we don't miss these short 447 periods when probing. */ 448 int stride = 601200; 449 450 /* In TZDB 2021e, the longest period of DST (or of non-DST), in 451 which the DST (or adjacent DST) difference is not one hour, 452 is 457243209 seconds: e.g., America/Cambridge_Bay with leap 453 seconds, starting 1965-10-31 00:00 in a switch from 454 double-daylight time (-05) to standard time (-07), and 455 continuing to 1980-04-27 02:00 in a switch from standard time 456 (-07) to daylight time (-06). */ 457 int duration_max = 457243209; 458 459 /* Search in both directions, so the maximum distance is half 460 the duration; add the stride to avoid off-by-1 problems. */ 461 int delta_bound = duration_max / 2 + stride; 462 463 int delta, direction; 464 465 for (delta = stride; delta < delta_bound; delta += stride) 466 for (direction = -1; direction <= 1; direction += 2) 467 { 468 long_int ot; 469 if (! ckd_add (&ot, t, delta * direction)) 470 { 471 struct tm otm; 472 if (! ranged_convert (convert, &ot, &otm)) 473 return -1; 474 if (! isdst_differ (isdst, otm.tm_isdst)) 475 { 476 /* We found the desired tm_isdst. 477 Extrapolate back to the desired time. */ 478 long_int gt = ot + tm_diff (year, yday, hour, min, sec, 479 &otm); 480 if (mktime_min <= gt && gt <= mktime_max) 481 { 482 if (convert_time (convert, gt, &tm)) 483 { 484 t = gt; 485 goto offset_found; 486 } 487 if (errno != EOVERFLOW) 488 return -1; 489 } 490 } 491 } 492 } 493 494 /* No unusual DST offset was found nearby. Assume one-hour DST. */ 495 t += 60 * 60 * dst_difference; 496 if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm)) 497 goto offset_found; 498 499 __set_errno (EOVERFLOW); 500 return -1; 501 } 502 503 offset_found: 504 /* Set *OFFSET to the low-order bits of T - T0 - NEGATIVE_OFFSET_GUESS. 505 This is just a heuristic to speed up the next mktime call, and 506 correctness is unaffected if integer overflow occurs here. */ 507 ckd_sub (offset, t, t0); 508 ckd_sub (offset, *offset, negative_offset_guess); 509 510 if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec) 511 { 512 /* Adjust time to reflect the tm_sec requested, not the normalized value. 513 Also, repair any damage from a false match due to a leap second. */ 514 long_int sec_adjustment = sec == 0 && tm.tm_sec == 60; 515 sec_adjustment -= sec; 516 sec_adjustment += sec_requested; 517 if (ckd_add (&t, t, sec_adjustment) 518 || ! (mktime_min <= t && t <= mktime_max)) 519 { 520 __set_errno (EOVERFLOW); 521 return -1; 522 } 523 if (! convert_time (convert, t, &tm)) 524 return -1; 525 } 526 527 *tp = tm; 528 return t; 529 } 530 531 #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */ 532 533 #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS 534 535 /* Convert *TP to a __time64_t value. */ 536 __time64_t 537 __mktime64 (struct tm *tp) 538 { 539 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the 540 time zone names contained in the external variable 'tzname' shall 541 be set as if the tzset() function had been called. */ 542 __tzset (); 543 544 # if defined _LIBC || NEED_MKTIME_WORKING 545 static mktime_offset_t localtime_offset; 546 return __mktime_internal (tp, __localtime64_r, &localtime_offset); 547 # else 548 # undef mktime 549 return mktime (tp); 550 # endif 551 } 552 #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */ 553 554 #if defined _LIBC && __TIMESIZE != 64 555 556 libc_hidden_def (__mktime64) 557 558 time_t 559 mktime (struct tm *tp) 560 { 561 struct tm tm = *tp; 562 __time64_t t = __mktime64 (&tm); 563 if (in_time_t_range (t)) 564 { 565 *tp = tm; 566 return t; 567 } 568 else 569 { 570 __set_errno (EOVERFLOW); 571 return -1; 572 } 573 } 574 575 #endif 576 577 weak_alias (mktime, timelocal) 578 libc_hidden_def (mktime) 579 libc_hidden_weak (timelocal)