2 * This file is in the public domain, so clarified as of
3 * 1996-06-05 by Arthur David Olson.
6 * src/timezone/localtime.c
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 */
19 #include "datatype/timestamp.h"
27 * Someone might make incorrect use of a time zone abbreviation:
28 * 1. They might reference tzname[0] before calling tzset (explicitly
30 * 2. They might reference tzname[1] before calling tzset (explicitly
32 * 3. They might reference tzname[1] after setting to a time zone
33 * in which Daylight Saving Time is never observed.
34 * 4. They might reference tzname[0] after setting to a time zone
35 * in which Standard Time is never observed.
36 * 5. They might reference tm.TM_ZONE after calling offtime.
37 * What's best to do in the above cases is open to debate;
38 * for now, we just set things up so that in any of the five cases
39 * WILDABBR is used. Another possibility: initialize tzname[0] to the
40 * string "tzname[0] used before set", and similarly for the other cases.
41 * And another: initialize tzname[0] to "ERA", with an explanation in the
42 * manual page of what this "time zone abbreviation" means (doing this so
43 * that tzname[0] has the "normal" length of three characters).
46 #endif /* !defined WILDABBR */
48 static const char wildabbr[] = WILDABBR;
50 static const char gmt[] = "GMT";
52 /* The minimum and maximum finite time values. This assumes no padding. */
53 static const pg_time_t time_t_min = MINVAL(pg_time_t, TYPE_BIT(pg_time_t));
54 static const pg_time_t time_t_max = MAXVAL(pg_time_t, TYPE_BIT(pg_time_t));
57 * The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
58 * We default to US rules as of 1999-08-17.
59 * POSIX 1003.1 section 8.1.1 says that the default DST rules are
60 * implementation dependent; for historical reasons, US rules are a
63 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
65 /* structs ttinfo, lsinfo, state have been moved to pgtz.h */
69 JULIAN_DAY, /* Jn = Julian day */
70 DAY_OF_YEAR, /* n = day of year */
71 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
76 enum r_type r_type; /* type of rule */
77 int r_day; /* day number of rule */
78 int r_week; /* week number of rule */
79 int r_mon; /* month number of rule */
80 int32 r_time; /* transition time of rule */
84 * Prototypes for static functions.
87 static struct pg_tm *gmtsub(pg_time_t const *, int32, struct pg_tm *);
88 static bool increment_overflow(int *, int);
89 static bool increment_overflow_time(pg_time_t *, int32);
90 static struct pg_tm *timesub(pg_time_t const *, int32, struct state const *,
92 static bool typesequiv(struct state const *, int, int);
96 * Section 4.12.3 of X3.159-1989 requires that
97 * Except for the strftime function, these functions [asctime,
98 * ctime, gmtime, localtime] return values in one of two static
99 * objects: a broken-down time structure and an array of char.
100 * Thanks to Paul Eggert for noting this.
103 static struct pg_tm tm;
105 /* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
107 init_ttinfo(struct ttinfo * s, int32 gmtoff, bool isdst, int abbrind)
109 s->tt_gmtoff = gmtoff;
111 s->tt_abbrind = abbrind;
112 s->tt_ttisstd = false;
113 s->tt_ttisgmt = false;
117 detzcode(const char *codep)
122 int32 halfmaxval = one << (32 - 2);
123 int32 maxval = halfmaxval - 1 + halfmaxval;
124 int32 minval = -1 - maxval;
126 result = codep[0] & 0x7f;
127 for (i = 1; i < 4; ++i)
128 result = (result << 8) | (codep[i] & 0xff);
133 * Do two's-complement negation even on non-two's-complement machines.
134 * If the result would be minval - 1, return minval.
136 result -= !TWOS_COMPLEMENT(int32) &&result != 0;
143 detzcode64(const char *codep)
148 int64 halfmaxval = one << (64 - 2);
149 int64 maxval = halfmaxval - 1 + halfmaxval;
150 int64 minval = -TWOS_COMPLEMENT(int64) -maxval;
152 result = codep[0] & 0x7f;
153 for (i = 1; i < 8; ++i)
154 result = (result << 8) | (codep[i] & 0xff);
159 * Do two's-complement negation even on non-two's-complement machines.
160 * If the result would be minval - 1, return minval.
162 result -= !TWOS_COMPLEMENT(int64) &&result != 0;
169 differ_by_repeat(const pg_time_t t1, const pg_time_t t0)
171 if (TYPE_BIT(pg_time_t) -TYPE_SIGNED(pg_time_t) <SECSPERREPEAT_BITS)
173 return t1 - t0 == SECSPERREPEAT;
176 /* Input buffer for data read from a compiled tz file. */
179 /* The first part of the buffer, interpreted as a header. */
180 struct tzhead tzhead;
182 /* The entire buffer. */
183 char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
187 /* Local storage needed for 'tzloadbody'. */
190 /* We don't need the "fullname" member */
192 /* The results of analyzing the file's contents after it is opened. */
195 /* The input buffer. */
196 union input_buffer u;
198 /* A temporary state used for parsing a TZ string in the file. */
203 /* Load tz data from the file named NAME into *SP. Read extended
204 * format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
205 * success, an errno value on failure.
206 * PG: If "canonname" is not NULL, then on success the canonical spelling of
207 * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
210 tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
211 union local_storage * lsp)
217 union input_buffer *up = &lsp->u.u;
218 int tzheadsize = sizeof(struct tzhead);
220 sp->goback = sp->goahead = false;
232 fid = pg_open_tzfile(name, canonname);
234 return ENOENT; /* pg_open_tzfile may not set errno */
236 nread = read(fid, up->buf, sizeof up->buf);
237 if (nread < tzheadsize)
239 int err = nread < 0 ? errno : EINVAL;
246 for (stored = 4; stored <= 8; stored *= 2)
248 int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
249 int32 ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
250 int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt);
251 int32 timecnt = detzcode(up->tzhead.tzh_timecnt);
252 int32 typecnt = detzcode(up->tzhead.tzh_typecnt);
253 int32 charcnt = detzcode(up->tzhead.tzh_charcnt);
254 char const *p = up->buf + tzheadsize;
256 if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
257 && 0 < typecnt && typecnt < TZ_MAX_TYPES
258 && 0 <= timecnt && timecnt < TZ_MAX_TIMES
259 && 0 <= charcnt && charcnt < TZ_MAX_CHARS
260 && (ttisstdcnt == typecnt || ttisstdcnt == 0)
261 && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
264 < (tzheadsize /* struct tzhead */
265 + timecnt * stored /* ats */
266 + timecnt /* types */
267 + typecnt * 6 /* ttinfos */
268 + charcnt /* chars */
269 + leapcnt * (stored + 4) /* lsinfos */
270 + ttisstdcnt /* ttisstds */
271 + ttisgmtcnt)) /* ttisgmts */
273 sp->leapcnt = leapcnt;
274 sp->timecnt = timecnt;
275 sp->typecnt = typecnt;
276 sp->charcnt = charcnt;
279 * Read transitions, discarding those out of pg_time_t range. But
280 * pretend the last transition before time_t_min occurred at
284 for (i = 0; i < sp->timecnt; ++i)
287 = stored == 4 ? detzcode(p) : detzcode64(p);
289 sp->types[i] = at <= time_t_max;
293 = ((TYPE_SIGNED(pg_time_t) ? at < time_t_min : at < 0)
296 if (timecnt && attime <= sp->ats[timecnt - 1])
298 if (attime < sp->ats[timecnt - 1])
300 sp->types[i - 1] = 0;
303 sp->ats[timecnt++] = attime;
309 for (i = 0; i < sp->timecnt; ++i)
311 unsigned char typ = *p++;
313 if (sp->typecnt <= typ)
316 sp->types[timecnt++] = typ;
318 sp->timecnt = timecnt;
319 for (i = 0; i < sp->typecnt; ++i)
321 struct ttinfo *ttisp;
325 ttisp = &sp->ttis[i];
326 ttisp->tt_gmtoff = detzcode(p);
331 ttisp->tt_isdst = isdst;
333 if (!(abbrind < sp->charcnt))
335 ttisp->tt_abbrind = abbrind;
337 for (i = 0; i < sp->charcnt; ++i)
339 sp->chars[i] = '\0'; /* ensure '\0' at end */
341 /* Read leap seconds, discarding those out of pg_time_t range. */
343 for (i = 0; i < sp->leapcnt; ++i)
345 int64 tr = stored == 4 ? detzcode(p) : detzcode64(p);
346 int32 corr = detzcode(p + stored);
349 if (tr <= time_t_max)
352 = ((TYPE_SIGNED(pg_time_t) ? tr < time_t_min : tr < 0)
355 if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans)
357 if (trans < sp->lsis[leapcnt - 1].ls_trans)
361 sp->lsis[leapcnt].ls_trans = trans;
362 sp->lsis[leapcnt].ls_corr = corr;
366 sp->leapcnt = leapcnt;
368 for (i = 0; i < sp->typecnt; ++i)
370 struct ttinfo *ttisp;
372 ttisp = &sp->ttis[i];
374 ttisp->tt_ttisstd = false;
377 if (*p != true && *p != false)
379 ttisp->tt_ttisstd = *p++;
382 for (i = 0; i < sp->typecnt; ++i)
384 struct ttinfo *ttisp;
386 ttisp = &sp->ttis[i];
388 ttisp->tt_ttisgmt = false;
391 if (*p != true && *p != false)
393 ttisp->tt_ttisgmt = *p++;
398 * If this is an old file, we're done.
400 if (up->tzhead.tzh_version[0] == '\0')
402 nread -= p - up->buf;
403 memmove(up->buf, p, nread);
405 if (doextend && nread > 2 &&
406 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
407 sp->typecnt + 2 <= TZ_MAX_TYPES)
409 struct state *ts = &lsp->u.st;
411 up->buf[nread - 1] = '\0';
412 if (tzparse(&up->buf[1], ts, false)
416 * Attempt to reuse existing abbreviations. Without this,
417 * America/Anchorage would stop working after 2037 when
418 * TZ_MAX_CHARS is 50, as sp->charcnt equals 42 (for LMT CAT CAWT
419 * CAPT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
420 * AKST AKDT). Reusing means sp->charcnt can stay 42 in this
424 int charcnt = sp->charcnt;
426 for (i = 0; i < 2; i++)
428 char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
431 for (j = 0; j < charcnt; j++)
432 if (strcmp(sp->chars + j, tsabbr) == 0)
434 ts->ttis[i].tt_abbrind = j;
440 int tsabbrlen = strlen(tsabbr);
442 if (j + tsabbrlen < TZ_MAX_CHARS)
444 strcpy(sp->chars + j, tsabbr);
445 charcnt = j + tsabbrlen + 1;
446 ts->ttis[i].tt_abbrind = j;
453 sp->charcnt = charcnt;
454 for (i = 0; i < ts->timecnt; i++)
455 if (sp->ats[sp->timecnt - 1] < ts->ats[i])
457 while (i < ts->timecnt
458 && sp->timecnt < TZ_MAX_TIMES)
460 sp->ats[sp->timecnt] = ts->ats[i];
461 sp->types[sp->timecnt] = (sp->typecnt
466 sp->ttis[sp->typecnt++] = ts->ttis[0];
467 sp->ttis[sp->typecnt++] = ts->ttis[1];
473 for (i = 1; i < sp->timecnt; ++i)
474 if (typesequiv(sp, sp->types[i], sp->types[0]) &&
475 differ_by_repeat(sp->ats[i], sp->ats[0]))
480 for (i = sp->timecnt - 2; i >= 0; --i)
481 if (typesequiv(sp, sp->types[sp->timecnt - 1],
483 differ_by_repeat(sp->ats[sp->timecnt - 1],
492 * If type 0 is is unused in transitions, it's the type to use for early
495 for (i = 0; i < sp->timecnt; ++i)
496 if (sp->types[i] == 0)
498 i = i < sp->timecnt ? -1 : 0;
501 * Absent the above, if there are transition times and the first
502 * transition is to a daylight time find the standard type less than and
503 * closest to the type of the first transition.
505 if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst)
509 if (!sp->ttis[i].tt_isdst)
514 * If no result yet, find the first standard type. If there is none, punt
520 while (sp->ttis[i].tt_isdst)
521 if (++i >= sp->typecnt)
531 /* Load tz data from the file named NAME into *SP. Read extended
532 * format if DOEXTEND. Return 0 on success, an errno value on failure.
533 * PG: If "canonname" is not NULL, then on success the canonical spelling of
534 * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
537 tzload(const char *name, char *canonname, struct state * sp, bool doextend)
539 union local_storage ls;
541 return tzloadbody(name, canonname, sp, doextend, &ls);
545 typesequiv(const struct state * sp, int a, int b)
550 a < 0 || a >= sp->typecnt ||
551 b < 0 || b >= sp->typecnt)
555 const struct ttinfo *ap = &sp->ttis[a];
556 const struct ttinfo *bp = &sp->ttis[b];
558 result = ap->tt_gmtoff == bp->tt_gmtoff &&
559 ap->tt_isdst == bp->tt_isdst &&
560 ap->tt_ttisstd == bp->tt_ttisstd &&
561 ap->tt_ttisgmt == bp->tt_ttisgmt &&
562 strcmp(&sp->chars[ap->tt_abbrind],
563 &sp->chars[bp->tt_abbrind]) == 0;
568 static const int mon_lengths[2][MONSPERYEAR] = {
569 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
570 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
573 static const int year_lengths[2] = {
574 DAYSPERNYEAR, DAYSPERLYEAR
578 * Given a pointer into a time zone string, scan until a character that is not
579 * a valid character in a zone name is found. Return a pointer to that
583 getzname(const char *strp)
587 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
594 * Given a pointer into an extended time zone string, scan until the ending
595 * delimiter of the zone name is located. Return a pointer to the delimiter.
597 * As with getzname above, the legal character set is actually quite
598 * restricted, with other characters producing undefined results.
599 * We don't do any checking here; checking is done later in common-case code.
602 getqzname(const char *strp, int delim)
606 while ((c = *strp) != '\0' && c != delim)
612 * Given a pointer into a time zone string, extract a number from that string.
613 * Check that the number is within a specified range; if it is not, return
615 * Otherwise, return a pointer to the first character not part of the number.
618 getnum(const char *strp, int *nump, int min, int max)
623 if (strp == NULL || !is_digit(c = *strp))
628 num = num * 10 + (c - '0');
630 return NULL; /* illegal value */
632 } while (is_digit(c));
634 return NULL; /* illegal value */
640 * Given a pointer into a time zone string, extract a number of seconds,
641 * in hh[:mm[:ss]] form, from the string.
642 * If any error occurs, return NULL.
643 * Otherwise, return a pointer to the first character not part of the number
647 getsecs(const char *strp, int32 *secsp)
652 * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
653 * "M10.4.6/26", which does not conform to Posix, but which specifies the
654 * equivalent of "02:00 on the first Sunday on or after 23 Oct".
656 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
659 *secsp = num * (int32) SECSPERHOUR;
663 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
666 *secsp += num * SECSPERMIN;
670 /* 'SECSPERMIN' allows for leap seconds. */
671 strp = getnum(strp, &num, 0, SECSPERMIN);
681 * Given a pointer into a time zone string, extract an offset, in
682 * [+-]hh[:mm[:ss]] form, from the string.
683 * If any error occurs, return NULL.
684 * Otherwise, return a pointer to the first character not part of the time.
687 getoffset(const char *strp, int32 *offsetp)
696 else if (*strp == '+')
698 strp = getsecs(strp, offsetp);
700 return NULL; /* illegal time */
702 *offsetp = -*offsetp;
707 * Given a pointer into a time zone string, extract a rule in the form
708 * date[/time]. See POSIX section 8 for the format of "date" and "time".
709 * If a valid rule is not found, return NULL.
710 * Otherwise, return a pointer to the first character not part of the rule.
713 getrule(const char *strp, struct rule * rulep)
720 rulep->r_type = JULIAN_DAY;
722 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
724 else if (*strp == 'M')
729 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
731 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
736 strp = getnum(strp, &rulep->r_week, 1, 5);
741 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
743 else if (is_digit(*strp))
748 rulep->r_type = DAY_OF_YEAR;
749 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
752 return NULL; /* invalid format */
761 strp = getoffset(strp, &rulep->r_time);
764 rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
769 * Given a year, a rule, and the offset from UT at the time that rule takes
770 * effect, calculate the year-relative time that rule takes effect.
773 transtime(int year, const struct rule * rulep,
787 leapyear = isleap(year);
788 switch (rulep->r_type)
794 * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
795 * years. In non-leap years, or if the day number is 59 or less,
796 * just add SECSPERDAY times the day number-1 to the time of
797 * January 1, midnight, to get the day.
799 value = (rulep->r_day - 1) * SECSPERDAY;
800 if (leapyear && rulep->r_day >= 60)
807 * n - day of year. Just add SECSPERDAY times the day number to
808 * the time of January 1, midnight, to get the day.
810 value = rulep->r_day * SECSPERDAY;
813 case MONTH_NTH_DAY_OF_WEEK:
816 * Mm.n.d - nth "dth day" of month m.
820 * Use Zeller's Congruence to get day-of-week of first day of
823 m1 = (rulep->r_mon + 9) % 12 + 1;
824 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
827 dow = ((26 * m1 - 2) / 10 +
828 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
833 * "dow" is the day-of-week of the first day of the month. Get the
834 * day-of-month (zero-origin) of the first "dow" day of the month.
836 d = rulep->r_day - dow;
839 for (i = 1; i < rulep->r_week; ++i)
841 if (d + DAYSPERWEEK >=
842 mon_lengths[(int) leapyear][rulep->r_mon - 1])
848 * "d" is the day-of-month (zero-origin) of the day we want.
850 value = d * SECSPERDAY;
851 for (i = 0; i < rulep->r_mon - 1; ++i)
852 value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
857 * "value" is the year-relative time of 00:00:00 UT on the day in
858 * question. To get the year-relative time of the specified local time on
859 * that day, add the transition time and the current offset from UT.
861 return value + rulep->r_time + offset;
865 * Given a POSIX section 8-style TZ string, fill in the rule tables as
867 * Returns true on success, false on failure.
870 tzparse(const char *name, struct state * sp, bool lastditch)
873 const char *dstname = NULL;
886 * This is intentionally somewhat different from the IANA code. We do
887 * not want to invoke tzload() in the lastditch case: we can't assume
888 * pg_open_tzfile() is sane yet, and we don't care about leap seconds
891 stdlen = strlen(name); /* length of standard zone name */
893 if (stdlen >= sizeof sp->chars)
894 stdlen = (sizeof sp->chars) - 1;
895 charcnt = stdlen + 1;
897 sp->goback = sp->goahead = false; /* simulate failed tzload() */
906 name = getqzname(name, '>');
909 stdlen = name - stdname;
914 name = getzname(name);
915 stdlen = name - stdname;
917 if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
919 name = getoffset(name, &stdoffset);
922 charcnt = stdlen + 1;
923 if (sizeof sp->chars < charcnt)
925 load_ok = tzload(TZDEFRULES, NULL, sp, false) == 0;
928 sp->leapcnt = 0; /* so, we're off a little */
934 name = getqzname(name, '>');
937 dstlen = name - dstname;
943 name = getzname(name);
944 dstlen = name - dstname; /* length of DST zone name */
948 charcnt += dstlen + 1;
949 if (sizeof sp->chars < charcnt)
951 if (*name != '\0' && *name != ',' && *name != ';')
953 name = getoffset(name, &dstoffset);
958 dstoffset = stdoffset - SECSPERHOUR;
959 if (*name == '\0' && !load_ok)
960 name = TZDEFRULESTRING;
961 if (*name == ',' || *name == ';')
971 if ((name = getrule(name, &start)) == NULL)
975 if ((name = getrule(name, &end)) == NULL)
979 sp->typecnt = 2; /* standard time and DST */
982 * Two transitions per year, from EPOCH_YEAR forward.
984 init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
985 init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
989 yearlim = EPOCH_YEAR + YEARSPERREPEAT;
990 for (year = EPOCH_YEAR; year < yearlim; year++)
993 starttime = transtime(year, &start, stdoffset),
994 endtime = transtime(year, &end, dstoffset);
996 yearsecs = (year_lengths[isleap(year)]
998 bool reversed = endtime < starttime;
1002 int32 swap = starttime;
1004 starttime = endtime;
1008 || (starttime < endtime
1009 && (endtime - starttime
1011 + (stdoffset - dstoffset)))))
1013 if (TZ_MAX_TIMES - 2 < timecnt)
1015 yearlim = year + YEARSPERREPEAT + 1;
1016 sp->ats[timecnt] = janfirst;
1017 if (increment_overflow_time
1018 (&sp->ats[timecnt], starttime))
1020 sp->types[timecnt++] = reversed;
1021 sp->ats[timecnt] = janfirst;
1022 if (increment_overflow_time
1023 (&sp->ats[timecnt], endtime))
1025 sp->types[timecnt++] = !reversed;
1027 if (increment_overflow_time(&janfirst, yearsecs))
1030 sp->timecnt = timecnt;
1032 sp->typecnt = 1; /* Perpetual DST. */
1036 int32 theirstdoffset;
1037 int32 theirdstoffset;
1047 * Initial values of theirstdoffset and theirdstoffset.
1050 for (i = 0; i < sp->timecnt; ++i)
1053 if (!sp->ttis[j].tt_isdst)
1056 -sp->ttis[j].tt_gmtoff;
1061 for (i = 0; i < sp->timecnt; ++i)
1064 if (sp->ttis[j].tt_isdst)
1067 -sp->ttis[j].tt_gmtoff;
1073 * Initially we're assumed to be in standard time.
1076 theiroffset = theirstdoffset;
1079 * Now juggle transition times and types tracking offsets as you
1082 for (i = 0; i < sp->timecnt; ++i)
1085 sp->types[i] = sp->ttis[j].tt_isdst;
1086 if (sp->ttis[j].tt_ttisgmt)
1088 /* No adjustment to transition time */
1093 * If summer time is in effect, and the transition time
1094 * was not specified as standard time, add the summer time
1095 * offset to the transition time; otherwise, add the
1096 * standard time offset to the transition time.
1100 * Transitions from DST to DDST will effectively disappear
1101 * since POSIX provides for only one DST offset.
1103 if (isdst && !sp->ttis[j].tt_ttisstd)
1105 sp->ats[i] += dstoffset -
1110 sp->ats[i] += stdoffset -
1114 theiroffset = -sp->ttis[j].tt_gmtoff;
1115 if (sp->ttis[j].tt_isdst)
1116 theirdstoffset = theiroffset;
1118 theirstdoffset = theiroffset;
1122 * Finally, fill in ttis.
1124 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1125 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1127 sp->defaulttype = 0;
1133 sp->typecnt = 1; /* only standard time */
1135 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1136 sp->defaulttype = 0;
1138 sp->charcnt = charcnt;
1140 memcpy(cp, stdname, stdlen);
1145 memcpy(cp, dstname, dstlen);
1146 *(cp + dstlen) = '\0';
1152 gmtload(struct state * sp)
1154 if (tzload(gmt, NULL, sp, true) != 0)
1155 tzparse(gmt, sp, true);
1160 * The easy way to behave "as if no library function calls" localtime
1161 * is to not call it, so we drop its guts into "localsub", which can be
1162 * freely called. (And no, the PANS doesn't require the above behavior,
1163 * but it *is* desirable.)
1165 static struct pg_tm *
1166 localsub(struct state const * sp, pg_time_t const * timep,
1169 const struct ttinfo *ttisp;
1171 struct pg_tm *result;
1172 const pg_time_t t = *timep;
1175 return gmtsub(timep, 0, tmp);
1176 if ((sp->goback && t < sp->ats[0]) ||
1177 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1184 seconds = sp->ats[0] - t;
1186 seconds = t - sp->ats[sp->timecnt - 1];
1188 years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1189 seconds = years * AVGSECSPERYEAR;
1194 if (newt < sp->ats[0] ||
1195 newt > sp->ats[sp->timecnt - 1])
1196 return NULL; /* "cannot happen" */
1197 result = localsub(sp, &newt, tmp);
1202 newy = result->tm_year;
1207 if (!(INT_MIN <= newy && newy <= INT_MAX))
1209 result->tm_year = newy;
1213 if (sp->timecnt == 0 || t < sp->ats[0])
1215 i = sp->defaulttype;
1220 int hi = sp->timecnt;
1224 int mid = (lo + hi) >> 1;
1226 if (t < sp->ats[mid])
1231 i = (int) sp->types[lo - 1];
1233 ttisp = &sp->ttis[i];
1235 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1238 result->tm_isdst = ttisp->tt_isdst;
1239 result->tm_zone = (char *) &sp->chars[ttisp->tt_abbrind];
1246 pg_localtime(const pg_time_t *timep, const pg_tz *tz)
1248 return localsub(&tz->state, timep, &tm);
1253 * gmtsub is to gmtime as localsub is to localtime.
1255 * Except we have a private "struct state" for GMT, so no sp is passed in.
1257 static struct pg_tm *
1258 gmtsub(pg_time_t const * timep, int32 offset, struct pg_tm * tmp)
1260 struct pg_tm *result;
1262 /* GMT timezone state data is kept here */
1263 static struct state gmtmem;
1264 static bool gmt_is_set = false;
1265 #define gmtptr (&gmtmem)
1272 result = timesub(timep, offset, gmtptr, tmp);
1275 * Could get fancy here and deliver something such as "UT+xxxx" or
1276 * "UT-xxxx" if offset is non-zero, but this is no time for a treasure
1280 tmp->tm_zone = wildabbr;
1282 tmp->tm_zone = gmtptr->chars;
1288 pg_gmtime(const pg_time_t *timep)
1290 return gmtsub(timep, 0, &tm);
1294 * Return the number of leap years through the end of the given year
1295 * where, to make the math easy, the answer for year zero is defined as zero.
1298 leaps_thru_end_of(const int y)
1300 return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1301 -(leaps_thru_end_of(-(y + 1)) + 1);
1304 static struct pg_tm *
1305 timesub(const pg_time_t *timep, int32 offset,
1306 const struct state * sp, struct pg_tm * tmp)
1308 const struct lsinfo *lp;
1310 int idays; /* unsigned would be so 2003 */
1320 i = (sp == NULL) ? 0 : sp->leapcnt;
1324 if (*timep >= lp->ls_trans)
1326 if (*timep == lp->ls_trans)
1328 hit = ((i == 0 && lp->ls_corr > 0) ||
1329 lp->ls_corr > sp->lsis[i - 1].ls_corr);
1332 sp->lsis[i].ls_trans ==
1333 sp->lsis[i - 1].ls_trans + 1 &&
1334 sp->lsis[i].ls_corr ==
1335 sp->lsis[i - 1].ls_corr + 1)
1346 tdays = *timep / SECSPERDAY;
1347 rem = *timep % SECSPERDAY;
1348 while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1355 tdelta = tdays / DAYSPERLYEAR;
1356 if (!((!TYPE_SIGNED(pg_time_t) ||INT_MIN <= tdelta)
1357 && tdelta <= INT_MAX))
1361 idelta = (tdays < 0) ? -1 : 1;
1363 if (increment_overflow(&newy, idelta))
1365 leapdays = leaps_thru_end_of(newy - 1) -
1366 leaps_thru_end_of(y - 1);
1367 tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1373 * Given the range, we can now fearlessly cast...
1376 rem += offset - corr;
1382 while (rem >= SECSPERDAY)
1389 if (increment_overflow(&y, -1))
1391 idays += year_lengths[isleap(y)];
1393 while (idays >= year_lengths[isleap(y)])
1395 idays -= year_lengths[isleap(y)];
1396 if (increment_overflow(&y, 1))
1400 if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1402 tmp->tm_yday = idays;
1405 * The "extra" mods below avoid overflow problems.
1407 tmp->tm_wday = EPOCH_WDAY +
1408 ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1409 (DAYSPERNYEAR % DAYSPERWEEK) +
1410 leaps_thru_end_of(y - 1) -
1411 leaps_thru_end_of(EPOCH_YEAR - 1) +
1413 tmp->tm_wday %= DAYSPERWEEK;
1414 if (tmp->tm_wday < 0)
1415 tmp->tm_wday += DAYSPERWEEK;
1416 tmp->tm_hour = (int) (rem / SECSPERHOUR);
1418 tmp->tm_min = (int) (rem / SECSPERMIN);
1421 * A positive leap second requires a special representation. This uses
1422 * "... ??:59:60" et seq.
1424 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1425 ip = mon_lengths[isleap(y)];
1426 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1427 idays -= ip[tmp->tm_mon];
1428 tmp->tm_mday = (int) (idays + 1);
1430 tmp->tm_gmtoff = offset;
1439 * Normalize logic courtesy Paul Eggert.
1443 increment_overflow(int *ip, int j)
1448 * If i >= 0 there can only be overflow if i + j > INT_MAX
1449 * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1450 * If i < 0 there can only be overflow if i + j < INT_MIN
1451 * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1454 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1461 increment_overflow_time(pg_time_t *tp, int32 j)
1465 * 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1466 * except that it does the right thing even if *tp + j would overflow.
1470 ? (TYPE_SIGNED(pg_time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1471 : *tp <= time_t_max - j))
1478 * Find the next DST transition time in the given zone after the given time
1480 * *timep and *tz are input arguments, the other parameters are output values.
1482 * When the function result is 1, *boundary is set to the pg_time_t
1483 * representation of the next DST transition time after *timep,
1484 * *before_gmtoff and *before_isdst are set to the GMT offset and isdst
1485 * state prevailing just before that boundary (in particular, the state
1486 * prevailing at *timep), and *after_gmtoff and *after_isdst are set to
1487 * the state prevailing just after that boundary.
1489 * When the function result is 0, there is no known DST transition
1490 * after *timep, but *before_gmtoff and *before_isdst indicate the GMT
1491 * offset and isdst state prevailing at *timep. (This would occur in
1492 * DST-less time zones, or if a zone has permanently ceased using DST.)
1494 * A function result of -1 indicates failure (this case does not actually
1495 * occur in our current implementation).
1498 pg_next_dst_boundary(const pg_time_t *timep,
1499 long int *before_gmtoff,
1501 pg_time_t *boundary,
1502 long int *after_gmtoff,
1506 const struct state *sp;
1507 const struct ttinfo *ttisp;
1510 const pg_time_t t = *timep;
1513 if (sp->timecnt == 0)
1515 /* non-DST zone, use lowest-numbered standard type */
1517 while (sp->ttis[i].tt_isdst)
1518 if (++i >= sp->typecnt)
1523 ttisp = &sp->ttis[i];
1524 *before_gmtoff = ttisp->tt_gmtoff;
1525 *before_isdst = ttisp->tt_isdst;
1528 if ((sp->goback && t < sp->ats[0]) ||
1529 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1531 /* For values outside the transition table, extrapolate */
1539 seconds = sp->ats[0] - t;
1541 seconds = t - sp->ats[sp->timecnt - 1];
1543 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1546 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1549 seconds *= YEARSPERREPEAT;
1550 seconds *= AVGSECSPERYEAR;
1555 if (newt < sp->ats[0] ||
1556 newt > sp->ats[sp->timecnt - 1])
1557 return -1; /* "cannot happen" */
1559 result = pg_next_dst_boundary(&newt, before_gmtoff,
1566 *boundary -= seconds;
1568 *boundary += seconds;
1572 if (t >= sp->ats[sp->timecnt - 1])
1574 /* No known transition > t, so use last known segment's type */
1575 i = sp->types[sp->timecnt - 1];
1576 ttisp = &sp->ttis[i];
1577 *before_gmtoff = ttisp->tt_gmtoff;
1578 *before_isdst = ttisp->tt_isdst;
1583 /* For "before", use lowest-numbered standard type */
1585 while (sp->ttis[i].tt_isdst)
1586 if (++i >= sp->typecnt)
1591 ttisp = &sp->ttis[i];
1592 *before_gmtoff = ttisp->tt_gmtoff;
1593 *before_isdst = ttisp->tt_isdst;
1594 *boundary = sp->ats[0];
1595 /* And for "after", use the first segment's type */
1597 ttisp = &sp->ttis[i];
1598 *after_gmtoff = ttisp->tt_gmtoff;
1599 *after_isdst = ttisp->tt_isdst;
1602 /* Else search to find the boundary following t */
1605 int hi = sp->timecnt - 1;
1609 int mid = (lo + hi) >> 1;
1611 if (t < sp->ats[mid])
1618 j = sp->types[i - 1];
1619 ttisp = &sp->ttis[j];
1620 *before_gmtoff = ttisp->tt_gmtoff;
1621 *before_isdst = ttisp->tt_isdst;
1622 *boundary = sp->ats[i];
1624 ttisp = &sp->ttis[j];
1625 *after_gmtoff = ttisp->tt_gmtoff;
1626 *after_isdst = ttisp->tt_isdst;
1631 * Identify a timezone abbreviation's meaning in the given zone
1633 * Determine the GMT offset and DST flag associated with the abbreviation.
1634 * This is generally used only when the abbreviation has actually changed
1635 * meaning over time; therefore, we also take a UTC cutoff time, and return
1636 * the meaning in use at or most recently before that time, or the meaning
1637 * in first use after that time if the abbrev was never used before that.
1639 * On success, returns true and sets *gmtoff and *isdst. If the abbreviation
1640 * was never used at all in this zone, returns false.
1642 * Note: abbrev is matched case-sensitively; it should be all-upper-case.
1645 pg_interpret_timezone_abbrev(const char *abbrev,
1646 const pg_time_t *timep,
1651 const struct state *sp;
1653 const struct ttinfo *ttisp;
1657 const pg_time_t t = *timep;
1662 * Locate the abbreviation in the zone's abbreviation list. We assume
1663 * there are not duplicates in the list.
1667 while (abbrind < sp->charcnt)
1669 if (strcmp(abbrev, abbrs + abbrind) == 0)
1671 while (abbrs[abbrind] != '\0')
1675 if (abbrind >= sp->charcnt)
1676 return false; /* not there! */
1679 * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1680 * (goback/goahead zones). Finding the newest or oldest meaning of the
1681 * abbreviation should get us what we want, since extrapolation would just
1682 * be repeating the newest or oldest meanings.
1684 * Use binary search to locate the first transition > cutoff time.
1688 int hi = sp->timecnt;
1692 int mid = (lo + hi) >> 1;
1694 if (t < sp->ats[mid])
1703 * Scan backwards to find the latest interval using the given abbrev
1704 * before the cutoff time.
1706 for (i = cutoff - 1; i >= 0; i--)
1708 ttisp = &sp->ttis[sp->types[i]];
1709 if (ttisp->tt_abbrind == abbrind)
1711 *gmtoff = ttisp->tt_gmtoff;
1712 *isdst = ttisp->tt_isdst;
1718 * Not there, so scan forwards to find the first one after.
1720 for (i = cutoff; i < sp->timecnt; i++)
1722 ttisp = &sp->ttis[sp->types[i]];
1723 if (ttisp->tt_abbrind == abbrind)
1725 *gmtoff = ttisp->tt_gmtoff;
1726 *isdst = ttisp->tt_isdst;
1731 return false; /* hm, not actually used in any interval? */
1735 * If the given timezone uses only one GMT offset, store that offset
1736 * into *gmtoff and return true, else return false.
1739 pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
1742 * The zone could have more than one ttinfo, if it's historically used
1743 * more than one abbreviation. We return true as long as they all have
1746 const struct state *sp;
1750 for (i = 1; i < sp->typecnt; i++)
1752 if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
1755 *gmtoff = sp->ttis[0].tt_gmtoff;
1760 * Return the name of the current timezone
1763 pg_get_timezone_name(pg_tz *tz)
1771 * Check whether timezone is acceptable.
1773 * What we are doing here is checking for leap-second-aware timekeeping.
1774 * We need to reject such TZ settings because they'll wreak havoc with our
1775 * date/time arithmetic.
1778 pg_tz_acceptable(pg_tz *tz)
1784 * To detect leap-second timekeeping, run pg_localtime for what should be
1785 * GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
1786 * other result has to be due to leap seconds.
1788 time2000 = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;
1789 tt = pg_localtime(&time2000, tz);
1790 if (!tt || tt->tm_sec != 0)