Force a checkpoint in CREATE DATABASE before starting to copy the files,
[PostgreSQL.git] / src / timezone / localtime.c
blob9d8c2694c1ee2d80a5569ba3ea6492e1d9cbc4ca
1 /*
2 * This file is in the public domain, so clarified as of
3 * 1996-06-05 by Arthur David Olson.
5 * IDENTIFICATION
6 * $PostgreSQL$
7 */
9 /*
10 * Leap second handling from Bradley White.
11 * POSIX-style TZ environment variable handling from Guy Harris.
14 /* this file needs to build in both frontend and backend contexts */
15 #include "c.h"
17 #include <fcntl.h>
19 #include "private.h"
20 #include "pgtz.h"
21 #include "tzfile.h"
24 #ifndef WILDABBR
25 /*----------
26 * Someone might make incorrect use of a time zone abbreviation:
27 * 1. They might reference tzname[0] before calling tzset (explicitly
28 * or implicitly).
29 * 2. They might reference tzname[1] before calling tzset (explicitly
30 * or implicitly).
31 * 3. They might reference tzname[1] after setting to a time zone
32 * in which Daylight Saving Time is never observed.
33 * 4. They might reference tzname[0] after setting to a time zone
34 * in which Standard Time is never observed.
35 * 5. They might reference tm.TM_ZONE after calling offtime.
36 * What's best to do in the above cases is open to debate;
37 * for now, we just set things up so that in any of the five cases
38 * WILDABBR is used. Another possibility: initialize tzname[0] to the
39 * string "tzname[0] used before set", and similarly for the other cases.
40 * And another: initialize tzname[0] to "ERA", with an explanation in the
41 * manual page of what this "time zone abbreviation" means (doing this so
42 * that tzname[0] has the "normal" length of three characters).
43 *----------
45 #define WILDABBR " "
46 #endif /* !defined WILDABBR */
48 static char wildabbr[] = WILDABBR;
50 static const char gmt[] = "GMT";
53 * The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
54 * We default to US rules as of 1999-08-17.
55 * POSIX 1003.1 section 8.1.1 says that the default DST rules are
56 * implementation dependent; for historical reasons, US rules are a
57 * common default.
59 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
61 struct rule
63 int r_type; /* type of rule--see below */
64 int r_day; /* day number of rule */
65 int r_week; /* week number of rule */
66 int r_mon; /* month number of rule */
67 long r_time; /* transition time of rule */
70 #define JULIAN_DAY 0 /* Jn - Julian day */
71 #define DAY_OF_YEAR 1 /* n - day of year */
72 #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
75 * Prototypes for static functions.
78 static long detzcode(const char *codep);
79 static pg_time_t detzcode64(const char *codep);
80 static int differ_by_repeat(pg_time_t t1, pg_time_t t0);
81 static const char *getzname(const char *strp);
82 static const char *getqzname(const char *strp, int delim);
83 static const char *getnum(const char *strp, int *nump, int min, int max);
84 static const char *getsecs(const char *strp, long *secsp);
85 static const char *getoffset(const char *strp, long *offsetp);
86 static const char *getrule(const char *strp, struct rule * rulep);
87 static void gmtload(struct state * sp);
88 static struct pg_tm *gmtsub(const pg_time_t *timep, long offset,
89 struct pg_tm *tmp);
90 static struct pg_tm *localsub(const pg_time_t *timep, long offset,
91 struct pg_tm *tmp, const pg_tz *tz);
92 static int increment_overflow(int *number, int delta);
93 static pg_time_t transtime(pg_time_t janfirst, int year,
94 const struct rule *rulep, long offset);
95 static int typesequiv(const struct state *sp, int a, int b);
96 static struct pg_tm *timesub(const pg_time_t *timep, long offset,
97 const struct state *sp, struct pg_tm *tmp);
99 /* GMT timezone */
100 static struct state gmtmem;
102 #define gmtptr (&gmtmem)
105 static int gmt_is_set = 0;
108 * Section 4.12.3 of X3.159-1989 requires that
109 * Except for the strftime function, these functions [asctime,
110 * ctime, gmtime, localtime] return values in one of two static
111 * objects: a broken-down time structure and an array of char.
112 * Thanks to Paul Eggert for noting this.
115 static struct pg_tm tm;
118 static long
119 detzcode(const char *codep)
121 long result;
122 int i;
124 result = (codep[0] & 0x80) ? ~0L : 0;
125 for (i = 0; i < 4; ++i)
126 result = (result << 8) | (codep[i] & 0xff);
127 return result;
130 static pg_time_t
131 detzcode64(const char *codep)
133 pg_time_t result;
134 int i;
136 result = (codep[0] & 0x80) ? (~(int64) 0) : 0;
137 for (i = 0; i < 8; ++i)
138 result = result * 256 + (codep[i] & 0xff);
139 return result;
142 static int
143 differ_by_repeat(pg_time_t t1, pg_time_t t0)
145 if (TYPE_INTEGRAL(pg_time_t) &&
146 TYPE_BIT(pg_time_t) - TYPE_SIGNED(pg_time_t) < SECSPERREPEAT_BITS)
147 return 0;
148 return t1 - t0 == SECSPERREPEAT;
152 tzload(const char *name, char *canonname, struct state * sp, int doextend)
154 const char *p;
155 int i;
156 int fid;
157 int stored;
158 int nread;
159 union
161 struct tzhead tzhead;
162 char buf[2 * sizeof(struct tzhead) +
163 2 * sizeof *sp +
164 4 * TZ_MAX_TIMES];
165 } u;
167 if (name == NULL && (name = TZDEFAULT) == NULL)
168 return -1;
169 if (name[0] == ':')
170 ++name;
171 fid = pg_open_tzfile(name, canonname);
172 if (fid < 0)
173 return -1;
174 nread = read(fid, u.buf, sizeof u.buf);
175 if (close(fid) != 0 || nread <= 0)
176 return -1;
177 for (stored = 4; stored <= 8; stored *= 2)
179 int ttisstdcnt;
180 int ttisgmtcnt;
182 ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
183 ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
184 sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
185 sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
186 sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
187 sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
188 p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
189 if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
190 sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
191 sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
192 sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
193 (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
194 (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
195 return -1;
196 if (nread - (p - u.buf) <
197 sp->timecnt * stored + /* ats */
198 sp->timecnt + /* types */
199 sp->typecnt * 6 + /* ttinfos */
200 sp->charcnt + /* chars */
201 sp->leapcnt * (stored + 4) + /* lsinfos */
202 ttisstdcnt + /* ttisstds */
203 ttisgmtcnt) /* ttisgmts */
204 return -1;
205 for (i = 0; i < sp->timecnt; ++i)
207 sp->ats[i] = (stored == 4) ? detzcode(p) : detzcode64(p);
208 p += stored;
210 for (i = 0; i < sp->timecnt; ++i)
212 sp->types[i] = (unsigned char) *p++;
213 if (sp->types[i] >= sp->typecnt)
214 return -1;
216 for (i = 0; i < sp->typecnt; ++i)
218 struct ttinfo *ttisp;
220 ttisp = &sp->ttis[i];
221 ttisp->tt_gmtoff = detzcode(p);
222 p += 4;
223 ttisp->tt_isdst = (unsigned char) *p++;
224 if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
225 return -1;
226 ttisp->tt_abbrind = (unsigned char) *p++;
227 if (ttisp->tt_abbrind < 0 ||
228 ttisp->tt_abbrind > sp->charcnt)
229 return -1;
231 for (i = 0; i < sp->charcnt; ++i)
232 sp->chars[i] = *p++;
233 sp->chars[i] = '\0'; /* ensure '\0' at end */
234 for (i = 0; i < sp->leapcnt; ++i)
236 struct lsinfo *lsisp;
238 lsisp = &sp->lsis[i];
239 lsisp->ls_trans = (stored == 4) ? detzcode(p) : detzcode64(p);
240 p += stored;
241 lsisp->ls_corr = detzcode(p);
242 p += 4;
244 for (i = 0; i < sp->typecnt; ++i)
246 struct ttinfo *ttisp;
248 ttisp = &sp->ttis[i];
249 if (ttisstdcnt == 0)
250 ttisp->tt_ttisstd = FALSE;
251 else
253 ttisp->tt_ttisstd = *p++;
254 if (ttisp->tt_ttisstd != TRUE &&
255 ttisp->tt_ttisstd != FALSE)
256 return -1;
259 for (i = 0; i < sp->typecnt; ++i)
261 struct ttinfo *ttisp;
263 ttisp = &sp->ttis[i];
264 if (ttisgmtcnt == 0)
265 ttisp->tt_ttisgmt = FALSE;
266 else
268 ttisp->tt_ttisgmt = *p++;
269 if (ttisp->tt_ttisgmt != TRUE &&
270 ttisp->tt_ttisgmt != FALSE)
271 return -1;
275 * Out-of-sort ats should mean we're running on a
276 * signed time_t system but using a data file with
277 * unsigned values (or vice versa).
279 for (i = 0; i < sp->timecnt - 2; ++i)
280 if (sp->ats[i] > sp->ats[i + 1])
282 ++i;
283 if (TYPE_SIGNED(pg_time_t))
286 * Ignore the end (easy).
288 sp->timecnt = i;
290 else
293 * Ignore the beginning (harder).
295 int j;
297 for (j = 0; j + i < sp->timecnt; ++j)
299 sp->ats[j] = sp->ats[j + i];
300 sp->types[j] = sp->types[j + i];
302 sp->timecnt = j;
304 break;
307 * If this is an old file, we're done.
309 if (u.tzhead.tzh_version[0] == '\0')
310 break;
311 nread -= p - u.buf;
312 for (i = 0; i < nread; ++i)
313 u.buf[i] = p[i];
315 * If this is a narrow integer time_t system, we're done.
317 if (stored >= (int) sizeof(pg_time_t) && TYPE_INTEGRAL(pg_time_t))
318 break;
320 if (doextend && nread > 2 &&
321 u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
322 sp->typecnt + 2 <= TZ_MAX_TYPES)
324 struct state ts;
325 int result;
327 u.buf[nread - 1] = '\0';
328 result = tzparse(&u.buf[1], &ts, FALSE);
329 if (result == 0 && ts.typecnt == 2 &&
330 sp->charcnt + ts.charcnt <= TZ_MAX_CHARS)
332 for (i = 0; i < 2; ++i)
333 ts.ttis[i].tt_abbrind +=
334 sp->charcnt;
335 for (i = 0; i < ts.charcnt; ++i)
336 sp->chars[sp->charcnt++] =
337 ts.chars[i];
338 i = 0;
339 while (i < ts.timecnt &&
340 ts.ats[i] <=
341 sp->ats[sp->timecnt - 1])
342 ++i;
343 while (i < ts.timecnt &&
344 sp->timecnt < TZ_MAX_TIMES)
346 sp->ats[sp->timecnt] =
347 ts.ats[i];
348 sp->types[sp->timecnt] =
349 sp->typecnt +
350 ts.types[i];
351 ++sp->timecnt;
352 ++i;
354 sp->ttis[sp->typecnt++] = ts.ttis[0];
355 sp->ttis[sp->typecnt++] = ts.ttis[1];
358 i = 2 * YEARSPERREPEAT;
359 sp->goback = sp->goahead = sp->timecnt > i;
360 sp->goback = sp->goback &&
361 typesequiv(sp, sp->types[i], sp->types[0]) &&
362 differ_by_repeat(sp->ats[i], sp->ats[0]);
363 sp->goahead = sp->goahead &&
364 typesequiv(sp, sp->types[sp->timecnt - 1],
365 sp->types[sp->timecnt - 1 - i]) &&
366 differ_by_repeat(sp->ats[sp->timecnt - 1],
367 sp->ats[sp->timecnt - 1 - i]);
368 return 0;
371 static int
372 typesequiv(const struct state *sp, int a, int b)
374 int result;
376 if (sp == NULL ||
377 a < 0 || a >= sp->typecnt ||
378 b < 0 || b >= sp->typecnt)
379 result = FALSE;
380 else
382 const struct ttinfo *ap = &sp->ttis[a];
383 const struct ttinfo *bp = &sp->ttis[b];
385 result = ap->tt_gmtoff == bp->tt_gmtoff &&
386 ap->tt_isdst == bp->tt_isdst &&
387 ap->tt_ttisstd == bp->tt_ttisstd &&
388 ap->tt_ttisgmt == bp->tt_ttisgmt &&
389 strcmp(&sp->chars[ap->tt_abbrind],
390 &sp->chars[bp->tt_abbrind]) == 0;
392 return result;
395 static const int mon_lengths[2][MONSPERYEAR] = {
396 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
397 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
400 static const int year_lengths[2] = {
401 DAYSPERNYEAR, DAYSPERLYEAR
405 * Given a pointer into a time zone string, scan until a character that is not
406 * a valid character in a zone name is found. Return a pointer to that
407 * character.
409 static const char *
410 getzname(const char *strp)
412 char c;
414 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
415 c != '+')
416 ++strp;
417 return strp;
421 * Given a pointer into an extended time zone string, scan until the ending
422 * delimiter of the zone name is located. Return a pointer to the delimiter.
424 * As with getzname above, the legal character set is actually quite
425 * restricted, with other characters producing undefined results.
426 * We don't do any checking here; checking is done later in common-case code.
428 static const char *
429 getqzname(const char *strp, int delim)
431 int c;
433 while ((c = *strp) != '\0' && c != delim)
434 ++strp;
435 return strp;
439 * Given a pointer into a time zone string, extract a number from that string.
440 * Check that the number is within a specified range; if it is not, return
441 * NULL.
442 * Otherwise, return a pointer to the first character not part of the number.
444 static const char *
445 getnum(const char *strp, int *nump, int min, int max)
447 char c;
448 int num;
450 if (strp == NULL || !is_digit(c = *strp))
451 return NULL;
452 num = 0;
455 num = num * 10 + (c - '0');
456 if (num > max)
457 return NULL; /* illegal value */
458 c = *++strp;
459 } while (is_digit(c));
460 if (num < min)
461 return NULL; /* illegal value */
462 *nump = num;
463 return strp;
467 * Given a pointer into a time zone string, extract a number of seconds,
468 * in hh[:mm[:ss]] form, from the string.
469 * If any error occurs, return NULL.
470 * Otherwise, return a pointer to the first character not part of the number
471 * of seconds.
473 static const char *
474 getsecs(const char *strp, long *secsp)
476 int num;
479 * `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
480 * "M10.4.6/26", which does not conform to Posix, but which specifies the
481 * equivalent of ``02:00 on the first Sunday on or after 23 Oct''.
483 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
484 if (strp == NULL)
485 return NULL;
486 *secsp = num * (long) SECSPERHOUR;
487 if (*strp == ':')
489 ++strp;
490 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
491 if (strp == NULL)
492 return NULL;
493 *secsp += num * SECSPERMIN;
494 if (*strp == ':')
496 ++strp;
497 /* `SECSPERMIN' allows for leap seconds. */
498 strp = getnum(strp, &num, 0, SECSPERMIN);
499 if (strp == NULL)
500 return NULL;
501 *secsp += num;
504 return strp;
508 * Given a pointer into a time zone string, extract an offset, in
509 * [+-]hh[:mm[:ss]] form, from the string.
510 * If any error occurs, return NULL.
511 * Otherwise, return a pointer to the first character not part of the time.
513 static const char *
514 getoffset(const char *strp, long *offsetp)
516 int neg = 0;
518 if (*strp == '-')
520 neg = 1;
521 ++strp;
523 else if (*strp == '+')
524 ++strp;
525 strp = getsecs(strp, offsetp);
526 if (strp == NULL)
527 return NULL; /* illegal time */
528 if (neg)
529 *offsetp = -*offsetp;
530 return strp;
534 * Given a pointer into a time zone string, extract a rule in the form
535 * date[/time]. See POSIX section 8 for the format of "date" and "time".
536 * If a valid rule is not found, return NULL.
537 * Otherwise, return a pointer to the first character not part of the rule.
539 static const char *
540 getrule(const char *strp, struct rule * rulep)
542 if (*strp == 'J')
545 * Julian day.
547 rulep->r_type = JULIAN_DAY;
548 ++strp;
549 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
551 else if (*strp == 'M')
554 * Month, week, day.
556 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
557 ++strp;
558 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
559 if (strp == NULL)
560 return NULL;
561 if (*strp++ != '.')
562 return NULL;
563 strp = getnum(strp, &rulep->r_week, 1, 5);
564 if (strp == NULL)
565 return NULL;
566 if (*strp++ != '.')
567 return NULL;
568 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
570 else if (is_digit(*strp))
573 * Day of year.
575 rulep->r_type = DAY_OF_YEAR;
576 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
578 else
579 return NULL; /* invalid format */
580 if (strp == NULL)
581 return NULL;
582 if (*strp == '/')
585 * Time specified.
587 ++strp;
588 strp = getsecs(strp, &rulep->r_time);
590 else
591 rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
592 return strp;
596 * Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
597 * year, a rule, and the offset from UTC at the time that rule takes effect,
598 * calculate the Epoch-relative time that rule takes effect.
600 static pg_time_t
601 transtime(pg_time_t janfirst, int year,
602 const struct rule * rulep, long offset)
604 int leapyear;
605 pg_time_t value = 0;
606 int i,
609 yy0,
610 yy1,
611 yy2,
612 dow;
614 leapyear = isleap(year);
615 switch (rulep->r_type)
618 case JULIAN_DAY:
621 * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
622 * years. In non-leap years, or if the day number is 59 or less,
623 * just add SECSPERDAY times the day number-1 to the time of
624 * January 1, midnight, to get the day.
626 value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
627 if (leapyear && rulep->r_day >= 60)
628 value += SECSPERDAY;
629 break;
631 case DAY_OF_YEAR:
634 * n - day of year. Just add SECSPERDAY times the day number to
635 * the time of January 1, midnight, to get the day.
637 value = janfirst + rulep->r_day * SECSPERDAY;
638 break;
640 case MONTH_NTH_DAY_OF_WEEK:
643 * Mm.n.d - nth "dth day" of month m.
645 value = janfirst;
646 for (i = 0; i < rulep->r_mon - 1; ++i)
647 value += mon_lengths[leapyear][i] * SECSPERDAY;
650 * Use Zeller's Congruence to get day-of-week of first day of
651 * month.
653 m1 = (rulep->r_mon + 9) % 12 + 1;
654 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
655 yy1 = yy0 / 100;
656 yy2 = yy0 % 100;
657 dow = ((26 * m1 - 2) / 10 +
658 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
659 if (dow < 0)
660 dow += DAYSPERWEEK;
663 * "dow" is the day-of-week of the first day of the month. Get the
664 * day-of-month (zero-origin) of the first "dow" day of the month.
666 d = rulep->r_day - dow;
667 if (d < 0)
668 d += DAYSPERWEEK;
669 for (i = 1; i < rulep->r_week; ++i)
671 if (d + DAYSPERWEEK >=
672 mon_lengths[leapyear][rulep->r_mon - 1])
673 break;
674 d += DAYSPERWEEK;
678 * "d" is the day-of-month (zero-origin) of the day we want.
680 value += d * SECSPERDAY;
681 break;
685 * "value" is the Epoch-relative time of 00:00:00 UTC on the day in
686 * question. To get the Epoch-relative time of the specified local time
687 * on that day, add the transition time and the current offset from UTC.
689 return value + rulep->r_time + offset;
693 * Given a POSIX section 8-style TZ string, fill in the rule tables as
694 * appropriate.
698 tzparse(const char *name, struct state * sp, int lastditch)
700 const char *stdname;
701 const char *dstname = NULL;
702 size_t stdlen;
703 size_t dstlen;
704 long stdoffset;
705 long dstoffset;
706 pg_time_t *atp;
707 unsigned char *typep;
708 char *cp;
709 int load_result;
711 stdname = name;
712 if (lastditch)
714 stdlen = strlen(name); /* length of standard zone name */
715 name += stdlen;
716 if (stdlen >= sizeof sp->chars)
717 stdlen = (sizeof sp->chars) - 1;
718 stdoffset = 0;
721 * Unlike the original zic library, do NOT invoke tzload() here; we
722 * can't assume pg_open_tzfile() is sane yet, and we don't care about
723 * leap seconds anyway.
725 load_result = -1;
727 else
729 if (*name == '<')
731 name++;
732 stdname = name;
733 name = getqzname(name, '>');
734 if (*name != '>')
735 return (-1);
736 stdlen = name - stdname;
737 name++;
739 else
741 name = getzname(name);
742 stdlen = name - stdname;
744 if (*name == '\0')
745 return -1;
746 name = getoffset(name, &stdoffset);
747 if (name == NULL)
748 return -1;
749 load_result = tzload(TZDEFRULES, NULL, sp, FALSE);
751 if (load_result != 0)
752 sp->leapcnt = 0; /* so, we're off a little */
753 if (*name != '\0')
755 if (*name == '<')
757 dstname = ++name;
758 name = getqzname(name, '>');
759 if (*name != '>')
760 return -1;
761 dstlen = name - dstname;
762 name++;
764 else
766 dstname = name;
767 name = getzname(name);
768 dstlen = name - dstname; /* length of DST zone name */
770 if (*name != '\0' && *name != ',' && *name != ';')
772 name = getoffset(name, &dstoffset);
773 if (name == NULL)
774 return -1;
776 else
777 dstoffset = stdoffset - SECSPERHOUR;
778 if (*name == '\0' && load_result != 0)
779 name = TZDEFRULESTRING;
780 if (*name == ',' || *name == ';')
782 struct rule start;
783 struct rule end;
784 int year;
785 pg_time_t janfirst;
786 pg_time_t starttime;
787 pg_time_t endtime;
789 ++name;
790 if ((name = getrule(name, &start)) == NULL)
791 return -1;
792 if (*name++ != ',')
793 return -1;
794 if ((name = getrule(name, &end)) == NULL)
795 return -1;
796 if (*name != '\0')
797 return -1;
798 sp->typecnt = 2; /* standard time and DST */
801 * Two transitions per year, from EPOCH_YEAR forward.
803 sp->ttis[0].tt_gmtoff = -dstoffset;
804 sp->ttis[0].tt_isdst = 1;
805 sp->ttis[0].tt_abbrind = stdlen + 1;
806 sp->ttis[1].tt_gmtoff = -stdoffset;
807 sp->ttis[1].tt_isdst = 0;
808 sp->ttis[1].tt_abbrind = 0;
809 atp = sp->ats;
810 typep = sp->types;
811 janfirst = 0;
812 sp->timecnt = 0;
813 for (year = EPOCH_YEAR;
814 sp->timecnt + 2 <= TZ_MAX_TIMES;
815 ++year)
817 pg_time_t newfirst;
819 starttime = transtime(janfirst, year, &start,
820 stdoffset);
821 endtime = transtime(janfirst, year, &end,
822 dstoffset);
823 if (starttime > endtime)
825 *atp++ = endtime;
826 *typep++ = 1; /* DST ends */
827 *atp++ = starttime;
828 *typep++ = 0; /* DST begins */
830 else
832 *atp++ = starttime;
833 *typep++ = 0; /* DST begins */
834 *atp++ = endtime;
835 *typep++ = 1; /* DST ends */
837 sp->timecnt += 2;
838 newfirst = janfirst;
839 newfirst += year_lengths[isleap(year)] *
840 SECSPERDAY;
841 if (newfirst <= janfirst)
842 break;
843 janfirst = newfirst;
846 else
848 long theirstdoffset;
849 long theirdstoffset;
850 long theiroffset;
851 int isdst;
852 int i;
853 int j;
855 if (*name != '\0')
856 return -1;
859 * Initial values of theirstdoffset and theirdstoffset.
861 theirstdoffset = 0;
862 for (i = 0; i < sp->timecnt; ++i)
864 j = sp->types[i];
865 if (!sp->ttis[j].tt_isdst)
867 theirstdoffset =
868 -sp->ttis[j].tt_gmtoff;
869 break;
872 theirdstoffset = 0;
873 for (i = 0; i < sp->timecnt; ++i)
875 j = sp->types[i];
876 if (sp->ttis[j].tt_isdst)
878 theirdstoffset =
879 -sp->ttis[j].tt_gmtoff;
880 break;
885 * Initially we're assumed to be in standard time.
887 isdst = FALSE;
888 theiroffset = theirstdoffset;
891 * Now juggle transition times and types tracking offsets as you
892 * do.
894 for (i = 0; i < sp->timecnt; ++i)
896 j = sp->types[i];
897 sp->types[i] = sp->ttis[j].tt_isdst;
898 if (sp->ttis[j].tt_ttisgmt)
900 /* No adjustment to transition time */
902 else
905 * If summer time is in effect, and the transition time
906 * was not specified as standard time, add the summer time
907 * offset to the transition time; otherwise, add the
908 * standard time offset to the transition time.
912 * Transitions from DST to DDST will effectively disappear
913 * since POSIX provides for only one DST offset.
915 if (isdst && !sp->ttis[j].tt_ttisstd)
917 sp->ats[i] += dstoffset -
918 theirdstoffset;
920 else
922 sp->ats[i] += stdoffset -
923 theirstdoffset;
926 theiroffset = -sp->ttis[j].tt_gmtoff;
927 if (sp->ttis[j].tt_isdst)
928 theirdstoffset = theiroffset;
929 else
930 theirstdoffset = theiroffset;
934 * Finally, fill in ttis. ttisstd and ttisgmt need not be handled.
936 sp->ttis[0].tt_gmtoff = -stdoffset;
937 sp->ttis[0].tt_isdst = FALSE;
938 sp->ttis[0].tt_abbrind = 0;
939 sp->ttis[1].tt_gmtoff = -dstoffset;
940 sp->ttis[1].tt_isdst = TRUE;
941 sp->ttis[1].tt_abbrind = stdlen + 1;
942 sp->typecnt = 2;
945 else
947 dstlen = 0;
948 sp->typecnt = 1; /* only standard time */
949 sp->timecnt = 0;
950 sp->ttis[0].tt_gmtoff = -stdoffset;
951 sp->ttis[0].tt_isdst = 0;
952 sp->ttis[0].tt_abbrind = 0;
954 sp->charcnt = stdlen + 1;
955 if (dstlen != 0)
956 sp->charcnt += dstlen + 1;
957 if ((size_t) sp->charcnt > sizeof sp->chars)
958 return -1;
959 cp = sp->chars;
960 (void) strncpy(cp, stdname, stdlen);
961 cp += stdlen;
962 *cp++ = '\0';
963 if (dstlen != 0)
965 (void) strncpy(cp, dstname, dstlen);
966 *(cp + dstlen) = '\0';
968 return 0;
971 static void
972 gmtload(struct state * sp)
974 if (tzload(gmt, NULL, sp, TRUE) != 0)
975 (void) tzparse(gmt, sp, TRUE);
980 * The easy way to behave "as if no library function calls" localtime
981 * is to not call it--so we drop its guts into "localsub", which can be
982 * freely called. (And no, the PANS doesn't require the above behavior--
983 * but it *is* desirable.)
985 * The unused offset argument is for the benefit of mktime variants.
987 static struct pg_tm *
988 localsub(const pg_time_t *timep, long offset,
989 struct pg_tm *tmp, const pg_tz *tz)
991 const struct state *sp;
992 const struct ttinfo *ttisp;
993 int i;
994 struct pg_tm *result;
995 const pg_time_t t = *timep;
997 sp = &tz->state;
998 if ((sp->goback && t < sp->ats[0]) ||
999 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1001 pg_time_t newt = t;
1002 pg_time_t seconds;
1003 pg_time_t tcycles;
1004 int64 icycles;
1006 if (t < sp->ats[0])
1007 seconds = sp->ats[0] - t;
1008 else seconds = t - sp->ats[sp->timecnt - 1];
1009 --seconds;
1010 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1011 ++tcycles;
1012 icycles = tcycles;
1013 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1014 return NULL;
1015 seconds = icycles;
1016 seconds *= YEARSPERREPEAT;
1017 seconds *= AVGSECSPERYEAR;
1018 if (t < sp->ats[0])
1019 newt += seconds;
1020 else newt -= seconds;
1021 if (newt < sp->ats[0] ||
1022 newt > sp->ats[sp->timecnt - 1])
1023 return NULL; /* "cannot happen" */
1024 result = localsub(&newt, offset, tmp, tz);
1025 if (result == tmp)
1027 pg_time_t newy;
1029 newy = tmp->tm_year;
1030 if (t < sp->ats[0])
1031 newy -= icycles * YEARSPERREPEAT;
1032 else newy += icycles * YEARSPERREPEAT;
1033 tmp->tm_year = newy;
1034 if (tmp->tm_year != newy)
1035 return NULL;
1037 return result;
1039 if (sp->timecnt == 0 || t < sp->ats[0])
1041 i = 0;
1042 while (sp->ttis[i].tt_isdst)
1043 if (++i >= sp->typecnt)
1045 i = 0;
1046 break;
1049 else
1051 int lo = 1;
1052 int hi = sp->timecnt;
1054 while (lo < hi)
1056 int mid = (lo + hi) >> 1;
1058 if (t < sp->ats[mid])
1059 hi = mid;
1060 else lo = mid + 1;
1062 i = (int) sp->types[lo - 1];
1064 ttisp = &sp->ttis[i];
1066 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1067 tmp->tm_isdst = ttisp->tt_isdst;
1068 tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
1069 return result;
1073 struct pg_tm *
1074 pg_localtime(const pg_time_t *timep, const pg_tz *tz)
1076 return localsub(timep, 0L, &tm, tz);
1081 * gmtsub is to gmtime as localsub is to localtime.
1083 static struct pg_tm *
1084 gmtsub(const pg_time_t *timep, long offset, struct pg_tm *tmp)
1086 struct pg_tm *result;
1088 if (!gmt_is_set)
1090 gmt_is_set = TRUE;
1091 gmtload(gmtptr);
1093 result = timesub(timep, offset, gmtptr, tmp);
1096 * Could get fancy here and deliver something such as "UTC+xxxx" or
1097 * "UTC-xxxx" if offset is non-zero, but this is no time for a treasure
1098 * hunt.
1100 if (offset != 0)
1101 tmp->tm_zone = wildabbr;
1102 else
1103 tmp->tm_zone = gmtptr->chars;
1105 return result;
1108 struct pg_tm *
1109 pg_gmtime(const pg_time_t *timep)
1111 return gmtsub(timep, 0L, &tm);
1115 * Return the number of leap years through the end of the given year
1116 * where, to make the math easy, the answer for year zero is defined as zero.
1118 static int
1119 leaps_thru_end_of(const int y)
1121 return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1122 -(leaps_thru_end_of(-(y + 1)) + 1);
1126 static struct pg_tm *
1127 timesub(const pg_time_t *timep, long offset,
1128 const struct state *sp, struct pg_tm *tmp)
1130 const struct lsinfo *lp;
1131 pg_time_t tdays;
1132 int idays; /* unsigned would be so 2003 */
1133 long rem;
1134 int y;
1135 const int *ip;
1136 long corr;
1137 int hit;
1138 int i;
1140 corr = 0;
1141 hit = 0;
1142 i = sp->leapcnt;
1143 while (--i >= 0)
1145 lp = &sp->lsis[i];
1146 if (*timep >= lp->ls_trans)
1148 if (*timep == lp->ls_trans)
1150 hit = ((i == 0 && lp->ls_corr > 0) ||
1151 lp->ls_corr > sp->lsis[i - 1].ls_corr);
1152 if (hit)
1153 while (i > 0 &&
1154 sp->lsis[i].ls_trans ==
1155 sp->lsis[i - 1].ls_trans + 1 &&
1156 sp->lsis[i].ls_corr ==
1157 sp->lsis[i - 1].ls_corr + 1)
1159 ++hit;
1160 --i;
1163 corr = lp->ls_corr;
1164 break;
1167 y = EPOCH_YEAR;
1168 tdays = *timep / SECSPERDAY;
1169 rem = *timep - tdays * SECSPERDAY;
1170 while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1172 int newy;
1173 pg_time_t tdelta;
1174 int idelta;
1175 int leapdays;
1177 tdelta = tdays / DAYSPERLYEAR;
1178 idelta = tdelta;
1179 if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
1180 return NULL;
1181 if (idelta == 0)
1182 idelta = (tdays < 0) ? -1 : 1;
1183 newy = y;
1184 if (increment_overflow(&newy, idelta))
1185 return NULL;
1186 leapdays = leaps_thru_end_of(newy - 1) -
1187 leaps_thru_end_of(y - 1);
1188 tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1189 tdays -= leapdays;
1190 y = newy;
1193 long seconds;
1195 seconds = tdays * SECSPERDAY + 0.5;
1196 tdays = seconds / SECSPERDAY;
1197 rem += seconds - tdays * SECSPERDAY;
1200 * Given the range, we can now fearlessly cast...
1202 idays = tdays;
1203 rem += offset - corr;
1204 while (rem < 0)
1206 rem += SECSPERDAY;
1207 --idays;
1209 while (rem >= SECSPERDAY)
1211 rem -= SECSPERDAY;
1212 ++idays;
1214 while (idays < 0)
1216 if (increment_overflow(&y, -1))
1217 return NULL;
1218 idays += year_lengths[isleap(y)];
1220 while (idays >= year_lengths[isleap(y)])
1222 idays -= year_lengths[isleap(y)];
1223 if (increment_overflow(&y, 1))
1224 return NULL;
1226 tmp->tm_year = y;
1227 if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1228 return NULL;
1229 tmp->tm_yday = idays;
1231 * The "extra" mods below avoid overflow problems.
1233 tmp->tm_wday = EPOCH_WDAY +
1234 ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1235 (DAYSPERNYEAR % DAYSPERWEEK) +
1236 leaps_thru_end_of(y - 1) -
1237 leaps_thru_end_of(EPOCH_YEAR - 1) +
1238 idays;
1239 tmp->tm_wday %= DAYSPERWEEK;
1240 if (tmp->tm_wday < 0)
1241 tmp->tm_wday += DAYSPERWEEK;
1242 tmp->tm_hour = (int) (rem / SECSPERHOUR);
1243 rem %= SECSPERHOUR;
1244 tmp->tm_min = (int) (rem / SECSPERMIN);
1247 * A positive leap second requires a special representation. This uses
1248 * "... ??:59:60" et seq.
1250 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1251 ip = mon_lengths[isleap(y)];
1252 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1253 idays -= ip[tmp->tm_mon];
1254 tmp->tm_mday = (int) (idays + 1);
1255 tmp->tm_isdst = 0;
1256 tmp->tm_gmtoff = offset;
1257 return tmp;
1261 * Simplified normalize logic courtesy Paul Eggert.
1264 static int
1265 increment_overflow(int *number, int delta)
1267 int number0;
1269 number0 = *number;
1270 *number += delta;
1271 return (*number < number0) != (delta < 0);
1275 * Find the next DST transition time at or after the given time
1277 * *timep is the input value, the other parameters are output values.
1279 * When the function result is 1, *boundary is set to the time_t
1280 * representation of the next DST transition time at or after *timep,
1281 * *before_gmtoff and *before_isdst are set to the GMT offset and isdst
1282 * state prevailing just before that boundary, and *after_gmtoff and
1283 * *after_isdst are set to the state prevailing just after that boundary.
1285 * When the function result is 0, there is no known DST transition at or
1286 * after *timep, but *before_gmtoff and *before_isdst indicate the GMT
1287 * offset and isdst state prevailing at *timep. (This would occur in
1288 * DST-less time zones, for example.)
1290 * A function result of -1 indicates failure (this case does not actually
1291 * occur in our current implementation).
1294 pg_next_dst_boundary(const pg_time_t *timep,
1295 long int *before_gmtoff,
1296 int *before_isdst,
1297 pg_time_t *boundary,
1298 long int *after_gmtoff,
1299 int *after_isdst,
1300 const pg_tz *tz)
1302 const struct state *sp;
1303 const struct ttinfo *ttisp;
1304 int i;
1305 int j;
1306 const pg_time_t t = *timep;
1308 sp = &tz->state;
1309 if (sp->timecnt == 0)
1311 /* non-DST zone, use lowest-numbered standard type */
1312 i = 0;
1313 while (sp->ttis[i].tt_isdst)
1314 if (++i >= sp->typecnt)
1316 i = 0;
1317 break;
1319 ttisp = &sp->ttis[i];
1320 *before_gmtoff = ttisp->tt_gmtoff;
1321 *before_isdst = ttisp->tt_isdst;
1322 return 0;
1324 if ((sp->goback && t < sp->ats[0]) ||
1325 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1327 /* For values outside the transition table, extrapolate */
1328 pg_time_t newt = t;
1329 pg_time_t seconds;
1330 pg_time_t tcycles;
1331 int64 icycles;
1332 int result;
1334 if (t < sp->ats[0])
1335 seconds = sp->ats[0] - t;
1336 else seconds = t - sp->ats[sp->timecnt - 1];
1337 --seconds;
1338 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1339 ++tcycles;
1340 icycles = tcycles;
1341 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1342 return -1;
1343 seconds = icycles;
1344 seconds *= YEARSPERREPEAT;
1345 seconds *= AVGSECSPERYEAR;
1346 if (t < sp->ats[0])
1347 newt += seconds;
1348 else newt -= seconds;
1349 if (newt < sp->ats[0] ||
1350 newt > sp->ats[sp->timecnt - 1])
1351 return -1; /* "cannot happen" */
1353 result = pg_next_dst_boundary(&newt, before_gmtoff,
1354 before_isdst,
1355 boundary,
1356 after_gmtoff,
1357 after_isdst,
1358 tz);
1359 if (t < sp->ats[0])
1360 *boundary -= seconds;
1361 else
1362 *boundary += seconds;
1363 return result;
1366 if (t > sp->ats[sp->timecnt - 1])
1368 /* No known transition >= t, so use last known segment's type */
1369 i = sp->types[sp->timecnt - 1];
1370 ttisp = &sp->ttis[i];
1371 *before_gmtoff = ttisp->tt_gmtoff;
1372 *before_isdst = ttisp->tt_isdst;
1373 return 0;
1375 if (t <= sp->ats[0])
1377 /* For "before", use lowest-numbered standard type */
1378 i = 0;
1379 while (sp->ttis[i].tt_isdst)
1380 if (++i >= sp->typecnt)
1382 i = 0;
1383 break;
1385 ttisp = &sp->ttis[i];
1386 *before_gmtoff = ttisp->tt_gmtoff;
1387 *before_isdst = ttisp->tt_isdst;
1388 *boundary = sp->ats[0];
1389 /* And for "after", use the first segment's type */
1390 i = sp->types[0];
1391 ttisp = &sp->ttis[i];
1392 *after_gmtoff = ttisp->tt_gmtoff;
1393 *after_isdst = ttisp->tt_isdst;
1394 return 1;
1396 /* Else search to find the containing segment */
1398 int lo = 1;
1399 int hi = sp->timecnt;
1401 while (lo < hi)
1403 int mid = (lo + hi) >> 1;
1405 if (t < sp->ats[mid])
1406 hi = mid;
1407 else lo = mid + 1;
1409 i = lo;
1411 j = sp->types[i - 1];
1412 ttisp = &sp->ttis[j];
1413 *before_gmtoff = ttisp->tt_gmtoff;
1414 *before_isdst = ttisp->tt_isdst;
1415 *boundary = sp->ats[i];
1416 j = sp->types[i];
1417 ttisp = &sp->ttis[j];
1418 *after_gmtoff = ttisp->tt_gmtoff;
1419 *after_isdst = ttisp->tt_isdst;
1420 return 1;
1424 * If the given timezone uses only one GMT offset, store that offset
1425 * into *gmtoff and return TRUE, else return FALSE.
1427 bool
1428 pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
1431 * The zone could have more than one ttinfo, if it's historically used
1432 * more than one abbreviation. We return TRUE as long as they all have
1433 * the same gmtoff.
1435 const struct state *sp;
1436 int i;
1438 sp = &tz->state;
1439 for (i = 1; i < sp->typecnt; i++)
1441 if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
1442 return false;
1444 *gmtoff = sp->ttis[0].tt_gmtoff;
1445 return true;
1449 * Return the name of the current timezone
1451 const char *
1452 pg_get_timezone_name(pg_tz *tz)
1454 if (tz)
1455 return tz->TZname;
1456 return NULL;