2 ** This file is in the public domain, so clarified as of
3 ** 1996-06-05 by Arthur David Olson.
5 ** $FreeBSD: head/contrib/tzcode/stdtime/localtime.c 226828 2011-10-27 08:44:07Z trociny $
9 ** Leap second handling from Bradley White.
10 ** POSIX-style TZ environment variable handling from Guy Harris.
15 #include "namespace.h"
16 #include <sys/types.h>
24 #include "libc_private.h"
25 #include <un-namespace.h>
29 #ifndef TZ_ABBR_MAX_LEN
30 #define TZ_ABBR_MAX_LEN 16
31 #endif /* !defined TZ_ABBR_MAX_LEN */
33 #ifndef TZ_ABBR_CHAR_SET
34 #define TZ_ABBR_CHAR_SET \
35 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
36 #endif /* !defined TZ_ABBR_CHAR_SET */
38 #ifndef TZ_ABBR_ERR_CHAR
39 #define TZ_ABBR_ERR_CHAR '_'
40 #endif /* !defined TZ_ABBR_ERR_CHAR */
42 #define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x)
43 #define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x)
45 #define _RWLOCK_RDLOCK(x) \
47 if (__isthreaded) _pthread_rwlock_rdlock(x); \
50 #define _RWLOCK_WRLOCK(x) \
52 if (__isthreaded) _pthread_rwlock_wrlock(x); \
55 #define _RWLOCK_UNLOCK(x) \
57 if (__isthreaded) _pthread_rwlock_unlock(x); \
61 ** Someone might make incorrect use of a time zone abbreviation:
62 ** 1. They might reference tzname[0] before calling tzset (explicitly
64 ** 2. They might reference tzname[1] before calling tzset (explicitly
66 ** 3. They might reference tzname[1] after setting to a time zone
67 ** in which Daylight Saving Time is never observed.
68 ** 4. They might reference tzname[0] after setting to a time zone
69 ** in which Standard Time is never observed.
70 ** 5. They might reference tm.TM_ZONE after calling offtime.
71 ** What's best to do in the above cases is open to debate;
72 ** for now, we just set things up so that in any of the five cases
73 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
74 ** string "tzname[0] used before set", and similarly for the other cases.
75 ** And another: initialize tzname[0] to "ERA", with an explanation in the
76 ** manual page of what this "time zone abbreviation" means (doing this so
77 ** that tzname[0] has the "normal" length of three characters).
81 static char wildabbr
[] = WILDABBR
;
83 static const char gmt
[] = "UTC";
86 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
87 ** We default to US rules as of 1999-08-17.
88 ** POSIX 1003.1 section 8.1.1 says that the default DST rules are
89 ** implementation dependent; for historical reasons, US rules are a
92 #ifndef TZDEFRULESTRING
93 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
94 #endif /* !defined TZDEFDST */
96 struct ttinfo
{ /* time type information */
97 int_fast32_t tt_gmtoff
; /* UT offset in seconds */
98 int tt_isdst
; /* used to set tm_isdst */
99 int tt_abbrind
; /* abbreviation list index */
100 int tt_ttisstd
; /* TRUE if transition is std time */
101 int tt_ttisgmt
; /* TRUE if transition is UT */
104 struct lsinfo
{ /* leap second information */
105 time_t ls_trans
; /* transition time */
106 int_fast64_t ls_corr
; /* correction to apply */
109 #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
112 #define MY_TZNAME_MAX TZNAME_MAX
113 #endif /* defined TZNAME_MAX */
115 #define MY_TZNAME_MAX 255
116 #endif /* !defined TZNAME_MAX */
125 time_t ats
[TZ_MAX_TIMES
];
126 unsigned char types
[TZ_MAX_TIMES
];
127 struct ttinfo ttis
[TZ_MAX_TYPES
];
128 char chars
[BIGGEST(BIGGEST(TZ_MAX_CHARS
+ 1, sizeof gmt
),
129 (2 * (MY_TZNAME_MAX
+ 1)))];
130 struct lsinfo lsis
[TZ_MAX_LEAPS
];
131 int defaulttype
; /* for early times or if no transitions */
135 int r_type
; /* type of rule--see below */
136 int r_day
; /* day number of rule */
137 int r_week
; /* week number of rule */
138 int r_mon
; /* month number of rule */
139 int_fast32_t r_time
; /* transition time of rule */
142 #define JULIAN_DAY 0 /* Jn - Julian day */
143 #define DAY_OF_YEAR 1 /* n - day of year */
144 #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
147 ** Prototypes for static functions.
150 static int_fast32_t detzcode(const char * codep
);
151 static int_fast64_t detzcode64(const char * codep
);
152 static int differ_by_repeat(time_t t1
, time_t t0
);
153 static const char * getzname(const char * strp
) __pure
;
154 static const char * getqzname(const char * strp
, const int delim
) __pure
;
155 static const char * getnum(const char * strp
, int * nump
, int min
,
157 static const char * getsecs(const char * strp
, int_fast32_t * secsp
);
158 static const char * getoffset(const char * strp
, int_fast32_t * offsetp
);
159 static const char * getrule(const char * strp
, struct rule
* rulep
);
160 static void gmtload(struct state
* sp
);
161 static struct tm
* gmtsub(const time_t * timep
, int_fast32_t offset
,
163 static struct tm
* localsub(const time_t * timep
, int_fast32_t offset
,
165 static int increment_overflow(int * number
, int delta
);
166 static int leaps_thru_end_of(int y
) __pure
;
167 static int increment_overflow32(int_fast32_t * number
, int delta
);
168 static int increment_overflow_time(time_t *t
, int_fast32_t delta
);
169 static int normalize_overflow32(int_fast32_t * tensptr
,
170 int * unitsptr
, int base
);
171 static int normalize_overflow(int * tensptr
, int * unitsptr
,
173 static void settzname(void);
174 static time_t time1(struct tm
* tmp
,
175 struct tm
* (*funcp
)(const time_t *,
176 int_fast32_t, struct tm
*),
177 int_fast32_t offset
);
178 static time_t time2(struct tm
*tmp
,
179 struct tm
* (*funcp
)(const time_t *,
180 int_fast32_t, struct tm
*),
181 int_fast32_t offset
, int * okayp
);
182 static time_t time2sub(struct tm
*tmp
,
183 struct tm
* (*funcp
)(const time_t *,
184 int_fast32_t, struct tm
*),
185 int_fast32_t offset
, int * okayp
, int do_norm_secs
);
186 static struct tm
* timesub(const time_t * timep
, int_fast32_t offset
,
187 const struct state
* sp
, struct tm
* tmp
);
188 static int tmcomp(const struct tm
* atmp
,
189 const struct tm
* btmp
);
190 static int_fast32_t transtime(int year
, const struct rule
* rulep
,
191 int_fast32_t offset
) __pure
;
192 static int typesequiv(const struct state
* sp
, int a
, int b
);
193 static int tzload(const char * name
, struct state
* sp
,
195 static int tzparse(const char * name
, struct state
* sp
,
198 static struct state lclmem
;
199 static struct state gmtmem
;
200 #define lclptr (&lclmem)
201 #define gmtptr (&gmtmem)
203 #ifndef TZ_STRLEN_MAX
204 #define TZ_STRLEN_MAX 255
205 #endif /* !defined TZ_STRLEN_MAX */
207 static char lcl_TZname
[TZ_STRLEN_MAX
+ 1];
208 static int lcl_is_set
;
209 static pthread_once_t gmt_once
= PTHREAD_ONCE_INIT
;
210 static pthread_rwlock_t lcl_rwlock
= PTHREAD_RWLOCK_INITIALIZER
;
211 static pthread_once_t gmtime_once
= PTHREAD_ONCE_INIT
;
212 static pthread_key_t gmtime_key
;
213 static int gmtime_key_error
;
214 static pthread_once_t localtime_once
= PTHREAD_ONCE_INIT
;
215 static pthread_key_t localtime_key
;
216 static int localtime_key_error
;
224 ** Section 4.12.3 of X3.159-1989 requires that
225 ** Except for the strftime function, these functions [asctime,
226 ** ctime, gmtime, localtime] return values in one of two static
227 ** objects: a broken-down time structure and an array of char.
228 ** Thanks to Paul Eggert for noting this.
237 detzcode(const char * const codep
)
242 result
= (codep
[0] & 0x80) ? -1 : 0;
243 for (i
= 0; i
< 4; ++i
)
244 result
= (result
<< 8) | (codep
[i
] & 0xff);
249 detzcode64(const char * const codep
)
254 result
= (codep
[0] & 0x80) ? -1 : 0;
255 for (i
= 0; i
< 8; ++i
)
256 result
= (result
<< 8) | (codep
[i
] & 0xff);
263 struct state
* const sp
= lclptr
;
266 tzname
[0] = wildabbr
;
267 tzname
[1] = wildabbr
;
272 ** And to get the latest zone names into tzname. . .
274 for (i
= 0; i
< sp
->typecnt
; ++i
) {
275 const struct ttinfo
* const ttisp
= &sp
->ttis
[i
];
277 tzname
[ttisp
->tt_isdst
] = &sp
->chars
[ttisp
->tt_abbrind
];
279 for (i
= 0; i
< sp
->timecnt
; ++i
) {
280 const struct ttinfo
* const ttisp
= &sp
->ttis
[sp
->types
[i
]];
282 tzname
[ttisp
->tt_isdst
] =
283 &sp
->chars
[ttisp
->tt_abbrind
];
286 if (!ttisp
->tt_isdst
)
287 timezone
= -(ttisp
->tt_gmtoff
);
290 ** Finally, scrub the abbreviations.
291 ** First, replace bogus characters.
293 for (i
= 0; i
< sp
->charcnt
; ++i
)
294 if (strchr(TZ_ABBR_CHAR_SET
, sp
->chars
[i
]) == NULL
)
295 sp
->chars
[i
] = TZ_ABBR_ERR_CHAR
;
297 ** Second, truncate long abbreviations.
299 for (i
= 0; i
< sp
->typecnt
; ++i
) {
300 const struct ttinfo
* const ttisp
= &sp
->ttis
[i
];
301 char * cp
= &sp
->chars
[ttisp
->tt_abbrind
];
303 if (strlen(cp
) > TZ_ABBR_MAX_LEN
&&
304 strcmp(cp
, GRANDPARENTED
) != 0)
305 *(cp
+ TZ_ABBR_MAX_LEN
) = '\0';
310 differ_by_repeat(const time_t t1
, const time_t t0
)
312 if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS
)
314 return t1
- t0
== SECSPERREPEAT
;
318 tzload(const char *name
, struct state
* const sp
, const int doextend
)
327 struct tzhead tzhead
;
328 char buf
[2 * sizeof(struct tzhead
) +
336 sp
->goback
= sp
->goahead
= FALSE
;
338 /* XXX The following is from OpenBSD, and I'm not sure it is correct */
339 if (name
!= NULL
&& issetugid() != 0)
340 if ((name
[0] == ':' && name
[1] == '/') ||
341 name
[0] == '/' || strchr(name
, '.'))
343 if (name
== NULL
&& (name
= TZDEFAULT
) == NULL
)
349 ** Section 4.9.1 of the C standard says that
350 ** "FILENAME_MAX expands to an integral constant expression
351 ** that is the size needed for an array of char large enough
352 ** to hold the longest file name string that the implementation
353 ** guarantees can be opened."
357 fullname
= malloc(FILENAME_MAX
+ 1);
358 if (fullname
== NULL
)
363 doaccess
= name
[0] == '/';
365 if ((p
= TZDIR
) == NULL
) {
369 if (strlen(p
) + 1 + strlen(name
) >= FILENAME_MAX
) {
374 strcat(fullname
, "/");
375 strcat(fullname
, name
);
377 ** Set doaccess if '.' (as in "../") shows up in name.
379 if (strchr(name
, '.') != NULL
)
383 if (doaccess
&& access(name
, R_OK
) != 0) {
387 if ((fid
= _open(name
, O_RDONLY
)) == -1) {
391 if ((_fstat(fid
, &stab
) < 0) || !S_ISREG(stab
.st_mode
)) {
398 u
= malloc(sizeof(*u
));
401 nread
= _read(fid
, u
->buf
, sizeof u
->buf
);
402 if (_close(fid
) < 0 || nread
<= 0)
404 for (stored
= 4; stored
<= 8; stored
*= 2) {
409 ttisstdcnt
= (int) detzcode(u
->tzhead
.tzh_ttisstdcnt
);
410 ttisgmtcnt
= (int) detzcode(u
->tzhead
.tzh_ttisgmtcnt
);
411 sp
->leapcnt
= (int) detzcode(u
->tzhead
.tzh_leapcnt
);
412 sp
->timecnt
= (int) detzcode(u
->tzhead
.tzh_timecnt
);
413 sp
->typecnt
= (int) detzcode(u
->tzhead
.tzh_typecnt
);
414 sp
->charcnt
= (int) detzcode(u
->tzhead
.tzh_charcnt
);
415 p
= u
->tzhead
.tzh_charcnt
+ sizeof u
->tzhead
.tzh_charcnt
;
416 if (sp
->leapcnt
< 0 || sp
->leapcnt
> TZ_MAX_LEAPS
||
417 sp
->typecnt
<= 0 || sp
->typecnt
> TZ_MAX_TYPES
||
418 sp
->timecnt
< 0 || sp
->timecnt
> TZ_MAX_TIMES
||
419 sp
->charcnt
< 0 || sp
->charcnt
> TZ_MAX_CHARS
||
420 (ttisstdcnt
!= sp
->typecnt
&& ttisstdcnt
!= 0) ||
421 (ttisgmtcnt
!= sp
->typecnt
&& ttisgmtcnt
!= 0))
423 if (nread
- (p
- u
->buf
) <
424 sp
->timecnt
* stored
+ /* ats */
425 sp
->timecnt
+ /* types */
426 sp
->typecnt
* 6 + /* ttinfos */
427 sp
->charcnt
+ /* chars */
428 sp
->leapcnt
* (stored
+ 4) + /* lsinfos */
429 ttisstdcnt
+ /* ttisstds */
430 ttisgmtcnt
) /* ttisgmts */
433 for (i
= 0; i
< sp
->timecnt
; ++i
) {
435 = stored
== 4 ? detzcode(p
) : detzcode64(p
);
436 sp
->types
[i
] = ((TYPE_SIGNED(time_t)
439 && at
<= time_t_max
);
441 if (i
&& !timecnt
&& at
!= time_t_min
) {
443 ** Keep the earlier record, but tweak
444 ** it so that it starts with the
445 ** minimum time_t value.
447 sp
->types
[i
- 1] = 1;
448 sp
->ats
[timecnt
++] = time_t_min
;
450 sp
->ats
[timecnt
++] = at
;
455 for (i
= 0; i
< sp
->timecnt
; ++i
) {
456 unsigned char typ
= *p
++;
457 if (sp
->typecnt
<= typ
)
460 sp
->types
[timecnt
++] = typ
;
462 sp
->timecnt
= timecnt
;
463 for (i
= 0; i
< sp
->typecnt
; ++i
) {
464 struct ttinfo
* ttisp
;
466 ttisp
= &sp
->ttis
[i
];
467 ttisp
->tt_gmtoff
= detzcode(p
);
469 ttisp
->tt_isdst
= (unsigned char) *p
++;
470 if (ttisp
->tt_isdst
!= 0 && ttisp
->tt_isdst
!= 1)
472 ttisp
->tt_abbrind
= (unsigned char) *p
++;
473 if (ttisp
->tt_abbrind
< 0 ||
474 ttisp
->tt_abbrind
> sp
->charcnt
)
477 for (i
= 0; i
< sp
->charcnt
; ++i
)
479 sp
->chars
[i
] = '\0'; /* ensure '\0' at end */
480 for (i
= 0; i
< sp
->leapcnt
; ++i
) {
481 struct lsinfo
* lsisp
;
483 lsisp
= &sp
->lsis
[i
];
484 lsisp
->ls_trans
= (stored
== 4) ?
485 detzcode(p
) : detzcode64(p
);
487 lsisp
->ls_corr
= detzcode(p
);
490 for (i
= 0; i
< sp
->typecnt
; ++i
) {
491 struct ttinfo
* ttisp
;
493 ttisp
= &sp
->ttis
[i
];
495 ttisp
->tt_ttisstd
= FALSE
;
497 ttisp
->tt_ttisstd
= *p
++;
498 if (ttisp
->tt_ttisstd
!= TRUE
&&
499 ttisp
->tt_ttisstd
!= FALSE
)
503 for (i
= 0; i
< sp
->typecnt
; ++i
) {
504 struct ttinfo
* ttisp
;
506 ttisp
= &sp
->ttis
[i
];
508 ttisp
->tt_ttisgmt
= FALSE
;
510 ttisp
->tt_ttisgmt
= *p
++;
511 if (ttisp
->tt_ttisgmt
!= TRUE
&&
512 ttisp
->tt_ttisgmt
!= FALSE
)
517 ** If this is an old file, we're done.
519 if (u
->tzhead
.tzh_version
[0] == '\0')
522 for (i
= 0; i
< nread
; ++i
)
525 ** If this is a signed narrow time_t system, we're done.
527 if (TYPE_SIGNED(time_t) && stored
>= (int) sizeof(time_t))
530 if (doextend
&& nread
> 2 &&
531 u
->buf
[0] == '\n' && u
->buf
[nread
- 1] == '\n' &&
532 sp
->typecnt
+ 2 <= TZ_MAX_TYPES
) {
536 ts
= malloc(sizeof(*ts
));
539 u
->buf
[nread
- 1] = '\0';
540 result
= tzparse(&u
->buf
[1], ts
, FALSE
);
541 if (result
== 0 && ts
->typecnt
== 2 &&
542 sp
->charcnt
+ ts
->charcnt
<= TZ_MAX_CHARS
) {
543 for (i
= 0; i
< 2; ++i
)
544 ts
->ttis
[i
].tt_abbrind
+=
546 for (i
= 0; i
< ts
->charcnt
; ++i
)
547 sp
->chars
[sp
->charcnt
++] =
550 while (i
< ts
->timecnt
&&
552 sp
->ats
[sp
->timecnt
- 1])
554 while (i
< ts
->timecnt
&&
555 sp
->timecnt
< TZ_MAX_TIMES
) {
556 sp
->ats
[sp
->timecnt
] =
558 sp
->types
[sp
->timecnt
] =
564 sp
->ttis
[sp
->typecnt
++] = ts
->ttis
[0];
565 sp
->ttis
[sp
->typecnt
++] = ts
->ttis
[1];
569 if (sp
->timecnt
> 1) {
570 for (i
= 1; i
< sp
->timecnt
; ++i
)
571 if (typesequiv(sp
, sp
->types
[i
], sp
->types
[0]) &&
572 differ_by_repeat(sp
->ats
[i
], sp
->ats
[0])) {
576 for (i
= sp
->timecnt
- 2; i
>= 0; --i
)
577 if (typesequiv(sp
, sp
->types
[sp
->timecnt
- 1],
579 differ_by_repeat(sp
->ats
[sp
->timecnt
- 1],
586 ** If type 0 is is unused in transitions,
587 ** it's the type to use for early times.
589 for (i
= 0; i
< sp
->typecnt
; ++i
)
590 if (sp
->types
[i
] == 0)
592 i
= (i
>= sp
->typecnt
) ? 0 : -1;
595 ** if there are transition times
596 ** and the first transition is to a daylight time
597 ** find the standard type less than and closest to
598 ** the type of the first transition.
600 if (i
< 0 && sp
->timecnt
> 0 && sp
->ttis
[sp
->types
[0]].tt_isdst
) {
603 if (!sp
->ttis
[i
].tt_isdst
)
607 ** If no result yet, find the first standard type.
608 ** If there is none, punt to type zero.
612 while (sp
->ttis
[i
].tt_isdst
)
613 if (++i
>= sp
->typecnt
) {
627 typesequiv(const struct state
* const sp
, const int a
, const int b
)
632 a
< 0 || a
>= sp
->typecnt
||
633 b
< 0 || b
>= sp
->typecnt
)
636 const struct ttinfo
* ap
= &sp
->ttis
[a
];
637 const struct ttinfo
* bp
= &sp
->ttis
[b
];
638 result
= ap
->tt_gmtoff
== bp
->tt_gmtoff
&&
639 ap
->tt_isdst
== bp
->tt_isdst
&&
640 ap
->tt_ttisstd
== bp
->tt_ttisstd
&&
641 ap
->tt_ttisgmt
== bp
->tt_ttisgmt
&&
642 strcmp(&sp
->chars
[ap
->tt_abbrind
],
643 &sp
->chars
[bp
->tt_abbrind
]) == 0;
648 static const int mon_lengths
[2][MONSPERYEAR
] = {
649 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
650 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
653 static const int year_lengths
[2] = {
654 DAYSPERNYEAR
, DAYSPERLYEAR
658 ** Given a pointer into a time zone string, scan until a character that is not
659 ** a valid character in a zone name is found. Return a pointer to that
664 getzname(const char *strp
)
668 while ((c
= *strp
) != '\0' && !is_digit(c
) && c
!= ',' && c
!= '-' &&
675 ** Given a pointer into an extended time zone string, scan until the ending
676 ** delimiter of the zone name is located. Return a pointer to the delimiter.
678 ** As with getzname above, the legal character set is actually quite
679 ** restricted, with other characters producing undefined results.
680 ** We don't do any checking here; checking is done later in common-case code.
684 getqzname(const char *strp
, const int delim
)
688 while ((c
= *strp
) != '\0' && c
!= delim
)
694 ** Given a pointer into a time zone string, extract a number from that string.
695 ** Check that the number is within a specified range; if it is not, return
697 ** Otherwise, return a pointer to the first character not part of the number.
701 getnum(const char *strp
, int * const nump
, const int min
, const int max
)
706 if (strp
== NULL
|| !is_digit(c
= *strp
))
710 num
= num
* 10 + (c
- '0');
712 return NULL
; /* illegal value */
714 } while (is_digit(c
));
716 return NULL
; /* illegal value */
722 ** Given a pointer into a time zone string, extract a number of seconds,
723 ** in hh[:mm[:ss]] form, from the string.
724 ** If any error occurs, return NULL.
725 ** Otherwise, return a pointer to the first character not part of the number
730 getsecs(const char *strp
, int_fast32_t * const secsp
)
735 ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
736 ** "M10.4.6/26", which does not conform to Posix,
737 ** but which specifies the equivalent of
738 ** ``02:00 on the first Sunday on or after 23 Oct''.
740 strp
= getnum(strp
, &num
, 0, HOURSPERDAY
* DAYSPERWEEK
- 1);
743 *secsp
= num
* (int_fast32_t) SECSPERHOUR
;
746 strp
= getnum(strp
, &num
, 0, MINSPERHOUR
- 1);
749 *secsp
+= num
* SECSPERMIN
;
752 /* `SECSPERMIN' allows for leap seconds. */
753 strp
= getnum(strp
, &num
, 0, SECSPERMIN
);
763 ** Given a pointer into a time zone string, extract an offset, in
764 ** [+-]hh[:mm[:ss]] form, from the string.
765 ** If any error occurs, return NULL.
766 ** Otherwise, return a pointer to the first character not part of the time.
770 getoffset(const char *strp
, int_fast32_t * const offsetp
)
777 } else if (*strp
== '+')
779 strp
= getsecs(strp
, offsetp
);
781 return NULL
; /* illegal time */
783 *offsetp
= -*offsetp
;
788 ** Given a pointer into a time zone string, extract a rule in the form
789 ** date[/time]. See POSIX section 8 for the format of "date" and "time".
790 ** If a valid rule is not found, return NULL.
791 ** Otherwise, return a pointer to the first character not part of the rule.
795 getrule(const char *strp
, struct rule
* const rulep
)
801 rulep
->r_type
= JULIAN_DAY
;
803 strp
= getnum(strp
, &rulep
->r_day
, 1, DAYSPERNYEAR
);
804 } else if (*strp
== 'M') {
808 rulep
->r_type
= MONTH_NTH_DAY_OF_WEEK
;
810 strp
= getnum(strp
, &rulep
->r_mon
, 1, MONSPERYEAR
);
815 strp
= getnum(strp
, &rulep
->r_week
, 1, 5);
820 strp
= getnum(strp
, &rulep
->r_day
, 0, DAYSPERWEEK
- 1);
821 } else if (is_digit(*strp
)) {
825 rulep
->r_type
= DAY_OF_YEAR
;
826 strp
= getnum(strp
, &rulep
->r_day
, 0, DAYSPERLYEAR
- 1);
827 } else return NULL
; /* invalid format */
835 strp
= getoffset(strp
, &rulep
->r_time
);
836 } else rulep
->r_time
= 2 * SECSPERHOUR
; /* default = 2:00:00 */
841 ** Given a year, a rule, and the offset from UT at the time that rule takes
842 ** effect, calculate the year-relative time that rule takes effect.
846 transtime(const int year
, const struct rule
* const rulep
,
847 const int_fast32_t offset
)
852 int d
, m1
, yy0
, yy1
, yy2
, dow
;
855 leapyear
= isleap(year
);
856 switch (rulep
->r_type
) {
860 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
862 ** In non-leap years, or if the day number is 59 or less, just
863 ** add SECSPERDAY times the day number-1 to the time of
864 ** January 1, midnight, to get the day.
866 value
= (rulep
->r_day
- 1) * SECSPERDAY
;
867 if (leapyear
&& rulep
->r_day
>= 60)
874 ** Just add SECSPERDAY times the day number to the time of
875 ** January 1, midnight, to get the day.
877 value
= rulep
->r_day
* SECSPERDAY
;
880 case MONTH_NTH_DAY_OF_WEEK
:
882 ** Mm.n.d - nth "dth day" of month m.
886 ** Use Zeller's Congruence to get day-of-week of first day of
889 m1
= (rulep
->r_mon
+ 9) % 12 + 1;
890 yy0
= (rulep
->r_mon
<= 2) ? (year
- 1) : year
;
893 dow
= ((26 * m1
- 2) / 10 +
894 1 + yy2
+ yy2
/ 4 + yy1
/ 4 - 2 * yy1
) % 7;
899 ** "dow" is the day-of-week of the first day of the month. Get
900 ** the day-of-month (zero-origin) of the first "dow" day of the
903 d
= rulep
->r_day
- dow
;
906 for (i
= 1; i
< rulep
->r_week
; ++i
) {
907 if (d
+ DAYSPERWEEK
>=
908 mon_lengths
[leapyear
][rulep
->r_mon
- 1])
914 ** "d" is the day-of-month (zero-origin) of the day we want.
916 value
= d
* SECSPERDAY
;
917 for (i
= 0; i
< rulep
->r_mon
- 1; ++i
)
918 value
+= mon_lengths
[leapyear
][i
] * SECSPERDAY
;
923 ** "value" is the year-relative time of 00:00:00 UT on the day in
924 ** question. To get the year-relative time of the specified local
925 ** time on that day, add the transition time and the current offset
928 return value
+ rulep
->r_time
+ offset
;
932 ** Given a POSIX section 8-style TZ string, fill in the rule tables as
937 tzparse(const char *name
, struct state
* const sp
, const int lastditch
)
939 const char * stdname
;
940 const char * dstname
;
943 int_fast32_t stdoffset
;
944 int_fast32_t dstoffset
;
947 static struct ttinfo zttinfo
;
952 stdlen
= strlen(name
); /* length of standard zone name */
954 if (stdlen
>= sizeof sp
->chars
)
955 stdlen
= (sizeof sp
->chars
) - 1;
961 name
= getqzname(name
, '>');
964 stdlen
= name
- stdname
;
967 name
= getzname(name
);
968 stdlen
= name
- stdname
;
972 name
= getoffset(name
, &stdoffset
);
976 load_result
= tzload(TZDEFRULES
, sp
, FALSE
);
977 if (load_result
!= 0)
978 sp
->leapcnt
= 0; /* so, we're off a little */
982 name
= getqzname(name
, '>');
985 dstlen
= name
- dstname
;
989 name
= getzname(name
);
990 dstlen
= name
- dstname
; /* length of DST zone name */
992 if (*name
!= '\0' && *name
!= ',' && *name
!= ';') {
993 name
= getoffset(name
, &dstoffset
);
996 } else dstoffset
= stdoffset
- SECSPERHOUR
;
997 if (*name
== '\0' && load_result
!= 0)
998 name
= TZDEFRULESTRING
;
999 if (*name
== ',' || *name
== ';') {
1008 if ((name
= getrule(name
, &start
)) == NULL
)
1012 if ((name
= getrule(name
, &end
)) == NULL
)
1016 sp
->typecnt
= 2; /* standard time and DST */
1018 ** Two transitions per year, from EPOCH_YEAR forward.
1020 sp
->ttis
[0] = sp
->ttis
[1] = zttinfo
;
1021 sp
->ttis
[0].tt_gmtoff
= -dstoffset
;
1022 sp
->ttis
[0].tt_isdst
= 1;
1023 sp
->ttis
[0].tt_abbrind
= stdlen
+ 1;
1024 sp
->ttis
[1].tt_gmtoff
= -stdoffset
;
1025 sp
->ttis
[1].tt_isdst
= 0;
1026 sp
->ttis
[1].tt_abbrind
= 0;
1029 yearlim
= EPOCH_YEAR
+ YEARSPERREPEAT
;
1030 for (year
= EPOCH_YEAR
; year
< yearlim
; year
++) {
1032 starttime
= transtime(year
, &start
, stdoffset
),
1033 endtime
= transtime(year
, &end
, dstoffset
);
1035 yearsecs
= (year_lengths
[isleap(year
)]
1037 int reversed
= endtime
< starttime
;
1039 int_fast32_t swap
= starttime
;
1040 starttime
= endtime
;
1044 || (starttime
< endtime
1045 && (endtime
- starttime
1047 + (stdoffset
- dstoffset
))))) {
1048 if (TZ_MAX_TIMES
- 2 < timecnt
)
1050 yearlim
= year
+ YEARSPERREPEAT
+ 1;
1051 sp
->ats
[timecnt
] = janfirst
;
1052 if (increment_overflow_time
1053 (&sp
->ats
[timecnt
], starttime
))
1055 sp
->types
[timecnt
++] = reversed
;
1056 sp
->ats
[timecnt
] = janfirst
;
1057 if (increment_overflow_time
1058 (&sp
->ats
[timecnt
], endtime
))
1060 sp
->types
[timecnt
++] = !reversed
;
1062 if (increment_overflow_time(&janfirst
, yearsecs
))
1065 sp
->timecnt
= timecnt
;
1067 sp
->typecnt
= 1; /* Perpetual DST. */
1069 int_fast32_t theirstdoffset
;
1070 int_fast32_t theirdstoffset
;
1071 int_fast32_t theiroffset
;
1079 ** Initial values of theirstdoffset and theirdstoffset.
1082 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1084 if (!sp
->ttis
[j
].tt_isdst
) {
1086 -sp
->ttis
[j
].tt_gmtoff
;
1091 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1093 if (sp
->ttis
[j
].tt_isdst
) {
1095 -sp
->ttis
[j
].tt_gmtoff
;
1100 ** Initially we're assumed to be in standard time.
1103 theiroffset
= theirstdoffset
;
1105 ** Now juggle transition times and types
1106 ** tracking offsets as you do.
1108 for (i
= 0; i
< sp
->timecnt
; ++i
) {
1110 sp
->types
[i
] = sp
->ttis
[j
].tt_isdst
;
1111 if (sp
->ttis
[j
].tt_ttisgmt
) {
1112 /* No adjustment to transition time */
1115 ** If summer time is in effect, and the
1116 ** transition time was not specified as
1117 ** standard time, add the summer time
1118 ** offset to the transition time;
1119 ** otherwise, add the standard time
1120 ** offset to the transition time.
1123 ** Transitions from DST to DDST
1124 ** will effectively disappear since
1125 ** POSIX provides for only one DST
1128 if (isdst
&& !sp
->ttis
[j
].tt_ttisstd
) {
1129 sp
->ats
[i
] += dstoffset
-
1132 sp
->ats
[i
] += stdoffset
-
1136 theiroffset
= -sp
->ttis
[j
].tt_gmtoff
;
1137 if (sp
->ttis
[j
].tt_isdst
)
1138 theirdstoffset
= theiroffset
;
1139 else theirstdoffset
= theiroffset
;
1142 ** Finally, fill in ttis.
1144 sp
->ttis
[0] = sp
->ttis
[1] = zttinfo
;
1145 sp
->ttis
[0].tt_gmtoff
= -stdoffset
;
1146 sp
->ttis
[0].tt_isdst
= FALSE
;
1147 sp
->ttis
[0].tt_abbrind
= 0;
1148 sp
->ttis
[1].tt_gmtoff
= -dstoffset
;
1149 sp
->ttis
[1].tt_isdst
= TRUE
;
1150 sp
->ttis
[1].tt_abbrind
= stdlen
+ 1;
1155 sp
->typecnt
= 1; /* only standard time */
1157 sp
->ttis
[0] = zttinfo
;
1158 sp
->ttis
[0].tt_gmtoff
= -stdoffset
;
1159 sp
->ttis
[0].tt_isdst
= 0;
1160 sp
->ttis
[0].tt_abbrind
= 0;
1162 sp
->charcnt
= stdlen
+ 1;
1164 sp
->charcnt
+= dstlen
+ 1;
1165 if ((size_t) sp
->charcnt
> sizeof sp
->chars
)
1168 strncpy(cp
, stdname
, stdlen
);
1172 strncpy(cp
, dstname
, dstlen
);
1173 *(cp
+ dstlen
) = '\0';
1179 gmtload(struct state
* const sp
)
1181 if (tzload(gmt
, sp
, TRUE
) != 0)
1182 tzparse(gmt
, sp
, TRUE
);
1186 tzsetwall_basic(int rdlocked
)
1189 _RWLOCK_RDLOCK(&lcl_rwlock
);
1190 if (lcl_is_set
< 0) {
1192 _RWLOCK_UNLOCK(&lcl_rwlock
);
1195 _RWLOCK_UNLOCK(&lcl_rwlock
);
1197 _RWLOCK_WRLOCK(&lcl_rwlock
);
1200 if (tzload(NULL
, lclptr
, TRUE
) != 0)
1203 _RWLOCK_UNLOCK(&lcl_rwlock
);
1206 _RWLOCK_RDLOCK(&lcl_rwlock
);
1216 tzset_basic(int rdlocked
)
1220 name
= getenv("TZ");
1222 tzsetwall_basic(rdlocked
);
1227 _RWLOCK_RDLOCK(&lcl_rwlock
);
1228 if (lcl_is_set
> 0 && strcmp(lcl_TZname
, name
) == 0) {
1230 _RWLOCK_UNLOCK(&lcl_rwlock
);
1233 _RWLOCK_UNLOCK(&lcl_rwlock
);
1235 _RWLOCK_WRLOCK(&lcl_rwlock
);
1236 lcl_is_set
= strlen(name
) < sizeof lcl_TZname
;
1238 strcpy(lcl_TZname
, name
);
1240 if (*name
== '\0') {
1242 ** User wants it fast rather than right.
1244 lclptr
->leapcnt
= 0; /* so, we're off a little */
1245 lclptr
->timecnt
= 0;
1246 lclptr
->typecnt
= 0;
1247 lclptr
->ttis
[0].tt_isdst
= 0;
1248 lclptr
->ttis
[0].tt_gmtoff
= 0;
1249 lclptr
->ttis
[0].tt_abbrind
= 0;
1250 strcpy(lclptr
->chars
, gmt
);
1251 } else if (tzload(name
, lclptr
, TRUE
) != 0)
1252 if (name
[0] == ':' || tzparse(name
, lclptr
, FALSE
) != 0)
1255 _RWLOCK_UNLOCK(&lcl_rwlock
);
1258 _RWLOCK_RDLOCK(&lcl_rwlock
);
1268 ** The easy way to behave "as if no library function calls" localtime
1269 ** is to not call it--so we drop its guts into "localsub", which can be
1270 ** freely called. (And no, the PANS doesn't require the above behavior--
1271 ** but it *is* desirable.)
1273 ** The unused offset argument is for the benefit of mktime variants.
1278 localsub(const time_t * const timep
, const int_fast32_t offset __unused
,
1279 struct tm
* const tmp
)
1282 const struct ttinfo
* ttisp
;
1285 const time_t t
= *timep
;
1289 if ((sp
->goback
&& t
< sp
->ats
[0]) ||
1290 (sp
->goahead
&& t
> sp
->ats
[sp
->timecnt
- 1])) {
1296 seconds
= sp
->ats
[0] - t
;
1297 else seconds
= t
- sp
->ats
[sp
->timecnt
- 1];
1299 years
= (seconds
/ SECSPERREPEAT
+ 1) * YEARSPERREPEAT
;
1300 seconds
= years
* AVGSECSPERYEAR
;
1303 else newt
-= seconds
;
1304 if (newt
< sp
->ats
[0] ||
1305 newt
> sp
->ats
[sp
->timecnt
- 1])
1306 return NULL
; /* "cannot happen" */
1307 result
= localsub(&newt
, offset
, tmp
);
1308 if (result
== tmp
) {
1311 newy
= tmp
->tm_year
;
1315 tmp
->tm_year
= newy
;
1316 if (tmp
->tm_year
!= newy
)
1321 if (sp
->timecnt
== 0 || t
< sp
->ats
[0]) {
1322 i
= sp
->defaulttype
;
1325 int hi
= sp
->timecnt
;
1328 int mid
= (lo
+ hi
) >> 1;
1330 if (t
< sp
->ats
[mid
])
1334 i
= (int) sp
->types
[lo
- 1];
1336 ttisp
= &sp
->ttis
[i
];
1338 ** To get (wrong) behavior that's compatible with System V Release 2.0
1339 ** you'd replace the statement below with
1340 ** t += ttisp->tt_gmtoff;
1341 ** timesub(&t, 0L, sp, tmp);
1343 result
= timesub(&t
, ttisp
->tt_gmtoff
, sp
, tmp
);
1344 tmp
->tm_isdst
= ttisp
->tt_isdst
;
1345 tzname
[tmp
->tm_isdst
] = &sp
->chars
[ttisp
->tt_abbrind
];
1347 tmp
->TM_ZONE
= &sp
->chars
[ttisp
->tt_abbrind
];
1348 #endif /* defined TM_ZONE */
1353 localtime_key_init(void)
1356 localtime_key_error
= _pthread_key_create(&localtime_key
, free
);
1360 localtime(const time_t * const timep
)
1364 if (__isthreaded
!= 0) {
1365 _pthread_once(&localtime_once
, localtime_key_init
);
1366 if (localtime_key_error
!= 0) {
1367 errno
= localtime_key_error
;
1370 p_tm
= _pthread_getspecific(localtime_key
);
1372 if ((p_tm
= (struct tm
*)malloc(sizeof(struct tm
)))
1375 _pthread_setspecific(localtime_key
, p_tm
);
1377 _RWLOCK_RDLOCK(&lcl_rwlock
);
1379 localsub(timep
, 0L, p_tm
);
1380 _RWLOCK_UNLOCK(&lcl_rwlock
);
1384 localsub(timep
, 0L, &tm
);
1390 ** Re-entrant version of localtime.
1394 localtime_r(const time_t * const timep
, struct tm
*tmp
)
1396 _RWLOCK_RDLOCK(&lcl_rwlock
);
1398 localsub(timep
, 0L, tmp
);
1399 _RWLOCK_UNLOCK(&lcl_rwlock
);
1410 ** gmtsub is to gmtime as localsub is to localtime.
1414 gmtsub(const time_t * const timep
, const int_fast32_t offset
,
1415 struct tm
* const tmp
)
1419 _once(&gmt_once
, gmt_init
);
1420 result
= timesub(timep
, offset
, gmtptr
, tmp
);
1423 ** Could get fancy here and deliver something such as
1424 ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
1425 ** but this is no time for a treasure hunt.
1428 tmp
->TM_ZONE
= wildabbr
;
1430 tmp
->TM_ZONE
= gmtptr
->chars
;
1431 #endif /* defined TM_ZONE */
1436 gmtime_key_init(void)
1438 gmtime_key_error
= _pthread_key_create(&gmtime_key
, free
);
1442 gmtime(const time_t * const timep
)
1446 if (__isthreaded
!= 0) {
1447 _pthread_once(&gmtime_once
, gmtime_key_init
);
1448 if (gmtime_key_error
!= 0) {
1449 errno
= gmtime_key_error
;
1453 * Changed to follow POSIX.1 threads standard, which
1454 * is what BSD currently has.
1456 if ((p_tm
= _pthread_getspecific(gmtime_key
)) == NULL
) {
1457 if ((p_tm
= (struct tm
*)malloc(sizeof(struct tm
)))
1461 _pthread_setspecific(gmtime_key
, p_tm
);
1463 return gmtsub(timep
, 0L, p_tm
);
1465 return gmtsub(timep
, 0L, &tm
);
1470 * Re-entrant version of gmtime.
1474 gmtime_r(const time_t * timep
, struct tm
* tmp
)
1476 return gmtsub(timep
, 0L, tmp
);
1480 offtime(const time_t * const timep
, const long offset
)
1482 return gmtsub(timep
, offset
, &tm
);
1486 ** Return the number of leap years through the end of the given year
1487 ** where, to make the math easy, the answer for year zero is defined as zero.
1491 leaps_thru_end_of(const int y
)
1493 return (y
>= 0) ? (y
/ 4 - y
/ 100 + y
/ 400) :
1494 -(leaps_thru_end_of(-(y
+ 1)) + 1);
1498 timesub(const time_t * const timep
, const int_fast32_t offset
,
1499 const struct state
* const sp
, struct tm
* const tmp
)
1501 const struct lsinfo
* lp
;
1503 int idays
; /* unsigned would be so 2003 */
1517 if (*timep
>= lp
->ls_trans
) {
1518 if (*timep
== lp
->ls_trans
) {
1519 hit
= ((i
== 0 && lp
->ls_corr
> 0) ||
1520 lp
->ls_corr
> sp
->lsis
[i
- 1].ls_corr
);
1523 sp
->lsis
[i
].ls_trans
==
1524 sp
->lsis
[i
- 1].ls_trans
+ 1 &&
1525 sp
->lsis
[i
].ls_corr
==
1526 sp
->lsis
[i
- 1].ls_corr
+ 1) {
1536 tdays
= *timep
/ SECSPERDAY
;
1537 rem
= *timep
- tdays
* SECSPERDAY
;
1538 while (tdays
< 0 || tdays
>= year_lengths
[isleap(y
)]) {
1544 tdelta
= tdays
/ DAYSPERLYEAR
;
1545 if (! ((! TYPE_SIGNED(time_t) || INT_MIN
<= tdelta
)
1546 && tdelta
<= INT_MAX
))
1550 idelta
= (tdays
< 0) ? -1 : 1;
1552 if (increment_overflow(&newy
, idelta
))
1554 leapdays
= leaps_thru_end_of(newy
- 1) -
1555 leaps_thru_end_of(y
- 1);
1556 tdays
-= ((time_t) newy
- y
) * DAYSPERNYEAR
;
1561 int_fast32_t seconds
;
1563 seconds
= tdays
* SECSPERDAY
;
1564 tdays
= seconds
/ SECSPERDAY
;
1565 rem
+= seconds
- tdays
* SECSPERDAY
;
1568 ** Given the range, we can now fearlessly cast...
1571 rem
+= offset
- corr
;
1576 while (rem
>= SECSPERDAY
) {
1581 if (increment_overflow(&y
, -1))
1583 idays
+= year_lengths
[isleap(y
)];
1585 while (idays
>= year_lengths
[isleap(y
)]) {
1586 idays
-= year_lengths
[isleap(y
)];
1587 if (increment_overflow(&y
, 1))
1591 if (increment_overflow(&tmp
->tm_year
, -TM_YEAR_BASE
))
1593 tmp
->tm_yday
= idays
;
1595 ** The "extra" mods below avoid overflow problems.
1597 tmp
->tm_wday
= EPOCH_WDAY
+
1598 ((y
- EPOCH_YEAR
) % DAYSPERWEEK
) *
1599 (DAYSPERNYEAR
% DAYSPERWEEK
) +
1600 leaps_thru_end_of(y
- 1) -
1601 leaps_thru_end_of(EPOCH_YEAR
- 1) +
1603 tmp
->tm_wday
%= DAYSPERWEEK
;
1604 if (tmp
->tm_wday
< 0)
1605 tmp
->tm_wday
+= DAYSPERWEEK
;
1606 tmp
->tm_hour
= (int) (rem
/ SECSPERHOUR
);
1608 tmp
->tm_min
= (int) (rem
/ SECSPERMIN
);
1610 ** A positive leap second requires a special
1611 ** representation. This uses "... ??:59:60" et seq.
1613 tmp
->tm_sec
= (int) (rem
% SECSPERMIN
) + hit
;
1614 ip
= mon_lengths
[isleap(y
)];
1615 for (tmp
->tm_mon
= 0; idays
>= ip
[tmp
->tm_mon
]; ++(tmp
->tm_mon
))
1616 idays
-= ip
[tmp
->tm_mon
];
1617 tmp
->tm_mday
= (int) (idays
+ 1);
1620 tmp
->TM_GMTOFF
= offset
;
1621 #endif /* defined TM_GMTOFF */
1626 ctime(const time_t * const timep
)
1629 ** Section 4.12.3.2 of X3.159-1989 requires that
1630 ** The ctime function converts the calendar time pointed to by timer
1631 ** to local time in the form of a string. It is equivalent to
1632 ** asctime(localtime(timer))
1634 return asctime(localtime(timep
));
1638 ctime_r(const time_t * const timep
, char *buf
)
1642 return asctime_r(localtime_r(timep
, &mytm
), buf
);
1646 ** Adapted from code provided by Robert Elz, who writes:
1647 ** The "best" way to do mktime I think is based on an idea of Bob
1648 ** Kridle's (so its said...) from a long time ago.
1649 ** It does a binary search of the time_t space. Since time_t's are
1650 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
1651 ** would still be very reasonable).
1656 #endif /* !defined WRONG */
1659 ** Normalize logic courtesy Paul Eggert.
1663 increment_overflow(int * const ip
, int j
)
1668 ** If i >= 0 there can only be overflow if i + j > INT_MAX
1669 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1670 ** If i < 0 there can only be overflow if i + j < INT_MIN
1671 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1673 if ((i
>= 0) ? (j
> INT_MAX
- i
) : (j
< INT_MIN
- i
))
1680 increment_overflow32(int_fast32_t * const lp
, int const m
)
1682 int_fast32_t const l
= *lp
;
1684 if ((l
>= 0) ? (m
> INT_FAST32_MAX
- l
) : (m
< INT_FAST32_MIN
- l
))
1691 increment_overflow_time(time_t *tp
, int_fast32_t j
)
1695 ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1696 ** except that it does the right thing even if *tp + j would overflow.
1699 ? (TYPE_SIGNED(time_t) ? time_t_min
- j
<= *tp
: -1 - j
< *tp
)
1700 : *tp
<= time_t_max
- j
))
1707 normalize_overflow(int * const tensptr
, int * const unitsptr
, const int base
)
1711 tensdelta
= (*unitsptr
>= 0) ?
1712 (*unitsptr
/ base
) :
1713 (-1 - (-1 - *unitsptr
) / base
);
1714 *unitsptr
-= tensdelta
* base
;
1715 return increment_overflow(tensptr
, tensdelta
);
1719 normalize_overflow32(int_fast32_t * const tensptr
, int * const unitsptr
,
1724 tensdelta
= (*unitsptr
>= 0) ?
1725 (*unitsptr
/ base
) :
1726 (-1 - (-1 - *unitsptr
) / base
);
1727 *unitsptr
-= tensdelta
* base
;
1728 return increment_overflow32(tensptr
, tensdelta
);
1732 tmcomp(const struct tm
* const atmp
, const struct tm
* const btmp
)
1736 if (atmp
->tm_year
!= btmp
->tm_year
)
1737 return atmp
->tm_year
< btmp
->tm_year
? -1 : 1;
1738 if ((result
= (atmp
->tm_mon
- btmp
->tm_mon
)) == 0 &&
1739 (result
= (atmp
->tm_mday
- btmp
->tm_mday
)) == 0 &&
1740 (result
= (atmp
->tm_hour
- btmp
->tm_hour
)) == 0 &&
1741 (result
= (atmp
->tm_min
- btmp
->tm_min
)) == 0)
1742 result
= atmp
->tm_sec
- btmp
->tm_sec
;
1747 time2sub(struct tm
* const tmp
,
1748 struct tm
* (* const funcp
)(const time_t *, int_fast32_t, struct tm
*),
1749 const int_fast32_t offset
, int * const okayp
, const int do_norm_secs
)
1751 const struct state
* sp
;
1761 struct tm yourtm
, mytm
;
1766 if (normalize_overflow(&yourtm
.tm_min
, &yourtm
.tm_sec
,
1770 if (normalize_overflow(&yourtm
.tm_hour
, &yourtm
.tm_min
, MINSPERHOUR
))
1772 if (normalize_overflow(&yourtm
.tm_mday
, &yourtm
.tm_hour
, HOURSPERDAY
))
1775 if (normalize_overflow32(&y
, &yourtm
.tm_mon
, MONSPERYEAR
))
1778 ** Turn y into an actual year number for now.
1779 ** It is converted back to an offset from TM_YEAR_BASE later.
1781 if (increment_overflow32(&y
, TM_YEAR_BASE
))
1783 while (yourtm
.tm_mday
<= 0) {
1784 if (increment_overflow32(&y
, -1))
1786 li
= y
+ (1 < yourtm
.tm_mon
);
1787 yourtm
.tm_mday
+= year_lengths
[isleap(li
)];
1789 while (yourtm
.tm_mday
> DAYSPERLYEAR
) {
1790 li
= y
+ (1 < yourtm
.tm_mon
);
1791 yourtm
.tm_mday
-= year_lengths
[isleap(li
)];
1792 if (increment_overflow32(&y
, 1))
1796 i
= mon_lengths
[isleap(y
)][yourtm
.tm_mon
];
1797 if (yourtm
.tm_mday
<= i
)
1799 yourtm
.tm_mday
-= i
;
1800 if (++yourtm
.tm_mon
>= MONSPERYEAR
) {
1802 if (increment_overflow32(&y
, 1))
1806 if (increment_overflow32(&y
, -TM_YEAR_BASE
))
1809 if (yourtm
.tm_year
!= y
)
1811 if (yourtm
.tm_sec
>= 0 && yourtm
.tm_sec
< SECSPERMIN
)
1813 else if (y
+ TM_YEAR_BASE
< EPOCH_YEAR
) {
1815 ** We can't set tm_sec to 0, because that might push the
1816 ** time below the minimum representable time.
1817 ** Set tm_sec to 59 instead.
1818 ** This assumes that the minimum representable time is
1819 ** not in the same minute that a leap second was deleted from,
1820 ** which is a safer assumption than using 58 would be.
1822 if (increment_overflow(&yourtm
.tm_sec
, 1 - SECSPERMIN
))
1824 saved_seconds
= yourtm
.tm_sec
;
1825 yourtm
.tm_sec
= SECSPERMIN
- 1;
1827 saved_seconds
= yourtm
.tm_sec
;
1831 ** Do a binary search (this works whatever time_t's type is).
1833 if (!TYPE_SIGNED(time_t)) {
1838 for (i
= 0; i
< (int) TYPE_BIT(time_t) - 1; ++i
)
1843 t
= lo
/ 2 + hi
/ 2;
1848 if ((*funcp
)(&t
, offset
, &mytm
) == NULL
) {
1850 ** Assume that t is too extreme to be represented in
1851 ** a struct tm; arrange things so that it is less
1852 ** extreme on the next pass.
1854 dir
= (t
> 0) ? 1 : -1;
1855 } else dir
= tmcomp(&mytm
, &yourtm
);
1858 if (t
== time_t_max
)
1862 } else if (t
== hi
) {
1863 if (t
== time_t_min
)
1875 if (yourtm
.tm_isdst
< 0 || mytm
.tm_isdst
== yourtm
.tm_isdst
)
1878 ** Right time, wrong type.
1879 ** Hunt for right time, right type.
1880 ** It's okay to guess wrong since the guess
1883 sp
= (const struct state
*)
1884 ((funcp
== localsub
) ? lclptr
: gmtptr
);
1886 for (i
= sp
->typecnt
- 1; i
>= 0; --i
) {
1887 if (sp
->ttis
[i
].tt_isdst
!= yourtm
.tm_isdst
)
1889 for (j
= sp
->typecnt
- 1; j
>= 0; --j
) {
1890 if (sp
->ttis
[j
].tt_isdst
== yourtm
.tm_isdst
)
1892 newt
= t
+ sp
->ttis
[j
].tt_gmtoff
-
1893 sp
->ttis
[i
].tt_gmtoff
;
1894 if ((*funcp
)(&newt
, offset
, &mytm
) == NULL
)
1896 if (tmcomp(&mytm
, &yourtm
) != 0)
1898 if (mytm
.tm_isdst
!= yourtm
.tm_isdst
)
1910 newt
= t
+ saved_seconds
;
1911 if ((newt
< t
) != (saved_seconds
< 0))
1914 if ((*funcp
)(&t
, offset
, tmp
))
1920 time2(struct tm
* const tmp
,
1921 struct tm
* (* const funcp
)(const time_t *, int_fast32_t, struct tm
*),
1922 const int_fast32_t offset
, int * const okayp
)
1927 ** First try without normalization of seconds
1928 ** (in case tm_sec contains a value associated with a leap second).
1929 ** If that fails, try with normalization of seconds.
1931 t
= time2sub(tmp
, funcp
, offset
, okayp
, FALSE
);
1932 return *okayp
? t
: time2sub(tmp
, funcp
, offset
, okayp
, TRUE
);
1936 time1(struct tm
* const tmp
,
1937 struct tm
* (* const funcp
)(const time_t *, int_fast32_t, struct tm
*),
1938 const int_fast32_t offset
)
1941 const struct state
* sp
;
1943 int sameind
, otherind
;
1946 int seen
[TZ_MAX_TYPES
];
1947 int types
[TZ_MAX_TYPES
];
1954 if (tmp
->tm_isdst
> 1)
1956 t
= time2(tmp
, funcp
, offset
, &okay
);
1959 ** PCTS code courtesy Grant Sullivan.
1963 if (tmp
->tm_isdst
< 0)
1964 tmp
->tm_isdst
= 0; /* reset to std and try again */
1967 ** We're supposed to assume that somebody took a time of one type
1968 ** and did some math on it that yielded a "struct tm" that's bad.
1969 ** We try to divine the type they started from and adjust to the
1972 sp
= (const struct state
*) ((funcp
== localsub
) ? lclptr
: gmtptr
);
1974 for (i
= 0; i
< sp
->typecnt
; ++i
)
1977 for (i
= sp
->timecnt
- 1; i
>= 0; --i
)
1978 if (!seen
[sp
->types
[i
]]) {
1979 seen
[sp
->types
[i
]] = TRUE
;
1980 types
[nseen
++] = sp
->types
[i
];
1982 for (sameind
= 0; sameind
< nseen
; ++sameind
) {
1983 samei
= types
[sameind
];
1984 if (sp
->ttis
[samei
].tt_isdst
!= tmp
->tm_isdst
)
1986 for (otherind
= 0; otherind
< nseen
; ++otherind
) {
1987 otheri
= types
[otherind
];
1988 if (sp
->ttis
[otheri
].tt_isdst
== tmp
->tm_isdst
)
1990 tmp
->tm_sec
+= sp
->ttis
[otheri
].tt_gmtoff
-
1991 sp
->ttis
[samei
].tt_gmtoff
;
1992 tmp
->tm_isdst
= !tmp
->tm_isdst
;
1993 t
= time2(tmp
, funcp
, offset
, &okay
);
1996 tmp
->tm_sec
-= sp
->ttis
[otheri
].tt_gmtoff
-
1997 sp
->ttis
[samei
].tt_gmtoff
;
1998 tmp
->tm_isdst
= !tmp
->tm_isdst
;
2005 mktime(struct tm
* const tmp
)
2007 time_t mktime_return_value
;
2008 _RWLOCK_RDLOCK(&lcl_rwlock
);
2010 mktime_return_value
= time1(tmp
, localsub
, 0L);
2011 _RWLOCK_UNLOCK(&lcl_rwlock
);
2012 return(mktime_return_value
);
2016 timelocal(struct tm
* const tmp
)
2019 tmp
->tm_isdst
= -1; /* in case it wasn't initialized */
2024 timegm(struct tm
* const tmp
)
2028 return time1(tmp
, gmtsub
, 0L);
2032 timeoff(struct tm
* const tmp
, const long offset
)
2036 return time1(tmp
, gmtsub
, offset
);
2040 ** XXX--is the below the right way to conditionalize??
2044 ** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
2045 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2046 ** is not the case if we are accounting for leap seconds.
2047 ** So, we provide the following conversion routines for use
2048 ** when exchanging timestamps with POSIX conforming systems.
2052 leapcorr(time_t *timep
)
2062 if (*timep
>= lp
->ls_trans
)
2069 time2posix(time_t t
)
2072 return t
- leapcorr(&t
);
2076 posix2time(time_t t
)
2083 ** For a positive leap second hit, the result
2084 ** is not unique. For a negative leap second
2085 ** hit, the corresponding time doesn't exist,
2086 ** so we return an adjacent second.
2088 x
= t
+ leapcorr(&t
);
2089 y
= x
- leapcorr(&x
);
2093 y
= x
- leapcorr(&x
);
2100 y
= x
- leapcorr(&x
);