1 /* Convert timestamp from time_t to struct tm. */
4 ** This file is in the public domain, so clarified as of
5 ** 1996-06-05 by Arthur David Olson.
9 ** Leap second handling from Bradley White.
10 ** POSIX-style TZ environment variable handling from Guy Harris.
15 #define LOCALTIME_IMPLEMENTATION
16 #include "namespace.h"
17 #ifdef DETECT_TZ_CHANGES
18 #ifndef DETECT_TZ_CHANGES_INTERVAL
19 #define DETECT_TZ_CHANGES_INTERVAL 61
28 #include "un-namespace.h"
32 #include "libc_private.h"
34 #if defined THREAD_SAFE && THREAD_SAFE
35 static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER;
36 static int lock(void) {
38 return _pthread_mutex_lock(&locallock);
41 static void unlock(void) {
43 _pthread_mutex_unlock(&locallock);
46 static int lock(void) { return 0; }
47 static void unlock(void) { }
50 #ifndef TZ_ABBR_MAX_LEN
51 # define TZ_ABBR_MAX_LEN 16
52 #endif /* !defined TZ_ABBR_MAX_LEN */
54 #ifndef TZ_ABBR_CHAR_SET
55 # define TZ_ABBR_CHAR_SET \
56 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
57 #endif /* !defined TZ_ABBR_CHAR_SET */
59 #ifndef TZ_ABBR_ERR_CHAR
60 # define TZ_ABBR_ERR_CHAR '_'
61 #endif /* !defined TZ_ABBR_ERR_CHAR */
64 ** Support non-POSIX platforms that distinguish between text and binary files.
73 ** Someone might make incorrect use of a time zone abbreviation:
74 ** 1. They might reference tzname[0] before calling tzset (explicitly
76 ** 2. They might reference tzname[1] before calling tzset (explicitly
78 ** 3. They might reference tzname[1] after setting to a time zone
79 ** in which Daylight Saving Time is never observed.
80 ** 4. They might reference tzname[0] after setting to a time zone
81 ** in which Standard Time is never observed.
82 ** 5. They might reference tm.TM_ZONE after calling offtime.
83 ** What's best to do in the above cases is open to debate;
84 ** for now, we just set things up so that in any of the five cases
85 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
86 ** string "tzname[0] used before set", and similarly for the other cases.
87 ** And another: initialize tzname[0] to "ERA", with an explanation in the
88 ** manual page of what this "time zone abbreviation" means (doing this so
89 ** that tzname[0] has the "normal" length of three characters).
92 #endif /* !defined WILDABBR */
94 static const char wildabbr[] = WILDABBR;
96 static char const etc_utc[] = "Etc/UTC";
97 static char const *utc = etc_utc + sizeof "Etc/" - 1;
100 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
101 ** Default to US rules as of 2017-05-07.
102 ** POSIX does not specify the default DST rules;
103 ** for historical reasons, US rules are a common default.
105 #ifndef TZDEFRULESTRING
106 # define TZDEFRULESTRING ",M3.2.0,M11.1.0"
109 struct ttinfo { /* time type information */
110 int_fast32_t tt_utoff; /* UT offset in seconds */
111 bool tt_isdst; /* used to set tm_isdst */
112 int tt_desigidx; /* abbreviation list index */
113 bool tt_ttisstd; /* transition is std time */
114 bool tt_ttisut; /* transition is UT */
117 struct lsinfo { /* leap second information */
118 time_t ls_trans; /* transition time */
119 int_fast32_t ls_corr; /* correction to apply */
122 /* This abbreviation means local time is unspecified. */
123 static char const UNSPEC[] = "-00";
125 /* How many extra bytes are needed at the end of struct state's chars array.
126 This needs to be at least 1 for null termination in case the input
127 data isn't properly terminated, and it also needs to be big enough
128 for ttunspecified to work without crashing. */
129 enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
132 # define MY_TZNAME_MAX TZNAME_MAX
133 #endif /* defined TZNAME_MAX */
135 # define MY_TZNAME_MAX 255
136 #endif /* !defined TZNAME_MAX */
145 time_t ats[TZ_MAX_TIMES];
146 unsigned char types[TZ_MAX_TIMES];
147 struct ttinfo ttis[TZ_MAX_TYPES];
148 char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
149 2 * (MY_TZNAME_MAX + 1))];
150 struct lsinfo lsis[TZ_MAX_LEAPS];
152 /* The time type to use for early times or if no transitions.
153 It is always zero for recent tzdb releases.
154 It might be nonzero for data from tzdb 2018e or earlier. */
159 JULIAN_DAY, /* Jn = Julian day */
160 DAY_OF_YEAR, /* n = day of year */
161 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
165 enum r_type r_type; /* type of rule */
166 int r_day; /* day number of rule */
167 int r_week; /* week number of rule */
168 int r_mon; /* month number of rule */
169 int_fast32_t r_time; /* transition time of rule */
172 static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t,
174 static bool increment_overflow(int *, int);
175 static bool increment_overflow_time(time_t *, int_fast32_t);
176 static int_fast32_t leapcorr(struct state const *, time_t);
177 static bool normalize_overflow32(int_fast32_t *, int *, int);
178 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
180 static bool typesequiv(struct state const *, int, int);
181 static bool tzparse(char const *, struct state *, struct state *);
184 static struct state * lclptr;
185 static struct state * gmtptr;
186 #endif /* defined ALL_STATE */
189 static struct state lclmem;
190 static struct state gmtmem;
191 static struct state *const lclptr = &lclmem;
192 static struct state *const gmtptr = &gmtmem;
193 #endif /* State Farm */
195 #ifndef TZ_STRLEN_MAX
196 # define TZ_STRLEN_MAX 255
197 #endif /* !defined TZ_STRLEN_MAX */
199 static char lcl_TZname[TZ_STRLEN_MAX + 1];
200 static int lcl_is_set;
202 static pthread_once_t gmt_once = PTHREAD_ONCE_INIT;
203 static pthread_once_t gmtime_once = PTHREAD_ONCE_INIT;
204 static pthread_key_t gmtime_key;
205 static int gmtime_key_error;
206 static pthread_once_t localtime_once = PTHREAD_ONCE_INIT;
207 static pthread_key_t localtime_key;
208 static int localtime_key_error;
211 ** Section 4.12.3 of X3.159-1989 requires that
212 ** Except for the strftime function, these functions [asctime,
213 ** ctime, gmtime, localtime] return values in one of two static
214 ** objects: a broken-down time structure and an array of char.
215 ** Thanks to Paul Eggert for noting this.
220 #if 2 <= HAVE_TZNAME + TZ_TIME_T
226 #if 2 <= USG_COMPAT + TZ_TIME_T
230 #if 2 <= ALTZONE + TZ_TIME_T
234 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
236 init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
240 s->tt_desigidx = desigidx;
241 s->tt_ttisstd = false;
242 s->tt_ttisut = false;
245 /* Return true if SP's time type I does not specify local time. */
247 ttunspecified(struct state const *sp, int i)
249 char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx];
250 /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */
251 return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0;
255 detzcode(const char *const codep)
257 register int_fast32_t result;
259 int_fast32_t one = 1;
260 int_fast32_t halfmaxval = one << (32 - 2);
261 int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
262 int_fast32_t minval = -1 - maxval;
264 result = codep[0] & 0x7f;
265 for (i = 1; i < 4; ++i)
266 result = (result << 8) | (codep[i] & 0xff);
268 if (codep[0] & 0x80) {
269 /* Do two's-complement negation even on non-two's-complement machines.
270 If the result would be minval - 1, return minval. */
271 result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
278 detzcode64(const char *const codep)
280 register int_fast64_t result;
282 int_fast64_t one = 1;
283 int_fast64_t halfmaxval = one << (64 - 2);
284 int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
285 int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
287 result = codep[0] & 0x7f;
288 for (i = 1; i < 8; ++i)
289 result = (result << 8) | (codep[i] & 0xff);
291 if (codep[0] & 0x80) {
292 /* Do two's-complement negation even on non-two's-complement machines.
293 If the result would be minval - 1, return minval. */
294 result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
301 update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
304 tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_desigidx];
307 if (!ttisp->tt_isdst)
308 timezone = - ttisp->tt_utoff;
312 altzone = - ttisp->tt_utoff;
316 /* If STDDST_MASK indicates that SP's TYPE provides useful info,
317 update tzname, timezone, and/or altzone and return STDDST_MASK,
318 diminished by the provided info if it is a specified local time.
319 Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */
321 may_update_tzname_etc(int stddst_mask, struct state *sp, int type)
323 struct ttinfo *ttisp = &sp->ttis[type];
324 int this_bit = 1 << ttisp->tt_isdst;
325 if (stddst_mask & this_bit) {
326 update_tzname_etc(sp, ttisp);
327 if (!ttunspecified(sp, type))
328 return stddst_mask & ~this_bit;
336 register struct state * const sp = lclptr;
339 /* If STDDST_MASK & 1 we need info about a standard time.
340 If STDDST_MASK & 2 we need info about a daylight saving time.
341 When STDDST_MASK becomes zero we can stop looking. */
345 tzname[0] = tzname[1] = (char *) (sp ? wildabbr : utc);
357 ** And to get the latest time zone abbreviations into tzname. . .
360 for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--)
361 stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]);
362 for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--)
363 stddst_mask = may_update_tzname_etc(stddst_mask, sp, i);
366 daylight = stddst_mask >> 1 ^ 1;
371 scrub_abbrs(struct state *sp)
375 ** First, replace bogus characters.
377 for (i = 0; i < sp->charcnt; ++i)
378 if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
379 sp->chars[i] = TZ_ABBR_ERR_CHAR;
381 ** Second, truncate long abbreviations.
383 for (i = 0; i < sp->typecnt; ++i) {
384 register const struct ttinfo * const ttisp = &sp->ttis[i];
385 char *cp = &sp->chars[ttisp->tt_desigidx];
387 if (strlen(cp) > TZ_ABBR_MAX_LEN &&
388 strcmp(cp, GRANDPARENTED) != 0)
389 *(cp + TZ_ABBR_MAX_LEN) = '\0';
393 #ifdef DETECT_TZ_CHANGES
395 * Determine if there's a change in the timezone since the last time we checked.
396 * Returns: -1 on error
397 * 0 if the timezone has not changed
398 * 1 if the timezone has changed
401 change_in_tz(const char *name)
403 static char old_name[PATH_MAX];
404 static struct stat old_sb;
408 error = stat(name, &sb);
412 if (strcmp(name, old_name) != 0) {
413 strlcpy(old_name, name, sizeof(old_name));
418 if (sb.st_dev != old_sb.st_dev ||
419 sb.st_ino != old_sb.st_ino ||
420 sb.st_ctime != old_sb.st_ctime ||
421 sb.st_mtime != old_sb.st_mtime) {
428 #else /* !DETECT_TZ_CHANGES */
429 #define change_in_tz(X) 1
430 #endif /* !DETECT_TZ_CHANGES */
432 /* Input buffer for data read from a compiled tz file. */
434 /* The first part of the buffer, interpreted as a header. */
435 struct tzhead tzhead;
437 /* The entire buffer. */
438 char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
442 /* TZDIR with a trailing '/' rather than a trailing '\0'. */
443 static char const tzdirslash[sizeof TZDIR] = TZDIR "/";
445 /* Local storage needed for 'tzloadbody'. */
446 union local_storage {
447 /* The results of analyzing the file's contents after it is opened. */
448 struct file_analysis {
449 /* The input buffer. */
450 union input_buffer u;
452 /* A temporary state used for parsing a TZ string in the file. */
456 /* The file name to be opened. */
457 char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)];
460 /* Load tz data from the file named NAME into *SP. Read extended
461 format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
462 success, an errno value on failure. */
464 tzloadbody(char const *name, struct state *sp, bool doextend,
465 union local_storage *lsp)
470 register ssize_t nread;
471 register union input_buffer *up = &lsp->u.u;
472 register int tzheadsize = sizeof(struct tzhead);
474 sp->goback = sp->goahead = false;
484 if (name[0] != '/') {
485 if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name))
488 /* Create a string "TZDIR/NAME". Using sprintf here
489 would pull in stdio (and would fail if the
490 resulting string length exceeded INT_MAX!). */
491 memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash);
492 strcpy(lsp->fullname + sizeof tzdirslash, name);
494 name = lsp->fullname;
498 * Detect if the timezone file has changed. Check
499 * 'doextend' to ignore TZDEFRULES; the change_in_tz()
500 * function can only keep state for a single file.
502 int ret = change_in_tz(name);
505 * Returns an errno value if there was an error,
506 * and 0 if the timezone had not changed.
511 fid = _open(name, O_RDONLY | O_BINARY);
515 nread = _read(fid, up->buf, sizeof up->buf);
516 if (nread < tzheadsize) {
517 int err = nread < 0 ? errno : EINVAL;
523 for (stored = 4; stored <= 8; stored *= 2) {
524 char version = up->tzhead.tzh_version[0];
525 bool skip_datablock = stored == 4 && version;
526 int_fast32_t datablock_size;
527 int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
528 int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
529 int_fast64_t prevtr = -1;
530 int_fast32_t prevcorr;
531 int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
532 int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
533 int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
534 int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
535 char const *p = up->buf + tzheadsize;
536 /* Although tzfile(5) currently requires typecnt to be nonzero,
537 support future formats that may allow zero typecnt
538 in files that have a TZ string and no transitions. */
539 if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
540 && 0 <= typecnt && typecnt < TZ_MAX_TYPES
541 && 0 <= timecnt && timecnt < TZ_MAX_TIMES
542 && 0 <= charcnt && charcnt < TZ_MAX_CHARS
543 && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES
544 && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES))
547 = (timecnt * stored /* ats */
548 + timecnt /* types */
549 + typecnt * 6 /* ttinfos */
550 + charcnt /* chars */
551 + leapcnt * (stored + 4) /* lsinfos */
552 + ttisstdcnt /* ttisstds */
553 + ttisutcnt); /* ttisuts */
554 if (nread < tzheadsize + datablock_size)
559 if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0)
560 && (ttisutcnt == typecnt || ttisutcnt == 0)))
563 sp->leapcnt = leapcnt;
564 sp->timecnt = timecnt;
565 sp->typecnt = typecnt;
566 sp->charcnt = charcnt;
568 /* Read transitions, discarding those out of time_t range.
569 But pretend the last transition before TIME_T_MIN
570 occurred at TIME_T_MIN. */
572 for (i = 0; i < sp->timecnt; ++i) {
574 = stored == 4 ? detzcode(p) : detzcode64(p);
575 sp->types[i] = at <= TIME_T_MAX;
578 = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0)
580 if (timecnt && attime <= sp->ats[timecnt - 1]) {
581 if (attime < sp->ats[timecnt - 1])
583 sp->types[i - 1] = 0;
586 sp->ats[timecnt++] = attime;
592 for (i = 0; i < sp->timecnt; ++i) {
593 unsigned char typ = *p++;
594 if (sp->typecnt <= typ)
597 sp->types[timecnt++] = typ;
599 sp->timecnt = timecnt;
600 for (i = 0; i < sp->typecnt; ++i) {
601 register struct ttinfo * ttisp;
602 unsigned char isdst, desigidx;
604 ttisp = &sp->ttis[i];
605 ttisp->tt_utoff = detzcode(p);
610 ttisp->tt_isdst = isdst;
612 if (! (desigidx < sp->charcnt))
614 ttisp->tt_desigidx = desigidx;
616 for (i = 0; i < sp->charcnt; ++i)
618 /* Ensure '\0'-terminated, and make it safe to call
619 ttunspecified later. */
620 memset(&sp->chars[i], 0, CHARS_EXTRA);
622 /* Read leap seconds, discarding those out of time_t range. */
624 for (i = 0; i < sp->leapcnt; ++i) {
625 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
626 int_fast32_t corr = detzcode(p + stored);
629 /* Leap seconds cannot occur before the Epoch,
634 /* To avoid other botches in this code, each leap second's
635 correction must differ from the previous one's by 1
636 second or less, except that the first correction can be
637 any value; these requirements are more generous than
638 RFC 8536, to allow future RFC extensions. */
641 ? corr == prevcorr + 1
643 || corr == prevcorr - 1))))
648 if (tr <= TIME_T_MAX) {
649 sp->lsis[leapcnt].ls_trans = tr;
650 sp->lsis[leapcnt].ls_corr = corr;
654 sp->leapcnt = leapcnt;
656 for (i = 0; i < sp->typecnt; ++i) {
657 register struct ttinfo * ttisp;
659 ttisp = &sp->ttis[i];
661 ttisp->tt_ttisstd = false;
663 if (*p != true && *p != false)
665 ttisp->tt_ttisstd = *p++;
668 for (i = 0; i < sp->typecnt; ++i) {
669 register struct ttinfo * ttisp;
671 ttisp = &sp->ttis[i];
673 ttisp->tt_ttisut = false;
675 if (*p != true && *p != false)
677 ttisp->tt_ttisut = *p++;
682 nread -= p - up->buf;
683 memmove(up->buf, p, nread);
685 /* If this is an old file, we're done. */
689 if (doextend && nread > 2 &&
690 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
691 sp->typecnt + 2 <= TZ_MAX_TYPES) {
692 struct state *ts = &lsp->u.st;
694 up->buf[nread - 1] = '\0';
695 if (tzparse(&up->buf[1], ts, sp)) {
697 /* Attempt to reuse existing abbreviations.
698 Without this, America/Anchorage would be right on
699 the edge after 2037 when TZ_MAX_CHARS is 50, as
700 sp->charcnt equals 40 (for LMT AST AWT APT AHST
701 AHDT YST AKDT AKST) and ts->charcnt equals 10
702 (for AKST AKDT). Reusing means sp->charcnt can
703 stay 40 in this example. */
705 int charcnt = sp->charcnt;
706 for (i = 0; i < ts->typecnt; i++) {
707 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
709 for (j = 0; j < charcnt; j++)
710 if (strcmp(sp->chars + j, tsabbr) == 0) {
711 ts->ttis[i].tt_desigidx = j;
715 if (! (j < charcnt)) {
716 int tsabbrlen = strlen(tsabbr);
717 if (j + tsabbrlen < TZ_MAX_CHARS) {
718 strcpy(sp->chars + j, tsabbr);
719 charcnt = j + tsabbrlen + 1;
720 ts->ttis[i].tt_desigidx = j;
725 if (gotabbr == ts->typecnt) {
726 sp->charcnt = charcnt;
728 /* Ignore any trailing, no-op transitions generated
729 by zic as they don't help here and can run afoul
730 of bugs in zic 2016j or earlier. */
731 while (1 < sp->timecnt
732 && (sp->types[sp->timecnt - 1]
733 == sp->types[sp->timecnt - 2]))
737 i < ts->timecnt && sp->timecnt < TZ_MAX_TIMES;
739 time_t t = ts->ats[i];
740 if (increment_overflow_time(&t, leapcorr(sp, t))
742 && t <= sp->ats[sp->timecnt - 1]))
744 sp->ats[sp->timecnt] = t;
745 sp->types[sp->timecnt] = (sp->typecnt
749 for (i = 0; i < ts->typecnt; i++)
750 sp->ttis[sp->typecnt++] = ts->ttis[i];
754 if (sp->typecnt == 0)
756 if (sp->timecnt > 1) {
757 if (sp->ats[0] <= TIME_T_MAX - SECSPERREPEAT) {
758 time_t repeatat = sp->ats[0] + SECSPERREPEAT;
759 int repeattype = sp->types[0];
760 for (i = 1; i < sp->timecnt; ++i)
761 if (sp->ats[i] == repeatat
762 && typesequiv(sp, sp->types[i], repeattype)) {
767 if (TIME_T_MIN + SECSPERREPEAT <= sp->ats[sp->timecnt - 1]) {
768 time_t repeatat = sp->ats[sp->timecnt - 1] - SECSPERREPEAT;
769 int repeattype = sp->types[sp->timecnt - 1];
770 for (i = sp->timecnt - 2; i >= 0; --i)
771 if (sp->ats[i] == repeatat
772 && typesequiv(sp, sp->types[i], repeattype)) {
779 /* Infer sp->defaulttype from the data. Although this default
780 type is always zero for data from recent tzdb releases,
781 things are trickier for data from tzdb 2018e or earlier.
783 The first set of heuristics work around bugs in 32-bit data
784 generated by tzdb 2013c or earlier. The workaround is for
785 zones like Australia/Macquarie where timestamps before the
786 first transition have a time type that is not the earliest
787 standard-time type. See:
788 https://mm.icann.org/pipermail/tz/2013-May/019368.html */
790 ** If type 0 does not specify local time, or is unused in transitions,
791 ** it's the type to use for early times.
793 for (i = 0; i < sp->timecnt; ++i)
794 if (sp->types[i] == 0)
796 i = i < sp->timecnt && ! ttunspecified(sp, 0) ? -1 : 0;
799 ** if there are transition times
800 ** and the first transition is to a daylight time
801 ** find the standard type less than and closest to
802 ** the type of the first transition.
804 if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
807 if (!sp->ttis[i].tt_isdst)
810 /* The next heuristics are for data generated by tzdb 2018e or
811 earlier, for zones like EST5EDT where the first transition
814 ** If no result yet, find the first standard type.
815 ** If there is none, punt to type zero.
819 while (sp->ttis[i].tt_isdst)
820 if (++i >= sp->typecnt) {
825 /* A simple 'sp->defaulttype = 0;' would suffice here if we
826 didn't have to worry about 2018e-or-earlier data. Even
827 simpler would be to remove the defaulttype member and just
828 use 0 in its place. */
834 /* Load tz data from the file named NAME into *SP. Read extended
835 format if DOEXTEND. Return 0 on success, an errno value on failure. */
837 tzload(char const *name, struct state *sp, bool doextend)
840 union local_storage *lsp = malloc(sizeof *lsp);
842 return HAVE_MALLOC_ERRNO ? errno : ENOMEM;
844 int err = tzloadbody(name, sp, doextend, lsp);
849 union local_storage ls;
850 return tzloadbody(name, sp, doextend, &ls);
855 typesequiv(const struct state *sp, int a, int b)
857 register bool result;
860 a < 0 || a >= sp->typecnt ||
861 b < 0 || b >= sp->typecnt)
864 /* Compare the relevant members of *AP and *BP.
865 Ignore tt_ttisstd and tt_ttisut, as they are
866 irrelevant now and counting them could cause
867 sp->goahead to mistakenly remain false. */
868 register const struct ttinfo * ap = &sp->ttis[a];
869 register const struct ttinfo * bp = &sp->ttis[b];
870 result = (ap->tt_utoff == bp->tt_utoff
871 && ap->tt_isdst == bp->tt_isdst
872 && (strcmp(&sp->chars[ap->tt_desigidx],
873 &sp->chars[bp->tt_desigidx])
879 static const int mon_lengths[2][MONSPERYEAR] = {
880 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
881 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
884 static const int year_lengths[2] = {
885 DAYSPERNYEAR, DAYSPERLYEAR
888 /* Is C an ASCII digit? */
892 return '0' <= c && c <= '9';
896 ** Given a pointer into a timezone string, scan until a character that is not
897 ** a valid character in a time zone abbreviation is found.
898 ** Return a pointer to that character.
901 static ATTRIBUTE_REPRODUCIBLE const char *
902 getzname(register const char *strp)
906 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
913 ** Given a pointer into an extended timezone string, scan until the ending
914 ** delimiter of the time zone abbreviation is located.
915 ** Return a pointer to the delimiter.
917 ** As with getzname above, the legal character set is actually quite
918 ** restricted, with other characters producing undefined results.
919 ** We don't do any checking here; checking is done later in common-case code.
922 static ATTRIBUTE_REPRODUCIBLE const char *
923 getqzname(register const char *strp, const int delim)
927 while ((c = *strp) != '\0' && c != delim)
933 ** Given a pointer into a timezone string, extract a number from that string.
934 ** Check that the number is within a specified range; if it is not, return
936 ** Otherwise, return a pointer to the first character not part of the number.
940 getnum(register const char *strp, int *const nump, const int min, const int max)
945 if (strp == NULL || !is_digit(c = *strp))
949 num = num * 10 + (c - '0');
951 return NULL; /* illegal value */
953 } while (is_digit(c));
955 return NULL; /* illegal value */
961 ** Given a pointer into a timezone string, extract a number of seconds,
962 ** in hh[:mm[:ss]] form, from the string.
963 ** If any error occurs, return NULL.
964 ** Otherwise, return a pointer to the first character not part of the number
969 getsecs(register const char *strp, int_fast32_t *const secsp)
972 int_fast32_t secsperhour = SECSPERHOUR;
975 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
976 ** "M10.4.6/26", which does not conform to Posix,
977 ** but which specifies the equivalent of
978 ** "02:00 on the first Sunday on or after 23 Oct".
980 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
983 *secsp = num * secsperhour;
986 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
989 *secsp += num * SECSPERMIN;
992 /* 'SECSPERMIN' allows for leap seconds. */
993 strp = getnum(strp, &num, 0, SECSPERMIN);
1003 ** Given a pointer into a timezone string, extract an offset, in
1004 ** [+-]hh[:mm[:ss]] form, from the string.
1005 ** If any error occurs, return NULL.
1006 ** Otherwise, return a pointer to the first character not part of the time.
1010 getoffset(register const char *strp, int_fast32_t *const offsetp)
1012 register bool neg = false;
1017 } else if (*strp == '+')
1019 strp = getsecs(strp, offsetp);
1021 return NULL; /* illegal time */
1023 *offsetp = -*offsetp;
1028 ** Given a pointer into a timezone string, extract a rule in the form
1029 ** date[/time]. See POSIX section 8 for the format of "date" and "time".
1030 ** If a valid rule is not found, return NULL.
1031 ** Otherwise, return a pointer to the first character not part of the rule.
1035 getrule(const char *strp, register struct rule *const rulep)
1041 rulep->r_type = JULIAN_DAY;
1043 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
1044 } else if (*strp == 'M') {
1046 ** Month, week, day.
1048 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
1050 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
1055 strp = getnum(strp, &rulep->r_week, 1, 5);
1060 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
1061 } else if (is_digit(*strp)) {
1065 rulep->r_type = DAY_OF_YEAR;
1066 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
1067 } else return NULL; /* invalid format */
1075 strp = getoffset(strp, &rulep->r_time);
1076 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
1081 ** Given a year, a rule, and the offset from UT at the time that rule takes
1082 ** effect, calculate the year-relative time that rule takes effect.
1086 transtime(const int year, register const struct rule *const rulep,
1087 const int_fast32_t offset)
1089 register bool leapyear;
1090 register int_fast32_t value;
1092 int d, m1, yy0, yy1, yy2, dow;
1094 leapyear = isleap(year);
1095 switch (rulep->r_type) {
1099 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
1101 ** In non-leap years, or if the day number is 59 or less, just
1102 ** add SECSPERDAY times the day number-1 to the time of
1103 ** January 1, midnight, to get the day.
1105 value = (rulep->r_day - 1) * SECSPERDAY;
1106 if (leapyear && rulep->r_day >= 60)
1107 value += SECSPERDAY;
1113 ** Just add SECSPERDAY times the day number to the time of
1114 ** January 1, midnight, to get the day.
1116 value = rulep->r_day * SECSPERDAY;
1119 case MONTH_NTH_DAY_OF_WEEK:
1121 ** Mm.n.d - nth "dth day" of month m.
1125 ** Use Zeller's Congruence to get day-of-week of first day of
1128 m1 = (rulep->r_mon + 9) % 12 + 1;
1129 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
1132 dow = ((26 * m1 - 2) / 10 +
1133 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
1138 ** "dow" is the day-of-week of the first day of the month. Get
1139 ** the day-of-month (zero-origin) of the first "dow" day of the
1142 d = rulep->r_day - dow;
1145 for (i = 1; i < rulep->r_week; ++i) {
1146 if (d + DAYSPERWEEK >=
1147 mon_lengths[leapyear][rulep->r_mon - 1])
1153 ** "d" is the day-of-month (zero-origin) of the day we want.
1155 value = d * SECSPERDAY;
1156 for (i = 0; i < rulep->r_mon - 1; ++i)
1157 value += mon_lengths[leapyear][i] * SECSPERDAY;
1160 default: unreachable();
1164 ** "value" is the year-relative time of 00:00:00 UT on the day in
1165 ** question. To get the year-relative time of the specified local
1166 ** time on that day, add the transition time and the current offset
1169 return value + rulep->r_time + offset;
1173 ** Given a POSIX section 8-style TZ string, fill in the rule tables as
1178 tzparse(const char *name, struct state *sp, struct state *basep)
1180 const char * stdname;
1181 const char * dstname;
1182 int_fast32_t stdoffset;
1183 int_fast32_t dstoffset;
1185 register bool load_ok;
1186 ptrdiff_t stdlen, dstlen, charcnt;
1187 time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN;
1193 name = getqzname(name, '>');
1196 stdlen = name - stdname;
1199 name = getzname(name);
1200 stdlen = name - stdname;
1204 name = getoffset(name, &stdoffset);
1207 charcnt = stdlen + 1;
1208 if (sizeof sp->chars < charcnt)
1211 if (0 < basep->timecnt)
1212 atlo = basep->ats[basep->timecnt - 1];
1214 sp->leapcnt = basep->leapcnt;
1215 memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis);
1217 load_ok = tzload(TZDEFRULES, sp, false) == 0;
1219 sp->leapcnt = 0; /* So, we're off a little. */
1221 if (0 < sp->leapcnt)
1222 leaplo = sp->lsis[sp->leapcnt - 1].ls_trans;
1223 if (*name != '\0') {
1226 name = getqzname(name, '>');
1229 dstlen = name - dstname;
1233 name = getzname(name);
1234 dstlen = name - dstname; /* length of DST abbr. */
1238 charcnt += dstlen + 1;
1239 if (sizeof sp->chars < charcnt)
1241 if (*name != '\0' && *name != ',' && *name != ';') {
1242 name = getoffset(name, &dstoffset);
1245 } else dstoffset = stdoffset - SECSPERHOUR;
1246 if (*name == '\0' && !load_ok)
1247 name = TZDEFRULESTRING;
1248 if (*name == ',' || *name == ';') {
1252 register int timecnt;
1254 int_fast32_t janoffset = 0;
1255 int yearbeg, yearlim;
1258 if ((name = getrule(name, &start)) == NULL)
1262 if ((name = getrule(name, &end)) == NULL)
1266 sp->typecnt = 2; /* standard time and DST */
1268 ** Two transitions per year, from EPOCH_YEAR forward.
1270 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1271 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1272 sp->defaulttype = 0;
1275 yearbeg = EPOCH_YEAR;
1278 int_fast32_t yearsecs
1279 = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
1281 if (increment_overflow_time(&janfirst, -yearsecs)) {
1282 janoffset = -yearsecs;
1285 } while (atlo < janfirst
1286 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1289 int_fast32_t yearsecs
1290 = year_lengths[isleap(yearbeg)] * SECSPERDAY;
1291 int yearbeg1 = yearbeg;
1292 time_t janfirst1 = janfirst;
1293 if (increment_overflow_time(&janfirst1, yearsecs)
1294 || increment_overflow(&yearbeg1, 1)
1295 || atlo <= janfirst1)
1298 janfirst = janfirst1;
1302 if (increment_overflow(&yearlim, YEARSPERREPEAT + 1))
1304 for (year = yearbeg; year < yearlim; year++) {
1306 starttime = transtime(year, &start, stdoffset),
1307 endtime = transtime(year, &end, dstoffset);
1309 yearsecs = (year_lengths[isleap(year)]
1311 bool reversed = endtime < starttime;
1313 int_fast32_t swap = starttime;
1314 starttime = endtime;
1318 || (starttime < endtime
1319 && endtime - starttime < yearsecs)) {
1320 if (TZ_MAX_TIMES - 2 < timecnt)
1322 sp->ats[timecnt] = janfirst;
1323 if (! increment_overflow_time
1325 janoffset + starttime)
1326 && atlo <= sp->ats[timecnt])
1327 sp->types[timecnt++] = !reversed;
1328 sp->ats[timecnt] = janfirst;
1329 if (! increment_overflow_time
1331 janoffset + endtime)
1332 && atlo <= sp->ats[timecnt]) {
1333 sp->types[timecnt++] = reversed;
1336 if (endtime < leaplo) {
1338 if (increment_overflow(&yearlim,
1339 YEARSPERREPEAT + 1))
1342 if (increment_overflow_time
1343 (&janfirst, janoffset + yearsecs))
1347 sp->timecnt = timecnt;
1349 sp->ttis[0] = sp->ttis[1];
1350 sp->typecnt = 1; /* Perpetual DST. */
1351 } else if (YEARSPERREPEAT < year - yearbeg)
1352 sp->goback = sp->goahead = true;
1354 register int_fast32_t theirstdoffset;
1355 register int_fast32_t theirdstoffset;
1356 register int_fast32_t theiroffset;
1357 register bool isdst;
1364 ** Initial values of theirstdoffset and theirdstoffset.
1367 for (i = 0; i < sp->timecnt; ++i) {
1369 if (!sp->ttis[j].tt_isdst) {
1371 - sp->ttis[j].tt_utoff;
1376 for (i = 0; i < sp->timecnt; ++i) {
1378 if (sp->ttis[j].tt_isdst) {
1380 - sp->ttis[j].tt_utoff;
1385 ** Initially we're assumed to be in standard time.
1389 ** Now juggle transition times and types
1390 ** tracking offsets as you do.
1392 for (i = 0; i < sp->timecnt; ++i) {
1394 sp->types[i] = sp->ttis[j].tt_isdst;
1395 if (sp->ttis[j].tt_ttisut) {
1396 /* No adjustment to transition time */
1399 ** If daylight saving time is in
1400 ** effect, and the transition time was
1401 ** not specified as standard time, add
1402 ** the daylight saving time offset to
1403 ** the transition time; otherwise, add
1404 ** the standard time offset to the
1408 ** Transitions from DST to DDST
1409 ** will effectively disappear since
1410 ** POSIX provides for only one DST
1413 if (isdst && !sp->ttis[j].tt_ttisstd) {
1414 sp->ats[i] += dstoffset -
1417 sp->ats[i] += stdoffset -
1421 theiroffset = -sp->ttis[j].tt_utoff;
1422 if (sp->ttis[j].tt_isdst)
1423 theirdstoffset = theiroffset;
1424 else theirstdoffset = theiroffset;
1427 ** Finally, fill in ttis.
1429 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1430 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1432 sp->defaulttype = 0;
1436 sp->typecnt = 1; /* only standard time */
1438 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1439 sp->defaulttype = 0;
1441 sp->charcnt = charcnt;
1443 memcpy(cp, stdname, stdlen);
1447 memcpy(cp, dstname, dstlen);
1448 *(cp + dstlen) = '\0';
1454 gmtload(struct state *const sp)
1456 if (tzload(etc_utc, sp, true) != 0)
1457 tzparse("UTC0", sp, NULL);
1460 #ifdef DETECT_TZ_CHANGES
1464 static time_t last_checked;
1465 struct timespec now;
1466 time_t current_time;
1470 * We want to recheck the timezone file every 61 sec.
1472 error = clock_gettime(CLOCK_MONOTONIC, &now);
1474 /* XXX: Can we somehow report this? */
1478 current_time = now.tv_sec;
1479 if ((current_time - last_checked > DETECT_TZ_CHANGES_INTERVAL) ||
1480 (last_checked > current_time)) {
1481 last_checked = current_time;
1487 #else /* !DETECT_TZ_CHANGES */
1488 #define recheck_tzdata() 0
1489 #endif /* !DETECT_TZ_CHANGES */
1491 /* Initialize *SP to a value appropriate for the TZ setting NAME.
1492 Return 0 on success, an errno value on failure. */
1494 zoneinit(struct state *sp, char const *name)
1496 if (name && ! name[0]) {
1498 ** User wants it fast rather than right.
1500 sp->leapcnt = 0; /* so, we're off a little */
1504 sp->goback = sp->goahead = false;
1505 init_ttinfo(&sp->ttis[0], 0, false, 0);
1506 strcpy(sp->chars, utc);
1507 sp->defaulttype = 0;
1510 int err = tzload(name, sp, true);
1511 if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
1520 tzset_unlocked(void)
1522 char const *name = getenv("TZ");
1523 struct state *sp = lclptr;
1524 int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
1527 : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)
1528 if (recheck_tzdata() == 0)
1532 lclptr = sp = malloc(sizeof *lclptr);
1533 #endif /* defined ALL_STATE */
1535 if (zoneinit(sp, name) != 0)
1538 strcpy(lcl_TZname, name);
1556 static bool gmt_is_set;
1561 gmtptr = malloc(sizeof *gmtptr);
1573 tzalloc(char const *name)
1575 timezone_t sp = malloc(sizeof *sp);
1577 int err = zoneinit(sp, name);
1583 } else if (!HAVE_MALLOC_ERRNO)
1589 tzfree(timezone_t sp)
1595 ** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
1596 ** ctime_r are obsolescent and have potential security problems that
1597 ** ctime_rz would share. Callers can instead use localtime_rz + strftime.
1599 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
1600 ** in zones with three or more time zone abbreviations.
1601 ** Callers can instead use localtime_rz + strftime.
1607 ** The easy way to behave "as if no library function calls" localtime
1608 ** is to not call it, so we drop its guts into "localsub", which can be
1609 ** freely called. (And no, the PANS doesn't require the above behavior,
1610 ** but it *is* desirable.)
1612 ** If successful and SETNAME is nonzero,
1613 ** set the applicable parts of tzname, timezone and altzone;
1614 ** however, it's OK to omit this step if the timezone is POSIX-compatible,
1615 ** since in that case tzset should have already done this step correctly.
1616 ** SETNAME's type is int_fast32_t for compatibility with gmtsub,
1617 ** but it is actually a boolean and its value should be 0 or 1.
1622 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
1623 struct tm *const tmp)
1625 register const struct ttinfo * ttisp;
1627 register struct tm * result;
1628 const time_t t = *timep;
1631 /* Don't bother to set tzname etc.; tzset has already done it. */
1632 return gmtsub(gmtptr, timep, 0, tmp);
1634 if ((sp->goback && t < sp->ats[0]) ||
1635 (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1637 register time_t seconds;
1638 register time_t years;
1641 seconds = sp->ats[0] - t;
1642 else seconds = t - sp->ats[sp->timecnt - 1];
1645 /* Beware integer overflow, as SECONDS might
1646 be close to the maximum time_t. */
1647 years = seconds / SECSPERREPEAT * YEARSPERREPEAT;
1648 seconds = years * AVGSECSPERYEAR;
1649 years += YEARSPERREPEAT;
1651 newt = t + seconds + SECSPERREPEAT;
1653 newt = t - seconds - SECSPERREPEAT;
1655 if (newt < sp->ats[0] ||
1656 newt > sp->ats[sp->timecnt - 1])
1657 return NULL; /* "cannot happen" */
1658 result = localsub(sp, &newt, setname, tmp);
1660 #if defined ckd_add && defined ckd_sub
1662 ? ckd_sub(&result->tm_year,
1663 result->tm_year, years)
1664 : ckd_add(&result->tm_year,
1665 result->tm_year, years))
1668 register int_fast64_t newy;
1670 newy = result->tm_year;
1674 if (! (INT_MIN <= newy && newy <= INT_MAX))
1676 result->tm_year = newy;
1681 if (sp->timecnt == 0 || t < sp->ats[0]) {
1682 i = sp->defaulttype;
1684 register int lo = 1;
1685 register int hi = sp->timecnt;
1688 register int mid = (lo + hi) >> 1;
1690 if (t < sp->ats[mid])
1694 i = sp->types[lo - 1];
1696 ttisp = &sp->ttis[i];
1698 ** To get (wrong) behavior that's compatible with System V Release 2.0
1699 ** you'd replace the statement below with
1700 ** t += ttisp->tt_utoff;
1701 ** timesub(&t, 0L, sp, tmp);
1703 result = timesub(&t, ttisp->tt_utoff, sp, tmp);
1705 result->tm_isdst = ttisp->tt_isdst;
1707 result->TM_ZONE = (char *) &sp->chars[ttisp->tt_desigidx];
1708 #endif /* defined TM_ZONE */
1710 update_tzname_etc(sp, ttisp);
1718 localtime_rz(struct state *sp, time_t const *timep, struct tm *tmp)
1720 return localsub(sp, timep, 0, tmp);
1726 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
1733 #ifndef DETECT_TZ_CHANGES
1734 if (setname || !lcl_is_set)
1737 tmp = localsub(lclptr, timep, setname, tmp);
1743 localtime_key_init(void)
1746 localtime_key_error = _pthread_key_create(&localtime_key, free);
1750 localtime(const time_t *timep)
1752 struct tm *p_tm = &tm;
1754 if (__isthreaded != 0) {
1755 _pthread_once(&localtime_once, localtime_key_init);
1756 if (localtime_key_error != 0) {
1757 errno = localtime_key_error;
1760 if ((p_tm = _pthread_getspecific(localtime_key)) == NULL) {
1761 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) {
1764 if (_pthread_setspecific(localtime_key, p_tm) != 0) {
1770 return localtime_tzset(timep, p_tm, true);
1774 localtime_r(const time_t *timep, struct tm *tmp)
1776 return localtime_tzset(timep, tmp, false);
1780 ** gmtsub is to gmtime as localsub is to localtime.
1784 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep,
1785 int_fast32_t offset, struct tm *tmp)
1787 register struct tm * result;
1789 result = timesub(timep, offset, gmtptr, tmp);
1792 ** Could get fancy here and deliver something such as
1793 ** "+xx" or "-xx" if offset is non-zero,
1794 ** but this is no time for a treasure hunt.
1796 tmp->TM_ZONE = ((char *)
1797 (offset ? wildabbr : gmtptr ? gmtptr->chars : utc));
1798 #endif /* defined TM_ZONE */
1803 * Re-entrant version of gmtime.
1807 gmtime_r(const time_t *timep, struct tm *tmp)
1809 _once(&gmt_once, gmtcheck);
1810 return gmtsub(gmtptr, timep, 0, tmp);
1814 gmtime_key_init(void)
1817 gmtime_key_error = _pthread_key_create(&gmtime_key, free);
1821 gmtime(const time_t *timep)
1823 struct tm *p_tm = &tm;
1825 if (__isthreaded != 0) {
1826 _pthread_once(&gmtime_once, gmtime_key_init);
1827 if (gmtime_key_error != 0) {
1828 errno = gmtime_key_error;
1831 if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) {
1832 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) {
1835 if (_pthread_setspecific(gmtime_key, p_tm) != 0) {
1841 return gmtime_r(timep, p_tm);
1847 offtime(const time_t *timep, long offset)
1849 _once(&gmt_once, gmtcheck);
1850 return gmtsub(gmtptr, timep, offset, &tm);
1853 #endif /* defined STD_INSPIRED */
1856 ** Return the number of leap years through the end of the given year
1857 ** where, to make the math easy, the answer for year zero is defined as zero.
1861 leaps_thru_end_of_nonneg(time_t y)
1863 return y / 4 - y / 100 + y / 400;
1867 leaps_thru_end_of(time_t y)
1870 ? -1 - leaps_thru_end_of_nonneg(-1 - y)
1871 : leaps_thru_end_of_nonneg(y));
1875 timesub(const time_t *timep, int_fast32_t offset,
1876 const struct state *sp, struct tm *tmp)
1878 register const struct lsinfo * lp;
1879 register time_t tdays;
1880 register const int * ip;
1881 register int_fast32_t corr;
1883 int_fast32_t idays, rem, dayoff, dayrem;
1886 /* If less than SECSPERMIN, the number of seconds since the
1887 most recent positive leap second; otherwise, do not add 1
1888 to localtime tm_sec because of leap seconds. */
1889 time_t secs_since_posleap = SECSPERMIN;
1892 i = (sp == NULL) ? 0 : sp->leapcnt;
1895 if (*timep >= lp->ls_trans) {
1897 if ((i == 0 ? 0 : lp[-1].ls_corr) < corr)
1898 secs_since_posleap = *timep - lp->ls_trans;
1903 /* Calculate the year, avoiding integer overflow even if
1904 time_t is unsigned. */
1905 tdays = *timep / SECSPERDAY;
1906 rem = *timep % SECSPERDAY;
1907 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
1908 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
1911 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT),
1912 sans overflow. But calculate against 1570 (EPOCH_YEAR -
1913 YEARSPERREPEAT) instead of against 1970 so that things work
1914 for localtime values before 1970 when time_t is unsigned. */
1915 dayrem = tdays % DAYSPERREPEAT;
1916 dayrem += dayoff % DAYSPERREPEAT;
1917 y = (EPOCH_YEAR - YEARSPERREPEAT
1918 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT
1919 - ((dayrem % DAYSPERREPEAT) < 0)
1920 + tdays / DAYSPERREPEAT)
1922 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */
1923 idays = tdays % DAYSPERREPEAT;
1924 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT;
1925 idays %= DAYSPERREPEAT;
1926 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */
1927 while (year_lengths[isleap(y)] <= idays) {
1928 int tdelta = idays / DAYSPERLYEAR;
1929 int_fast32_t ydelta = tdelta + !tdelta;
1930 time_t newy = y + ydelta;
1931 register int leapdays;
1932 leapdays = leaps_thru_end_of(newy - 1) -
1933 leaps_thru_end_of(y - 1);
1934 idays -= ydelta * DAYSPERNYEAR;
1940 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) {
1945 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) {
1947 tmp->tm_year = signed_y - TM_YEAR_BASE;
1948 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y)
1949 && y - TM_YEAR_BASE <= INT_MAX)
1950 tmp->tm_year = y - TM_YEAR_BASE;
1956 tmp->tm_yday = idays;
1958 ** The "extra" mods below avoid overflow problems.
1960 tmp->tm_wday = (TM_WDAY_BASE
1961 + ((tmp->tm_year % DAYSPERWEEK)
1962 * (DAYSPERNYEAR % DAYSPERWEEK))
1963 + leaps_thru_end_of(y - 1)
1964 - leaps_thru_end_of(TM_YEAR_BASE - 1)
1966 tmp->tm_wday %= DAYSPERWEEK;
1967 if (tmp->tm_wday < 0)
1968 tmp->tm_wday += DAYSPERWEEK;
1969 tmp->tm_hour = rem / SECSPERHOUR;
1971 tmp->tm_min = rem / SECSPERMIN;
1972 tmp->tm_sec = rem % SECSPERMIN;
1974 /* Use "... ??:??:60" at the end of the localtime minute containing
1975 the second just before the positive leap second. */
1976 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec;
1978 ip = mon_lengths[isleap(y)];
1979 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1980 idays -= ip[tmp->tm_mon];
1981 tmp->tm_mday = idays + 1;
1984 tmp->TM_GMTOFF = offset;
1985 #endif /* defined TM_GMTOFF */
1990 ctime(const time_t *timep)
1993 ** Section 4.12.3.2 of X3.159-1989 requires that
1994 ** The ctime function converts the calendar time pointed to by timer
1995 ** to local time in the form of a string. It is equivalent to
1996 ** asctime(localtime(timer))
1998 struct tm *tmp = localtime(timep);
1999 return tmp ? asctime(tmp) : NULL;
2003 ctime_r(const time_t *timep, char *buf)
2006 struct tm *tmp = localtime_r(timep, &mytm);
2007 return tmp ? asctime_r(tmp, buf) : NULL;
2011 ** Adapted from code provided by Robert Elz, who writes:
2012 ** The "best" way to do mktime I think is based on an idea of Bob
2013 ** Kridle's (so its said...) from a long time ago.
2014 ** It does a binary search of the time_t space. Since time_t's are
2015 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
2016 ** would still be very reasonable).
2021 #endif /* !defined WRONG */
2024 ** Normalize logic courtesy Paul Eggert.
2028 increment_overflow(int *ip, int j)
2031 return ckd_add(ip, *ip, j);
2033 register int const i = *ip;
2036 ** If i >= 0 there can only be overflow if i + j > INT_MAX
2037 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
2038 ** If i < 0 there can only be overflow if i + j < INT_MIN
2039 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
2041 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
2049 increment_overflow32(int_fast32_t *const lp, int const m)
2052 return ckd_add(lp, *lp, m);
2054 register int_fast32_t const l = *lp;
2056 if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
2064 increment_overflow_time(time_t *tp, int_fast32_t j)
2067 return ckd_add(tp, *tp, j);
2071 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
2072 ** except that it does the right thing even if *tp + j would overflow.
2075 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
2076 : *tp <= TIME_T_MAX - j))
2084 normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
2086 register int tensdelta;
2088 tensdelta = (*unitsptr >= 0) ?
2089 (*unitsptr / base) :
2090 (-1 - (-1 - *unitsptr) / base);
2091 *unitsptr -= tensdelta * base;
2092 return increment_overflow(tensptr, tensdelta);
2096 normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
2098 register int tensdelta;
2100 tensdelta = (*unitsptr >= 0) ?
2101 (*unitsptr / base) :
2102 (-1 - (-1 - *unitsptr) / base);
2103 *unitsptr -= tensdelta * base;
2104 return increment_overflow32(tensptr, tensdelta);
2108 tmcomp(register const struct tm *const atmp,
2109 register const struct tm *const btmp)
2111 register int result;
2113 if (atmp->tm_year != btmp->tm_year)
2114 return atmp->tm_year < btmp->tm_year ? -1 : 1;
2115 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
2116 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
2117 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
2118 (result = (atmp->tm_min - btmp->tm_min)) == 0)
2119 result = atmp->tm_sec - btmp->tm_sec;
2123 /* Copy to *DEST from *SRC. Copy only the members needed for mktime,
2124 as other members might not be initialized. */
2126 mktmcpy(struct tm *dest, struct tm const *src)
2128 dest->tm_sec = src->tm_sec;
2129 dest->tm_min = src->tm_min;
2130 dest->tm_hour = src->tm_hour;
2131 dest->tm_mday = src->tm_mday;
2132 dest->tm_mon = src->tm_mon;
2133 dest->tm_year = src->tm_year;
2134 dest->tm_isdst = src->tm_isdst;
2135 #if defined TM_GMTOFF && ! UNINIT_TRAP
2136 dest->TM_GMTOFF = src->TM_GMTOFF;
2141 time2sub(struct tm *const tmp,
2142 struct tm *(*funcp)(struct state const *, time_t const *,
2143 int_fast32_t, struct tm *),
2144 struct state const *sp,
2145 const int_fast32_t offset,
2151 register int saved_seconds;
2152 register int_fast32_t li;
2158 struct tm yourtm, mytm;
2161 mktmcpy(&yourtm, tmp);
2164 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
2168 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
2170 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
2173 if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
2176 ** Turn y into an actual year number for now.
2177 ** It is converted back to an offset from TM_YEAR_BASE later.
2179 if (increment_overflow32(&y, TM_YEAR_BASE))
2181 while (yourtm.tm_mday <= 0) {
2182 if (increment_overflow32(&y, -1))
2184 li = y + (1 < yourtm.tm_mon);
2185 yourtm.tm_mday += year_lengths[isleap(li)];
2187 while (yourtm.tm_mday > DAYSPERLYEAR) {
2188 li = y + (1 < yourtm.tm_mon);
2189 yourtm.tm_mday -= year_lengths[isleap(li)];
2190 if (increment_overflow32(&y, 1))
2194 i = mon_lengths[isleap(y)][yourtm.tm_mon];
2195 if (yourtm.tm_mday <= i)
2197 yourtm.tm_mday -= i;
2198 if (++yourtm.tm_mon >= MONSPERYEAR) {
2200 if (increment_overflow32(&y, 1))
2205 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE))
2208 if (increment_overflow32(&y, -TM_YEAR_BASE))
2210 if (! (INT_MIN <= y && y <= INT_MAX))
2214 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
2216 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) {
2218 ** We can't set tm_sec to 0, because that might push the
2219 ** time below the minimum representable time.
2220 ** Set tm_sec to 59 instead.
2221 ** This assumes that the minimum representable time is
2222 ** not in the same minute that a leap second was deleted from,
2223 ** which is a safer assumption than using 58 would be.
2225 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
2227 saved_seconds = yourtm.tm_sec;
2228 yourtm.tm_sec = SECSPERMIN - 1;
2230 saved_seconds = yourtm.tm_sec;
2234 ** Do a binary search (this works whatever time_t's type is).
2239 t = lo / 2 + hi / 2;
2244 if (! funcp(sp, &t, offset, &mytm)) {
2246 ** Assume that t is too extreme to be represented in
2247 ** a struct tm; arrange things so that it is less
2248 ** extreme on the next pass.
2250 dir = (t > 0) ? 1 : -1;
2251 } else dir = tmcomp(&mytm, &yourtm);
2254 if (t == TIME_T_MAX)
2258 } else if (t == hi) {
2259 if (t == TIME_T_MIN)
2271 #if defined TM_GMTOFF && ! UNINIT_TRAP
2272 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
2273 && (yourtm.TM_GMTOFF < 0
2274 ? (-SECSPERDAY <= yourtm.TM_GMTOFF
2275 && (mytm.TM_GMTOFF <=
2276 (min(INT_FAST32_MAX, LONG_MAX)
2277 + yourtm.TM_GMTOFF)))
2278 : (yourtm.TM_GMTOFF <= SECSPERDAY
2279 && ((max(INT_FAST32_MIN, LONG_MIN)
2281 <= mytm.TM_GMTOFF)))) {
2282 /* MYTM matches YOURTM except with the wrong UT offset.
2283 YOURTM.TM_GMTOFF is plausible, so try it instead.
2284 It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
2285 since the guess gets checked. */
2287 int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF;
2288 if (!increment_overflow_time(&altt, diff)) {
2290 if (funcp(sp, &altt, offset, &alttm)
2291 && alttm.tm_isdst == mytm.tm_isdst
2292 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF
2293 && tmcomp(&alttm, &yourtm) == 0) {
2300 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
2303 ** Right time, wrong type.
2304 ** Hunt for right time, right type.
2305 ** It's okay to guess wrong since the guess
2310 for (i = sp->typecnt - 1; i >= 0; --i) {
2311 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
2313 for (j = sp->typecnt - 1; j >= 0; --j) {
2314 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
2316 if (ttunspecified(sp, j))
2318 newt = (t + sp->ttis[j].tt_utoff
2319 - sp->ttis[i].tt_utoff);
2320 if (! funcp(sp, &newt, offset, &mytm))
2322 if (tmcomp(&mytm, &yourtm) != 0)
2324 if (mytm.tm_isdst != yourtm.tm_isdst)
2336 newt = t + saved_seconds;
2337 if ((newt < t) != (saved_seconds < 0))
2340 if (funcp(sp, &t, offset, tmp))
2346 time2(struct tm * const tmp,
2347 struct tm *(*funcp)(struct state const *, time_t const *,
2348 int_fast32_t, struct tm *),
2349 struct state const *sp,
2350 const int_fast32_t offset,
2356 ** First try without normalization of seconds
2357 ** (in case tm_sec contains a value associated with a leap second).
2358 ** If that fails, try with normalization of seconds.
2360 t = time2sub(tmp, funcp, sp, offset, okayp, false);
2361 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
2365 time1(struct tm *const tmp,
2366 struct tm *(*funcp)(struct state const *, time_t const *,
2367 int_fast32_t, struct tm *),
2368 struct state const *sp,
2369 const int_fast32_t offset)
2372 register int samei, otheri;
2373 register int sameind, otherind;
2376 char seen[TZ_MAX_TYPES];
2377 unsigned char types[TZ_MAX_TYPES];
2385 if (tmp->tm_isdst > 1)
2387 t = time2(tmp, funcp, sp, offset, &okay);
2390 if (tmp->tm_isdst < 0)
2393 ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2395 tmp->tm_isdst = 0; /* reset to std and try again */
2398 #endif /* !defined PCTS */
2400 ** We're supposed to assume that somebody took a time of one type
2401 ** and did some math on it that yielded a "struct tm" that's bad.
2402 ** We try to divine the type they started from and adjust to the
2407 for (i = 0; i < sp->typecnt; ++i)
2410 for (i = sp->timecnt - 1; i >= 0; --i)
2411 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) {
2412 seen[sp->types[i]] = true;
2413 types[nseen++] = sp->types[i];
2415 for (sameind = 0; sameind < nseen; ++sameind) {
2416 samei = types[sameind];
2417 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
2419 for (otherind = 0; otherind < nseen; ++otherind) {
2420 otheri = types[otherind];
2421 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
2423 tmp->tm_sec += (sp->ttis[otheri].tt_utoff
2424 - sp->ttis[samei].tt_utoff);
2425 tmp->tm_isdst = !tmp->tm_isdst;
2426 t = time2(tmp, funcp, sp, offset, &okay);
2429 tmp->tm_sec -= (sp->ttis[otheri].tt_utoff
2430 - sp->ttis[samei].tt_utoff);
2431 tmp->tm_isdst = !tmp->tm_isdst;
2438 mktime_tzname(struct state *sp, struct tm *tmp, bool setname)
2441 return time1(tmp, localsub, sp, setname);
2443 _once(&gmt_once, gmtcheck);
2444 return time1(tmp, gmtsub, gmtptr, 0);
2451 mktime_z(struct state *sp, struct tm *tmp)
2453 return mktime_tzname(sp, tmp, false);
2459 mktime(struct tm *tmp)
2468 t = mktime_tzname(lclptr, tmp, true);
2475 timelocal(struct tm *tmp)
2478 tmp->tm_isdst = -1; /* in case it wasn't initialized */
2485 timeoff(struct tm *tmp, long offset)
2489 _once(&gmt_once, gmtcheck);
2490 return time1(tmp, gmtsub, gmtptr, offset);
2494 timegm(struct tm *tmp)
2498 mktmcpy(&tmcpy, tmp);
2500 t = timeoff(&tmcpy, 0);
2501 if (0 <= tmcpy.tm_wday)
2507 leapcorr(struct state const *sp, time_t t)
2509 register struct lsinfo const * lp;
2515 if (t >= lp->ls_trans)
2522 ** XXX--is the below the right way to conditionalize??
2527 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if
2528 NETBSD_INSPIRED is defined, and are private otherwise. */
2529 # if NETBSD_INSPIRED
2530 # define NETBSD_INSPIRED_EXTERN
2532 # define NETBSD_INSPIRED_EXTERN static
2536 ** IEEE Std 1003.1 (POSIX) says that 536457599
2537 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2538 ** is not the case if we are accounting for leap seconds.
2539 ** So, we provide the following conversion routines for use
2540 ** when exchanging timestamps with POSIX conforming systems.
2543 NETBSD_INSPIRED_EXTERN time_t
2544 time2posix_z(struct state *sp, time_t t)
2546 return t - leapcorr(sp, t);
2550 time2posix(time_t t)
2557 #ifndef DETECT_TZ_CHANGES
2562 t = time2posix_z(lclptr, t);
2567 NETBSD_INSPIRED_EXTERN time_t
2568 posix2time_z(struct state *sp, time_t t)
2573 ** For a positive leap second hit, the result
2574 ** is not unique. For a negative leap second
2575 ** hit, the corresponding time doesn't exist,
2576 ** so we return an adjacent second.
2578 x = t + leapcorr(sp, t);
2579 y = x - leapcorr(sp, x);
2583 y = x - leapcorr(sp, x);
2589 y = x - leapcorr(sp, x);
2597 posix2time(time_t t)
2604 #ifndef DETECT_TZ_CHANGES
2609 t = posix2time_z(lclptr, t);
2614 #endif /* defined STD_INSPIRED */
2626 /* Convert from the underlying system's time_t to the ersatz time_tz,
2627 which is called 'time_t' in this file. Typically, this merely
2628 converts the time's integer width. On some platforms, the system
2629 time is local time not UT, or uses some epoch other than the POSIX
2632 Although this code appears to define a function named 'time' that
2633 returns time_t, the macros in private.h cause this code to actually
2634 define a function named 'tz_time' that returns tz_time_t. The call
2635 to sys_time invokes the underlying system's 'time' function. */
2640 time_t r = sys_time(0);
2641 if (r != (time_t) -1) {
2642 int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0;
2643 if (increment_overflow32(&offset, -EPOCH_OFFSET)
2644 || increment_overflow_time(&r, offset)) {