2 ** This file is in the public domain, so clarified as of
3 ** 1996-06-05 by Arthur David Olson.
7 ** Leap second handling from Bradley White.
8 ** POSIX-style TZ environment variable handling from Guy Harris.
13 #define LOCALTIME_IMPLEMENTATION
19 #if defined THREAD_SAFE && THREAD_SAFE
21 static pthread_mutex_t locallock
= PTHREAD_MUTEX_INITIALIZER
;
22 static int lock(void) { return pthread_mutex_lock(&locallock
); }
23 static void unlock(void) { pthread_mutex_unlock(&locallock
); }
25 static int lock(void) { return 0; }
26 static void unlock(void) { }
29 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if
30 NETBSD_INSPIRED is defined, and are private otherwise. */
32 # define NETBSD_INSPIRED_EXTERN
34 # define NETBSD_INSPIRED_EXTERN static
37 #ifndef TZ_ABBR_MAX_LEN
38 #define TZ_ABBR_MAX_LEN 16
39 #endif /* !defined TZ_ABBR_MAX_LEN */
41 #ifndef TZ_ABBR_CHAR_SET
42 #define TZ_ABBR_CHAR_SET \
43 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
44 #endif /* !defined TZ_ABBR_CHAR_SET */
46 #ifndef TZ_ABBR_ERR_CHAR
47 #define TZ_ABBR_ERR_CHAR '_'
48 #endif /* !defined TZ_ABBR_ERR_CHAR */
51 ** SunOS 4.1.1 headers lack O_BINARY.
55 #define OPEN_MODE (O_RDONLY | O_BINARY)
56 #endif /* defined O_BINARY */
58 #define OPEN_MODE O_RDONLY
59 #endif /* !defined O_BINARY */
63 ** Someone might make incorrect use of a time zone abbreviation:
64 ** 1. They might reference tzname[0] before calling tzset (explicitly
66 ** 2. They might reference tzname[1] before calling tzset (explicitly
68 ** 3. They might reference tzname[1] after setting to a time zone
69 ** in which Daylight Saving Time is never observed.
70 ** 4. They might reference tzname[0] after setting to a time zone
71 ** in which Standard Time is never observed.
72 ** 5. They might reference tm.TM_ZONE after calling offtime.
73 ** What's best to do in the above cases is open to debate;
74 ** for now, we just set things up so that in any of the five cases
75 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
76 ** string "tzname[0] used before set", and similarly for the other cases.
77 ** And another: initialize tzname[0] to "ERA", with an explanation in the
78 ** manual page of what this "time zone abbreviation" means (doing this so
79 ** that tzname[0] has the "normal" length of three characters).
82 #endif /* !defined WILDABBR */
84 static const char wildabbr
[] = WILDABBR
;
86 static const char gmt
[] = "GMT";
89 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
90 ** We default to US rules as of 1999-08-17.
91 ** POSIX 1003.1 section 8.1.1 says that the default DST rules are
92 ** implementation dependent; for historical reasons, US rules are a
95 #ifndef TZDEFRULESTRING
96 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
97 #endif /* !defined TZDEFDST */
99 struct ttinfo
{ /* time type information */
100 int_fast32_t tt_gmtoff
; /* UT offset in seconds */
101 bool tt_isdst
; /* used to set tm_isdst */
102 int tt_abbrind
; /* abbreviation list index */
103 bool tt_ttisstd
; /* transition is std time */
104 bool tt_ttisgmt
; /* transition is UT */
107 struct lsinfo
{ /* leap second information */
108 time_t ls_trans
; /* transition time */
109 int_fast64_t ls_corr
; /* correction to apply */
112 #define SMALLEST(a, b) (((a) < (b)) ? (a) : (b))
113 #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
116 #define MY_TZNAME_MAX TZNAME_MAX
117 #endif /* defined TZNAME_MAX */
119 #define MY_TZNAME_MAX 255
120 #endif /* !defined TZNAME_MAX */
129 time_t ats
[TZ_MAX_TIMES
];
130 unsigned char types
[TZ_MAX_TIMES
];
131 struct ttinfo ttis
[TZ_MAX_TYPES
];
132 char chars
[BIGGEST(BIGGEST(TZ_MAX_CHARS
+ 1, sizeof gmt
),
133 (2 * (MY_TZNAME_MAX
+ 1)))];
134 struct lsinfo lsis
[TZ_MAX_LEAPS
];
135 int defaulttype
; /* for early times or if no transitions */
139 JULIAN_DAY
, /* Jn = Julian day */
140 DAY_OF_YEAR
, /* n = day of year */
141 MONTH_NTH_DAY_OF_WEEK
/* Mm.n.d = month, week, day of week */
145 enum r_type r_type
; /* type of rule */
146 int r_day
; /* day number of rule */
147 int r_week
; /* week number of rule */
148 int r_mon
; /* month number of rule */
149 int_fast32_t r_time
; /* transition time of rule */
152 static struct tm
*gmtsub(struct state
const *, time_t const *, int_fast32_t,
154 static bool increment_overflow(int *, int);
155 static bool increment_overflow_time(time_t *, int_fast32_t);
156 static bool normalize_overflow32(int_fast32_t *, int *, int);
157 static struct tm
*timesub(time_t const *, int_fast32_t, struct state
const *,
159 static bool typesequiv(struct state
const *, int, int);
160 static bool tzparse(char const *, struct state
*, bool);
163 static struct state
* lclptr
;
164 static struct state
* gmtptr
;
165 #endif /* defined ALL_STATE */
168 static struct state lclmem
;
169 static struct state gmtmem
;
170 #define lclptr (&lclmem)
171 #define gmtptr (&gmtmem)
172 #endif /* State Farm */
174 #ifndef TZ_STRLEN_MAX
175 #define TZ_STRLEN_MAX 255
176 #endif /* !defined TZ_STRLEN_MAX */
178 static char lcl_TZname
[TZ_STRLEN_MAX
+ 1];
179 static int lcl_is_set
;
182 ** Section 4.12.3 of X3.159-1989 requires that
183 ** Except for the strftime function, these functions [asctime,
184 ** ctime, gmtime, localtime] return values in one of two static
185 ** objects: a broken-down time structure and an array of char.
186 ** Thanks to Paul Eggert for noting this.
191 #if !HAVE_POSIX_DECLS
204 #endif /* defined ALTZONE */
206 /* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
208 init_ttinfo(struct ttinfo
*s
, int_fast32_t gmtoff
, bool isdst
, int abbrind
)
210 s
->tt_gmtoff
= gmtoff
;
212 s
->tt_abbrind
= abbrind
;
213 s
->tt_ttisstd
= false;
214 s
->tt_ttisgmt
= false;
218 detzcode(const char *const codep
)
220 register int_fast32_t result
;
222 int_fast32_t one
= 1;
223 int_fast32_t halfmaxval
= one
<< (32 - 2);
224 int_fast32_t maxval
= halfmaxval
- 1 + halfmaxval
;
225 int_fast32_t minval
= -1 - maxval
;
227 result
= codep
[0] & 0x7f;
228 for (i
= 1; i
< 4; ++i
)
229 result
= (result
<< 8) | (codep
[i
] & 0xff);
231 if (codep
[0] & 0x80) {
232 /* Do two's-complement negation even on non-two's-complement machines.
233 If the result would be minval - 1, return minval. */
234 result
-= !TWOS_COMPLEMENT(int_fast32_t) && result
!= 0;
241 detzcode64(const char *const codep
)
243 register uint_fast64_t result
;
245 int_fast64_t one
= 1;
246 int_fast64_t halfmaxval
= one
<< (64 - 2);
247 int_fast64_t maxval
= halfmaxval
- 1 + halfmaxval
;
248 int_fast64_t minval
= -TWOS_COMPLEMENT(int_fast64_t) - maxval
;
250 result
= codep
[0] & 0x7f;
251 for (i
= 1; i
< 8; ++i
)
252 result
= (result
<< 8) | (codep
[i
] & 0xff);
254 if (codep
[0] & 0x80) {
255 /* Do two's-complement negation even on non-two's-complement machines.
256 If the result would be minval - 1, return minval. */
257 result
-= !TWOS_COMPLEMENT(int_fast64_t) && result
!= 0;
264 update_tzname_etc(struct state
const *sp
, struct ttinfo
const *ttisp
)
266 tzname
[ttisp
->tt_isdst
] = (char *) &sp
->chars
[ttisp
->tt_abbrind
];
268 if (!ttisp
->tt_isdst
)
269 timezone
= - ttisp
->tt_gmtoff
;
273 altzone
= - ttisp
->tt_gmtoff
;
280 register struct state
* const sp
= lclptr
;
283 tzname
[0] = tzname
[1] = (char *) wildabbr
;
287 #endif /* defined USG_COMPAT */
290 #endif /* defined ALTZONE */
292 tzname
[0] = tzname
[1] = (char *) gmt
;
296 ** And to get the latest zone names into tzname. . .
298 for (i
= 0; i
< sp
->typecnt
; ++i
) {
299 register const struct ttinfo
* const ttisp
= &sp
->ttis
[i
];
300 update_tzname_etc(sp
, ttisp
);
302 for (i
= 0; i
< sp
->timecnt
; ++i
) {
303 register const struct ttinfo
* const ttisp
=
306 update_tzname_etc(sp
, ttisp
);
310 #endif /* defined USG_COMPAT */
315 scrub_abbrs(struct state
*sp
)
319 ** First, replace bogus characters.
321 for (i
= 0; i
< sp
->charcnt
; ++i
)
322 if (strchr(TZ_ABBR_CHAR_SET
, sp
->chars
[i
]) == NULL
)
323 sp
->chars
[i
] = TZ_ABBR_ERR_CHAR
;
325 ** Second, truncate long abbreviations.
327 for (i
= 0; i
< sp
->typecnt
; ++i
) {
328 register const struct ttinfo
* const ttisp
= &sp
->ttis
[i
];
329 register char * cp
= &sp
->chars
[ttisp
->tt_abbrind
];
331 if (strlen(cp
) > TZ_ABBR_MAX_LEN
&&
332 strcmp(cp
, GRANDPARENTED
) != 0)
333 *(cp
+ TZ_ABBR_MAX_LEN
) = '\0';
338 differ_by_repeat(const time_t t1
, const time_t t0
)
340 if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS
)
342 return t1
- t0
== SECSPERREPEAT
;
345 /* Input buffer for data read from a compiled tz file. */
347 /* The first part of the buffer, interpreted as a header. */
348 struct tzhead tzhead
;
350 /* The entire buffer. */
351 char buf
[2 * sizeof(struct tzhead
) + 2 * sizeof (struct state
)
355 /* Local storage needed for 'tzloadbody'. */
356 union local_storage
{
357 /* The file name to be opened. */
358 char fullname
[FILENAME_MAX
+ 1];
360 /* The results of analyzing the file's contents after it is opened. */
362 /* The input buffer. */
363 union input_buffer u
;
365 /* A temporary state used for parsing a TZ string in the file. */
370 /* Load tz data from the file named NAME into *SP. Read extended
371 format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
372 success, an errno value on failure. */
374 tzloadbody(char const *name
, struct state
*sp
, bool doextend
,
375 union local_storage
*lsp
)
380 register ssize_t nread
;
381 register bool doaccess
;
382 register char *fullname
= lsp
->fullname
;
383 register union input_buffer
*up
= &lsp
->u
.u
;
384 register int tzheadsize
= sizeof (struct tzhead
);
386 sp
->goback
= sp
->goahead
= false;
396 doaccess
= name
[0] == '/';
398 char const *p
= TZDIR
;
401 if (sizeof lsp
->fullname
- 1 <= strlen(p
) + strlen(name
))
404 strcat(fullname
, "/");
405 strcat(fullname
, name
);
406 /* Set doaccess if '.' (as in "../") shows up in name. */
407 if (strchr(name
, '.'))
411 if (doaccess
&& access(name
, R_OK
) != 0)
413 fid
= open(name
, OPEN_MODE
);
417 nread
= read(fid
, up
->buf
, sizeof up
->buf
);
418 if (nread
< tzheadsize
) {
419 int err
= nread
< 0 ? errno
: EINVAL
;
425 for (stored
= 4; stored
<= 8; stored
*= 2) {
426 int_fast32_t ttisstdcnt
= detzcode(up
->tzhead
.tzh_ttisstdcnt
);
427 int_fast32_t ttisgmtcnt
= detzcode(up
->tzhead
.tzh_ttisgmtcnt
);
428 int_fast32_t leapcnt
= detzcode(up
->tzhead
.tzh_leapcnt
);
429 int_fast32_t timecnt
= detzcode(up
->tzhead
.tzh_timecnt
);
430 int_fast32_t typecnt
= detzcode(up
->tzhead
.tzh_typecnt
);
431 int_fast32_t charcnt
= detzcode(up
->tzhead
.tzh_charcnt
);
432 char const *p
= up
->buf
+ tzheadsize
;
433 if (! (0 <= leapcnt
&& leapcnt
< TZ_MAX_LEAPS
434 && 0 < typecnt
&& typecnt
< TZ_MAX_TYPES
435 && 0 <= timecnt
&& timecnt
< TZ_MAX_TIMES
436 && 0 <= charcnt
&& charcnt
< TZ_MAX_CHARS
437 && (ttisstdcnt
== typecnt
|| ttisstdcnt
== 0)
438 && (ttisgmtcnt
== typecnt
|| ttisgmtcnt
== 0)))
441 < (tzheadsize
/* struct tzhead */
442 + timecnt
* stored
/* ats */
443 + timecnt
/* types */
444 + typecnt
* 6 /* ttinfos */
445 + charcnt
/* chars */
446 + leapcnt
* (stored
+ 4) /* lsinfos */
447 + ttisstdcnt
/* ttisstds */
448 + ttisgmtcnt
)) /* ttisgmts */
450 sp
->leapcnt
= leapcnt
;
451 sp
->timecnt
= timecnt
;
452 sp
->typecnt
= typecnt
;
453 sp
->charcnt
= charcnt
;
455 /* Read transitions, discarding those out of time_t range.
456 But pretend the last transition before time_t_min
457 occurred at time_t_min. */
459 for (i
= 0; i
< sp
->timecnt
; ++i
) {
461 = stored
== 4 ? detzcode(p
) : detzcode64(p
);
462 sp
->types
[i
] = at
<= time_t_max
;
465 = ((TYPE_SIGNED(time_t) ? at
< time_t_min
: at
< 0)
467 if (timecnt
&& attime
<= sp
->ats
[timecnt
- 1]) {
468 if (attime
< sp
->ats
[timecnt
- 1])
470 sp
->types
[i
- 1] = 0;
473 sp
->ats
[timecnt
++] = attime
;
479 for (i
= 0; i
< sp
->timecnt
; ++i
) {
480 unsigned char typ
= *p
++;
481 if (sp
->typecnt
<= typ
)
484 sp
->types
[timecnt
++] = typ
;
486 sp
->timecnt
= timecnt
;
487 for (i
= 0; i
< sp
->typecnt
; ++i
) {
488 register struct ttinfo
* ttisp
;
489 unsigned char isdst
, abbrind
;
491 ttisp
= &sp
->ttis
[i
];
492 ttisp
->tt_gmtoff
= detzcode(p
);
497 ttisp
->tt_isdst
= isdst
;
499 if (! (abbrind
< sp
->charcnt
))
501 ttisp
->tt_abbrind
= abbrind
;
503 for (i
= 0; i
< sp
->charcnt
; ++i
)
505 sp
->chars
[i
] = '\0'; /* ensure '\0' at end */
507 /* Read leap seconds, discarding those out of time_t range. */
509 for (i
= 0; i
< sp
->leapcnt
; ++i
) {
510 int_fast64_t tr
= stored
== 4 ? detzcode(p
) : detzcode64(p
);
511 int_fast32_t corr
= detzcode(p
+ stored
);
513 if (tr
<= time_t_max
) {
515 = ((TYPE_SIGNED(time_t) ? tr
< time_t_min
: tr
< 0)
517 if (leapcnt
&& trans
<= sp
->lsis
[leapcnt
- 1].ls_trans
) {
518 if (trans
< sp
->lsis
[leapcnt
- 1].ls_trans
)
522 sp
->lsis
[leapcnt
].ls_trans
= trans
;
523 sp
->lsis
[leapcnt
].ls_corr
= corr
;
527 sp
->leapcnt
= leapcnt
;
529 for (i
= 0; i
< sp
->typecnt
; ++i
) {
530 register struct ttinfo
* ttisp
;
532 ttisp
= &sp
->ttis
[i
];
534 ttisp
->tt_ttisstd
= false;
536 if (*p
!= true && *p
!= false)
538 ttisp
->tt_ttisstd
= *p
++;
541 for (i
= 0; i
< sp
->typecnt
; ++i
) {
542 register struct ttinfo
* ttisp
;
544 ttisp
= &sp
->ttis
[i
];
546 ttisp
->tt_ttisgmt
= false;
548 if (*p
!= true && *p
!= false)
550 ttisp
->tt_ttisgmt
= *p
++;
554 ** If this is an old file, we're done.
556 if (up
->tzhead
.tzh_version
[0] == '\0')
558 nread
-= p
- up
->buf
;
559 memmove(up
->buf
, p
, nread
);
561 if (doextend
&& nread
> 2 &&
562 up
->buf
[0] == '\n' && up
->buf
[nread
- 1] == '\n' &&
563 sp
->typecnt
+ 2 <= TZ_MAX_TYPES
) {
564 struct state
*ts
= &lsp
->u
.st
;
566 up
->buf
[nread
- 1] = '\0';
567 if (tzparse(&up
->buf
[1], ts
, false)
568 && ts
->typecnt
== 2) {
570 /* Attempt to reuse existing abbreviations.
571 Without this, America/Anchorage would be right on
572 the edge after 2037 when TZ_MAX_CHARS is 50, as
573 sp->charcnt equals 40 (for LMT AST AWT APT AHST
574 AHDT YST AKDT AKST) and ts->charcnt equals 10
575 (for AKST AKDT). Reusing means sp->charcnt can
576 stay 40 in this example. */
578 int charcnt
= sp
->charcnt
;
579 for (i
= 0; i
< 2; i
++) {
580 char *tsabbr
= ts
->chars
+ ts
->ttis
[i
].tt_abbrind
;
582 for (j
= 0; j
< charcnt
; j
++)
583 if (strcmp(sp
->chars
+ j
, tsabbr
) == 0) {
584 ts
->ttis
[i
].tt_abbrind
= j
;
588 if (! (j
< charcnt
)) {
589 int tsabbrlen
= strlen(tsabbr
);
590 if (j
+ tsabbrlen
< TZ_MAX_CHARS
) {
591 strcpy(sp
->chars
+ j
, tsabbr
);
592 charcnt
= j
+ tsabbrlen
+ 1;
593 ts
->ttis
[i
].tt_abbrind
= j
;
599 sp
->charcnt
= charcnt
;
601 /* Ignore any trailing, no-op transitions generated
602 by zic as they don't help here and can run afoul
603 of bugs in zic 2016j or earlier. */
604 while (1 < sp
->timecnt
605 && (sp
->types
[sp
->timecnt
- 1]
606 == sp
->types
[sp
->timecnt
- 2]))
609 for (i
= 0; i
< ts
->timecnt
; i
++)
610 if (sp
->ats
[sp
->timecnt
- 1] < ts
->ats
[i
])
612 while (i
< ts
->timecnt
613 && sp
->timecnt
< TZ_MAX_TIMES
) {
614 sp
->ats
[sp
->timecnt
] = ts
->ats
[i
];
615 sp
->types
[sp
->timecnt
] = (sp
->typecnt
620 sp
->ttis
[sp
->typecnt
++] = ts
->ttis
[0];
621 sp
->ttis
[sp
->typecnt
++] = ts
->ttis
[1];
625 if (sp
->timecnt
> 1) {
626 for (i
= 1; i
< sp
->timecnt
; ++i
)
627 if (typesequiv(sp
, sp
->types
[i
], sp
->types
[0]) &&
628 differ_by_repeat(sp
->ats
[i
], sp
->ats
[0])) {
632 for (i
= sp
->timecnt
- 2; i
>= 0; --i
)
633 if (typesequiv(sp
, sp
->types
[sp
->timecnt
- 1],
635 differ_by_repeat(sp
->ats
[sp
->timecnt
- 1],
642 ** If type 0 is is unused in transitions,
643 ** it's the type to use for early times.
645 for (i
= 0; i
< sp
->timecnt
; ++i
)
646 if (sp
->types
[i
] == 0)
648 i
= i
< sp
->timecnt
? -1 : 0;
651 ** if there are transition times
652 ** and the first transition is to a daylight time
653 ** find the standard type less than and closest to
654 ** the type of the first transition.
656 if (i
< 0 && sp
->timecnt
> 0 && sp
->ttis
[sp
->types
[0]].tt_isdst
) {
659 if (!sp
->ttis
[i
].tt_isdst
)
663 ** If no result yet, find the first standard type.
664 ** If there is none, punt to type zero.
668 while (sp
->ttis
[i
].tt_isdst
)
669 if (++i
>= sp
->typecnt
) {
678 /* Load tz data from the file named NAME into *SP. Read extended
679 format if DOEXTEND. Return 0 on success, an errno value on failure. */
681 tzload(char const *name
, struct state
*sp
, bool doextend
)
684 union local_storage
*lsp
= malloc(sizeof *lsp
);
688 int err
= tzloadbody(name
, sp
, doextend
, lsp
);
693 union local_storage ls
;
694 return tzloadbody(name
, sp
, doextend
, &ls
);
699 typesequiv(const struct state
*sp
, int a
, int b
)
701 register bool result
;
704 a
< 0 || a
>= sp
->typecnt
||
705 b
< 0 || b
>= sp
->typecnt
)
708 register const struct ttinfo
* ap
= &sp
->ttis
[a
];
709 register const struct ttinfo
* bp
= &sp
->ttis
[b
];
710 result
= ap
->tt_gmtoff
== bp
->tt_gmtoff
&&
711 ap
->tt_isdst
== bp
->tt_isdst
&&
712 ap
->tt_ttisstd
== bp
->tt_ttisstd
&&
713 ap
->tt_ttisgmt
== bp
->tt_ttisgmt
&&
714 strcmp(&sp
->chars
[ap
->tt_abbrind
],
715 &sp
->chars
[bp
->tt_abbrind
]) == 0;
720 static const int mon_lengths
[2][MONSPERYEAR
] = {
721 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
722 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
725 static const int year_lengths
[2] = {
726 DAYSPERNYEAR
, DAYSPERLYEAR
730 ** Given a pointer into a time zone string, scan until a character that is not
731 ** a valid character in a zone name is found. Return a pointer to that
735 static const char * ATTRIBUTE_PURE
736 getzname(register const char *strp
)
740 while ((c
= *strp
) != '\0' && !is_digit(c
) && c
!= ',' && c
!= '-' &&
747 ** Given a pointer into an extended time zone string, scan until the ending
748 ** delimiter of the zone name is located. Return a pointer to the delimiter.
750 ** As with getzname above, the legal character set is actually quite
751 ** restricted, with other characters producing undefined results.
752 ** We don't do any checking here; checking is done later in common-case code.
755 static const char * ATTRIBUTE_PURE
756 getqzname(register const char *strp
, const int delim
)
760 while ((c
= *strp
) != '\0' && c
!= delim
)
766 ** Given a pointer into a time zone string, extract a number from that string.
767 ** Check that the number is within a specified range; if it is not, return
769 ** Otherwise, return a pointer to the first character not part of the number.
773 getnum(register const char *strp
, int *const nump
, const int min
, const int max
)
778 if (strp
== NULL
|| !is_digit(c
= *strp
))
782 num
= num
* 10 + (c
- '0');
784 return NULL
; /* illegal value */
786 } while (is_digit(c
));
788 return NULL
; /* illegal value */
794 ** Given a pointer into a time zone string, extract a number of seconds,
795 ** in hh[:mm[:ss]] form, from the string.
796 ** If any error occurs, return NULL.
797 ** Otherwise, return a pointer to the first character not part of the number
802 getsecs(register const char *strp
, int_fast32_t *const secsp
)
807 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
808 ** "M10.4.6/26", which does not conform to Posix,
809 ** but which specifies the equivalent of
810 ** "02:00 on the first Sunday on or after 23 Oct".
812 strp
= getnum(strp
, &num
, 0, HOURSPERDAY
* DAYSPERWEEK
- 1);
815 *secsp
= num
* (int_fast32_t) SECSPERHOUR
;
818 strp
= getnum(strp
, &num
, 0, MINSPERHOUR
- 1);
821 *secsp
+= num
* SECSPERMIN
;
824 /* 'SECSPERMIN' allows for leap seconds. */
825 strp
= getnum(strp
, &num
, 0, SECSPERMIN
);
835 ** Given a pointer into a time zone string, extract an offset, in
836 ** [+-]hh[:mm[:ss]] form, from the string.
837 ** If any error occurs, return NULL.
838 ** Otherwise, return a pointer to the first character not part of the time.
842 getoffset(register const char *strp
, int_fast32_t *const offsetp
)
844 register bool neg
= false;
849 } else if (*strp
== '+')
851 strp
= getsecs(strp
, offsetp
);
853 return NULL
; /* illegal time */
855 *offsetp
= -*offsetp
;
860 ** Given a pointer into a time zone string, extract a rule in the form
861 ** date[/time]. See POSIX section 8 for the format of "date" and "time".
862 ** If a valid rule is not found, return NULL.
863 ** Otherwise, return a pointer to the first character not part of the rule.
867 getrule(const char *strp
, register struct rule
*const rulep
)
873 rulep
->r_type
= JULIAN_DAY
;
875 strp
= getnum(strp
, &rulep
->r_day
, 1, DAYSPERNYEAR
);
876 } else if (*strp
== 'M') {
880 rulep
->r_type
= MONTH_NTH_DAY_OF_WEEK
;
882 strp
= getnum(strp
, &rulep
->r_mon
, 1, MONSPERYEAR
);
887 strp
= getnum(strp
, &rulep
->r_week
, 1, 5);
892 strp
= getnum(strp
, &rulep
->r_day
, 0, DAYSPERWEEK
- 1);
893 } else if (is_digit(*strp
)) {
897 rulep
->r_type
= DAY_OF_YEAR
;
898 strp
= getnum(strp
, &rulep
->r_day
, 0, DAYSPERLYEAR
- 1);
899 } else return NULL
; /* invalid format */
907 strp
= getoffset(strp
, &rulep
->r_time
);
908 } else rulep
->r_time
= 2 * SECSPERHOUR
; /* default = 2:00:00 */
913 ** Given a year, a rule, and the offset from UT at the time that rule takes
914 ** effect, calculate the year-relative time that rule takes effect.
917 static int_fast32_t ATTRIBUTE_PURE
918 transtime(const int year
, register const struct rule
*const rulep
,
919 const int_fast32_t offset
)
921 register bool leapyear
;
922 register int_fast32_t value
;
924 int d
, m1
, yy0
, yy1
, yy2
, dow
;
927 leapyear
= isleap(year
);
928 switch (rulep
->r_type
) {
932 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
934 ** In non-leap years, or if the day number is 59 or less, just
935 ** add SECSPERDAY times the day number-1 to the time of
936 ** January 1, midnight, to get the day.
938 value
= (rulep
->r_day
- 1) * SECSPERDAY
;
939 if (leapyear
&& rulep
->r_day
>= 60)
946 ** Just add SECSPERDAY times the day number to the time of
947 ** January 1, midnight, to get the day.
949 value
= rulep
->r_day
* SECSPERDAY
;
952 case MONTH_NTH_DAY_OF_WEEK
:
954 ** Mm.n.d - nth "dth day" of month m.
958 ** Use Zeller's Congruence to get day-of-week of first day of
961 m1
= (rulep
->r_mon
+ 9) % 12 + 1;
962 yy0
= (rulep
->r_mon
<= 2) ? (year
- 1) : year
;
965 dow
= ((26 * m1
- 2) / 10 +
966 1 + yy2
+ yy2
/ 4 + yy1
/ 4 - 2 * yy1
) % 7;
971 ** "dow" is the day-of-week of the first day of the month. Get
972 ** the day-of-month (zero-origin) of the first "dow" day of the
975 d
= rulep
->r_day
- dow
;
978 for (i
= 1; i
< rulep
->r_week
; ++i
) {
979 if (d
+ DAYSPERWEEK
>=
980 mon_lengths
[leapyear
][rulep
->r_mon
- 1])
986 ** "d" is the day-of-month (zero-origin) of the day we want.
988 value
= d
* SECSPERDAY
;
989 for (i
= 0; i
< rulep
->r_mon
- 1; ++i
)
990 value
+= mon_lengths
[leapyear
][i
] * SECSPERDAY
;
995 ** "value" is the year-relative time of 00:00:00 UT on the day in
996 ** question. To get the year-relative time of the specified local
997 ** time on that day, add the transition time and the current offset
1000 return value
+ rulep
->r_time
+ offset
;
1004 ** Given a POSIX section 8-style TZ string, fill in the rule tables as
1009 tzparse(const char *name
, struct state
*sp
, bool lastditch
)
1011 const char * stdname
;
1012 const char * dstname
;
1016 int_fast32_t stdoffset
;
1017 int_fast32_t dstoffset
;
1019 register bool load_ok
;
1023 stdlen
= sizeof gmt
- 1;
1030 name
= getqzname(name
, '>');
1033 stdlen
= name
- stdname
;
1036 name
= getzname(name
);
1037 stdlen
= name
- stdname
;
1041 name
= getoffset(name
, &stdoffset
);
1045 charcnt
= stdlen
+ 1;
1046 if (sizeof sp
->chars
< charcnt
)
1048 load_ok
= tzload(TZDEFRULES
, sp
, false) == 0;
1050 sp
->leapcnt
= 0; /* so, we're off a little */
1051 if (*name
!= '\0') {
1054 name
= getqzname(name
, '>');
1057 dstlen
= name
- dstname
;
1061 name
= getzname(name
);
1062 dstlen
= name
- dstname
; /* length of DST zone name */
1066 charcnt
+= dstlen
+ 1;
1067 if (sizeof sp
->chars
< charcnt
)
1069 if (*name
!= '\0' && *name
!= ',' && *name
!= ';') {
1070 name
= getoffset(name
, &dstoffset
);
1073 } else dstoffset
= stdoffset
- SECSPERHOUR
;
1074 if (*name
== '\0' && !load_ok
)
1075 name
= TZDEFRULESTRING
;
1076 if (*name
== ',' || *name
== ';') {
1080 register int yearlim
;
1081 register int timecnt
;
1083 int_fast32_t janoffset
= 0;
1087 if ((name
= getrule(name
, &start
)) == NULL
)
1091 if ((name
= getrule(name
, &end
)) == NULL
)
1095 sp
->typecnt
= 2; /* standard time and DST */
1097 ** Two transitions per year, from EPOCH_YEAR forward.
1099 init_ttinfo(&sp
->ttis
[0], -dstoffset
, true, stdlen
+ 1);
1100 init_ttinfo(&sp
->ttis
[1], -stdoffset
, false, 0);
1101 sp
->defaulttype
= 0;
1104 yearbeg
= EPOCH_YEAR
;
1107 int_fast32_t yearsecs
1108 = year_lengths
[isleap(yearbeg
- 1)] * SECSPERDAY
;
1110 if (increment_overflow_time(&janfirst
, -yearsecs
)) {
1111 janoffset
= -yearsecs
;
1114 } while (EPOCH_YEAR
- YEARSPERREPEAT
/ 2 < yearbeg
);
1116 yearlim
= yearbeg
+ YEARSPERREPEAT
+ 1;
1117 for (year
= yearbeg
; year
< yearlim
; year
++) {
1119 starttime
= transtime(year
, &start
, stdoffset
),
1120 endtime
= transtime(year
, &end
, dstoffset
);
1122 yearsecs
= (year_lengths
[isleap(year
)]
1124 bool reversed
= endtime
< starttime
;
1126 int_fast32_t swap
= starttime
;
1127 starttime
= endtime
;
1131 || (starttime
< endtime
1132 && (endtime
- starttime
1134 + (stdoffset
- dstoffset
))))) {
1135 if (TZ_MAX_TIMES
- 2 < timecnt
)
1137 sp
->ats
[timecnt
] = janfirst
;
1138 if (! increment_overflow_time
1140 janoffset
+ starttime
))
1141 sp
->types
[timecnt
++] = reversed
;
1143 sp
->defaulttype
= reversed
;
1144 sp
->ats
[timecnt
] = janfirst
;
1145 if (! increment_overflow_time
1147 janoffset
+ endtime
)) {
1148 sp
->types
[timecnt
++] = !reversed
;
1149 yearlim
= year
+ YEARSPERREPEAT
+ 1;
1150 } else if (janoffset
)
1151 sp
->defaulttype
= !reversed
;
1153 if (increment_overflow_time
1154 (&janfirst
, janoffset
+ yearsecs
))
1158 sp
->timecnt
= timecnt
;
1160 sp
->typecnt
= 1; /* Perpetual DST. */
1161 else if (YEARSPERREPEAT
< year
- yearbeg
)
1162 sp
->goback
= sp
->goahead
= true;
1164 register int_fast32_t theirstdoffset
;
1165 register int_fast32_t theirdstoffset
;
1166 register int_fast32_t theiroffset
;
1167 register bool isdst
;
1174 ** Initial values of theirstdoffset and theirdstoffset.
1177 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1179 if (!sp
->ttis
[j
].tt_isdst
) {
1181 -sp
->ttis
[j
].tt_gmtoff
;
1186 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1188 if (sp
->ttis
[j
].tt_isdst
) {
1190 -sp
->ttis
[j
].tt_gmtoff
;
1195 ** Initially we're assumed to be in standard time.
1198 theiroffset
= theirstdoffset
;
1200 ** Now juggle transition times and types
1201 ** tracking offsets as you do.
1203 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1205 sp
->types
[i
] = sp
->ttis
[j
].tt_isdst
;
1206 if (sp
->ttis
[j
].tt_ttisgmt
) {
1207 /* No adjustment to transition time */
1210 ** If summer time is in effect, and the
1211 ** transition time was not specified as
1212 ** standard time, add the summer time
1213 ** offset to the transition time;
1214 ** otherwise, add the standard time
1215 ** offset to the transition time.
1218 ** Transitions from DST to DDST
1219 ** will effectively disappear since
1220 ** POSIX provides for only one DST
1223 if (isdst
&& !sp
->ttis
[j
].tt_ttisstd
) {
1224 sp
->ats
[i
] += dstoffset
-
1227 sp
->ats
[i
] += stdoffset
-
1231 theiroffset
= -sp
->ttis
[j
].tt_gmtoff
;
1232 if (sp
->ttis
[j
].tt_isdst
)
1233 theirdstoffset
= theiroffset
;
1234 else theirstdoffset
= theiroffset
;
1237 ** Finally, fill in ttis.
1239 init_ttinfo(&sp
->ttis
[0], -stdoffset
, false, 0);
1240 init_ttinfo(&sp
->ttis
[1], -dstoffset
, true, stdlen
+ 1);
1242 sp
->defaulttype
= 0;
1246 sp
->typecnt
= 1; /* only standard time */
1248 init_ttinfo(&sp
->ttis
[0], -stdoffset
, false, 0);
1249 sp
->defaulttype
= 0;
1251 sp
->charcnt
= charcnt
;
1253 memcpy(cp
, stdname
, stdlen
);
1257 memcpy(cp
, dstname
, dstlen
);
1258 *(cp
+ dstlen
) = '\0';
1264 gmtload(struct state
*const sp
)
1266 if (tzload(gmt
, sp
, true) != 0)
1267 tzparse(gmt
, sp
, true);
1270 /* Initialize *SP to a value appropriate for the TZ setting NAME.
1271 Return 0 on success, an errno value on failure. */
1273 zoneinit(struct state
*sp
, char const *name
)
1275 if (name
&& ! name
[0]) {
1277 ** User wants it fast rather than right.
1279 sp
->leapcnt
= 0; /* so, we're off a little */
1283 sp
->goback
= sp
->goahead
= false;
1284 init_ttinfo(&sp
->ttis
[0], 0, false, 0);
1285 strcpy(sp
->chars
, gmt
);
1286 sp
->defaulttype
= 0;
1289 int err
= tzload(name
, sp
, true);
1290 if (err
!= 0 && name
&& name
[0] != ':' && tzparse(name
, sp
, false))
1299 tzsetlcl(char const *name
)
1301 struct state
*sp
= lclptr
;
1302 int lcl
= name
? strlen(name
) < sizeof lcl_TZname
: -1;
1305 : 0 < lcl_is_set
&& strcmp(lcl_TZname
, name
) == 0)
1309 lclptr
= sp
= malloc(sizeof *lclptr
);
1310 #endif /* defined ALL_STATE */
1312 if (zoneinit(sp
, name
) != 0)
1315 strcpy(lcl_TZname
, name
);
1333 tzset_unlocked(void)
1335 tzsetlcl(getenv("TZ"));
1350 static bool gmt_is_set
;
1355 gmtptr
= malloc(sizeof *gmtptr
);
1367 tzalloc(char const *name
)
1369 timezone_t sp
= malloc(sizeof *sp
);
1371 int err
= zoneinit(sp
, name
);
1382 tzfree(timezone_t sp
)
1388 ** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
1389 ** ctime_r are obsolescent and have potential security problems that
1390 ** ctime_rz would share. Callers can instead use localtime_rz + strftime.
1392 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
1393 ** in zones with three or more time zone abbreviations.
1394 ** Callers can instead use localtime_rz + strftime.
1400 ** The easy way to behave "as if no library function calls" localtime
1401 ** is to not call it, so we drop its guts into "localsub", which can be
1402 ** freely called. (And no, the PANS doesn't require the above behavior,
1403 ** but it *is* desirable.)
1405 ** If successful and SETNAME is nonzero,
1406 ** set the applicable parts of tzname, timezone and altzone;
1407 ** however, it's OK to omit this step if the time zone is POSIX-compatible,
1408 ** since in that case tzset should have already done this step correctly.
1409 ** SETNAME's type is intfast32_t for compatibility with gmtsub,
1410 ** but it is actually a boolean and its value should be 0 or 1.
1415 localsub(struct state
const *sp
, time_t const *timep
, int_fast32_t setname
,
1416 struct tm
*const tmp
)
1418 register const struct ttinfo
* ttisp
;
1420 register struct tm
* result
;
1421 const time_t t
= *timep
;
1424 /* Don't bother to set tzname etc.; tzset has already done it. */
1425 return gmtsub(gmtptr
, timep
, 0, tmp
);
1427 if ((sp
->goback
&& t
< sp
->ats
[0]) ||
1428 (sp
->goahead
&& t
> sp
->ats
[sp
->timecnt
- 1])) {
1430 register time_t seconds
;
1431 register time_t years
;
1434 seconds
= sp
->ats
[0] - t
;
1435 else seconds
= t
- sp
->ats
[sp
->timecnt
- 1];
1437 years
= (seconds
/ SECSPERREPEAT
+ 1) * YEARSPERREPEAT
;
1438 seconds
= years
* AVGSECSPERYEAR
;
1441 else newt
-= seconds
;
1442 if (newt
< sp
->ats
[0] ||
1443 newt
> sp
->ats
[sp
->timecnt
- 1])
1444 return NULL
; /* "cannot happen" */
1445 result
= localsub(sp
, &newt
, setname
, tmp
);
1447 register int_fast64_t newy
;
1449 newy
= result
->tm_year
;
1453 if (! (INT_MIN
<= newy
&& newy
<= INT_MAX
))
1455 result
->tm_year
= newy
;
1459 if (sp
->timecnt
== 0 || t
< sp
->ats
[0]) {
1460 i
= sp
->defaulttype
;
1462 register int lo
= 1;
1463 register int hi
= sp
->timecnt
;
1466 register int mid
= (lo
+ hi
) >> 1;
1468 if (t
< sp
->ats
[mid
])
1472 i
= (int) sp
->types
[lo
- 1];
1474 ttisp
= &sp
->ttis
[i
];
1476 ** To get (wrong) behavior that's compatible with System V Release 2.0
1477 ** you'd replace the statement below with
1478 ** t += ttisp->tt_gmtoff;
1479 ** timesub(&t, 0L, sp, tmp);
1481 result
= timesub(&t
, ttisp
->tt_gmtoff
, sp
, tmp
);
1483 result
->tm_isdst
= ttisp
->tt_isdst
;
1485 result
->TM_ZONE
= (char *) &sp
->chars
[ttisp
->tt_abbrind
];
1486 #endif /* defined TM_ZONE */
1488 update_tzname_etc(sp
, ttisp
);
1496 localtime_rz(struct state
*sp
, time_t const *timep
, struct tm
*tmp
)
1498 return localsub(sp
, timep
, 0, tmp
);
1504 localtime_tzset(time_t const *timep
, struct tm
*tmp
, bool setname
)
1511 if (setname
|| !lcl_is_set
)
1513 tmp
= localsub(lclptr
, timep
, setname
, tmp
);
1519 localtime(const time_t *timep
)
1521 return localtime_tzset(timep
, &tm
, true);
1525 localtime_r(const time_t *timep
, struct tm
*tmp
)
1527 return localtime_tzset(timep
, tmp
, false);
1531 ** gmtsub is to gmtime as localsub is to localtime.
1535 gmtsub(struct state
const *sp
, time_t const *timep
, int_fast32_t offset
,
1538 register struct tm
* result
;
1540 result
= timesub(timep
, offset
, gmtptr
, tmp
);
1543 ** Could get fancy here and deliver something such as
1544 ** "+xx" or "-xx" if offset is non-zero,
1545 ** but this is no time for a treasure hunt.
1547 tmp
->TM_ZONE
= ((char *)
1548 (offset
? wildabbr
: gmtptr
? gmtptr
->chars
: gmt
));
1549 #endif /* defined TM_ZONE */
1554 * Re-entrant version of gmtime.
1558 gmtime_r(const time_t *timep
, struct tm
*tmp
)
1561 return gmtsub(gmtptr
, timep
, 0, tmp
);
1565 gmtime(const time_t *timep
)
1567 return gmtime_r(timep
, &tm
);
1573 offtime(const time_t *timep
, long offset
)
1576 return gmtsub(gmtptr
, timep
, offset
, &tm
);
1579 #endif /* defined STD_INSPIRED */
1582 ** Return the number of leap years through the end of the given year
1583 ** where, to make the math easy, the answer for year zero is defined as zero.
1586 static int ATTRIBUTE_PURE
1587 leaps_thru_end_of(register const int y
)
1589 return (y
>= 0) ? (y
/ 4 - y
/ 100 + y
/ 400) :
1590 -(leaps_thru_end_of(-(y
+ 1)) + 1);
1594 timesub(const time_t *timep
, int_fast32_t offset
,
1595 const struct state
*sp
, struct tm
*tmp
)
1597 register const struct lsinfo
* lp
;
1598 register time_t tdays
;
1599 register int idays
; /* unsigned would be so 2003 */
1600 register int_fast64_t rem
;
1602 register const int * ip
;
1603 register int_fast64_t corr
;
1609 i
= (sp
== NULL
) ? 0 : sp
->leapcnt
;
1612 if (*timep
>= lp
->ls_trans
) {
1613 if (*timep
== lp
->ls_trans
) {
1614 hit
= ((i
== 0 && lp
->ls_corr
> 0) ||
1615 lp
->ls_corr
> sp
->lsis
[i
- 1].ls_corr
);
1618 sp
->lsis
[i
].ls_trans
==
1619 sp
->lsis
[i
- 1].ls_trans
+ 1 &&
1620 sp
->lsis
[i
].ls_corr
==
1621 sp
->lsis
[i
- 1].ls_corr
+ 1) {
1631 tdays
= *timep
/ SECSPERDAY
;
1632 rem
= *timep
% SECSPERDAY
;
1633 while (tdays
< 0 || tdays
>= year_lengths
[isleap(y
)]) {
1635 register time_t tdelta
;
1636 register int idelta
;
1637 register int leapdays
;
1639 tdelta
= tdays
/ DAYSPERLYEAR
;
1640 if (! ((! TYPE_SIGNED(time_t) || INT_MIN
<= tdelta
)
1641 && tdelta
<= INT_MAX
))
1645 idelta
= (tdays
< 0) ? -1 : 1;
1647 if (increment_overflow(&newy
, idelta
))
1649 leapdays
= leaps_thru_end_of(newy
- 1) -
1650 leaps_thru_end_of(y
- 1);
1651 tdays
-= ((time_t) newy
- y
) * DAYSPERNYEAR
;
1656 ** Given the range, we can now fearlessly cast...
1659 rem
+= offset
- corr
;
1664 while (rem
>= SECSPERDAY
) {
1669 if (increment_overflow(&y
, -1))
1671 idays
+= year_lengths
[isleap(y
)];
1673 while (idays
>= year_lengths
[isleap(y
)]) {
1674 idays
-= year_lengths
[isleap(y
)];
1675 if (increment_overflow(&y
, 1))
1679 if (increment_overflow(&tmp
->tm_year
, -TM_YEAR_BASE
))
1681 tmp
->tm_yday
= idays
;
1683 ** The "extra" mods below avoid overflow problems.
1685 tmp
->tm_wday
= EPOCH_WDAY
+
1686 ((y
- EPOCH_YEAR
) % DAYSPERWEEK
) *
1687 (DAYSPERNYEAR
% DAYSPERWEEK
) +
1688 leaps_thru_end_of(y
- 1) -
1689 leaps_thru_end_of(EPOCH_YEAR
- 1) +
1691 tmp
->tm_wday
%= DAYSPERWEEK
;
1692 if (tmp
->tm_wday
< 0)
1693 tmp
->tm_wday
+= DAYSPERWEEK
;
1694 tmp
->tm_hour
= (int) (rem
/ SECSPERHOUR
);
1696 tmp
->tm_min
= (int) (rem
/ SECSPERMIN
);
1698 ** A positive leap second requires a special
1699 ** representation. This uses "... ??:59:60" et seq.
1701 tmp
->tm_sec
= (int) (rem
% SECSPERMIN
) + hit
;
1702 ip
= mon_lengths
[isleap(y
)];
1703 for (tmp
->tm_mon
= 0; idays
>= ip
[tmp
->tm_mon
]; ++(tmp
->tm_mon
))
1704 idays
-= ip
[tmp
->tm_mon
];
1705 tmp
->tm_mday
= (int) (idays
+ 1);
1708 tmp
->TM_GMTOFF
= offset
;
1709 #endif /* defined TM_GMTOFF */
1718 ctime(const time_t *timep
)
1721 ** Section 4.12.3.2 of X3.159-1989 requires that
1722 ** The ctime function converts the calendar time pointed to by timer
1723 ** to local time in the form of a string. It is equivalent to
1724 ** asctime(localtime(timer))
1726 struct tm
*tmp
= localtime(timep
);
1727 return tmp
? asctime(tmp
) : NULL
;
1731 ctime_r(const time_t *timep
, char *buf
)
1734 struct tm
*tmp
= localtime_r(timep
, &mytm
);
1735 return tmp
? asctime_r(tmp
, buf
) : NULL
;
1739 ** Adapted from code provided by Robert Elz, who writes:
1740 ** The "best" way to do mktime I think is based on an idea of Bob
1741 ** Kridle's (so its said...) from a long time ago.
1742 ** It does a binary search of the time_t space. Since time_t's are
1743 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
1744 ** would still be very reasonable).
1749 #endif /* !defined WRONG */
1752 ** Normalize logic courtesy Paul Eggert.
1756 increment_overflow(int *ip
, int j
)
1758 register int const i
= *ip
;
1761 ** If i >= 0 there can only be overflow if i + j > INT_MAX
1762 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1763 ** If i < 0 there can only be overflow if i + j < INT_MIN
1764 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1766 if ((i
>= 0) ? (j
> INT_MAX
- i
) : (j
< INT_MIN
- i
))
1773 increment_overflow32(int_fast32_t *const lp
, int const m
)
1775 register int_fast32_t const l
= *lp
;
1777 if ((l
>= 0) ? (m
> INT_FAST32_MAX
- l
) : (m
< INT_FAST32_MIN
- l
))
1784 increment_overflow_time(time_t *tp
, int_fast32_t j
)
1788 ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1789 ** except that it does the right thing even if *tp + j would overflow.
1792 ? (TYPE_SIGNED(time_t) ? time_t_min
- j
<= *tp
: -1 - j
< *tp
)
1793 : *tp
<= time_t_max
- j
))
1800 normalize_overflow(int *const tensptr
, int *const unitsptr
, const int base
)
1802 register int tensdelta
;
1804 tensdelta
= (*unitsptr
>= 0) ?
1805 (*unitsptr
/ base
) :
1806 (-1 - (-1 - *unitsptr
) / base
);
1807 *unitsptr
-= tensdelta
* base
;
1808 return increment_overflow(tensptr
, tensdelta
);
1812 normalize_overflow32(int_fast32_t *tensptr
, int *unitsptr
, int base
)
1814 register int tensdelta
;
1816 tensdelta
= (*unitsptr
>= 0) ?
1817 (*unitsptr
/ base
) :
1818 (-1 - (-1 - *unitsptr
) / base
);
1819 *unitsptr
-= tensdelta
* base
;
1820 return increment_overflow32(tensptr
, tensdelta
);
1824 tmcomp(register const struct tm
*const atmp
,
1825 register const struct tm
*const btmp
)
1827 register int result
;
1829 if (atmp
->tm_year
!= btmp
->tm_year
)
1830 return atmp
->tm_year
< btmp
->tm_year
? -1 : 1;
1831 if ((result
= (atmp
->tm_mon
- btmp
->tm_mon
)) == 0 &&
1832 (result
= (atmp
->tm_mday
- btmp
->tm_mday
)) == 0 &&
1833 (result
= (atmp
->tm_hour
- btmp
->tm_hour
)) == 0 &&
1834 (result
= (atmp
->tm_min
- btmp
->tm_min
)) == 0)
1835 result
= atmp
->tm_sec
- btmp
->tm_sec
;
1840 time2sub(struct tm
*const tmp
,
1841 struct tm
*(*funcp
)(struct state
const *, time_t const *,
1842 int_fast32_t, struct tm
*),
1843 struct state
const *sp
,
1844 const int_fast32_t offset
,
1850 register int saved_seconds
;
1851 register int_fast32_t li
;
1857 struct tm yourtm
, mytm
;
1862 if (normalize_overflow(&yourtm
.tm_min
, &yourtm
.tm_sec
,
1866 if (normalize_overflow(&yourtm
.tm_hour
, &yourtm
.tm_min
, MINSPERHOUR
))
1868 if (normalize_overflow(&yourtm
.tm_mday
, &yourtm
.tm_hour
, HOURSPERDAY
))
1871 if (normalize_overflow32(&y
, &yourtm
.tm_mon
, MONSPERYEAR
))
1874 ** Turn y into an actual year number for now.
1875 ** It is converted back to an offset from TM_YEAR_BASE later.
1877 if (increment_overflow32(&y
, TM_YEAR_BASE
))
1879 while (yourtm
.tm_mday
<= 0) {
1880 if (increment_overflow32(&y
, -1))
1882 li
= y
+ (1 < yourtm
.tm_mon
);
1883 yourtm
.tm_mday
+= year_lengths
[isleap(li
)];
1885 while (yourtm
.tm_mday
> DAYSPERLYEAR
) {
1886 li
= y
+ (1 < yourtm
.tm_mon
);
1887 yourtm
.tm_mday
-= year_lengths
[isleap(li
)];
1888 if (increment_overflow32(&y
, 1))
1892 i
= mon_lengths
[isleap(y
)][yourtm
.tm_mon
];
1893 if (yourtm
.tm_mday
<= i
)
1895 yourtm
.tm_mday
-= i
;
1896 if (++yourtm
.tm_mon
>= MONSPERYEAR
) {
1898 if (increment_overflow32(&y
, 1))
1902 if (increment_overflow32(&y
, -TM_YEAR_BASE
))
1904 if (! (INT_MIN
<= y
&& y
<= INT_MAX
))
1907 if (yourtm
.tm_sec
>= 0 && yourtm
.tm_sec
< SECSPERMIN
)
1909 else if (y
+ TM_YEAR_BASE
< EPOCH_YEAR
) {
1911 ** We can't set tm_sec to 0, because that might push the
1912 ** time below the minimum representable time.
1913 ** Set tm_sec to 59 instead.
1914 ** This assumes that the minimum representable time is
1915 ** not in the same minute that a leap second was deleted from,
1916 ** which is a safer assumption than using 58 would be.
1918 if (increment_overflow(&yourtm
.tm_sec
, 1 - SECSPERMIN
))
1920 saved_seconds
= yourtm
.tm_sec
;
1921 yourtm
.tm_sec
= SECSPERMIN
- 1;
1923 saved_seconds
= yourtm
.tm_sec
;
1927 ** Do a binary search (this works whatever time_t's type is).
1932 t
= lo
/ 2 + hi
/ 2;
1937 if (! funcp(sp
, &t
, offset
, &mytm
)) {
1939 ** Assume that t is too extreme to be represented in
1940 ** a struct tm; arrange things so that it is less
1941 ** extreme on the next pass.
1943 dir
= (t
> 0) ? 1 : -1;
1944 } else dir
= tmcomp(&mytm
, &yourtm
);
1947 if (t
== time_t_max
)
1951 } else if (t
== hi
) {
1952 if (t
== time_t_min
)
1964 #if defined TM_GMTOFF && ! UNINIT_TRAP
1965 if (mytm
.TM_GMTOFF
!= yourtm
.TM_GMTOFF
1966 && (yourtm
.TM_GMTOFF
< 0
1967 ? (-SECSPERDAY
<= yourtm
.TM_GMTOFF
1968 && (mytm
.TM_GMTOFF
<=
1969 (SMALLEST (INT_FAST32_MAX
, LONG_MAX
)
1970 + yourtm
.TM_GMTOFF
)))
1971 : (yourtm
.TM_GMTOFF
<= SECSPERDAY
1972 && ((BIGGEST (INT_FAST32_MIN
, LONG_MIN
)
1974 <= mytm
.TM_GMTOFF
)))) {
1975 /* MYTM matches YOURTM except with the wrong UTC offset.
1976 YOURTM.TM_GMTOFF is plausible, so try it instead.
1977 It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
1978 since the guess gets checked. */
1980 int_fast32_t diff
= mytm
.TM_GMTOFF
- yourtm
.TM_GMTOFF
;
1981 if (!increment_overflow_time(&altt
, diff
)) {
1983 if (funcp(sp
, &altt
, offset
, &alttm
)
1984 && alttm
.tm_isdst
== mytm
.tm_isdst
1985 && alttm
.TM_GMTOFF
== yourtm
.TM_GMTOFF
1986 && tmcomp(&alttm
, &yourtm
) == 0) {
1993 if (yourtm
.tm_isdst
< 0 || mytm
.tm_isdst
== yourtm
.tm_isdst
)
1996 ** Right time, wrong type.
1997 ** Hunt for right time, right type.
1998 ** It's okay to guess wrong since the guess
2003 for (i
= sp
->typecnt
- 1; i
>= 0; --i
) {
2004 if (sp
->ttis
[i
].tt_isdst
!= yourtm
.tm_isdst
)
2006 for (j
= sp
->typecnt
- 1; j
>= 0; --j
) {
2007 if (sp
->ttis
[j
].tt_isdst
== yourtm
.tm_isdst
)
2009 newt
= t
+ sp
->ttis
[j
].tt_gmtoff
-
2010 sp
->ttis
[i
].tt_gmtoff
;
2011 if (! funcp(sp
, &newt
, offset
, &mytm
))
2013 if (tmcomp(&mytm
, &yourtm
) != 0)
2015 if (mytm
.tm_isdst
!= yourtm
.tm_isdst
)
2027 newt
= t
+ saved_seconds
;
2028 if ((newt
< t
) != (saved_seconds
< 0))
2031 if (funcp(sp
, &t
, offset
, tmp
))
2037 time2(struct tm
* const tmp
,
2038 struct tm
*(*funcp
)(struct state
const *, time_t const *,
2039 int_fast32_t, struct tm
*),
2040 struct state
const *sp
,
2041 const int_fast32_t offset
,
2047 ** First try without normalization of seconds
2048 ** (in case tm_sec contains a value associated with a leap second).
2049 ** If that fails, try with normalization of seconds.
2051 t
= time2sub(tmp
, funcp
, sp
, offset
, okayp
, false);
2052 return *okayp
? t
: time2sub(tmp
, funcp
, sp
, offset
, okayp
, true);
2056 time1(struct tm
*const tmp
,
2057 struct tm
*(*funcp
) (struct state
const *, time_t const *,
2058 int_fast32_t, struct tm
*),
2059 struct state
const *sp
,
2060 const int_fast32_t offset
)
2063 register int samei
, otheri
;
2064 register int sameind
, otherind
;
2067 char seen
[TZ_MAX_TYPES
];
2068 unsigned char types
[TZ_MAX_TYPES
];
2075 if (tmp
->tm_isdst
> 1)
2077 t
= time2(tmp
, funcp
, sp
, offset
, &okay
);
2080 if (tmp
->tm_isdst
< 0)
2083 ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2085 tmp
->tm_isdst
= 0; /* reset to std and try again */
2088 #endif /* !defined PCTS */
2090 ** We're supposed to assume that somebody took a time of one type
2091 ** and did some math on it that yielded a "struct tm" that's bad.
2092 ** We try to divine the type they started from and adjust to the
2097 for (i
= 0; i
< sp
->typecnt
; ++i
)
2100 for (i
= sp
->timecnt
- 1; i
>= 0; --i
)
2101 if (!seen
[sp
->types
[i
]]) {
2102 seen
[sp
->types
[i
]] = true;
2103 types
[nseen
++] = sp
->types
[i
];
2105 for (sameind
= 0; sameind
< nseen
; ++sameind
) {
2106 samei
= types
[sameind
];
2107 if (sp
->ttis
[samei
].tt_isdst
!= tmp
->tm_isdst
)
2109 for (otherind
= 0; otherind
< nseen
; ++otherind
) {
2110 otheri
= types
[otherind
];
2111 if (sp
->ttis
[otheri
].tt_isdst
== tmp
->tm_isdst
)
2113 tmp
->tm_sec
+= sp
->ttis
[otheri
].tt_gmtoff
-
2114 sp
->ttis
[samei
].tt_gmtoff
;
2115 tmp
->tm_isdst
= !tmp
->tm_isdst
;
2116 t
= time2(tmp
, funcp
, sp
, offset
, &okay
);
2119 tmp
->tm_sec
-= sp
->ttis
[otheri
].tt_gmtoff
-
2120 sp
->ttis
[samei
].tt_gmtoff
;
2121 tmp
->tm_isdst
= !tmp
->tm_isdst
;
2128 mktime_tzname(struct state
*sp
, struct tm
*tmp
, bool setname
)
2131 return time1(tmp
, localsub
, sp
, setname
);
2134 return time1(tmp
, gmtsub
, gmtptr
, 0);
2141 mktime_z(struct state
*sp
, struct tm
*tmp
)
2143 return mktime_tzname(sp
, tmp
, false);
2149 mktime(struct tm
*tmp
)
2158 t
= mktime_tzname(lclptr
, tmp
, true);
2166 timelocal(struct tm
*tmp
)
2169 tmp
->tm_isdst
= -1; /* in case it wasn't initialized */
2174 timegm(struct tm
*tmp
)
2176 return timeoff(tmp
, 0);
2180 timeoff(struct tm
*tmp
, long offset
)
2185 return time1(tmp
, gmtsub
, gmtptr
, offset
);
2188 #endif /* defined STD_INSPIRED */
2191 ** XXX--is the below the right way to conditionalize??
2197 ** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
2198 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2199 ** is not the case if we are accounting for leap seconds.
2200 ** So, we provide the following conversion routines for use
2201 ** when exchanging timestamps with POSIX conforming systems.
2205 leapcorr(struct state
const *sp
, time_t t
)
2207 register struct lsinfo
const * lp
;
2213 if (t
>= lp
->ls_trans
)
2219 NETBSD_INSPIRED_EXTERN
time_t ATTRIBUTE_PURE
2220 time2posix_z(struct state
*sp
, time_t t
)
2222 return t
- leapcorr(sp
, t
);
2226 time2posix(time_t t
)
2236 t
= time2posix_z(lclptr
, t
);
2241 NETBSD_INSPIRED_EXTERN
time_t ATTRIBUTE_PURE
2242 posix2time_z(struct state
*sp
, time_t t
)
2247 ** For a positive leap second hit, the result
2248 ** is not unique. For a negative leap second
2249 ** hit, the corresponding time doesn't exist,
2250 ** so we return an adjacent second.
2252 x
= t
+ leapcorr(sp
, t
);
2253 y
= x
- leapcorr(sp
, x
);
2257 y
= x
- leapcorr(sp
, x
);
2263 y
= x
- leapcorr(sp
, x
);
2271 posix2time(time_t t
)
2281 t
= posix2time_z(lclptr
, t
);
2286 #endif /* defined STD_INSPIRED */
2288 #if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
2298 /* Convert from the underlying system's time_t to the ersatz time_tz,
2299 which is called 'time_t' in this file. Typically, this merely
2300 converts the time's integer width. On some platforms, the system
2301 time is local time not UT, or uses some epoch other than the POSIX
2304 Although this code appears to define a function named 'time' that
2305 returns time_t, the macros in private.h cause this code to actually
2306 define a function named 'tz_time' that returns tz_time_t. The call
2307 to sys_time invokes the underlying system's 'time' function. */
2312 time_t r
= sys_time(0);
2313 if (r
!= (time_t) -1) {
2314 int_fast32_t offset
= EPOCH_LOCAL
? (daylight
? timezone
: altzone
) : 0;
2315 if (increment_overflow32(&offset
, -EPOCH_OFFSET
)
2316 || increment_overflow_time (&r
, offset
)) {