blob: d6448a1dad90fb7912f375ba891db8e026b1bd7f [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
2** This file is in the public domain, so clarified as of
3** 1996-06-05 by Arthur David Olson.
4*/
5
6#include <stdio.h>
7
8#ifndef lint
9#ifndef NOID
10static char elsieid[] = "@(#)localtime.c 8.3";
11#endif /* !defined NOID */
12#endif /* !defined lint */
13
14/*
15** Leap second handling from Bradley White.
16** POSIX-style TZ environment variable handling from Guy Harris.
17*/
18
19/*LINTLIBRARY*/
20
21#include "private.h"
22#include "tzfile.h"
23#include "fcntl.h"
24#include "float.h" /* for FLT_MAX and DBL_MAX */
25
26#ifndef TZ_ABBR_MAX_LEN
27#define TZ_ABBR_MAX_LEN 16
28#endif /* !defined TZ_ABBR_MAX_LEN */
29
30#ifndef TZ_ABBR_CHAR_SET
31#define TZ_ABBR_CHAR_SET \
32 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
33#endif /* !defined TZ_ABBR_CHAR_SET */
34
35#ifndef TZ_ABBR_ERR_CHAR
36#define TZ_ABBR_ERR_CHAR '_'
37#endif /* !defined TZ_ABBR_ERR_CHAR */
38
39#define INDEXFILE "/system/usr/share/zoneinfo/zoneinfo.idx"
40#define DATAFILE "/system/usr/share/zoneinfo/zoneinfo.dat"
41#define NAMELEN 40
42#define INTLEN 4
43#define READLEN (NAMELEN + 3 * INTLEN)
44
45/*
46** SunOS 4.1.1 headers lack O_BINARY.
47*/
48
49#ifdef O_BINARY
50#define OPEN_MODE (O_RDONLY | O_BINARY)
51#endif /* defined O_BINARY */
52#ifndef O_BINARY
53#define OPEN_MODE O_RDONLY
54#endif /* !defined O_BINARY */
55
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -070056/* Complex computations to determine the min/max of time_t depending
57 * on TYPE_BIT / TYPE_SIGNED / TYPE_INTEGRAL.
58 * These macros cannot be used in pre-processor directives, so we
59 * let the C compiler do the work, which makes things a bit funky.
60 */
61static const time_t TIME_T_MAX =
62 TYPE_INTEGRAL(time_t) ?
63 ( TYPE_SIGNED(time_t) ?
64 ~((time_t)1 << (TYPE_BIT(time_t)-1))
65 :
66 ~(time_t)0
67 )
68 : /* if time_t is a floating point number */
69 ( sizeof(time_t) > sizeof(float) ? (time_t)DBL_MAX : (time_t)FLT_MAX );
70
71static const time_t TIME_T_MIN =
72 TYPE_INTEGRAL(time_t) ?
73 ( TYPE_SIGNED(time_t) ?
74 ((time_t)1 << (TYPE_BIT(time_t)-1))
75 :
76 0
77 )
78 :
79 ( sizeof(time_t) > sizeof(float) ? (time_t)DBL_MIN : (time_t)FLT_MIN );
80
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080081#ifndef WILDABBR
82/*
83** Someone might make incorrect use of a time zone abbreviation:
84** 1. They might reference tzname[0] before calling tzset (explicitly
85** or implicitly).
86** 2. They might reference tzname[1] before calling tzset (explicitly
87** or implicitly).
88** 3. They might reference tzname[1] after setting to a time zone
89** in which Daylight Saving Time is never observed.
90** 4. They might reference tzname[0] after setting to a time zone
91** in which Standard Time is never observed.
92** 5. They might reference tm.TM_ZONE after calling offtime.
93** What's best to do in the above cases is open to debate;
94** for now, we just set things up so that in any of the five cases
95** WILDABBR is used. Another possibility: initialize tzname[0] to the
96** string "tzname[0] used before set", and similarly for the other cases.
97** And another: initialize tzname[0] to "ERA", with an explanation in the
98** manual page of what this "time zone abbreviation" means (doing this so
99** that tzname[0] has the "normal" length of three characters).
100*/
101#define WILDABBR " "
102#endif /* !defined WILDABBR */
103
104static char wildabbr[] = WILDABBR;
105
106static const char gmt[] = "GMT";
107
108/*
109** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
110** We default to US rules as of 1999-08-17.
111** POSIX 1003.1 section 8.1.1 says that the default DST rules are
112** implementation dependent; for historical reasons, US rules are a
113** common default.
114*/
115#ifndef TZDEFRULESTRING
116#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
117#endif /* !defined TZDEFDST */
118
119struct ttinfo { /* time type information */
120 long tt_gmtoff; /* UTC offset in seconds */
121 int tt_isdst; /* used to set tm_isdst */
122 int tt_abbrind; /* abbreviation list index */
123 int tt_ttisstd; /* TRUE if transition is std time */
124 int tt_ttisgmt; /* TRUE if transition is UTC */
125};
126
127struct lsinfo { /* leap second information */
128 time_t ls_trans; /* transition time */
129 long ls_corr; /* correction to apply */
130};
131
132#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
133
134#ifdef TZNAME_MAX
135#define MY_TZNAME_MAX TZNAME_MAX
136#endif /* defined TZNAME_MAX */
137#ifndef TZNAME_MAX
138#define MY_TZNAME_MAX 255
139#endif /* !defined TZNAME_MAX */
140
141struct state {
142 int leapcnt;
143 int timecnt;
144 int typecnt;
145 int charcnt;
146 int goback;
147 int goahead;
148 time_t ats[TZ_MAX_TIMES];
149 unsigned char types[TZ_MAX_TIMES];
150 struct ttinfo ttis[TZ_MAX_TYPES];
151 char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
152 (2 * (MY_TZNAME_MAX + 1)))];
153 struct lsinfo lsis[TZ_MAX_LEAPS];
154};
155
156struct rule {
157 int r_type; /* type of rule--see below */
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 long r_time; /* transition time of rule */
162};
163
164#define JULIAN_DAY 0 /* Jn - Julian day */
165#define DAY_OF_YEAR 1 /* n - day of year */
166#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
167
168/*
169** Prototypes for static functions.
170*/
171
172static long detzcode P((const char * codep));
173static time_t detzcode64 P((const char * codep));
174static int differ_by_repeat P((time_t t1, time_t t0));
175static const char * getzname P((const char * strp));
176static const char * getqzname P((const char * strp, const int delim));
177static const char * getnum P((const char * strp, int * nump, int min,
178 int max));
179static const char * getsecs P((const char * strp, long * secsp));
180static const char * getoffset P((const char * strp, long * offsetp));
181static const char * getrule P((const char * strp, struct rule * rulep));
182static void gmtload P((struct state * sp));
183static struct tm * gmtsub P((const time_t * timep, long offset,
184 struct tm * tmp));
185static struct tm * localsub P((const time_t * timep, long offset,
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -0700186 struct tm * tmp, const struct state *sp));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800187static int increment_overflow P((int * number, int delta));
188static int leaps_thru_end_of P((int y));
189static int long_increment_overflow P((long * number, int delta));
190static int long_normalize_overflow P((long * tensptr,
191 int * unitsptr, int base));
192static int normalize_overflow P((int * tensptr, int * unitsptr,
193 int base));
194static void settzname P((void));
195static time_t time1 P((struct tm * tmp,
196 struct tm * (*funcp) P((const time_t *,
197 long, struct tm *, const struct state* sp)),
198 long offset, const struct state * sp));
199static time_t time2 P((struct tm *tmp,
200 struct tm * (*funcp) P((const time_t *,
201 long, struct tm*, const struct state* sp)),
202 long offset, int * okayp, const struct state * sp));
203static time_t time2sub P((struct tm *tmp,
204 struct tm * (*funcp) P((const time_t*, long, struct tm*,const struct state *sp)),
205 long offset, int * okayp, int do_norm_secs,
206 const struct state *sp));
207static struct tm * timesub P((const time_t * timep, long offset,
208 const struct state * sp, struct tm * tmp));
209static int tmcomp P((const struct tm * atmp,
210 const struct tm * btmp));
211static time_t transtime P((time_t janfirst, int year,
212 const struct rule * rulep, long offset));
213static int tzload P((const char * name, struct state * sp,
214 int doextend));
215static int tzload_uncached P((const char * name, struct state * sp,
216 int doextend));
217static int tzparse P((const char * name, struct state * sp,
218 int lastditch));
219
220#ifdef ALL_STATE
221static struct state * gmtptr;
222#endif /* defined ALL_STATE */
223
224#ifndef ALL_STATE
225static struct state gmtmem;
226#define gmtptr (&gmtmem)
227#endif /* State Farm */
228
229#define CACHE_COUNT 4
230static char * g_cacheNames[CACHE_COUNT] = {0,0};
231static struct state g_cacheStates[CACHE_COUNT];
232static int g_lastCache = 0;
233static struct state g_utc;
234unsigned char g_utcSet = 0;
235
236
237#ifndef TZ_STRLEN_MAX
238#define TZ_STRLEN_MAX 255
239#endif /* !defined TZ_STRLEN_MAX */
240
241static char lcl_TZname[TZ_STRLEN_MAX + 1];
242static int lcl_is_set;
243static int gmt_is_set;
244
245char * tzname[2] = {
246 wildabbr,
247 wildabbr
248};
249
250/*
251** Section 4.12.3 of X3.159-1989 requires that
252** Except for the strftime function, these functions [asctime,
253** ctime, gmtime, localtime] return values in one of two static
254** objects: a broken-down time structure and an array of char.
255** Thanks to Paul Eggert for noting this.
256*/
257
258static struct tm tm;
259
260#ifdef USG_COMPAT
261time_t timezone = 0;
262int daylight = 0;
263#endif /* defined USG_COMPAT */
264
265#ifdef ALTZONE
266time_t altzone = 0;
267#endif /* defined ALTZONE */
268
269static long
270detzcode(codep)
271const char * const codep;
272{
273 register long result;
274 register int i;
275
276 result = (codep[0] & 0x80) ? ~0L : 0;
277 for (i = 0; i < 4; ++i)
278 result = (result << 8) | (codep[i] & 0xff);
279 return result;
280}
281
282static time_t
283detzcode64(codep)
284const char * const codep;
285{
286 register time_t result;
287 register int i;
288
289 result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0;
290 for (i = 0; i < 8; ++i)
291 result = result * 256 + (codep[i] & 0xff);
292 return result;
293}
294
295static int
296differ_by_repeat(t1, t0)
297const time_t t1;
298const time_t t0;
299{
300 if (TYPE_INTEGRAL(time_t) &&
301 TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
302 return 0;
303 return t1 - t0 == SECSPERREPEAT;
304}
305
306static int toint(unsigned char *s) {
307 return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
308}
309
310static int
311tzload(const char *name, struct state * const sp, const int doextend)
312{
313 if (name) {
314 int i, err;
315 if (0 == strcmp(name, "UTC")) {
316 if (!g_utcSet) {
317 tzload_uncached(name, &g_utc, 1);
318 g_utcSet = 1;
319 }
320 //printf("tzload: utc\n");
321 *sp = g_utc;
322 return 0;
323 }
324 for (i=0; i<CACHE_COUNT; i++) {
325 if (g_cacheNames[i] && 0 == strcmp(name, g_cacheNames[i])) {
326 *sp = g_cacheStates[i];
327 //printf("tzload: hit: %s\n", name);
328 return 0;
329 }
330 }
331 //printf("tzload: miss: %s\n", name);
332 g_lastCache++;
333 if (g_lastCache >= CACHE_COUNT) {
334 g_lastCache = 0;
335 }
336 i = g_lastCache;
337 if (g_cacheNames[i]) {
338 free(g_cacheNames[i]);
339 }
340 err = tzload_uncached(name, &(g_cacheStates[i]), 1);
341 if (err == 0) {
342 g_cacheNames[i] = strdup(name);
343 *sp = g_cacheStates[i];
344 return 0;
345 } else {
346 g_cacheNames[i] = NULL;
347 return err;
348 }
349 }
350 return tzload_uncached(name, sp, doextend);
351}
352
353static int
354tzload_uncached(name, sp, doextend)
355register const char * name;
356register struct state * const sp;
357register const int doextend;
358{
359 register const char * p;
360 register int i;
361 register int fid;
362 register int stored;
363 register int nread;
364 union {
365 struct tzhead tzhead;
366 char buf[2 * sizeof(struct tzhead) +
367 2 * sizeof *sp +
368 4 * TZ_MAX_TIMES];
369 } u;
370 int toread = sizeof u.buf;
371
372 if (name == NULL && (name = TZDEFAULT) == NULL)
373 return -1;
374 {
375 register int doaccess;
376 /*
377 ** Section 4.9.1 of the C standard says that
378 ** "FILENAME_MAX expands to an integral constant expression
379 ** that is the size needed for an array of char large enough
380 ** to hold the longest file name string that the implementation
381 ** guarantees can be opened."
382 */
383 char fullname[FILENAME_MAX + 1];
384 const char *origname = name;
385
386 if (name[0] == ':')
387 ++name;
388 doaccess = name[0] == '/';
389 if (!doaccess) {
390 if ((p = TZDIR) == NULL)
391 return -1;
392 if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
393 return -1;
394 (void) strcpy(fullname, p);
395 (void) strcat(fullname, "/");
396 (void) strcat(fullname, name);
397 /*
398 ** Set doaccess if '.' (as in "../") shows up in name.
399 */
400 if (strchr(name, '.') != NULL)
401 doaccess = TRUE;
402 name = fullname;
403 }
404 if (doaccess && access(name, R_OK) != 0)
405 return -1;
406 if ((fid = open(name, OPEN_MODE)) == -1) {
407 char buf[READLEN];
408 char name[NAMELEN + 1];
409 int fidix = open(INDEXFILE, OPEN_MODE);
410 int off = -1;
411
412 if (fidix < 0) {
413 return -1;
414 }
415
416 while (read(fidix, buf, sizeof(buf)) == sizeof(buf)) {
417 memcpy(name, buf, NAMELEN);
418 name[NAMELEN] = '\0';
419
420 if (strcmp(name, origname) == 0) {
421 off = toint((unsigned char *) buf + NAMELEN);
422 toread = toint((unsigned char *) buf + NAMELEN + INTLEN);
423 break;
424 }
425 }
426
427 close(fidix);
428
429 if (off < 0)
430 return -1;
431
432 fid = open(DATAFILE, OPEN_MODE);
433
434 if (fid < 0) {
435 return -1;
436 }
437
438 if (lseek(fid, off, SEEK_SET) < 0) {
439 return -1;
440 }
441 }
442 }
443 nread = read(fid, u.buf, toread);
444 if (close(fid) < 0 || nread <= 0)
445 return -1;
446 for (stored = 4; stored <= 8; stored *= 2) {
447 int ttisstdcnt;
448 int ttisgmtcnt;
449
450 ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
451 ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
452 sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
453 sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
454 sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
455 sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
456 p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
457 if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
458 sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
459 sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
460 sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
461 (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
462 (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
463 return -1;
464 if (nread - (p - u.buf) <
465 sp->timecnt * stored + /* ats */
466 sp->timecnt + /* types */
467 sp->typecnt * 6 + /* ttinfos */
468 sp->charcnt + /* chars */
469 sp->leapcnt * (stored + 4) + /* lsinfos */
470 ttisstdcnt + /* ttisstds */
471 ttisgmtcnt) /* ttisgmts */
472 return -1;
473 for (i = 0; i < sp->timecnt; ++i) {
474 sp->ats[i] = (stored == 4) ?
475 detzcode(p) : detzcode64(p);
476 p += stored;
477 }
478 for (i = 0; i < sp->timecnt; ++i) {
479 sp->types[i] = (unsigned char) *p++;
480 if (sp->types[i] >= sp->typecnt)
481 return -1;
482 }
483 for (i = 0; i < sp->typecnt; ++i) {
484 register struct ttinfo * ttisp;
485
486 ttisp = &sp->ttis[i];
487 ttisp->tt_gmtoff = detzcode(p);
488 p += 4;
489 ttisp->tt_isdst = (unsigned char) *p++;
490 if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
491 return -1;
492 ttisp->tt_abbrind = (unsigned char) *p++;
493 if (ttisp->tt_abbrind < 0 ||
494 ttisp->tt_abbrind > sp->charcnt)
495 return -1;
496 }
497 for (i = 0; i < sp->charcnt; ++i)
498 sp->chars[i] = *p++;
499 sp->chars[i] = '\0'; /* ensure '\0' at end */
500 for (i = 0; i < sp->leapcnt; ++i) {
501 register struct lsinfo * lsisp;
502
503 lsisp = &sp->lsis[i];
504 lsisp->ls_trans = (stored == 4) ?
505 detzcode(p) : detzcode64(p);
506 p += stored;
507 lsisp->ls_corr = detzcode(p);
508 p += 4;
509 }
510 for (i = 0; i < sp->typecnt; ++i) {
511 register struct ttinfo * ttisp;
512
513 ttisp = &sp->ttis[i];
514 if (ttisstdcnt == 0)
515 ttisp->tt_ttisstd = FALSE;
516 else {
517 ttisp->tt_ttisstd = *p++;
518 if (ttisp->tt_ttisstd != TRUE &&
519 ttisp->tt_ttisstd != FALSE)
520 return -1;
521 }
522 }
523 for (i = 0; i < sp->typecnt; ++i) {
524 register struct ttinfo * ttisp;
525
526 ttisp = &sp->ttis[i];
527 if (ttisgmtcnt == 0)
528 ttisp->tt_ttisgmt = FALSE;
529 else {
530 ttisp->tt_ttisgmt = *p++;
531 if (ttisp->tt_ttisgmt != TRUE &&
532 ttisp->tt_ttisgmt != FALSE)
533 return -1;
534 }
535 }
536 /*
537 ** Out-of-sort ats should mean we're running on a
538 ** signed time_t system but using a data file with
539 ** unsigned values (or vice versa).
540 */
541 for (i = 0; i < sp->timecnt - 2; ++i)
542 if (sp->ats[i] > sp->ats[i + 1]) {
543 ++i;
544 if (TYPE_SIGNED(time_t)) {
545 /*
546 ** Ignore the end (easy).
547 */
548 sp->timecnt = i;
549 } else {
550 /*
551 ** Ignore the beginning (harder).
552 */
553 register int j;
554
555 for (j = 0; j + i < sp->timecnt; ++j) {
556 sp->ats[j] = sp->ats[j + i];
557 sp->types[j] = sp->types[j + i];
558 }
559 sp->timecnt = j;
560 }
561 break;
562 }
563 /*
564 ** If this is an old file, we're done.
565 */
566 if (u.tzhead.tzh_version[0] == '\0')
567 break;
568 nread -= p - u.buf;
569 for (i = 0; i < nread; ++i)
570 u.buf[i] = p[i];
571 /*
572 ** If this is a narrow integer time_t system, we're done.
573 */
574 if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
575 break;
576 }
577 if (doextend && nread > 2 &&
578 u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
579 sp->typecnt + 2 <= TZ_MAX_TYPES) {
580 struct state ts;
581 register int result;
582
583 u.buf[nread - 1] = '\0';
584 result = tzparse(&u.buf[1], &ts, FALSE);
585 if (result == 0 && ts.typecnt == 2 &&
586 sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
587 for (i = 0; i < 2; ++i)
588 ts.ttis[i].tt_abbrind +=
589 sp->charcnt;
590 for (i = 0; i < ts.charcnt; ++i)
591 sp->chars[sp->charcnt++] =
592 ts.chars[i];
593 i = 0;
594 while (i < ts.timecnt &&
595 ts.ats[i] <=
596 sp->ats[sp->timecnt - 1])
597 ++i;
598 while (i < ts.timecnt &&
599 sp->timecnt < TZ_MAX_TIMES) {
600 sp->ats[sp->timecnt] =
601 ts.ats[i];
602 sp->types[sp->timecnt] =
603 sp->typecnt +
604 ts.types[i];
605 ++sp->timecnt;
606 ++i;
607 }
608 sp->ttis[sp->typecnt++] = ts.ttis[0];
609 sp->ttis[sp->typecnt++] = ts.ttis[1];
610 }
611 }
612 i = 2 * YEARSPERREPEAT;
613 sp->goback = sp->goahead = sp->timecnt > i;
614 sp->goback &= sp->types[i] == sp->types[0] &&
615 differ_by_repeat(sp->ats[i], sp->ats[0]);
616 sp->goahead &=
617 sp->types[sp->timecnt - 1] == sp->types[sp->timecnt - 1 - i] &&
618 differ_by_repeat(sp->ats[sp->timecnt - 1],
619 sp->ats[sp->timecnt - 1 - i]);
620 return 0;
621}
622
623static const int mon_lengths[2][MONSPERYEAR] = {
624 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
625 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
626};
627
628static const int year_lengths[2] = {
629 DAYSPERNYEAR, DAYSPERLYEAR
630};
631
632/*
633** Given a pointer into a time zone string, scan until a character that is not
634** a valid character in a zone name is found. Return a pointer to that
635** character.
636*/
637
638static const char *
639getzname(strp)
640register const char * strp;
641{
642 register char c;
643
644 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
645 c != '+')
646 ++strp;
647 return strp;
648}
649
650/*
651** Given a pointer into an extended time zone string, scan until the ending
652** delimiter of the zone name is located. Return a pointer to the delimiter.
653**
654** As with getzname above, the legal character set is actually quite
655** restricted, with other characters producing undefined results.
656** We don't do any checking here; checking is done later in common-case code.
657*/
658
659static const char *
660getqzname(register const char *strp, const int delim)
661{
662 register int c;
663
664 while ((c = *strp) != '\0' && c != delim)
665 ++strp;
666 return strp;
667}
668
669/*
670** Given a pointer into a time zone string, extract a number from that string.
671** Check that the number is within a specified range; if it is not, return
672** NULL.
673** Otherwise, return a pointer to the first character not part of the number.
674*/
675
676static const char *
677getnum(strp, nump, min, max)
678register const char * strp;
679int * const nump;
680const int min;
681const int max;
682{
683 register char c;
684 register int num;
685
686 if (strp == NULL || !is_digit(c = *strp))
687 return NULL;
688 num = 0;
689 do {
690 num = num * 10 + (c - '0');
691 if (num > max)
692 return NULL; /* illegal value */
693 c = *++strp;
694 } while (is_digit(c));
695 if (num < min)
696 return NULL; /* illegal value */
697 *nump = num;
698 return strp;
699}
700
701/*
702** Given a pointer into a time zone string, extract a number of seconds,
703** in hh[:mm[:ss]] form, from the string.
704** If any error occurs, return NULL.
705** Otherwise, return a pointer to the first character not part of the number
706** of seconds.
707*/
708
709static const char *
710getsecs(strp, secsp)
711register const char * strp;
712long * const secsp;
713{
714 int num;
715
716 /*
717 ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
718 ** "M10.4.6/26", which does not conform to Posix,
719 ** but which specifies the equivalent of
720 ** ``02:00 on the first Sunday on or after 23 Oct''.
721 */
722 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
723 if (strp == NULL)
724 return NULL;
725 *secsp = num * (long) SECSPERHOUR;
726 if (*strp == ':') {
727 ++strp;
728 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
729 if (strp == NULL)
730 return NULL;
731 *secsp += num * SECSPERMIN;
732 if (*strp == ':') {
733 ++strp;
734 /* `SECSPERMIN' allows for leap seconds. */
735 strp = getnum(strp, &num, 0, SECSPERMIN);
736 if (strp == NULL)
737 return NULL;
738 *secsp += num;
739 }
740 }
741 return strp;
742}
743
744/*
745** Given a pointer into a time zone string, extract an offset, in
746** [+-]hh[:mm[:ss]] form, from the string.
747** If any error occurs, return NULL.
748** Otherwise, return a pointer to the first character not part of the time.
749*/
750
751static const char *
752getoffset(strp, offsetp)
753register const char * strp;
754long * const offsetp;
755{
756 register int neg = 0;
757
758 if (*strp == '-') {
759 neg = 1;
760 ++strp;
761 } else if (*strp == '+')
762 ++strp;
763 strp = getsecs(strp, offsetp);
764 if (strp == NULL)
765 return NULL; /* illegal time */
766 if (neg)
767 *offsetp = -*offsetp;
768 return strp;
769}
770
771/*
772** Given a pointer into a time zone string, extract a rule in the form
773** date[/time]. See POSIX section 8 for the format of "date" and "time".
774** If a valid rule is not found, return NULL.
775** Otherwise, return a pointer to the first character not part of the rule.
776*/
777
778static const char *
779getrule(strp, rulep)
780const char * strp;
781register struct rule * const rulep;
782{
783 if (*strp == 'J') {
784 /*
785 ** Julian day.
786 */
787 rulep->r_type = JULIAN_DAY;
788 ++strp;
789 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
790 } else if (*strp == 'M') {
791 /*
792 ** Month, week, day.
793 */
794 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
795 ++strp;
796 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
797 if (strp == NULL)
798 return NULL;
799 if (*strp++ != '.')
800 return NULL;
801 strp = getnum(strp, &rulep->r_week, 1, 5);
802 if (strp == NULL)
803 return NULL;
804 if (*strp++ != '.')
805 return NULL;
806 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
807 } else if (is_digit(*strp)) {
808 /*
809 ** Day of year.
810 */
811 rulep->r_type = DAY_OF_YEAR;
812 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
813 } else return NULL; /* invalid format */
814 if (strp == NULL)
815 return NULL;
816 if (*strp == '/') {
817 /*
818 ** Time specified.
819 */
820 ++strp;
821 strp = getsecs(strp, &rulep->r_time);
822 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
823 return strp;
824}
825
826/*
827** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
828** year, a rule, and the offset from UTC at the time that rule takes effect,
829** calculate the Epoch-relative time that rule takes effect.
830*/
831
832static time_t
833transtime(janfirst, year, rulep, offset)
834const time_t janfirst;
835const int year;
836register const struct rule * const rulep;
837const long offset;
838{
839 register int leapyear;
840 register time_t value;
841 register int i;
842 int d, m1, yy0, yy1, yy2, dow;
843
844 INITIALIZE(value);
845 leapyear = isleap(year);
846 switch (rulep->r_type) {
847
848 case JULIAN_DAY:
849 /*
850 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
851 ** years.
852 ** In non-leap years, or if the day number is 59 or less, just
853 ** add SECSPERDAY times the day number-1 to the time of
854 ** January 1, midnight, to get the day.
855 */
856 value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
857 if (leapyear && rulep->r_day >= 60)
858 value += SECSPERDAY;
859 break;
860
861 case DAY_OF_YEAR:
862 /*
863 ** n - day of year.
864 ** Just add SECSPERDAY times the day number to the time of
865 ** January 1, midnight, to get the day.
866 */
867 value = janfirst + rulep->r_day * SECSPERDAY;
868 break;
869
870 case MONTH_NTH_DAY_OF_WEEK:
871 /*
872 ** Mm.n.d - nth "dth day" of month m.
873 */
874 value = janfirst;
875 for (i = 0; i < rulep->r_mon - 1; ++i)
876 value += mon_lengths[leapyear][i] * SECSPERDAY;
877
878 /*
879 ** Use Zeller's Congruence to get day-of-week of first day of
880 ** month.
881 */
882 m1 = (rulep->r_mon + 9) % 12 + 1;
883 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
884 yy1 = yy0 / 100;
885 yy2 = yy0 % 100;
886 dow = ((26 * m1 - 2) / 10 +
887 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
888 if (dow < 0)
889 dow += DAYSPERWEEK;
890
891 /*
892 ** "dow" is the day-of-week of the first day of the month. Get
893 ** the day-of-month (zero-origin) of the first "dow" day of the
894 ** month.
895 */
896 d = rulep->r_day - dow;
897 if (d < 0)
898 d += DAYSPERWEEK;
899 for (i = 1; i < rulep->r_week; ++i) {
900 if (d + DAYSPERWEEK >=
901 mon_lengths[leapyear][rulep->r_mon - 1])
902 break;
903 d += DAYSPERWEEK;
904 }
905
906 /*
907 ** "d" is the day-of-month (zero-origin) of the day we want.
908 */
909 value += d * SECSPERDAY;
910 break;
911 }
912
913 /*
914 ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
915 ** question. To get the Epoch-relative time of the specified local
916 ** time on that day, add the transition time and the current offset
917 ** from UTC.
918 */
919 return value + rulep->r_time + offset;
920}
921
922/*
923** Given a POSIX section 8-style TZ string, fill in the rule tables as
924** appropriate.
925*/
926
927static int
928tzparse(name, sp, lastditch)
929const char * name;
930register struct state * const sp;
931const int lastditch;
932{
933 const char * stdname;
934 const char * dstname;
935 size_t stdlen;
936 size_t dstlen;
937 long stdoffset;
938 long dstoffset;
939 register time_t * atp;
940 register unsigned char * typep;
941 register char * cp;
942 register int load_result;
943
944 INITIALIZE(dstname);
945 stdname = name;
946 if (lastditch) {
947 stdlen = strlen(name); /* length of standard zone name */
948 name += stdlen;
949 if (stdlen >= sizeof sp->chars)
950 stdlen = (sizeof sp->chars) - 1;
951 stdoffset = 0;
952 } else {
953 if (*name == '<') {
954 name++;
955 stdname = name;
956 name = getqzname(name, '>');
957 if (*name != '>')
958 return (-1);
959 stdlen = name - stdname;
960 name++;
961 } else {
962 name = getzname(name);
963 stdlen = name - stdname;
964 }
965 if (*name == '\0')
966 return -1;
967 name = getoffset(name, &stdoffset);
968 if (name == NULL)
969 return -1;
970 }
971 load_result = tzload(TZDEFRULES, sp, FALSE);
972 if (load_result != 0)
973 sp->leapcnt = 0; /* so, we're off a little */
974 sp->timecnt = 0;
975 if (*name != '\0') {
976 if (*name == '<') {
977 dstname = ++name;
978 name = getqzname(name, '>');
979 if (*name != '>')
980 return -1;
981 dstlen = name - dstname;
982 name++;
983 } else {
984 dstname = name;
985 name = getzname(name);
986 dstlen = name - dstname; /* length of DST zone name */
987 }
988 if (*name != '\0' && *name != ',' && *name != ';') {
989 name = getoffset(name, &dstoffset);
990 if (name == NULL)
991 return -1;
992 } else dstoffset = stdoffset - SECSPERHOUR;
993 if (*name == '\0' && load_result != 0)
994 name = TZDEFRULESTRING;
995 if (*name == ',' || *name == ';') {
996 struct rule start;
997 struct rule end;
998 register int year;
999 register time_t janfirst;
1000 time_t starttime;
1001 time_t endtime;
1002
1003 ++name;
1004 if ((name = getrule(name, &start)) == NULL)
1005 return -1;
1006 if (*name++ != ',')
1007 return -1;
1008 if ((name = getrule(name, &end)) == NULL)
1009 return -1;
1010 if (*name != '\0')
1011 return -1;
1012 sp->typecnt = 2; /* standard time and DST */
1013 /*
1014 ** Two transitions per year, from EPOCH_YEAR forward.
1015 */
1016 sp->ttis[0].tt_gmtoff = -dstoffset;
1017 sp->ttis[0].tt_isdst = 1;
1018 sp->ttis[0].tt_abbrind = stdlen + 1;
1019 sp->ttis[1].tt_gmtoff = -stdoffset;
1020 sp->ttis[1].tt_isdst = 0;
1021 sp->ttis[1].tt_abbrind = 0;
1022 atp = sp->ats;
1023 typep = sp->types;
1024 janfirst = 0;
1025 for (year = EPOCH_YEAR;
1026 sp->timecnt + 2 <= TZ_MAX_TIMES;
1027 ++year) {
1028 time_t newfirst;
1029
1030 starttime = transtime(janfirst, year, &start,
1031 stdoffset);
1032 endtime = transtime(janfirst, year, &end,
1033 dstoffset);
1034 if (starttime > endtime) {
1035 *atp++ = endtime;
1036 *typep++ = 1; /* DST ends */
1037 *atp++ = starttime;
1038 *typep++ = 0; /* DST begins */
1039 } else {
1040 *atp++ = starttime;
1041 *typep++ = 0; /* DST begins */
1042 *atp++ = endtime;
1043 *typep++ = 1; /* DST ends */
1044 }
1045 sp->timecnt += 2;
1046 newfirst = janfirst;
1047 newfirst += year_lengths[isleap(year)] *
1048 SECSPERDAY;
1049 if (newfirst <= janfirst)
1050 break;
1051 janfirst = newfirst;
1052 }
1053 } else {
1054 register long theirstdoffset;
1055 register long theirdstoffset;
1056 register long theiroffset;
1057 register int isdst;
1058 register int i;
1059 register int j;
1060
1061 if (*name != '\0')
1062 return -1;
1063 /*
1064 ** Initial values of theirstdoffset and theirdstoffset.
1065 */
1066 theirstdoffset = 0;
1067 for (i = 0; i < sp->timecnt; ++i) {
1068 j = sp->types[i];
1069 if (!sp->ttis[j].tt_isdst) {
1070 theirstdoffset =
1071 -sp->ttis[j].tt_gmtoff;
1072 break;
1073 }
1074 }
1075 theirdstoffset = 0;
1076 for (i = 0; i < sp->timecnt; ++i) {
1077 j = sp->types[i];
1078 if (sp->ttis[j].tt_isdst) {
1079 theirdstoffset =
1080 -sp->ttis[j].tt_gmtoff;
1081 break;
1082 }
1083 }
1084 /*
1085 ** Initially we're assumed to be in standard time.
1086 */
1087 isdst = FALSE;
1088 theiroffset = theirstdoffset;
1089 /*
1090 ** Now juggle transition times and types
1091 ** tracking offsets as you do.
1092 */
1093 for (i = 0; i < sp->timecnt; ++i) {
1094 j = sp->types[i];
1095 sp->types[i] = sp->ttis[j].tt_isdst;
1096 if (sp->ttis[j].tt_ttisgmt) {
1097 /* No adjustment to transition time */
1098 } else {
1099 /*
1100 ** If summer time is in effect, and the
1101 ** transition time was not specified as
1102 ** standard time, add the summer time
1103 ** offset to the transition time;
1104 ** otherwise, add the standard time
1105 ** offset to the transition time.
1106 */
1107 /*
1108 ** Transitions from DST to DDST
1109 ** will effectively disappear since
1110 ** POSIX provides for only one DST
1111 ** offset.
1112 */
1113 if (isdst && !sp->ttis[j].tt_ttisstd) {
1114 sp->ats[i] += dstoffset -
1115 theirdstoffset;
1116 } else {
1117 sp->ats[i] += stdoffset -
1118 theirstdoffset;
1119 }
1120 }
1121 theiroffset = -sp->ttis[j].tt_gmtoff;
1122 if (sp->ttis[j].tt_isdst)
1123 theirdstoffset = theiroffset;
1124 else theirstdoffset = theiroffset;
1125 }
1126 /*
1127 ** Finally, fill in ttis.
1128 ** ttisstd and ttisgmt need not be handled.
1129 */
1130 sp->ttis[0].tt_gmtoff = -stdoffset;
1131 sp->ttis[0].tt_isdst = FALSE;
1132 sp->ttis[0].tt_abbrind = 0;
1133 sp->ttis[1].tt_gmtoff = -dstoffset;
1134 sp->ttis[1].tt_isdst = TRUE;
1135 sp->ttis[1].tt_abbrind = stdlen + 1;
1136 sp->typecnt = 2;
1137 }
1138 } else {
1139 dstlen = 0;
1140 sp->typecnt = 1; /* only standard time */
1141 sp->timecnt = 0;
1142 sp->ttis[0].tt_gmtoff = -stdoffset;
1143 sp->ttis[0].tt_isdst = 0;
1144 sp->ttis[0].tt_abbrind = 0;
1145 }
1146 sp->charcnt = stdlen + 1;
1147 if (dstlen != 0)
1148 sp->charcnt += dstlen + 1;
1149 if ((size_t) sp->charcnt > sizeof sp->chars)
1150 return -1;
1151 cp = sp->chars;
1152 (void) strncpy(cp, stdname, stdlen);
1153 cp += stdlen;
1154 *cp++ = '\0';
1155 if (dstlen != 0) {
1156 (void) strncpy(cp, dstname, dstlen);
1157 *(cp + dstlen) = '\0';
1158 }
1159 return 0;
1160}
1161
1162static void
1163gmtload(sp)
1164struct state * const sp;
1165{
1166 if (tzload(gmt, sp, TRUE) != 0)
1167 (void) tzparse(gmt, sp, TRUE);
1168}
1169
1170/*
1171** The easy way to behave "as if no library function calls" localtime
1172** is to not call it--so we drop its guts into "localsub", which can be
1173** freely called. (And no, the PANS doesn't require the above behavior--
1174** but it *is* desirable.)
1175**
1176** The unused offset argument is for the benefit of mktime variants.
1177*/
1178
1179/*ARGSUSED*/
1180static struct tm *
1181localsub(timep, offset, tmp, sp)
1182const time_t * const timep;
1183const long offset;
1184struct tm * const tmp;
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001185const struct state * sp;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001186{
1187 register const struct ttinfo * ttisp;
1188 register int i;
1189 register struct tm * result;
1190 const time_t t = *timep;
1191
1192#ifdef ALL_STATE
1193 if (sp == NULL)
1194 return gmtsub(timep, offset, tmp);
1195#endif /* defined ALL_STATE */
1196 if ((sp->goback && t < sp->ats[0]) ||
1197 (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1198 time_t newt = t;
1199 register time_t seconds;
1200 register time_t tcycles;
1201 register int_fast64_t icycles;
1202
1203 if (t < sp->ats[0])
1204 seconds = sp->ats[0] - t;
1205 else seconds = t - sp->ats[sp->timecnt - 1];
1206 --seconds;
1207 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1208 ++tcycles;
1209 icycles = tcycles;
1210 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1211 return NULL;
1212 seconds = icycles;
1213 seconds *= YEARSPERREPEAT;
1214 seconds *= AVGSECSPERYEAR;
1215 if (t < sp->ats[0])
1216 newt += seconds;
1217 else newt -= seconds;
1218 if (newt < sp->ats[0] ||
1219 newt > sp->ats[sp->timecnt - 1])
1220 return NULL; /* "cannot happen" */
1221 result = localsub(&newt, offset, tmp, sp);
1222 if (result == tmp) {
1223 register time_t newy;
1224
1225 newy = tmp->tm_year;
1226 if (t < sp->ats[0])
1227 newy -= icycles * YEARSPERREPEAT;
1228 else newy += icycles * YEARSPERREPEAT;
1229 tmp->tm_year = newy;
1230 if (tmp->tm_year != newy)
1231 return NULL;
1232 }
1233 return result;
1234 }
1235 if (sp->timecnt == 0 || t < sp->ats[0]) {
1236 i = 0;
1237 while (sp->ttis[i].tt_isdst)
1238 if (++i >= sp->typecnt) {
1239 i = 0;
1240 break;
1241 }
1242 } else {
1243 register int lo = 1;
1244 register int hi = sp->timecnt;
1245
1246 while (lo < hi) {
1247 register int mid = (lo + hi) >> 1;
1248
1249 if (t < sp->ats[mid])
1250 hi = mid;
1251 else lo = mid + 1;
1252 }
1253 i = (int) sp->types[lo - 1];
1254 }
1255 ttisp = &sp->ttis[i];
1256 /*
1257 ** To get (wrong) behavior that's compatible with System V Release 2.0
1258 ** you'd replace the statement below with
1259 ** t += ttisp->tt_gmtoff;
1260 ** timesub(&t, 0L, sp, tmp);
1261 */
1262 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1263 tmp->tm_isdst = ttisp->tt_isdst;
1264#ifdef HAVE_TM_GMTOFF
1265 tmp->tm_gmtoff = ttisp->tt_gmtoff;
1266#endif
1267 tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
1268#ifdef TM_ZONE
1269 tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1270#endif /* defined TM_ZONE */
1271 return result;
1272}
1273
1274
1275// ============================================================================
1276#if 0
1277struct tm *
1278localtime(timep)
1279const time_t * const timep;
1280{
1281 tzset();
1282 return localsub(timep, 0L, &tm);
1283}
1284#endif
1285
1286/*
1287** Re-entrant version of localtime.
1288*/
1289
1290// ============================================================================
1291void
1292localtime_tz(const time_t * const timep, struct tm * tmp, const char* tz)
1293{
1294 struct state st;
1295 if (tzload(tz, &st, TRUE) != 0) {
1296 // not sure what's best here, but for now, we fall back to gmt
1297 gmtload(&st);
1298 }
1299
1300 localsub(timep, 0L, tmp, &st);
1301}
1302
1303/*
1304** gmtsub is to gmtime as localsub is to localtime.
1305*/
1306
1307static struct tm *
1308gmtsub(timep, offset, tmp)
1309const time_t * const timep;
1310const long offset;
1311struct tm * const tmp;
1312{
1313 register struct tm * result;
1314
1315 if (!gmt_is_set) {
1316 gmt_is_set = TRUE;
1317#ifdef ALL_STATE
1318 gmtptr = (struct state *) malloc(sizeof *gmtptr);
1319 if (gmtptr != NULL)
1320#endif /* defined ALL_STATE */
1321 gmtload(gmtptr);
1322 }
1323 result = timesub(timep, offset, gmtptr, tmp);
1324#ifdef TM_ZONE
1325 /*
1326 ** Could get fancy here and deliver something such as
1327 ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
1328 ** but this is no time for a treasure hunt.
1329 */
1330 if (offset != 0)
1331 tmp->TM_ZONE = wildabbr;
1332 else {
1333#ifdef ALL_STATE
1334 if (gmtptr == NULL)
1335 tmp->TM_ZONE = gmt;
1336 else tmp->TM_ZONE = gmtptr->chars;
1337#endif /* defined ALL_STATE */
1338#ifndef ALL_STATE
1339 tmp->TM_ZONE = gmtptr->chars;
1340#endif /* State Farm */
1341 }
1342#endif /* defined TM_ZONE */
1343 return result;
1344}
1345
1346// ============================================================================
1347#if 0
1348struct tm *
1349gmtime(timep)
1350const time_t * const timep;
1351{
1352 return gmtsub(timep, 0L, &tm);
1353}
1354#endif
1355
1356/*
1357* Re-entrant version of gmtime.
1358*/
1359
1360// ============================================================================
1361#if 0
1362struct tm *
1363gmtime_r(timep, tmp)
1364const time_t * const timep;
1365struct tm * tmp;
1366{
1367 return gmtsub(timep, 0L, tmp);
1368}
1369#endif
1370
1371#ifdef STD_INSPIRED
1372
1373// ============================================================================
1374#if 0
1375struct tm *
1376offtime(timep, offset)
1377const time_t * const timep;
1378const long offset;
1379{
1380 return gmtsub(timep, offset, &tm);
1381}
1382#endif
1383
1384#endif /* defined STD_INSPIRED */
1385
1386/*
1387** Return the number of leap years through the end of the given year
1388** where, to make the math easy, the answer for year zero is defined as zero.
1389*/
1390
1391static int
1392leaps_thru_end_of(y)
1393register const int y;
1394{
1395 return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1396 -(leaps_thru_end_of(-(y + 1)) + 1);
1397}
1398
1399static struct tm *
1400timesub(timep, offset, sp, tmp)
1401const time_t * const timep;
1402const long offset;
1403register const struct state * const sp;
1404register struct tm * const tmp;
1405{
1406 register const struct lsinfo * lp;
1407 register time_t tdays;
1408 register int idays; /* unsigned would be so 2003 */
1409 register long rem;
1410 int y;
1411 register const int * ip;
1412 register long corr;
1413 register int hit;
1414 register int i;
1415
1416 corr = 0;
1417 hit = 0;
1418#ifdef ALL_STATE
1419 i = (sp == NULL) ? 0 : sp->leapcnt;
1420#endif /* defined ALL_STATE */
1421#ifndef ALL_STATE
1422 i = sp->leapcnt;
1423#endif /* State Farm */
1424 while (--i >= 0) {
1425 lp = &sp->lsis[i];
1426 if (*timep >= lp->ls_trans) {
1427 if (*timep == lp->ls_trans) {
1428 hit = ((i == 0 && lp->ls_corr > 0) ||
1429 lp->ls_corr > sp->lsis[i - 1].ls_corr);
1430 if (hit)
1431 while (i > 0 &&
1432 sp->lsis[i].ls_trans ==
1433 sp->lsis[i - 1].ls_trans + 1 &&
1434 sp->lsis[i].ls_corr ==
1435 sp->lsis[i - 1].ls_corr + 1) {
1436 ++hit;
1437 --i;
1438 }
1439 }
1440 corr = lp->ls_corr;
1441 break;
1442 }
1443 }
1444 y = EPOCH_YEAR;
1445 tdays = *timep / SECSPERDAY;
1446 rem = *timep - tdays * SECSPERDAY;
1447 while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1448 int newy;
1449 register time_t tdelta;
1450 register int idelta;
1451 register int leapdays;
1452
1453 tdelta = tdays / DAYSPERLYEAR;
1454 idelta = tdelta;
1455 if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
1456 return NULL;
1457 if (idelta == 0)
1458 idelta = (tdays < 0) ? -1 : 1;
1459 newy = y;
1460 if (increment_overflow(&newy, idelta))
1461 return NULL;
1462 leapdays = leaps_thru_end_of(newy - 1) -
1463 leaps_thru_end_of(y - 1);
1464 tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1465 tdays -= leapdays;
1466 y = newy;
1467 }
1468 {
1469 register long seconds;
1470
1471 seconds = tdays * SECSPERDAY + 0.5;
1472 tdays = seconds / SECSPERDAY;
1473 rem += seconds - tdays * SECSPERDAY;
1474 }
1475 /*
1476 ** Given the range, we can now fearlessly cast...
1477 */
1478 idays = tdays;
1479 rem += offset - corr;
1480 while (rem < 0) {
1481 rem += SECSPERDAY;
1482 --idays;
1483 }
1484 while (rem >= SECSPERDAY) {
1485 rem -= SECSPERDAY;
1486 ++idays;
1487 }
1488 while (idays < 0) {
1489 if (increment_overflow(&y, -1))
1490 return NULL;
1491 idays += year_lengths[isleap(y)];
1492 }
1493 while (idays >= year_lengths[isleap(y)]) {
1494 idays -= year_lengths[isleap(y)];
1495 if (increment_overflow(&y, 1))
1496 return NULL;
1497 }
1498 tmp->tm_year = y;
1499 if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1500 return NULL;
1501 tmp->tm_yday = idays;
1502 /*
1503 ** The "extra" mods below avoid overflow problems.
1504 */
1505 tmp->tm_wday = EPOCH_WDAY +
1506 ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1507 (DAYSPERNYEAR % DAYSPERWEEK) +
1508 leaps_thru_end_of(y - 1) -
1509 leaps_thru_end_of(EPOCH_YEAR - 1) +
1510 idays;
1511 tmp->tm_wday %= DAYSPERWEEK;
1512 if (tmp->tm_wday < 0)
1513 tmp->tm_wday += DAYSPERWEEK;
1514 tmp->tm_hour = (int) (rem / SECSPERHOUR);
1515 rem %= SECSPERHOUR;
1516 tmp->tm_min = (int) (rem / SECSPERMIN);
1517 /*
1518 ** A positive leap second requires a special
1519 ** representation. This uses "... ??:59:60" et seq.
1520 */
1521 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1522 ip = mon_lengths[isleap(y)];
1523 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1524 idays -= ip[tmp->tm_mon];
1525 tmp->tm_mday = (int) (idays + 1);
1526 tmp->tm_isdst = 0;
1527#ifdef TM_GMTOFF
1528 tmp->TM_GMTOFF = offset;
1529#endif /* defined TM_GMTOFF */
1530 return tmp;
1531}
1532
1533// ============================================================================
1534#if 0
1535char *
1536ctime(timep)
1537const time_t * const timep;
1538{
1539/*
1540** Section 4.12.3.2 of X3.159-1989 requires that
1541** The ctime function converts the calendar time pointed to by timer
1542** to local time in the form of a string. It is equivalent to
1543** asctime(localtime(timer))
1544*/
1545 return asctime(localtime(timep));
1546}
1547#endif
1548
1549// ============================================================================
1550#if 0
1551char *
1552ctime_r(timep, buf)
1553const time_t * const timep;
1554char * buf;
1555{
1556 struct tm mytm;
1557
1558 return asctime_r(localtime_r(timep, &mytm), buf);
1559}
1560#endif
1561
1562/*
1563** Adapted from code provided by Robert Elz, who writes:
1564** The "best" way to do mktime I think is based on an idea of Bob
1565** Kridle's (so its said...) from a long time ago.
1566** It does a binary search of the time_t space. Since time_t's are
1567** just 32 bits, its a max of 32 iterations (even at 64 bits it
1568** would still be very reasonable).
1569*/
1570
1571#ifndef WRONG
1572#define WRONG (-1)
1573#endif /* !defined WRONG */
1574
1575/*
1576** Simplified normalize logic courtesy Paul Eggert.
1577*/
1578
1579static int
1580increment_overflow(number, delta)
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001581int * number;
1582int delta;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001583{
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001584 unsigned number0 = (unsigned)*number;
1585 unsigned number1 = (unsigned)(number0 + delta);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001586
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001587 *number = (int)number1;
1588
1589 if (delta >= 0) {
1590 return ((int)number1 < (int)number0);
1591 } else {
1592 return ((int)number1 > (int)number0);
1593 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001594}
1595
1596static int
1597long_increment_overflow(number, delta)
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001598long * number;
1599int delta;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001600{
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001601 unsigned long number0 = (unsigned long)*number;
1602 unsigned long number1 = (unsigned long)(number0 + delta);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001603
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001604 *number = (long)number1;
1605
1606 if (delta >= 0) {
1607 return ((long)number1 < (long)number0);
1608 } else {
1609 return ((long)number1 > (long)number0);
1610 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001611}
1612
1613static int
1614normalize_overflow(tensptr, unitsptr, base)
1615int * const tensptr;
1616int * const unitsptr;
1617const int base;
1618{
1619 register int tensdelta;
1620
1621 tensdelta = (*unitsptr >= 0) ?
1622 (*unitsptr / base) :
1623 (-1 - (-1 - *unitsptr) / base);
1624 *unitsptr -= tensdelta * base;
1625 return increment_overflow(tensptr, tensdelta);
1626}
1627
1628static int
1629long_normalize_overflow(tensptr, unitsptr, base)
1630long * const tensptr;
1631int * const unitsptr;
1632const int base;
1633{
1634 register int tensdelta;
1635
1636 tensdelta = (*unitsptr >= 0) ?
1637 (*unitsptr / base) :
1638 (-1 - (-1 - *unitsptr) / base);
1639 *unitsptr -= tensdelta * base;
1640 return long_increment_overflow(tensptr, tensdelta);
1641}
1642
1643static int
1644tmcomp(atmp, btmp)
1645register const struct tm * const atmp;
1646register const struct tm * const btmp;
1647{
1648 register int result;
1649
1650 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1651 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1652 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1653 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1654 (result = (atmp->tm_min - btmp->tm_min)) == 0)
1655 result = atmp->tm_sec - btmp->tm_sec;
1656 return result;
1657}
1658
1659static time_t
1660time2sub(tmp, funcp, offset, okayp, do_norm_secs, sp)
1661struct tm * const tmp;
1662struct tm * (* const funcp) P((const time_t*, long, struct tm*,const struct state *sp));
1663const long offset;
1664int * const okayp;
1665const int do_norm_secs;
1666const struct state * sp;
1667{
1668 register int dir;
1669 register int i, j;
1670 register int saved_seconds;
1671 register long li;
1672 register time_t lo;
1673 register time_t hi;
1674 long y;
1675 time_t newt;
1676 time_t t;
1677 struct tm yourtm, mytm;
1678
1679 *okayp = FALSE;
1680 yourtm = *tmp;
1681 if (do_norm_secs) {
1682 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1683 SECSPERMIN))
1684 return WRONG;
1685 }
1686 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1687 return WRONG;
1688 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1689 return WRONG;
1690 y = yourtm.tm_year;
1691 if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
1692 return WRONG;
1693 /*
1694 ** Turn y into an actual year number for now.
1695 ** It is converted back to an offset from TM_YEAR_BASE later.
1696 */
1697 if (long_increment_overflow(&y, TM_YEAR_BASE))
1698 return WRONG;
1699 while (yourtm.tm_mday <= 0) {
1700 if (long_increment_overflow(&y, -1))
1701 return WRONG;
1702 li = y + (1 < yourtm.tm_mon);
1703 yourtm.tm_mday += year_lengths[isleap(li)];
1704 }
1705 while (yourtm.tm_mday > DAYSPERLYEAR) {
1706 li = y + (1 < yourtm.tm_mon);
1707 yourtm.tm_mday -= year_lengths[isleap(li)];
1708 if (long_increment_overflow(&y, 1))
1709 return WRONG;
1710 }
1711 for ( ; ; ) {
1712 i = mon_lengths[isleap(y)][yourtm.tm_mon];
1713 if (yourtm.tm_mday <= i)
1714 break;
1715 yourtm.tm_mday -= i;
1716 if (++yourtm.tm_mon >= MONSPERYEAR) {
1717 yourtm.tm_mon = 0;
1718 if (long_increment_overflow(&y, 1))
1719 return WRONG;
1720 }
1721 }
1722 if (long_increment_overflow(&y, -TM_YEAR_BASE))
1723 return WRONG;
1724 yourtm.tm_year = y;
1725 if (yourtm.tm_year != y)
1726 return WRONG;
1727 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1728 saved_seconds = 0;
1729 else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1730 /*
1731 ** We can't set tm_sec to 0, because that might push the
1732 ** time below the minimum representable time.
1733 ** Set tm_sec to 59 instead.
1734 ** This assumes that the minimum representable time is
1735 ** not in the same minute that a leap second was deleted from,
1736 ** which is a safer assumption than using 58 would be.
1737 */
1738 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1739 return WRONG;
1740 saved_seconds = yourtm.tm_sec;
1741 yourtm.tm_sec = SECSPERMIN - 1;
1742 } else {
1743 saved_seconds = yourtm.tm_sec;
1744 yourtm.tm_sec = 0;
1745 }
1746 /*
1747 ** Do a binary search (this works whatever time_t's type is).
1748 */
1749 if (!TYPE_SIGNED(time_t)) {
1750 lo = 0;
1751 hi = lo - 1;
1752 } else if (!TYPE_INTEGRAL(time_t)) {
1753 if (sizeof(time_t) > sizeof(float))
1754 hi = (time_t) DBL_MAX;
1755 else hi = (time_t) FLT_MAX;
1756 lo = -hi;
1757 } else {
1758 lo = 1;
1759 for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
1760 lo *= 2;
1761 hi = -(lo + 1);
1762 }
1763 for ( ; ; ) {
1764 t = lo / 2 + hi / 2;
1765 if (t < lo)
1766 t = lo;
1767 else if (t > hi)
1768 t = hi;
1769 if ((*funcp)(&t, offset, &mytm, sp) == NULL) {
1770 /*
1771 ** Assume that t is too extreme to be represented in
1772 ** a struct tm; arrange things so that it is less
1773 ** extreme on the next pass.
1774 */
1775 dir = (t > 0) ? 1 : -1;
1776 } else dir = tmcomp(&mytm, &yourtm);
1777 if (dir != 0) {
1778 if (t == lo) {
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001779 if (t == TIME_T_MAX)
1780 return WRONG;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001781 ++t;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001782 ++lo;
1783 } else if (t == hi) {
David 'Digit' Turner833ea8d2009-09-09 18:32:07 -07001784 if (t == TIME_T_MIN)
1785 return WRONG;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001786 --t;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001787 --hi;
1788 }
1789 if (lo > hi)
1790 return WRONG;
1791 if (dir > 0)
1792 hi = t;
1793 else lo = t;
1794 continue;
1795 }
1796 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1797 break;
1798 /*
1799 ** Right time, wrong type.
1800 ** Hunt for right time, right type.
1801 ** It's okay to guess wrong since the guess
1802 ** gets checked.
1803 */
1804 /*
1805 ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
1806 */
1807#ifdef ALL_STATE
1808 if (sp == NULL)
1809 return WRONG;
1810#endif /* defined ALL_STATE */
1811 for (i = sp->typecnt - 1; i >= 0; --i) {
1812 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1813 continue;
1814 for (j = sp->typecnt - 1; j >= 0; --j) {
1815 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
1816 continue;
1817 newt = t + sp->ttis[j].tt_gmtoff -
1818 sp->ttis[i].tt_gmtoff;
1819 if ((*funcp)(&newt, offset, &mytm, sp) == NULL)
1820 continue;
1821 if (tmcomp(&mytm, &yourtm) != 0)
1822 continue;
1823 if (mytm.tm_isdst != yourtm.tm_isdst)
1824 continue;
1825 /*
1826 ** We have a match.
1827 */
1828 t = newt;
1829 goto label;
1830 }
1831 }
1832 return WRONG;
1833 }
1834label:
1835 newt = t + saved_seconds;
1836 if ((newt < t) != (saved_seconds < 0))
1837 return WRONG;
1838 t = newt;
1839 if ((*funcp)(&t, offset, tmp, sp))
1840 *okayp = TRUE;
1841 return t;
1842}
1843
1844static time_t
1845time2(tmp, funcp, offset, okayp, sp)
1846struct tm * const tmp;
1847struct tm * (* const funcp) P((const time_t*, long, struct tm*,
1848 const struct state* sp));
1849const long offset;
1850int * const okayp;
1851const struct state * sp;
1852{
1853 time_t t;
1854
1855 /*
1856 ** First try without normalization of seconds
1857 ** (in case tm_sec contains a value associated with a leap second).
1858 ** If that fails, try with normalization of seconds.
1859 */
1860 t = time2sub(tmp, funcp, offset, okayp, FALSE, sp);
1861 return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, sp);
1862}
1863
1864static time_t
1865time1(tmp, funcp, offset, sp)
1866struct tm * const tmp;
1867struct tm * (* const funcp) P((const time_t *, long, struct tm *, const struct state* sp));
1868const long offset;
1869const struct state * sp;
1870{
1871 register time_t t;
1872 register int samei, otheri;
1873 register int sameind, otherind;
1874 register int i;
1875 register int nseen;
1876 int seen[TZ_MAX_TYPES];
1877 int types[TZ_MAX_TYPES];
1878 int okay;
1879
1880 if (tmp->tm_isdst > 1)
1881 tmp->tm_isdst = 1;
1882 t = time2(tmp, funcp, offset, &okay, sp);
1883#define PCTS 1
1884#ifdef PCTS
1885 /*
1886 ** PCTS code courtesy Grant Sullivan.
1887 */
1888 if (okay)
1889 return t;
1890 if (tmp->tm_isdst < 0)
1891 tmp->tm_isdst = 0; /* reset to std and try again */
1892#endif /* defined PCTS */
1893#ifndef PCTS
1894 if (okay || tmp->tm_isdst < 0)
1895 return t;
1896#endif /* !defined PCTS */
1897 /*
1898 ** We're supposed to assume that somebody took a time of one type
1899 ** and did some math on it that yielded a "struct tm" that's bad.
1900 ** We try to divine the type they started from and adjust to the
1901 ** type they need.
1902 */
1903 /*
1904 ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
1905 */
1906#ifdef ALL_STATE
1907 if (sp == NULL)
1908 return WRONG;
1909#endif /* defined ALL_STATE */
1910 for (i = 0; i < sp->typecnt; ++i)
1911 seen[i] = FALSE;
1912 nseen = 0;
1913 for (i = sp->timecnt - 1; i >= 0; --i)
1914 if (!seen[sp->types[i]]) {
1915 seen[sp->types[i]] = TRUE;
1916 types[nseen++] = sp->types[i];
1917 }
1918 for (sameind = 0; sameind < nseen; ++sameind) {
1919 samei = types[sameind];
1920 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
1921 continue;
1922 for (otherind = 0; otherind < nseen; ++otherind) {
1923 otheri = types[otherind];
1924 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
1925 continue;
1926 tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
1927 sp->ttis[samei].tt_gmtoff;
1928 tmp->tm_isdst = !tmp->tm_isdst;
1929 t = time2(tmp, funcp, offset, &okay, sp);
1930 if (okay)
1931 return t;
1932 tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
1933 sp->ttis[samei].tt_gmtoff;
1934 tmp->tm_isdst = !tmp->tm_isdst;
1935 }
1936 }
1937 return WRONG;
1938}
1939
1940// ============================================================================
1941time_t
1942mktime_tz(struct tm * const tmp, char const * tz)
1943{
1944 struct state st;
1945 if (tzload(tz, &st, TRUE) != 0) {
1946 // not sure what's best here, but for now, we fall back to gmt
1947 gmtload(&st);
1948 }
1949 return time1(tmp, localsub, 0L, &st);
1950}