1 /* $NetBSD: localtime.c,v 1.122 2019/07/03 15:50:16 christos Exp $ */
3 /* Convert timestamp from time_t to struct tm. */
6 ** This file is in the public domain, so clarified as of
7 ** 1996-06-05 by Arthur David Olson.
10 #include <sys/cdefs.h>
11 #if defined(LIBC_SCCS) && !defined(lint)
13 static char elsieid
[] = "@(#)localtime.c 8.17";
15 __RCSID("$NetBSD: localtime.c,v 1.122 2019/07/03 15:50:16 christos Exp $");
17 #endif /* LIBC_SCCS and not lint */
20 ** Leap second handling from Bradley White.
21 ** POSIX-style TZ environment variable handling from Guy Harris.
26 #include "namespace.h"
28 #define LOCALTIME_IMPLEMENTATION
35 # define NETBSD_INSPIRED_EXTERN
37 # define NETBSD_INSPIRED_EXTERN static
40 #if defined(__weak_alias)
41 __weak_alias(daylight
,_daylight
)
42 __weak_alias(tzname
,_tzname
)
45 #ifndef TZ_ABBR_MAX_LEN
46 #define TZ_ABBR_MAX_LEN 16
47 #endif /* !defined TZ_ABBR_MAX_LEN */
49 #ifndef TZ_ABBR_CHAR_SET
50 #define TZ_ABBR_CHAR_SET \
51 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
52 #endif /* !defined TZ_ABBR_CHAR_SET */
54 #ifndef TZ_ABBR_ERR_CHAR
55 #define TZ_ABBR_ERR_CHAR '_'
56 #endif /* !defined TZ_ABBR_ERR_CHAR */
59 ** SunOS 4.1.1 headers lack O_BINARY.
63 #define OPEN_MODE (O_RDONLY | O_BINARY | O_CLOEXEC)
64 #endif /* defined O_BINARY */
66 #define OPEN_MODE (O_RDONLY | O_CLOEXEC)
67 #endif /* !defined O_BINARY */
71 ** Someone might make incorrect use of a time zone abbreviation:
72 ** 1. They might reference tzname[0] before calling tzset (explicitly
74 ** 2. They might reference tzname[1] before calling tzset (explicitly
76 ** 3. They might reference tzname[1] after setting to a time zone
77 ** in which Daylight Saving Time is never observed.
78 ** 4. They might reference tzname[0] after setting to a time zone
79 ** in which Standard Time is never observed.
80 ** 5. They might reference tm.TM_ZONE after calling offtime.
81 ** What's best to do in the above cases is open to debate;
82 ** for now, we just set things up so that in any of the five cases
83 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
84 ** string "tzname[0] used before set", and similarly for the other cases.
85 ** And another: initialize tzname[0] to "ERA", with an explanation in the
86 ** manual page of what this "time zone abbreviation" means (doing this so
87 ** that tzname[0] has the "normal" length of three characters).
90 #endif /* !defined WILDABBR */
92 static const char wildabbr
[] = WILDABBR
;
94 static const char gmt
[] = "GMT";
97 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
98 ** Default to US rules as of 2017-05-07.
99 ** POSIX does not specify the default DST rules;
100 ** for historical reasons, US rules are a common default.
102 #ifndef TZDEFRULESTRING
103 #define TZDEFRULESTRING ",M3.2.0,M11.1.0"
106 struct ttinfo
{ /* time type information */
107 int_fast32_t tt_utoff
; /* UT offset in seconds */
108 bool tt_isdst
; /* used to set tm_isdst */
109 int tt_desigidx
; /* abbreviation list index */
110 bool tt_ttisstd
; /* transition is std time */
111 bool tt_ttisut
; /* transition is UT */
114 struct lsinfo
{ /* leap second information */
115 time_t ls_trans
; /* transition time */
116 int_fast64_t ls_corr
; /* correction to apply */
119 #define SMALLEST(a, b) (((a) < (b)) ? (a) : (b))
120 #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
123 #define MY_TZNAME_MAX TZNAME_MAX
124 #endif /* defined TZNAME_MAX */
126 #define MY_TZNAME_MAX 255
127 #endif /* !defined TZNAME_MAX */
129 #define state __state
137 time_t ats
[TZ_MAX_TIMES
];
138 unsigned char types
[TZ_MAX_TIMES
];
139 struct ttinfo ttis
[TZ_MAX_TYPES
];
140 char chars
[/*CONSTCOND*/BIGGEST(BIGGEST(TZ_MAX_CHARS
+ 1,
141 sizeof gmt
), (2 * (MY_TZNAME_MAX
+ 1)))];
142 struct lsinfo lsis
[TZ_MAX_LEAPS
];
144 /* The time type to use for early times or if no transitions.
145 It is always zero for recent tzdb releases.
146 It might be nonzero for data from tzdb 2018e or earlier. */
151 JULIAN_DAY
, /* Jn = Julian day */
152 DAY_OF_YEAR
, /* n = day of year */
153 MONTH_NTH_DAY_OF_WEEK
/* Mm.n.d = month, week, day of week */
157 enum r_type r_type
; /* type of rule */
158 int r_day
; /* day number of rule */
159 int r_week
; /* week number of rule */
160 int r_mon
; /* month number of rule */
161 int_fast32_t r_time
; /* transition time of rule */
164 static struct tm
*gmtsub(struct state
const *, time_t const *, int_fast32_t,
166 static bool increment_overflow(int *, int);
167 static bool increment_overflow_time(time_t *, int_fast32_t);
168 static bool normalize_overflow32(int_fast32_t *, int *, int);
169 static struct tm
*timesub(time_t const *, int_fast32_t, struct state
const *,
171 static bool typesequiv(struct state
const *, int, int);
172 static bool tzparse(char const *, struct state
*, bool);
174 static timezone_t gmtptr
;
176 #ifndef TZ_STRLEN_MAX
177 #define TZ_STRLEN_MAX 255
178 #endif /* !defined TZ_STRLEN_MAX */
180 static char lcl_TZname
[TZ_STRLEN_MAX
+ 1];
181 static int lcl_is_set
;
184 #if !defined(__LIBC12_SOURCE__)
187 rwlock_t __lcl_lock
= RWLOCK_INITIALIZER
;
192 ** Section 4.12.3 of X3.159-1989 requires that
193 ** Except for the strftime function, these functions [asctime,
194 ** ctime, gmtime, localtime] return values in one of two static
195 ** objects: a broken-down time structure and an array of char.
196 ** Thanks to Paul Eggert for noting this.
201 #if !HAVE_POSIX_DECLS || TZ_TIME_T || defined(__NetBSD__)
202 # if !defined(__LIBC12_SOURCE__)
204 __aconst
char * tzname
[2] = {
205 (__aconst
char *)__UNCONST(wildabbr
),
206 (__aconst
char *)__UNCONST(wildabbr
)
211 extern __aconst
char * tzname
[2];
213 # endif /* __LIBC12_SOURCE__ */
216 # if !defined(__LIBC12_SOURCE__)
221 extern long timezone
__RENAME(__timezone13
);
222 # endif /* __LIBC12_SOURCE__ */
223 # endif /* defined USG_COMPAT */
227 # endif /* defined ALTZONE */
228 #endif /* !HAVE_POSIX_DECLS */
230 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
232 init_ttinfo(struct ttinfo
*s
, int_fast32_t utoff
, bool isdst
, int desigidx
)
236 s
->tt_desigidx
= desigidx
;
237 s
->tt_ttisstd
= false;
238 s
->tt_ttisut
= false;
242 detzcode(const char *const codep
)
246 int_fast32_t one
= 1;
247 int_fast32_t halfmaxval
= one
<< (32 - 2);
248 int_fast32_t maxval
= halfmaxval
- 1 + halfmaxval
;
249 int_fast32_t minval
= -1 - maxval
;
251 result
= codep
[0] & 0x7f;
252 for (i
= 1; i
< 4; ++i
)
253 result
= (result
<< 8) | (codep
[i
] & 0xff);
255 if (codep
[0] & 0x80) {
256 /* Do two's-complement negation even on non-two's-complement machines.
257 If the result would be minval - 1, return minval. */
258 result
-= !TWOS_COMPLEMENT(int_fast32_t) && result
!= 0;
265 detzcode64(const char *const codep
)
269 int_fast64_t one
= 1;
270 int_fast64_t halfmaxval
= one
<< (64 - 2);
271 int_fast64_t maxval
= halfmaxval
- 1 + halfmaxval
;
272 int_fast64_t minval
= -TWOS_COMPLEMENT(int_fast64_t) - maxval
;
274 result
= codep
[0] & 0x7f;
275 for (i
= 1; i
< 8; ++i
)
276 result
= (result
<< 8) | (codep
[i
] & 0xff);
278 if (codep
[0] & 0x80) {
279 /* Do two's-complement negation even on non-two's-complement machines.
280 If the result would be minval - 1, return minval. */
281 result
-= !TWOS_COMPLEMENT(int_fast64_t) && result
!= 0;
290 tzgetname(const timezone_t sp
, int isdst
)
293 const char *name
= NULL
;
294 for (i
= 0; i
< sp
->typecnt
; ++i
) {
295 const struct ttinfo
*const ttisp
= &sp
->ttis
[i
];
296 if (ttisp
->tt_isdst
== isdst
)
297 name
= &sp
->chars
[ttisp
->tt_desigidx
];
306 tzgetgmtoff(const timezone_t sp
, int isdst
)
310 for (i
= 0; i
< sp
->typecnt
; ++i
) {
311 const struct ttinfo
*const ttisp
= &sp
->ttis
[i
];
313 if (ttisp
->tt_isdst
== isdst
) {
323 scrub_abbrs(struct state
*sp
)
328 ** First, replace bogus characters.
330 for (i
= 0; i
< sp
->charcnt
; ++i
)
331 if (strchr(TZ_ABBR_CHAR_SET
, sp
->chars
[i
]) == NULL
)
332 sp
->chars
[i
] = TZ_ABBR_ERR_CHAR
;
334 ** Second, truncate long abbreviations.
336 for (i
= 0; i
< sp
->typecnt
; ++i
) {
337 const struct ttinfo
* const ttisp
= &sp
->ttis
[i
];
338 char *cp
= &sp
->chars
[ttisp
->tt_desigidx
];
340 if (strlen(cp
) > TZ_ABBR_MAX_LEN
&&
341 strcmp(cp
, GRANDPARENTED
) != 0)
342 *(cp
+ TZ_ABBR_MAX_LEN
) = '\0';
347 update_tzname_etc(const struct state
*sp
, const struct ttinfo
*ttisp
)
350 tzname
[ttisp
->tt_isdst
] = __UNCONST(&sp
->chars
[ttisp
->tt_desigidx
]);
353 if (!ttisp
->tt_isdst
)
354 timezone
= - ttisp
->tt_utoff
;
358 altzone
= - ttisp
->tt_utoff
;
359 #endif /* defined ALTZONE */
365 timezone_t
const sp
= __lclptr
;
369 tzname
[0] = tzname
[1] =
370 (__aconst
char *) __UNCONST(sp
? wildabbr
: gmt
);
378 #endif /* defined ALTZONE */
383 ** And to get the latest time zone abbreviations into tzname. . .
385 for (i
= 0; i
< sp
->typecnt
; ++i
)
386 update_tzname_etc(sp
, &sp
->ttis
[i
]);
388 for (i
= 0; i
< sp
->timecnt
; ++i
) {
389 const struct ttinfo
* const ttisp
= &sp
->ttis
[sp
->types
[i
]];
390 update_tzname_etc(sp
, ttisp
);
399 differ_by_repeat(const time_t t1
, const time_t t0
)
401 if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS
)
403 return (int_fast64_t)t1
- (int_fast64_t)t0
== SECSPERREPEAT
;
407 /* The first part of the buffer, interpreted as a header. */
408 struct tzhead tzhead
;
410 /* The entire buffer. */
411 char buf
[2 * sizeof(struct tzhead
) + 2 * sizeof (struct state
)
415 /* TZDIR with a trailing '/' rather than a trailing '\0'. */
416 static char const tzdirslash
[sizeof TZDIR
] = TZDIR
"/";
418 /* Local storage needed for 'tzloadbody'. */
419 union local_storage
{
420 /* The results of analyzing the file's contents after it is opened. */
421 struct file_analysis
{
422 /* The input buffer. */
423 union input_buffer u
;
425 /* A temporary state used for parsing a TZ string in the file. */
429 /* The file name to be opened. */
430 char fullname
[/*CONSTCOND*/BIGGEST(sizeof (struct file_analysis
),
431 sizeof tzdirslash
+ 1024)];
434 /* Load tz data from the file named NAME into *SP. Read extended
435 format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
436 success, an errno value on failure. */
438 tzloadbody(char const *name
, struct state
*sp
, bool doextend
,
439 union local_storage
*lsp
)
446 union input_buffer
*up
= &lsp
->u
.u
;
447 size_t tzheadsize
= sizeof(struct tzhead
);
449 sp
->goback
= sp
->goahead
= false;
459 #ifdef SUPPRESS_TZDIR
460 /* Do not prepend TZDIR. This is intended for specialized
461 applications only, due to its security implications. */
464 doaccess
= name
[0] == '/';
468 size_t namelen
= strlen(name
);
469 if (sizeof lsp
->fullname
- sizeof tzdirslash
<= namelen
)
472 /* Create a string "TZDIR/NAME". Using sprintf here
473 would pull in stdio (and would fail if the
474 resulting string length exceeded INT_MAX!). */
475 memcpy(lsp
->fullname
, tzdirslash
, sizeof tzdirslash
);
476 strcpy(lsp
->fullname
+ sizeof tzdirslash
, name
);
478 /* Set doaccess if NAME contains a ".." file name
479 component, as such a name could read a file outside
480 the TZDIR virtual subtree. */
481 for (dot
= name
; (dot
= strchr(dot
, '.')) != NULL
; dot
++)
482 if ((dot
== name
|| dot
[-1] == '/') && dot
[1] == '.'
483 && (dot
[2] == '/' || !dot
[2])) {
488 name
= lsp
->fullname
;
490 if (doaccess
&& access(name
, R_OK
) != 0)
493 fid
= open(name
, OPEN_MODE
);
496 nread
= read(fid
, up
->buf
, sizeof up
->buf
);
497 if (nread
< (ssize_t
)tzheadsize
) {
498 int err
= nread
< 0 ? errno
: EINVAL
;
504 for (stored
= 4; stored
<= 8; stored
*= 2) {
505 int_fast32_t ttisstdcnt
= detzcode(up
->tzhead
.tzh_ttisstdcnt
);
506 int_fast32_t ttisutcnt
= detzcode(up
->tzhead
.tzh_ttisutcnt
);
507 int_fast64_t prevtr
= 0;
508 int_fast32_t prevcorr
= 0;
509 int_fast32_t leapcnt
= detzcode(up
->tzhead
.tzh_leapcnt
);
510 int_fast32_t timecnt
= detzcode(up
->tzhead
.tzh_timecnt
);
511 int_fast32_t typecnt
= detzcode(up
->tzhead
.tzh_typecnt
);
512 int_fast32_t charcnt
= detzcode(up
->tzhead
.tzh_charcnt
);
513 char const *p
= up
->buf
+ tzheadsize
;
514 /* Although tzfile(5) currently requires typecnt to be nonzero,
515 support future formats that may allow zero typecnt
516 in files that have a TZ string and no transitions. */
517 if (! (0 <= leapcnt
&& leapcnt
< TZ_MAX_LEAPS
518 && 0 <= typecnt
&& typecnt
< TZ_MAX_TYPES
519 && 0 <= timecnt
&& timecnt
< TZ_MAX_TIMES
520 && 0 <= charcnt
&& charcnt
< TZ_MAX_CHARS
521 && (ttisstdcnt
== typecnt
|| ttisstdcnt
== 0)
522 && (ttisutcnt
== typecnt
|| ttisutcnt
== 0)))
525 < (tzheadsize
/* struct tzhead */
526 + timecnt
* stored
/* ats */
527 + timecnt
/* types */
528 + typecnt
* 6 /* ttinfos */
529 + charcnt
/* chars */
530 + leapcnt
* (stored
+ 4) /* lsinfos */
531 + ttisstdcnt
/* ttisstds */
532 + ttisutcnt
)) /* ttisuts */
534 sp
->leapcnt
= leapcnt
;
535 sp
->timecnt
= timecnt
;
536 sp
->typecnt
= typecnt
;
537 sp
->charcnt
= charcnt
;
539 /* Read transitions, discarding those out of time_t range.
540 But pretend the last transition before TIME_T_MIN
541 occurred at TIME_T_MIN. */
543 for (i
= 0; i
< sp
->timecnt
; ++i
) {
545 = stored
== 4 ? detzcode(p
) : detzcode64(p
);
546 sp
->types
[i
] = at
<= TIME_T_MAX
;
549 = ((TYPE_SIGNED(time_t) ?
550 at
< TIME_T_MIN
: at
< 0)
551 ? TIME_T_MIN
: (time_t)at
);
552 if (timecnt
&& attime
<= sp
->ats
[timecnt
- 1]) {
553 if (attime
< sp
->ats
[timecnt
- 1])
555 sp
->types
[i
- 1] = 0;
558 sp
->ats
[timecnt
++] = attime
;
564 for (i
= 0; i
< sp
->timecnt
; ++i
) {
565 unsigned char typ
= *p
++;
566 if (sp
->typecnt
<= typ
)
569 sp
->types
[timecnt
++] = typ
;
571 sp
->timecnt
= timecnt
;
572 for (i
= 0; i
< sp
->typecnt
; ++i
) {
573 struct ttinfo
* ttisp
;
574 unsigned char isdst
, desigidx
;
576 ttisp
= &sp
->ttis
[i
];
577 ttisp
->tt_utoff
= detzcode(p
);
582 ttisp
->tt_isdst
= isdst
;
584 if (! (desigidx
< sp
->charcnt
))
586 ttisp
->tt_desigidx
= desigidx
;
588 for (i
= 0; i
< sp
->charcnt
; ++i
)
590 sp
->chars
[i
] = '\0'; /* ensure '\0' at end */
592 /* Read leap seconds, discarding those out of time_t range. */
594 for (i
= 0; i
< sp
->leapcnt
; ++i
) {
595 int_fast64_t tr
= stored
== 4 ? detzcode(p
) :
597 int_fast32_t corr
= detzcode(p
+ stored
);
599 /* Leap seconds cannot occur before the Epoch. */
602 if (tr
<= TIME_T_MAX
) {
603 /* Leap seconds cannot occur more than once per UTC month,
604 and UTC months are at least 28 days long (minus 1
605 second for a negative leap second). Each leap second's
606 correction must differ from the previous one's by 1
608 if (tr
- prevtr
< 28 * SECSPERDAY
- 1
609 || (corr
!= prevcorr
- 1
610 && corr
!= prevcorr
+ 1))
613 sp
->lsis
[leapcnt
].ls_trans
=
614 (time_t)(prevtr
= tr
);
615 sp
->lsis
[leapcnt
].ls_corr
= prevcorr
= corr
;
619 sp
->leapcnt
= leapcnt
;
621 for (i
= 0; i
< sp
->typecnt
; ++i
) {
622 struct ttinfo
* ttisp
;
624 ttisp
= &sp
->ttis
[i
];
626 ttisp
->tt_ttisstd
= false;
628 if (*p
!= true && *p
!= false)
630 ttisp
->tt_ttisstd
= *p
++;
633 for (i
= 0; i
< sp
->typecnt
; ++i
) {
634 struct ttinfo
* ttisp
;
636 ttisp
= &sp
->ttis
[i
];
638 ttisp
->tt_ttisut
= false;
640 if (*p
!= true && *p
!= false)
642 ttisp
->tt_ttisut
= *p
++;
646 ** If this is an old file, we're done.
648 if (up
->tzhead
.tzh_version
[0] == '\0')
650 nread
-= p
- up
->buf
;
651 memmove(up
->buf
, p
, (size_t)nread
);
653 if (doextend
&& nread
> 2 &&
654 up
->buf
[0] == '\n' && up
->buf
[nread
- 1] == '\n' &&
655 sp
->typecnt
+ 2 <= TZ_MAX_TYPES
) {
656 struct state
*ts
= &lsp
->u
.st
;
658 up
->buf
[nread
- 1] = '\0';
659 if (tzparse(&up
->buf
[1], ts
, false)) {
661 /* Attempt to reuse existing abbreviations.
662 Without this, America/Anchorage would be right on
663 the edge after 2037 when TZ_MAX_CHARS is 50, as
664 sp->charcnt equals 40 (for LMT AST AWT APT AHST
665 AHDT YST AKDT AKST) and ts->charcnt equals 10
666 (for AKST AKDT). Reusing means sp->charcnt can
667 stay 40 in this example. */
669 int charcnt
= sp
->charcnt
;
670 for (i
= 0; i
< ts
->typecnt
; i
++) {
671 char *tsabbr
= ts
->chars
+ ts
->ttis
[i
].tt_desigidx
;
673 for (j
= 0; j
< charcnt
; j
++)
674 if (strcmp(sp
->chars
+ j
, tsabbr
) == 0) {
675 ts
->ttis
[i
].tt_desigidx
= j
;
679 if (! (j
< charcnt
)) {
680 size_t tsabbrlen
= strlen(tsabbr
);
681 if (j
+ tsabbrlen
< TZ_MAX_CHARS
) {
682 strcpy(sp
->chars
+ j
, tsabbr
);
683 charcnt
= (int_fast32_t)(j
+ tsabbrlen
+ 1);
684 ts
->ttis
[i
].tt_desigidx
= j
;
689 if (gotabbr
== ts
->typecnt
) {
690 sp
->charcnt
= charcnt
;
692 /* Ignore any trailing, no-op transitions generated
693 by zic as they don't help here and can run afoul
694 of bugs in zic 2016j or earlier. */
695 while (1 < sp
->timecnt
696 && (sp
->types
[sp
->timecnt
- 1]
697 == sp
->types
[sp
->timecnt
- 2]))
700 for (i
= 0; i
< ts
->timecnt
; i
++)
702 || sp
->ats
[sp
->timecnt
- 1] < ts
->ats
[i
])
704 while (i
< ts
->timecnt
705 && sp
->timecnt
< TZ_MAX_TIMES
) {
706 sp
->ats
[sp
->timecnt
] = ts
->ats
[i
];
707 sp
->types
[sp
->timecnt
] = (sp
->typecnt
712 for (i
= 0; i
< ts
->typecnt
; i
++)
713 sp
->ttis
[sp
->typecnt
++] = ts
->ttis
[i
];
717 if (sp
->typecnt
== 0)
719 if (sp
->timecnt
> 1) {
720 for (i
= 1; i
< sp
->timecnt
; ++i
)
721 if (typesequiv(sp
, sp
->types
[i
], sp
->types
[0]) &&
722 differ_by_repeat(sp
->ats
[i
], sp
->ats
[0])) {
726 for (i
= sp
->timecnt
- 2; i
>= 0; --i
)
727 if (typesequiv(sp
, sp
->types
[sp
->timecnt
- 1],
729 differ_by_repeat(sp
->ats
[sp
->timecnt
- 1],
736 /* Infer sp->defaulttype from the data. Although this default
737 type is always zero for data from recent tzdb releases,
738 things are trickier for data from tzdb 2018e or earlier.
740 The first set of heuristics work around bugs in 32-bit data
741 generated by tzdb 2013c or earlier. The workaround is for
742 zones like Australia/Macquarie where timestamps before the
743 first transition have a time type that is not the earliest
744 standard-time type. See:
745 https://mm.icann.org/pipermail/tz/2013-May/019368.html */
747 ** If type 0 is unused in transitions,
748 ** it's the type to use for early times.
750 for (i
= 0; i
< sp
->timecnt
; ++i
)
751 if (sp
->types
[i
] == 0)
753 i
= i
< sp
->timecnt
? -1 : 0;
756 ** if there are transition times
757 ** and the first transition is to a daylight time
758 ** find the standard type less than and closest to
759 ** the type of the first transition.
761 if (i
< 0 && sp
->timecnt
> 0 && sp
->ttis
[sp
->types
[0]].tt_isdst
) {
764 if (!sp
->ttis
[i
].tt_isdst
)
767 /* The next heuristics are for data generated by tzdb 2018e or
768 earlier, for zones like EST5EDT where the first transition
771 ** If no result yet, find the first standard type.
772 ** If there is none, punt to type zero.
776 while (sp
->ttis
[i
].tt_isdst
)
777 if (++i
>= sp
->typecnt
) {
782 /* A simple 'sp->defaulttype = 0;' would suffice here if we
783 didn't have to worry about 2018e-or-earlier data. Even
784 simpler would be to remove the defaulttype member and just
785 use 0 in its place. */
791 /* Load tz data from the file named NAME into *SP. Read extended
792 format if DOEXTEND. Return 0 on success, an errno value on failure. */
794 tzload(char const *name
, struct state
*sp
, bool doextend
)
796 union local_storage
*lsp
= malloc(sizeof *lsp
);
800 int err
= tzloadbody(name
, sp
, doextend
, lsp
);
807 typesequiv(const struct state
*sp
, int a
, int b
)
812 a
< 0 || a
>= sp
->typecnt
||
813 b
< 0 || b
>= sp
->typecnt
)
816 const struct ttinfo
* ap
= &sp
->ttis
[a
];
817 const struct ttinfo
* bp
= &sp
->ttis
[b
];
818 result
= (ap
->tt_utoff
== bp
->tt_utoff
819 && ap
->tt_isdst
== bp
->tt_isdst
820 && ap
->tt_ttisstd
== bp
->tt_ttisstd
821 && ap
->tt_ttisut
== bp
->tt_ttisut
822 && (strcmp(&sp
->chars
[ap
->tt_desigidx
],
823 &sp
->chars
[bp
->tt_desigidx
])
829 static const int mon_lengths
[2][MONSPERYEAR
] = {
830 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
831 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
834 static const int year_lengths
[2] = {
835 DAYSPERNYEAR
, DAYSPERLYEAR
839 ** Given a pointer into a timezone string, scan until a character that is not
840 ** a valid character in a time zone abbreviation is found.
841 ** Return a pointer to that character.
844 static ATTRIBUTE_PURE
const char *
845 getzname(const char *strp
)
849 while ((c
= *strp
) != '\0' && !is_digit(c
) && c
!= ',' && c
!= '-' &&
856 ** Given a pointer into an extended timezone string, scan until the ending
857 ** delimiter of the time zone abbreviation is located.
858 ** Return a pointer to the delimiter.
860 ** As with getzname above, the legal character set is actually quite
861 ** restricted, with other characters producing undefined results.
862 ** We don't do any checking here; checking is done later in common-case code.
865 static ATTRIBUTE_PURE
const char *
866 getqzname(const char *strp
, const int delim
)
870 while ((c
= *strp
) != '\0' && c
!= delim
)
876 ** Given a pointer into a timezone string, extract a number from that string.
877 ** Check that the number is within a specified range; if it is not, return
879 ** Otherwise, return a pointer to the first character not part of the number.
883 getnum(const char *strp
, int *const nump
, const int min
, const int max
)
888 if (strp
== NULL
|| !is_digit(c
= *strp
)) {
894 num
= num
* 10 + (c
- '0');
897 return NULL
; /* illegal value */
900 } while (is_digit(c
));
903 return NULL
; /* illegal value */
910 ** Given a pointer into a timezone string, extract a number of seconds,
911 ** in hh[:mm[:ss]] form, from the string.
912 ** If any error occurs, return NULL.
913 ** Otherwise, return a pointer to the first character not part of the number
918 getsecs(const char *strp
, int_fast32_t *const secsp
)
923 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
924 ** "M10.4.6/26", which does not conform to Posix,
925 ** but which specifies the equivalent of
926 ** "02:00 on the first Sunday on or after 23 Oct".
928 strp
= getnum(strp
, &num
, 0, HOURSPERDAY
* DAYSPERWEEK
- 1);
931 *secsp
= num
* (int_fast32_t) SECSPERHOUR
;
934 strp
= getnum(strp
, &num
, 0, MINSPERHOUR
- 1);
937 *secsp
+= num
* SECSPERMIN
;
940 /* 'SECSPERMIN' allows for leap seconds. */
941 strp
= getnum(strp
, &num
, 0, SECSPERMIN
);
951 ** Given a pointer into a timezone string, extract an offset, in
952 ** [+-]hh[:mm[:ss]] form, from the string.
953 ** If any error occurs, return NULL.
954 ** Otherwise, return a pointer to the first character not part of the time.
958 getoffset(const char *strp
, int_fast32_t *const offsetp
)
965 } else if (*strp
== '+')
967 strp
= getsecs(strp
, offsetp
);
969 return NULL
; /* illegal time */
971 *offsetp
= -*offsetp
;
976 ** Given a pointer into a timezone string, extract a rule in the form
977 ** date[/time]. See POSIX section 8 for the format of "date" and "time".
978 ** If a valid rule is not found, return NULL.
979 ** Otherwise, return a pointer to the first character not part of the rule.
983 getrule(const char *strp
, struct rule
*const rulep
)
989 rulep
->r_type
= JULIAN_DAY
;
991 strp
= getnum(strp
, &rulep
->r_day
, 1, DAYSPERNYEAR
);
992 } else if (*strp
== 'M') {
996 rulep
->r_type
= MONTH_NTH_DAY_OF_WEEK
;
998 strp
= getnum(strp
, &rulep
->r_mon
, 1, MONSPERYEAR
);
1003 strp
= getnum(strp
, &rulep
->r_week
, 1, 5);
1008 strp
= getnum(strp
, &rulep
->r_day
, 0, DAYSPERWEEK
- 1);
1009 } else if (is_digit(*strp
)) {
1013 rulep
->r_type
= DAY_OF_YEAR
;
1014 strp
= getnum(strp
, &rulep
->r_day
, 0, DAYSPERLYEAR
- 1);
1015 } else return NULL
; /* invalid format */
1023 strp
= getoffset(strp
, &rulep
->r_time
);
1024 } else rulep
->r_time
= 2 * SECSPERHOUR
; /* default = 2:00:00 */
1029 ** Given a year, a rule, and the offset from UT at the time that rule takes
1030 ** effect, calculate the year-relative time that rule takes effect.
1034 transtime(const int year
, const struct rule
*const rulep
,
1035 const int_fast32_t offset
)
1040 int d
, m1
, yy0
, yy1
, yy2
, dow
;
1043 leapyear
= isleap(year
);
1044 switch (rulep
->r_type
) {
1048 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
1050 ** In non-leap years, or if the day number is 59 or less, just
1051 ** add SECSPERDAY times the day number-1 to the time of
1052 ** January 1, midnight, to get the day.
1054 value
= (rulep
->r_day
- 1) * SECSPERDAY
;
1055 if (leapyear
&& rulep
->r_day
>= 60)
1056 value
+= SECSPERDAY
;
1062 ** Just add SECSPERDAY times the day number to the time of
1063 ** January 1, midnight, to get the day.
1065 value
= rulep
->r_day
* SECSPERDAY
;
1068 case MONTH_NTH_DAY_OF_WEEK
:
1070 ** Mm.n.d - nth "dth day" of month m.
1074 ** Use Zeller's Congruence to get day-of-week of first day of
1077 m1
= (rulep
->r_mon
+ 9) % 12 + 1;
1078 yy0
= (rulep
->r_mon
<= 2) ? (year
- 1) : year
;
1081 dow
= ((26 * m1
- 2) / 10 +
1082 1 + yy2
+ yy2
/ 4 + yy1
/ 4 - 2 * yy1
) % 7;
1087 ** "dow" is the day-of-week of the first day of the month. Get
1088 ** the day-of-month (zero-origin) of the first "dow" day of the
1091 d
= rulep
->r_day
- dow
;
1094 for (i
= 1; i
< rulep
->r_week
; ++i
) {
1095 if (d
+ DAYSPERWEEK
>=
1096 mon_lengths
[leapyear
][rulep
->r_mon
- 1])
1102 ** "d" is the day-of-month (zero-origin) of the day we want.
1104 value
= d
* SECSPERDAY
;
1105 for (i
= 0; i
< rulep
->r_mon
- 1; ++i
)
1106 value
+= mon_lengths
[leapyear
][i
] * SECSPERDAY
;
1111 ** "value" is the year-relative time of 00:00:00 UT on the day in
1112 ** question. To get the year-relative time of the specified local
1113 ** time on that day, add the transition time and the current offset
1116 return value
+ rulep
->r_time
+ offset
;
1120 ** Given a POSIX section 8-style TZ string, fill in the rule tables as
1125 tzparse(const char *name
, struct state
*sp
, bool lastditch
)
1127 const char * stdname
;
1128 const char * dstname
;
1132 int_fast32_t stdoffset
;
1133 int_fast32_t dstoffset
;
1137 dstname
= NULL
; /* XXX gcc */
1140 stdlen
= sizeof gmt
- 1;
1147 name
= getqzname(name
, '>');
1150 stdlen
= name
- stdname
;
1153 name
= getzname(name
);
1154 stdlen
= name
- stdname
;
1158 name
= getoffset(name
, &stdoffset
);
1162 charcnt
= stdlen
+ 1;
1163 if (sizeof sp
->chars
< charcnt
)
1165 load_ok
= tzload(TZDEFRULES
, sp
, false) == 0;
1167 sp
->leapcnt
= 0; /* so, we're off a little */
1168 if (*name
!= '\0') {
1171 name
= getqzname(name
, '>');
1174 dstlen
= name
- dstname
;
1178 name
= getzname(name
);
1179 dstlen
= name
- dstname
; /* length of DST abbr. */
1183 charcnt
+= dstlen
+ 1;
1184 if (sizeof sp
->chars
< charcnt
)
1186 if (*name
!= '\0' && *name
!= ',' && *name
!= ';') {
1187 name
= getoffset(name
, &dstoffset
);
1190 } else dstoffset
= stdoffset
- SECSPERHOUR
;
1191 if (*name
== '\0' && !load_ok
)
1192 name
= TZDEFRULESTRING
;
1193 if (*name
== ',' || *name
== ';') {
1200 int_fast32_t janoffset
= 0;
1204 if ((name
= getrule(name
, &start
)) == NULL
)
1208 if ((name
= getrule(name
, &end
)) == NULL
)
1212 sp
->typecnt
= 2; /* standard time and DST */
1214 ** Two transitions per year, from EPOCH_YEAR forward.
1216 init_ttinfo(&sp
->ttis
[0], -stdoffset
, false, 0);
1217 init_ttinfo(&sp
->ttis
[1], -dstoffset
, true,
1219 sp
->defaulttype
= 0;
1222 yearbeg
= EPOCH_YEAR
;
1225 int_fast32_t yearsecs
1226 = year_lengths
[isleap(yearbeg
- 1)] * SECSPERDAY
;
1228 if (increment_overflow_time(&janfirst
, -yearsecs
)) {
1229 janoffset
= -yearsecs
;
1232 } while (EPOCH_YEAR
- YEARSPERREPEAT
/ 2 < yearbeg
);
1234 yearlim
= yearbeg
+ YEARSPERREPEAT
+ 1;
1235 for (year
= yearbeg
; year
< yearlim
; year
++) {
1237 starttime
= transtime(year
, &start
, stdoffset
),
1238 endtime
= transtime(year
, &end
, dstoffset
);
1240 yearsecs
= (year_lengths
[isleap(year
)]
1242 bool reversed
= endtime
< starttime
;
1244 int_fast32_t swap
= starttime
;
1245 starttime
= endtime
;
1249 || (starttime
< endtime
1250 && (endtime
- starttime
1252 + (stdoffset
- dstoffset
))))) {
1253 if (TZ_MAX_TIMES
- 2 < timecnt
)
1255 sp
->ats
[timecnt
] = janfirst
;
1256 if (! increment_overflow_time
1258 janoffset
+ starttime
))
1259 sp
->types
[timecnt
++] = !reversed
;
1260 sp
->ats
[timecnt
] = janfirst
;
1261 if (! increment_overflow_time
1263 janoffset
+ endtime
)) {
1264 sp
->types
[timecnt
++] = reversed
;
1265 yearlim
= year
+ YEARSPERREPEAT
+ 1;
1268 if (increment_overflow_time
1269 (&janfirst
, janoffset
+ yearsecs
))
1273 sp
->timecnt
= timecnt
;
1275 sp
->ttis
[0] = sp
->ttis
[1];
1276 sp
->typecnt
= 1; /* Perpetual DST. */
1277 } else if (YEARSPERREPEAT
< year
- yearbeg
)
1278 sp
->goback
= sp
->goahead
= true;
1280 int_fast32_t theirstdoffset
;
1281 int_fast32_t theirdstoffset
;
1282 int_fast32_t theiroffset
;
1290 ** Initial values of theirstdoffset and theirdstoffset.
1293 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1295 if (!sp
->ttis
[j
].tt_isdst
) {
1297 - sp
->ttis
[j
].tt_utoff
;
1302 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1304 if (sp
->ttis
[j
].tt_isdst
) {
1306 - sp
->ttis
[j
].tt_utoff
;
1311 ** Initially we're assumed to be in standard time.
1314 theiroffset
= theirstdoffset
;
1316 ** Now juggle transition times and types
1317 ** tracking offsets as you do.
1319 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1321 sp
->types
[i
] = sp
->ttis
[j
].tt_isdst
;
1322 if (sp
->ttis
[j
].tt_ttisut
) {
1323 /* No adjustment to transition time */
1326 ** If daylight saving time is in
1327 ** effect, and the transition time was
1328 ** not specified as standard time, add
1329 ** the daylight saving time offset to
1330 ** the transition time; otherwise, add
1331 ** the standard time offset to the
1335 ** Transitions from DST to DDST
1336 ** will effectively disappear since
1337 ** POSIX provides for only one DST
1340 if (isdst
&& !sp
->ttis
[j
].tt_ttisstd
) {
1341 sp
->ats
[i
] += (time_t)
1342 (dstoffset
- theirdstoffset
);
1344 sp
->ats
[i
] += (time_t)
1345 (stdoffset
- theirstdoffset
);
1348 theiroffset
= -sp
->ttis
[j
].tt_utoff
;
1349 if (sp
->ttis
[j
].tt_isdst
)
1350 theirstdoffset
= theiroffset
;
1351 else theirdstoffset
= theiroffset
;
1354 ** Finally, fill in ttis.
1356 init_ttinfo(&sp
->ttis
[0], -stdoffset
, false, 0);
1357 init_ttinfo(&sp
->ttis
[1], -dstoffset
, true,
1360 sp
->defaulttype
= 0;
1364 sp
->typecnt
= 1; /* only standard time */
1366 init_ttinfo(&sp
->ttis
[0], -stdoffset
, false, 0);
1367 init_ttinfo(&sp
->ttis
[1], 0, false, 0);
1368 sp
->defaulttype
= 0;
1370 sp
->charcnt
= (int)charcnt
;
1372 (void) memcpy(cp
, stdname
, stdlen
);
1376 (void) memcpy(cp
, dstname
, dstlen
);
1377 *(cp
+ dstlen
) = '\0';
1383 gmtload(struct state
*const sp
)
1385 if (tzload(gmt
, sp
, true) != 0)
1386 (void) tzparse(gmt
, sp
, true);
1390 zoneinit(struct state
*sp
, char const *name
)
1392 if (name
&& ! name
[0]) {
1394 ** User wants it fast rather than right.
1396 sp
->leapcnt
= 0; /* so, we're off a little */
1400 sp
->goback
= sp
->goahead
= false;
1401 init_ttinfo(&sp
->ttis
[0], 0, false, 0);
1402 strcpy(sp
->chars
, gmt
);
1403 sp
->defaulttype
= 0;
1406 int err
= tzload(name
, sp
, true);
1407 if (err
!= 0 && name
&& name
[0] != ':' &&
1408 tzparse(name
, sp
, false))
1417 tzsetlcl(char const *name
)
1419 struct state
*sp
= __lclptr
;
1420 int lcl
= name
? strlen(name
) < sizeof lcl_TZname
: -1;
1421 if (lcl
< 0 ? lcl_is_set
< 0
1422 : 0 < lcl_is_set
&& strcmp(lcl_TZname
, name
) == 0)
1426 __lclptr
= sp
= malloc(sizeof *__lclptr
);
1428 if (zoneinit(sp
, name
) != 0)
1431 strcpy(lcl_TZname
, name
);
1441 rwlock_wrlock(&__lcl_lock
);
1443 rwlock_unlock(&__lcl_lock
);
1448 tzset_unlocked(void)
1450 tzsetlcl(getenv("TZ"));
1456 rwlock_wrlock(&__lcl_lock
);
1458 rwlock_unlock(&__lcl_lock
);
1464 static bool gmt_is_set
;
1465 rwlock_wrlock(&__lcl_lock
);
1467 gmtptr
= malloc(sizeof *gmtptr
);
1472 rwlock_unlock(&__lcl_lock
);
1478 tzalloc(const char *name
)
1480 timezone_t sp
= malloc(sizeof *sp
);
1482 int err
= zoneinit(sp
, name
);
1493 tzfree(timezone_t sp
)
1499 ** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
1500 ** ctime_r are obsolescent and have potential security problems that
1501 ** ctime_rz would share. Callers can instead use localtime_rz + strftime.
1503 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
1504 ** in zones with three or more time zone abbreviations.
1505 ** Callers can instead use localtime_rz + strftime.
1511 ** The easy way to behave "as if no library function calls" localtime
1512 ** is to not call it, so we drop its guts into "localsub", which can be
1513 ** freely called. (And no, the PANS doesn't require the above behavior,
1514 ** but it *is* desirable.)
1516 ** If successful and SETNAME is nonzero,
1517 ** set the applicable parts of tzname, timezone and altzone;
1518 ** however, it's OK to omit this step if the timezone is POSIX-compatible,
1519 ** since in that case tzset should have already done this step correctly.
1520 ** SETNAME's type is intfast32_t for compatibility with gmtsub,
1521 ** but it is actually a boolean and its value should be 0 or 1.
1526 localsub(struct state
const *sp
, time_t const *timep
, int_fast32_t setname
,
1527 struct tm
*const tmp
)
1529 const struct ttinfo
* ttisp
;
1532 const time_t t
= *timep
;
1535 /* Don't bother to set tzname etc.; tzset has already done it. */
1536 return gmtsub(gmtptr
, timep
, 0, tmp
);
1538 if ((sp
->goback
&& t
< sp
->ats
[0]) ||
1539 (sp
->goahead
&& t
> sp
->ats
[sp
->timecnt
- 1])) {
1545 seconds
= sp
->ats
[0] - t
;
1546 else seconds
= t
- sp
->ats
[sp
->timecnt
- 1];
1548 years
= (time_t)((seconds
/ SECSPERREPEAT
+ 1) * YEARSPERREPEAT
);
1549 seconds
= (time_t)(years
* AVGSECSPERYEAR
);
1552 else newt
-= seconds
;
1553 if (newt
< sp
->ats
[0] ||
1554 newt
> sp
->ats
[sp
->timecnt
- 1]) {
1556 return NULL
; /* "cannot happen" */
1558 result
= localsub(sp
, &newt
, setname
, tmp
);
1562 newy
= result
->tm_year
;
1566 if (! (INT_MIN
<= newy
&& newy
<= INT_MAX
)) {
1570 result
->tm_year
= (int)newy
;
1574 if (sp
->timecnt
== 0 || t
< sp
->ats
[0]) {
1575 i
= sp
->defaulttype
;
1578 int hi
= sp
->timecnt
;
1581 int mid
= (lo
+ hi
) / 2;
1583 if (t
< sp
->ats
[mid
])
1587 i
= (int) sp
->types
[lo
- 1];
1589 ttisp
= &sp
->ttis
[i
];
1591 ** To get (wrong) behavior that's compatible with System V Release 2.0
1592 ** you'd replace the statement below with
1593 ** t += ttisp->tt_utoff;
1594 ** timesub(&t, 0L, sp, tmp);
1596 result
= timesub(&t
, ttisp
->tt_utoff
, sp
, tmp
);
1598 result
->tm_isdst
= ttisp
->tt_isdst
;
1600 result
->TM_ZONE
= __UNCONST(&sp
->chars
[ttisp
->tt_desigidx
]);
1601 #endif /* defined TM_ZONE */
1603 update_tzname_etc(sp
, ttisp
);
1611 localtime_rz(timezone_t sp
, time_t const *timep
, struct tm
*tmp
)
1613 return localsub(sp
, timep
, 0, tmp
);
1619 localtime_tzset(time_t const *timep
, struct tm
*tmp
, bool setname
)
1621 rwlock_wrlock(&__lcl_lock
);
1622 if (setname
|| !lcl_is_set
)
1624 tmp
= localsub(__lclptr
, timep
, setname
, tmp
);
1625 rwlock_unlock(&__lcl_lock
);
1630 localtime(const time_t *timep
)
1632 return localtime_tzset(timep
, &tm
, true);
1636 localtime_r(const time_t * __restrict timep
, struct tm
*tmp
)
1638 return localtime_tzset(timep
, tmp
, true);
1642 ** gmtsub is to gmtime as localsub is to localtime.
1646 gmtsub(struct state
const *sp
, const time_t *timep
, int_fast32_t offset
,
1651 result
= timesub(timep
, offset
, gmtptr
, tmp
);
1654 ** Could get fancy here and deliver something such as
1655 ** "+xx" or "-xx" if offset is non-zero,
1656 ** but this is no time for a treasure hunt.
1659 result
->TM_ZONE
= offset
? __UNCONST(wildabbr
) : gmtptr
?
1660 gmtptr
->chars
: __UNCONST(gmt
);
1661 #endif /* defined TM_ZONE */
1667 ** Re-entrant version of gmtime.
1671 gmtime_r(const time_t *timep
, struct tm
*tmp
)
1674 return gmtsub(NULL
, timep
, 0, tmp
);
1678 gmtime(const time_t *timep
)
1680 return gmtime_r(timep
, &tm
);
1685 offtime(const time_t *timep
, long offset
)
1688 return gmtsub(gmtptr
, timep
, (int_fast32_t)offset
, &tm
);
1692 offtime_r(const time_t *timep
, long offset
, struct tm
*tmp
)
1695 return gmtsub(NULL
, timep
, (int_fast32_t)offset
, tmp
);
1698 #endif /* defined STD_INSPIRED */
1710 /* Convert from the underlying system's time_t to the ersatz time_tz,
1711 which is called 'time_t' in this file. Typically, this merely
1712 converts the time's integer width. On some platforms, the system
1713 time is local time not UT, or uses some epoch other than the POSIX
1716 Although this code appears to define a function named 'time' that
1717 returns time_t, the macros in private.h cause this code to actually
1718 define a function named 'tz_time' that returns tz_time_t. The call
1719 to sys_time invokes the underlying system's 'time' function. */
1724 time_t r
= sys_time(0);
1725 if (r
!= (time_t) -1) {
1726 int_fast32_t offset
= EPOCH_LOCAL
? (daylight
? timezone
: altzone
) : 0;
1727 if (increment_overflow32(&offset
, -EPOCH_OFFSET
)
1728 || increment_overflow_time (&r
, offset
)) {
1740 ** Return the number of leap years through the end of the given year
1741 ** where, to make the math easy, the answer for year zero is defined as zero.
1744 leaps_thru_end_of_nonneg(int y
)
1746 return y
/ 4 - y
/ 100 + y
/ 400;
1749 static int ATTRIBUTE_PURE
1750 leaps_thru_end_of(const int y
)
1753 ? -1 - leaps_thru_end_of_nonneg(-1 - y
)
1754 : leaps_thru_end_of_nonneg(y
));
1758 timesub(const time_t *timep
, int_fast32_t offset
,
1759 const struct state
*sp
, struct tm
*tmp
)
1761 const struct lsinfo
* lp
;
1763 int idays
; /* unsigned would be so 2003 */
1773 i
= (sp
== NULL
) ? 0 : sp
->leapcnt
;
1776 if (*timep
>= lp
->ls_trans
) {
1778 hit
= (*timep
== lp
->ls_trans
1779 && (i
== 0 ? 0 : lp
[-1].ls_corr
) < corr
);
1784 tdays
= (time_t)(*timep
/ SECSPERDAY
);
1785 rem
= *timep
% SECSPERDAY
;
1786 while (tdays
< 0 || tdays
>= year_lengths
[isleap(y
)]) {
1792 tdelta
= tdays
/ DAYSPERLYEAR
;
1793 if (! ((! TYPE_SIGNED(time_t) || INT_MIN
<= tdelta
)
1794 && tdelta
<= INT_MAX
))
1796 _DIAGASSERT(__type_fit(int, tdelta
));
1797 idelta
= (int)tdelta
;
1799 idelta
= (tdays
< 0) ? -1 : 1;
1801 if (increment_overflow(&newy
, idelta
))
1803 leapdays
= leaps_thru_end_of(newy
- 1) -
1804 leaps_thru_end_of(y
- 1);
1805 tdays
-= ((time_t) newy
- y
) * DAYSPERNYEAR
;
1810 ** Given the range, we can now fearlessly cast...
1812 idays
= (int) tdays
;
1813 rem
+= offset
- corr
;
1818 while (rem
>= SECSPERDAY
) {
1823 if (increment_overflow(&y
, -1))
1825 idays
+= year_lengths
[isleap(y
)];
1827 while (idays
>= year_lengths
[isleap(y
)]) {
1828 idays
-= year_lengths
[isleap(y
)];
1829 if (increment_overflow(&y
, 1))
1833 if (increment_overflow(&tmp
->tm_year
, -TM_YEAR_BASE
))
1835 tmp
->tm_yday
= idays
;
1837 ** The "extra" mods below avoid overflow problems.
1839 tmp
->tm_wday
= EPOCH_WDAY
+
1840 ((y
- EPOCH_YEAR
) % DAYSPERWEEK
) *
1841 (DAYSPERNYEAR
% DAYSPERWEEK
) +
1842 leaps_thru_end_of(y
- 1) -
1843 leaps_thru_end_of(EPOCH_YEAR
- 1) +
1845 tmp
->tm_wday
%= DAYSPERWEEK
;
1846 if (tmp
->tm_wday
< 0)
1847 tmp
->tm_wday
+= DAYSPERWEEK
;
1848 tmp
->tm_hour
= (int) (rem
/ SECSPERHOUR
);
1850 tmp
->tm_min
= (int) (rem
/ SECSPERMIN
);
1852 ** A positive leap second requires a special
1853 ** representation. This uses "... ??:59:60" et seq.
1855 tmp
->tm_sec
= (int) (rem
% SECSPERMIN
) + hit
;
1856 ip
= mon_lengths
[isleap(y
)];
1857 for (tmp
->tm_mon
= 0; idays
>= ip
[tmp
->tm_mon
]; ++(tmp
->tm_mon
))
1858 idays
-= ip
[tmp
->tm_mon
];
1859 tmp
->tm_mday
= (int) (idays
+ 1);
1862 tmp
->TM_GMTOFF
= offset
;
1863 #endif /* defined TM_GMTOFF */
1871 ctime(const time_t *timep
)
1874 ** Section 4.12.3.2 of X3.159-1989 requires that
1875 ** The ctime function converts the calendar time pointed to by timer
1876 ** to local time in the form of a string. It is equivalent to
1877 ** asctime(localtime(timer))
1879 struct tm
*tmp
= localtime(timep
);
1880 return tmp
? asctime(tmp
) : NULL
;
1884 ctime_r(const time_t *timep
, char *buf
)
1887 struct tm
*tmp
= localtime_r(timep
, &mytm
);
1888 return tmp
? asctime_r(tmp
, buf
) : NULL
;
1892 ctime_rz(const timezone_t sp
, const time_t * timep
, char *buf
)
1894 struct tm mytm
, *rtm
;
1896 rtm
= localtime_rz(sp
, timep
, &mytm
);
1899 return asctime_r(rtm
, buf
);
1903 ** Adapted from code provided by Robert Elz, who writes:
1904 ** The "best" way to do mktime I think is based on an idea of Bob
1905 ** Kridle's (so its said...) from a long time ago.
1906 ** It does a binary search of the time_t space. Since time_t's are
1907 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
1908 ** would still be very reasonable).
1912 #define WRONG ((time_t)-1)
1913 #endif /* !defined WRONG */
1916 ** Normalize logic courtesy Paul Eggert.
1920 increment_overflow(int *ip
, int j
)
1925 ** If i >= 0 there can only be overflow if i + j > INT_MAX
1926 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1927 ** If i < 0 there can only be overflow if i + j < INT_MIN
1928 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1930 if ((i
>= 0) ? (j
> INT_MAX
- i
) : (j
< INT_MIN
- i
))
1937 increment_overflow32(int_fast32_t *const lp
, int const m
)
1939 int_fast32_t const l
= *lp
;
1941 if ((l
>= 0) ? (m
> INT_FAST32_MAX
- l
) : (m
< INT_FAST32_MIN
- l
))
1948 increment_overflow_time(time_t *tp
, int_fast32_t j
)
1952 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
1953 ** except that it does the right thing even if *tp + j would overflow.
1956 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN
- j
<= *tp
: -1 - j
< *tp
)
1957 : *tp
<= TIME_T_MAX
- j
))
1964 normalize_overflow(int *const tensptr
, int *const unitsptr
, const int base
)
1968 tensdelta
= (*unitsptr
>= 0) ?
1969 (*unitsptr
/ base
) :
1970 (-1 - (-1 - *unitsptr
) / base
);
1971 *unitsptr
-= tensdelta
* base
;
1972 return increment_overflow(tensptr
, tensdelta
);
1976 normalize_overflow32(int_fast32_t *tensptr
, int *unitsptr
, int base
)
1980 tensdelta
= (*unitsptr
>= 0) ?
1981 (*unitsptr
/ base
) :
1982 (-1 - (-1 - *unitsptr
) / base
);
1983 *unitsptr
-= tensdelta
* base
;
1984 return increment_overflow32(tensptr
, tensdelta
);
1988 tmcomp(const struct tm
*const atmp
,
1989 const struct tm
*const btmp
)
1993 if (atmp
->tm_year
!= btmp
->tm_year
)
1994 return atmp
->tm_year
< btmp
->tm_year
? -1 : 1;
1995 if ((result
= (atmp
->tm_mon
- btmp
->tm_mon
)) == 0 &&
1996 (result
= (atmp
->tm_mday
- btmp
->tm_mday
)) == 0 &&
1997 (result
= (atmp
->tm_hour
- btmp
->tm_hour
)) == 0 &&
1998 (result
= (atmp
->tm_min
- btmp
->tm_min
)) == 0)
1999 result
= atmp
->tm_sec
- btmp
->tm_sec
;
2004 time2sub(struct tm
*const tmp
,
2005 struct tm
*(*funcp
)(struct state
const *, time_t const *,
2006 int_fast32_t, struct tm
*),
2007 struct state
const *sp
,
2008 const int_fast32_t offset
,
2018 #ifdef NO_ERROR_IN_DST_GAP
2024 struct tm yourtm
, mytm
;
2028 #ifdef NO_ERROR_IN_DST_GAP
2032 if (normalize_overflow(&yourtm
.tm_min
, &yourtm
.tm_sec
,
2036 if (normalize_overflow(&yourtm
.tm_hour
, &yourtm
.tm_min
, MINSPERHOUR
))
2038 if (normalize_overflow(&yourtm
.tm_mday
, &yourtm
.tm_hour
, HOURSPERDAY
))
2041 if (normalize_overflow32(&y
, &yourtm
.tm_mon
, MONSPERYEAR
))
2044 ** Turn y into an actual year number for now.
2045 ** It is converted back to an offset from TM_YEAR_BASE later.
2047 if (increment_overflow32(&y
, TM_YEAR_BASE
))
2049 while (yourtm
.tm_mday
<= 0) {
2050 if (increment_overflow32(&y
, -1))
2052 li
= y
+ (1 < yourtm
.tm_mon
);
2053 yourtm
.tm_mday
+= year_lengths
[isleap(li
)];
2055 while (yourtm
.tm_mday
> DAYSPERLYEAR
) {
2056 li
= y
+ (1 < yourtm
.tm_mon
);
2057 yourtm
.tm_mday
-= year_lengths
[isleap(li
)];
2058 if (increment_overflow32(&y
, 1))
2062 i
= mon_lengths
[isleap(y
)][yourtm
.tm_mon
];
2063 if (yourtm
.tm_mday
<= i
)
2065 yourtm
.tm_mday
-= i
;
2066 if (++yourtm
.tm_mon
>= MONSPERYEAR
) {
2068 if (increment_overflow32(&y
, 1))
2072 if (increment_overflow32(&y
, -TM_YEAR_BASE
))
2074 if (! (INT_MIN
<= y
&& y
<= INT_MAX
))
2076 yourtm
.tm_year
= (int)y
;
2077 if (yourtm
.tm_sec
>= 0 && yourtm
.tm_sec
< SECSPERMIN
)
2079 else if (y
+ TM_YEAR_BASE
< EPOCH_YEAR
) {
2081 ** We can't set tm_sec to 0, because that might push the
2082 ** time below the minimum representable time.
2083 ** Set tm_sec to 59 instead.
2084 ** This assumes that the minimum representable time is
2085 ** not in the same minute that a leap second was deleted from,
2086 ** which is a safer assumption than using 58 would be.
2088 if (increment_overflow(&yourtm
.tm_sec
, 1 - SECSPERMIN
))
2090 saved_seconds
= yourtm
.tm_sec
;
2091 yourtm
.tm_sec
= SECSPERMIN
- 1;
2093 saved_seconds
= yourtm
.tm_sec
;
2097 ** Do a binary search (this works whatever time_t's type is).
2101 #ifdef NO_ERROR_IN_DST_GAP
2105 t
= lo
/ 2 + hi
/ 2;
2110 if (! funcp(sp
, &t
, offset
, &mytm
)) {
2112 ** Assume that t is too extreme to be represented in
2113 ** a struct tm; arrange things so that it is less
2114 ** extreme on the next pass.
2116 dir
= (t
> 0) ? 1 : -1;
2117 } else dir
= tmcomp(&mytm
, &yourtm
);
2120 if (t
== TIME_T_MAX
)
2124 } else if (t
== hi
) {
2125 if (t
== TIME_T_MIN
)
2130 #ifdef NO_ERROR_IN_DST_GAP
2131 if (ilo
!= lo
&& lo
- 1 == hi
&& yourtm
.tm_isdst
< 0 &&
2133 for (i
= sp
->typecnt
- 1; i
>= 0; --i
) {
2134 for (j
= sp
->typecnt
- 1; j
>= 0; --j
) {
2136 if (sp
->ttis
[j
].tt_isdst
==
2137 sp
->ttis
[i
].tt_isdst
)
2139 off
= sp
->ttis
[j
].tt_utoff
-
2140 sp
->ttis
[i
].tt_utoff
;
2141 yourtm
.tm_sec
+= off
< 0 ?
2155 #if defined TM_GMTOFF && ! UNINIT_TRAP
2156 if (mytm
.TM_GMTOFF
!= yourtm
.TM_GMTOFF
2157 && (yourtm
.TM_GMTOFF
< 0
2158 ? (-SECSPERDAY
<= yourtm
.TM_GMTOFF
2159 && (mytm
.TM_GMTOFF
<=
2160 (/*CONSTCOND*/SMALLEST (INT_FAST32_MAX
, LONG_MAX
)
2161 + yourtm
.TM_GMTOFF
)))
2162 : (yourtm
.TM_GMTOFF
<= SECSPERDAY
2163 && ((/*CONSTCOND*/BIGGEST (INT_FAST32_MIN
, LONG_MIN
)
2165 <= mytm
.TM_GMTOFF
)))) {
2166 /* MYTM matches YOURTM except with the wrong UT offset.
2167 YOURTM.TM_GMTOFF is plausible, so try it instead.
2168 It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
2169 since the guess gets checked. */
2171 int_fast32_t diff
= (int_fast32_t)
2172 (mytm
.TM_GMTOFF
- yourtm
.TM_GMTOFF
);
2173 if (!increment_overflow_time(&altt
, diff
)) {
2175 if (! funcp(sp
, &altt
, offset
, &alttm
)
2176 && alttm
.tm_isdst
== mytm
.tm_isdst
2177 && alttm
.TM_GMTOFF
== yourtm
.TM_GMTOFF
2178 && tmcomp(&alttm
, &yourtm
)) {
2185 if (yourtm
.tm_isdst
< 0 || mytm
.tm_isdst
== yourtm
.tm_isdst
)
2188 ** Right time, wrong type.
2189 ** Hunt for right time, right type.
2190 ** It's okay to guess wrong since the guess
2195 for (i
= sp
->typecnt
- 1; i
>= 0; --i
) {
2196 if (sp
->ttis
[i
].tt_isdst
!= yourtm
.tm_isdst
)
2198 for (j
= sp
->typecnt
- 1; j
>= 0; --j
) {
2199 if (sp
->ttis
[j
].tt_isdst
== yourtm
.tm_isdst
)
2201 newt
= (time_t)(t
+ sp
->ttis
[j
].tt_utoff
-
2202 sp
->ttis
[i
].tt_utoff
);
2203 if (! funcp(sp
, &newt
, offset
, &mytm
))
2205 if (tmcomp(&mytm
, &yourtm
) != 0)
2207 if (mytm
.tm_isdst
!= yourtm
.tm_isdst
)
2219 newt
= t
+ saved_seconds
;
2220 if ((newt
< t
) != (saved_seconds
< 0))
2223 if (funcp(sp
, &t
, offset
, tmp
)) {
2236 time2(struct tm
* const tmp
,
2237 struct tm
*(*funcp
)(struct state
const *, time_t const *,
2238 int_fast32_t, struct tm
*),
2239 struct state
const *sp
,
2240 const int_fast32_t offset
,
2246 ** First try without normalization of seconds
2247 ** (in case tm_sec contains a value associated with a leap second).
2248 ** If that fails, try with normalization of seconds.
2250 t
= time2sub(tmp
, funcp
, sp
, offset
, okayp
, false);
2251 return *okayp
? t
: time2sub(tmp
, funcp
, sp
, offset
, okayp
, true);
2255 time1(struct tm
*const tmp
,
2256 struct tm
*(*funcp
) (struct state
const *, time_t const *,
2257 int_fast32_t, struct tm
*),
2258 struct state
const *sp
,
2259 const int_fast32_t offset
)
2263 int sameind
, otherind
;
2267 char seen
[TZ_MAX_TYPES
];
2268 unsigned char types
[TZ_MAX_TYPES
];
2275 if (tmp
->tm_isdst
> 1)
2278 t
= time2(tmp
, funcp
, sp
, offset
, &okay
);
2283 if (tmp
->tm_isdst
< 0)
2286 ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2288 tmp
->tm_isdst
= 0; /* reset to std and try again */
2291 #endif /* !defined PCTS */
2293 ** We're supposed to assume that somebody took a time of one type
2294 ** and did some math on it that yielded a "struct tm" that's bad.
2295 ** We try to divine the type they started from and adjust to the
2302 for (i
= 0; i
< sp
->typecnt
; ++i
)
2305 for (i
= sp
->timecnt
- 1; i
>= 0; --i
)
2306 if (!seen
[sp
->types
[i
]]) {
2307 seen
[sp
->types
[i
]] = true;
2308 types
[nseen
++] = sp
->types
[i
];
2310 for (sameind
= 0; sameind
< nseen
; ++sameind
) {
2311 samei
= types
[sameind
];
2312 if (sp
->ttis
[samei
].tt_isdst
!= tmp
->tm_isdst
)
2314 for (otherind
= 0; otherind
< nseen
; ++otherind
) {
2315 otheri
= types
[otherind
];
2316 if (sp
->ttis
[otheri
].tt_isdst
== tmp
->tm_isdst
)
2318 tmp
->tm_sec
+= (int)(sp
->ttis
[otheri
].tt_utoff
-
2319 sp
->ttis
[samei
].tt_utoff
);
2320 tmp
->tm_isdst
= !tmp
->tm_isdst
;
2321 t
= time2(tmp
, funcp
, sp
, offset
, &okay
);
2326 tmp
->tm_sec
-= (int)(sp
->ttis
[otheri
].tt_utoff
-
2327 sp
->ttis
[samei
].tt_utoff
);
2328 tmp
->tm_isdst
= !tmp
->tm_isdst
;
2336 mktime_tzname(timezone_t sp
, struct tm
*tmp
, bool setname
)
2339 return time1(tmp
, localsub
, sp
, setname
);
2342 return time1(tmp
, gmtsub
, gmtptr
, 0);
2349 mktime_z(timezone_t sp
, struct tm
*const tmp
)
2351 return mktime_tzname(sp
, tmp
, false);
2357 mktime(struct tm
*tmp
)
2361 rwlock_wrlock(&__lcl_lock
);
2363 t
= mktime_tzname(__lclptr
, tmp
, true);
2364 rwlock_unlock(&__lcl_lock
);
2371 timelocal_z(const timezone_t sp
, struct tm
*const tmp
)
2374 tmp
->tm_isdst
= -1; /* in case it wasn't initialized */
2375 return mktime_z(sp
, tmp
);
2379 timelocal(struct tm
*tmp
)
2382 tmp
->tm_isdst
= -1; /* in case it wasn't initialized */
2387 timegm(struct tm
*tmp
)
2390 return timeoff(tmp
, 0);
2394 timeoff(struct tm
*tmp
, long offset
)
2399 return time1(tmp
, gmtsub
, gmtptr
, (int_fast32_t)offset
);
2402 #endif /* defined STD_INSPIRED */
2405 ** XXX--is the below the right way to conditionalize??
2411 ** IEEE Std 1003.1 (POSIX) says that 536457599
2412 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2413 ** is not the case if we are accounting for leap seconds.
2414 ** So, we provide the following conversion routines for use
2415 ** when exchanging timestamps with POSIX conforming systems.
2419 leapcorr(const timezone_t sp
, time_t t
)
2421 struct lsinfo
const * lp
;
2427 if (t
>= lp
->ls_trans
)
2433 NETBSD_INSPIRED_EXTERN
time_t
2434 time2posix_z(timezone_t sp
, time_t t
)
2436 return (time_t)(t
- leapcorr(sp
, t
));
2440 time2posix(time_t t
)
2442 rwlock_wrlock(&__lcl_lock
);
2446 t
= (time_t)(t
- leapcorr(__lclptr
, t
));
2447 rwlock_unlock(&__lcl_lock
);
2451 NETBSD_INSPIRED_EXTERN
time_t
2452 posix2time_z(timezone_t sp
, time_t t
)
2458 ** For a positive leap second hit, the result
2459 ** is not unique. For a negative leap second
2460 ** hit, the corresponding time doesn't exist,
2461 ** so we return an adjacent second.
2463 x
= (time_t)(t
+ leapcorr(sp
, t
));
2464 y
= (time_t)(x
- leapcorr(sp
, x
));
2468 y
= (time_t)(x
- leapcorr(sp
, x
));
2474 y
= (time_t)(x
- leapcorr(sp
, x
));
2482 posix2time(time_t t
)
2484 rwlock_wrlock(&__lcl_lock
);
2488 t
= posix2time_z(__lclptr
, t
);
2489 rwlock_unlock(&__lcl_lock
);
2493 #endif /* defined STD_INSPIRED */