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 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 *lsp = malloc(sizeof *lsp);
545 int err = tzloadbody(name, canonname, sp, doextend, lsp);
553 typesequiv(const struct state * sp, int a, int b)
558 a < 0 || a >= sp->typecnt ||
559 b < 0 || b >= sp->typecnt)
563 const struct ttinfo *ap = &sp->ttis[a];
564 const struct ttinfo *bp = &sp->ttis[b];
566 result = ap->tt_gmtoff == bp->tt_gmtoff &&
567 ap->tt_isdst == bp->tt_isdst &&
568 ap->tt_ttisstd == bp->tt_ttisstd &&
569 ap->tt_ttisgmt == bp->tt_ttisgmt &&
570 strcmp(&sp->chars[ap->tt_abbrind],
571 &sp->chars[bp->tt_abbrind]) == 0;
576 static const int mon_lengths[2][MONSPERYEAR] = {
577 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
578 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
581 static const int year_lengths[2] = {
582 DAYSPERNYEAR, DAYSPERLYEAR
586 * Given a pointer into a time zone string, scan until a character that is not
587 * a valid character in a zone name is found. Return a pointer to that
591 getzname(const char *strp)
595 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
602 * Given a pointer into an extended time zone string, scan until the ending
603 * delimiter of the zone name is located. Return a pointer to the delimiter.
605 * As with getzname above, the legal character set is actually quite
606 * restricted, with other characters producing undefined results.
607 * We don't do any checking here; checking is done later in common-case code.
610 getqzname(const char *strp, int delim)
614 while ((c = *strp) != '\0' && c != delim)
620 * Given a pointer into a time zone string, extract a number from that string.
621 * Check that the number is within a specified range; if it is not, return
623 * Otherwise, return a pointer to the first character not part of the number.
626 getnum(const char *strp, int *nump, int min, int max)
631 if (strp == NULL || !is_digit(c = *strp))
636 num = num * 10 + (c - '0');
638 return NULL; /* illegal value */
640 } while (is_digit(c));
642 return NULL; /* illegal value */
648 * Given a pointer into a time zone string, extract a number of seconds,
649 * in hh[:mm[:ss]] form, from the string.
650 * If any error occurs, return NULL.
651 * Otherwise, return a pointer to the first character not part of the number
655 getsecs(const char *strp, int32 *secsp)
660 * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
661 * "M10.4.6/26", which does not conform to Posix, but which specifies the
662 * equivalent of "02:00 on the first Sunday on or after 23 Oct".
664 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
667 *secsp = num * (int32) SECSPERHOUR;
671 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
674 *secsp += num * SECSPERMIN;
678 /* 'SECSPERMIN' allows for leap seconds. */
679 strp = getnum(strp, &num, 0, SECSPERMIN);
689 * Given a pointer into a time zone string, extract an offset, in
690 * [+-]hh[:mm[:ss]] form, from the string.
691 * If any error occurs, return NULL.
692 * Otherwise, return a pointer to the first character not part of the time.
695 getoffset(const char *strp, int32 *offsetp)
704 else if (*strp == '+')
706 strp = getsecs(strp, offsetp);
708 return NULL; /* illegal time */
710 *offsetp = -*offsetp;
715 * Given a pointer into a time zone string, extract a rule in the form
716 * date[/time]. See POSIX section 8 for the format of "date" and "time".
717 * If a valid rule is not found, return NULL.
718 * Otherwise, return a pointer to the first character not part of the rule.
721 getrule(const char *strp, struct rule * rulep)
728 rulep->r_type = JULIAN_DAY;
730 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
732 else if (*strp == 'M')
737 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
739 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
744 strp = getnum(strp, &rulep->r_week, 1, 5);
749 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
751 else if (is_digit(*strp))
756 rulep->r_type = DAY_OF_YEAR;
757 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
760 return NULL; /* invalid format */
769 strp = getoffset(strp, &rulep->r_time);
772 rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
777 * Given a year, a rule, and the offset from UT at the time that rule takes
778 * effect, calculate the year-relative time that rule takes effect.
781 transtime(int year, const struct rule * rulep,
795 leapyear = isleap(year);
796 switch (rulep->r_type)
802 * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
803 * years. In non-leap years, or if the day number is 59 or less,
804 * just add SECSPERDAY times the day number-1 to the time of
805 * January 1, midnight, to get the day.
807 value = (rulep->r_day - 1) * SECSPERDAY;
808 if (leapyear && rulep->r_day >= 60)
815 * n - day of year. Just add SECSPERDAY times the day number to
816 * the time of January 1, midnight, to get the day.
818 value = rulep->r_day * SECSPERDAY;
821 case MONTH_NTH_DAY_OF_WEEK:
824 * Mm.n.d - nth "dth day" of month m.
828 * Use Zeller's Congruence to get day-of-week of first day of
831 m1 = (rulep->r_mon + 9) % 12 + 1;
832 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
835 dow = ((26 * m1 - 2) / 10 +
836 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
841 * "dow" is the day-of-week of the first day of the month. Get the
842 * day-of-month (zero-origin) of the first "dow" day of the month.
844 d = rulep->r_day - dow;
847 for (i = 1; i < rulep->r_week; ++i)
849 if (d + DAYSPERWEEK >=
850 mon_lengths[(int) leapyear][rulep->r_mon - 1])
856 * "d" is the day-of-month (zero-origin) of the day we want.
858 value = d * SECSPERDAY;
859 for (i = 0; i < rulep->r_mon - 1; ++i)
860 value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
865 * "value" is the year-relative time of 00:00:00 UT on the day in
866 * question. To get the year-relative time of the specified local time on
867 * that day, add the transition time and the current offset from UT.
869 return value + rulep->r_time + offset;
873 * Given a POSIX section 8-style TZ string, fill in the rule tables as
875 * Returns true on success, false on failure.
878 tzparse(const char *name, struct state * sp, bool lastditch)
881 const char *dstname = NULL;
894 * This is intentionally somewhat different from the IANA code. We do
895 * not want to invoke tzload() in the lastditch case: we can't assume
896 * pg_open_tzfile() is sane yet, and we don't care about leap seconds
899 stdlen = strlen(name); /* length of standard zone name */
901 if (stdlen >= sizeof sp->chars)
902 stdlen = (sizeof sp->chars) - 1;
903 charcnt = stdlen + 1;
905 sp->goback = sp->goahead = false; /* simulate failed tzload() */
914 name = getqzname(name, '>');
917 stdlen = name - stdname;
922 name = getzname(name);
923 stdlen = name - stdname;
925 if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
927 name = getoffset(name, &stdoffset);
930 charcnt = stdlen + 1;
931 if (sizeof sp->chars < charcnt)
933 load_ok = tzload(TZDEFRULES, NULL, sp, false) == 0;
936 sp->leapcnt = 0; /* so, we're off a little */
942 name = getqzname(name, '>');
945 dstlen = name - dstname;
951 name = getzname(name);
952 dstlen = name - dstname; /* length of DST zone name */
956 charcnt += dstlen + 1;
957 if (sizeof sp->chars < charcnt)
959 if (*name != '\0' && *name != ',' && *name != ';')
961 name = getoffset(name, &dstoffset);
966 dstoffset = stdoffset - SECSPERHOUR;
967 if (*name == '\0' && !load_ok)
968 name = TZDEFRULESTRING;
969 if (*name == ',' || *name == ';')
979 if ((name = getrule(name, &start)) == NULL)
983 if ((name = getrule(name, &end)) == NULL)
987 sp->typecnt = 2; /* standard time and DST */
990 * Two transitions per year, from EPOCH_YEAR forward.
992 init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
993 init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
997 yearlim = EPOCH_YEAR + YEARSPERREPEAT;
998 for (year = EPOCH_YEAR; year < yearlim; year++)
1001 starttime = transtime(year, &start, stdoffset),
1002 endtime = transtime(year, &end, dstoffset);
1004 yearsecs = (year_lengths[isleap(year)]
1006 bool reversed = endtime < starttime;
1010 int32 swap = starttime;
1012 starttime = endtime;
1016 || (starttime < endtime
1017 && (endtime - starttime
1019 + (stdoffset - dstoffset)))))
1021 if (TZ_MAX_TIMES - 2 < timecnt)
1023 yearlim = year + YEARSPERREPEAT + 1;
1024 sp->ats[timecnt] = janfirst;
1025 if (increment_overflow_time
1026 (&sp->ats[timecnt], starttime))
1028 sp->types[timecnt++] = reversed;
1029 sp->ats[timecnt] = janfirst;
1030 if (increment_overflow_time
1031 (&sp->ats[timecnt], endtime))
1033 sp->types[timecnt++] = !reversed;
1035 if (increment_overflow_time(&janfirst, yearsecs))
1038 sp->timecnt = timecnt;
1040 sp->typecnt = 1; /* Perpetual DST. */
1044 int32 theirstdoffset;
1045 int32 theirdstoffset;
1055 * Initial values of theirstdoffset and theirdstoffset.
1058 for (i = 0; i < sp->timecnt; ++i)
1061 if (!sp->ttis[j].tt_isdst)
1064 -sp->ttis[j].tt_gmtoff;
1069 for (i = 0; i < sp->timecnt; ++i)
1072 if (sp->ttis[j].tt_isdst)
1075 -sp->ttis[j].tt_gmtoff;
1081 * Initially we're assumed to be in standard time.
1084 theiroffset = theirstdoffset;
1087 * Now juggle transition times and types tracking offsets as you
1090 for (i = 0; i < sp->timecnt; ++i)
1093 sp->types[i] = sp->ttis[j].tt_isdst;
1094 if (sp->ttis[j].tt_ttisgmt)
1096 /* No adjustment to transition time */
1101 * If summer time is in effect, and the transition time
1102 * was not specified as standard time, add the summer time
1103 * offset to the transition time; otherwise, add the
1104 * standard time offset to the transition time.
1108 * Transitions from DST to DDST will effectively disappear
1109 * since POSIX provides for only one DST offset.
1111 if (isdst && !sp->ttis[j].tt_ttisstd)
1113 sp->ats[i] += dstoffset -
1118 sp->ats[i] += stdoffset -
1122 theiroffset = -sp->ttis[j].tt_gmtoff;
1123 if (sp->ttis[j].tt_isdst)
1124 theirdstoffset = theiroffset;
1126 theirstdoffset = theiroffset;
1130 * Finally, fill in ttis.
1132 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1133 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1135 sp->defaulttype = 0;
1141 sp->typecnt = 1; /* only standard time */
1143 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1144 sp->defaulttype = 0;
1146 sp->charcnt = charcnt;
1148 memcpy(cp, stdname, stdlen);
1153 memcpy(cp, dstname, dstlen);
1154 *(cp + dstlen) = '\0';
1160 gmtload(struct state * sp)
1162 if (tzload(gmt, NULL, sp, true) != 0)
1163 tzparse(gmt, sp, true);
1168 * The easy way to behave "as if no library function calls" localtime
1169 * is to not call it, so we drop its guts into "localsub", which can be
1170 * freely called. (And no, the PANS doesn't require the above behavior,
1171 * but it *is* desirable.)
1173 static struct pg_tm *
1174 localsub(struct state const * sp, pg_time_t const * timep,
1177 const struct ttinfo *ttisp;
1179 struct pg_tm *result;
1180 const pg_time_t t = *timep;
1183 return gmtsub(timep, 0, tmp);
1184 if ((sp->goback && t < sp->ats[0]) ||
1185 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1192 seconds = sp->ats[0] - t;
1194 seconds = t - sp->ats[sp->timecnt - 1];
1196 years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1197 seconds = years * AVGSECSPERYEAR;
1202 if (newt < sp->ats[0] ||
1203 newt > sp->ats[sp->timecnt - 1])
1204 return NULL; /* "cannot happen" */
1205 result = localsub(sp, &newt, tmp);
1210 newy = result->tm_year;
1215 if (!(INT_MIN <= newy && newy <= INT_MAX))
1217 result->tm_year = newy;
1221 if (sp->timecnt == 0 || t < sp->ats[0])
1223 i = sp->defaulttype;
1228 int hi = sp->timecnt;
1232 int mid = (lo + hi) >> 1;
1234 if (t < sp->ats[mid])
1239 i = (int) sp->types[lo - 1];
1241 ttisp = &sp->ttis[i];
1243 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1246 result->tm_isdst = ttisp->tt_isdst;
1247 result->tm_zone = (char *) &sp->chars[ttisp->tt_abbrind];
1254 pg_localtime(const pg_time_t *timep, const pg_tz *tz)
1256 return localsub(&tz->state, timep, &tm);
1261 * gmtsub is to gmtime as localsub is to localtime.
1263 * Except we have a private "struct state" for GMT, so no sp is passed in.
1265 static struct pg_tm *
1266 gmtsub(pg_time_t const * timep, int32 offset, struct pg_tm * tmp)
1268 struct pg_tm *result;
1270 /* GMT timezone state data is kept here */
1271 static struct state gmtmem;
1272 static bool gmt_is_set = false;
1273 #define gmtptr (&gmtmem)
1280 result = timesub(timep, offset, gmtptr, tmp);
1283 * Could get fancy here and deliver something such as "+xx" or "-xx" if
1284 * offset is non-zero, but this is no time for a treasure hunt.
1287 tmp->tm_zone = wildabbr;
1289 tmp->tm_zone = gmtptr->chars;
1295 pg_gmtime(const pg_time_t *timep)
1297 return gmtsub(timep, 0, &tm);
1301 * Return the number of leap years through the end of the given year
1302 * where, to make the math easy, the answer for year zero is defined as zero.
1305 leaps_thru_end_of(const int y)
1307 return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1308 -(leaps_thru_end_of(-(y + 1)) + 1);
1311 static struct pg_tm *
1312 timesub(const pg_time_t *timep, int32 offset,
1313 const struct state * sp, struct pg_tm * tmp)
1315 const struct lsinfo *lp;
1317 int idays; /* unsigned would be so 2003 */
1327 i = (sp == NULL) ? 0 : sp->leapcnt;
1331 if (*timep >= lp->ls_trans)
1333 if (*timep == lp->ls_trans)
1335 hit = ((i == 0 && lp->ls_corr > 0) ||
1336 lp->ls_corr > sp->lsis[i - 1].ls_corr);
1339 sp->lsis[i].ls_trans ==
1340 sp->lsis[i - 1].ls_trans + 1 &&
1341 sp->lsis[i].ls_corr ==
1342 sp->lsis[i - 1].ls_corr + 1)
1353 tdays = *timep / SECSPERDAY;
1354 rem = *timep % SECSPERDAY;
1355 while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1362 tdelta = tdays / DAYSPERLYEAR;
1363 if (!((!TYPE_SIGNED(pg_time_t) ||INT_MIN <= tdelta)
1364 && tdelta <= INT_MAX))
1368 idelta = (tdays < 0) ? -1 : 1;
1370 if (increment_overflow(&newy, idelta))
1372 leapdays = leaps_thru_end_of(newy - 1) -
1373 leaps_thru_end_of(y - 1);
1374 tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1380 * Given the range, we can now fearlessly cast...
1383 rem += offset - corr;
1389 while (rem >= SECSPERDAY)
1396 if (increment_overflow(&y, -1))
1398 idays += year_lengths[isleap(y)];
1400 while (idays >= year_lengths[isleap(y)])
1402 idays -= year_lengths[isleap(y)];
1403 if (increment_overflow(&y, 1))
1407 if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1409 tmp->tm_yday = idays;
1412 * The "extra" mods below avoid overflow problems.
1414 tmp->tm_wday = EPOCH_WDAY +
1415 ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1416 (DAYSPERNYEAR % DAYSPERWEEK) +
1417 leaps_thru_end_of(y - 1) -
1418 leaps_thru_end_of(EPOCH_YEAR - 1) +
1420 tmp->tm_wday %= DAYSPERWEEK;
1421 if (tmp->tm_wday < 0)
1422 tmp->tm_wday += DAYSPERWEEK;
1423 tmp->tm_hour = (int) (rem / SECSPERHOUR);
1425 tmp->tm_min = (int) (rem / SECSPERMIN);
1428 * A positive leap second requires a special representation. This uses
1429 * "... ??:59:60" et seq.
1431 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1432 ip = mon_lengths[isleap(y)];
1433 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1434 idays -= ip[tmp->tm_mon];
1435 tmp->tm_mday = (int) (idays + 1);
1437 tmp->tm_gmtoff = offset;
1446 * Normalize logic courtesy Paul Eggert.
1450 increment_overflow(int *ip, int j)
1455 * If i >= 0 there can only be overflow if i + j > INT_MAX
1456 * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1457 * If i < 0 there can only be overflow if i + j < INT_MIN
1458 * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1461 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1468 increment_overflow_time(pg_time_t *tp, int32 j)
1472 * 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1473 * except that it does the right thing even if *tp + j would overflow.
1477 ? (TYPE_SIGNED(pg_time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1478 : *tp <= time_t_max - j))
1485 * Find the next DST transition time in the given zone after the given time
1487 * *timep and *tz are input arguments, the other parameters are output values.
1489 * When the function result is 1, *boundary is set to the pg_time_t
1490 * representation of the next DST transition time after *timep,
1491 * *before_gmtoff and *before_isdst are set to the GMT offset and isdst
1492 * state prevailing just before that boundary (in particular, the state
1493 * prevailing at *timep), and *after_gmtoff and *after_isdst are set to
1494 * the state prevailing just after that boundary.
1496 * When the function result is 0, there is no known DST transition
1497 * after *timep, but *before_gmtoff and *before_isdst indicate the GMT
1498 * offset and isdst state prevailing at *timep. (This would occur in
1499 * DST-less time zones, or if a zone has permanently ceased using DST.)
1501 * A function result of -1 indicates failure (this case does not actually
1502 * occur in our current implementation).
1505 pg_next_dst_boundary(const pg_time_t *timep,
1506 long int *before_gmtoff,
1508 pg_time_t *boundary,
1509 long int *after_gmtoff,
1513 const struct state *sp;
1514 const struct ttinfo *ttisp;
1517 const pg_time_t t = *timep;
1520 if (sp->timecnt == 0)
1522 /* non-DST zone, use lowest-numbered standard type */
1524 while (sp->ttis[i].tt_isdst)
1525 if (++i >= sp->typecnt)
1530 ttisp = &sp->ttis[i];
1531 *before_gmtoff = ttisp->tt_gmtoff;
1532 *before_isdst = ttisp->tt_isdst;
1535 if ((sp->goback && t < sp->ats[0]) ||
1536 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1538 /* For values outside the transition table, extrapolate */
1546 seconds = sp->ats[0] - t;
1548 seconds = t - sp->ats[sp->timecnt - 1];
1550 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1553 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1556 seconds *= YEARSPERREPEAT;
1557 seconds *= AVGSECSPERYEAR;
1562 if (newt < sp->ats[0] ||
1563 newt > sp->ats[sp->timecnt - 1])
1564 return -1; /* "cannot happen" */
1566 result = pg_next_dst_boundary(&newt, before_gmtoff,
1573 *boundary -= seconds;
1575 *boundary += seconds;
1579 if (t >= sp->ats[sp->timecnt - 1])
1581 /* No known transition > t, so use last known segment's type */
1582 i = sp->types[sp->timecnt - 1];
1583 ttisp = &sp->ttis[i];
1584 *before_gmtoff = ttisp->tt_gmtoff;
1585 *before_isdst = ttisp->tt_isdst;
1590 /* For "before", use lowest-numbered standard type */
1592 while (sp->ttis[i].tt_isdst)
1593 if (++i >= sp->typecnt)
1598 ttisp = &sp->ttis[i];
1599 *before_gmtoff = ttisp->tt_gmtoff;
1600 *before_isdst = ttisp->tt_isdst;
1601 *boundary = sp->ats[0];
1602 /* And for "after", use the first segment's type */
1604 ttisp = &sp->ttis[i];
1605 *after_gmtoff = ttisp->tt_gmtoff;
1606 *after_isdst = ttisp->tt_isdst;
1609 /* Else search to find the boundary following t */
1612 int hi = sp->timecnt - 1;
1616 int mid = (lo + hi) >> 1;
1618 if (t < sp->ats[mid])
1625 j = sp->types[i - 1];
1626 ttisp = &sp->ttis[j];
1627 *before_gmtoff = ttisp->tt_gmtoff;
1628 *before_isdst = ttisp->tt_isdst;
1629 *boundary = sp->ats[i];
1631 ttisp = &sp->ttis[j];
1632 *after_gmtoff = ttisp->tt_gmtoff;
1633 *after_isdst = ttisp->tt_isdst;
1638 * Identify a timezone abbreviation's meaning in the given zone
1640 * Determine the GMT offset and DST flag associated with the abbreviation.
1641 * This is generally used only when the abbreviation has actually changed
1642 * meaning over time; therefore, we also take a UTC cutoff time, and return
1643 * the meaning in use at or most recently before that time, or the meaning
1644 * in first use after that time if the abbrev was never used before that.
1646 * On success, returns true and sets *gmtoff and *isdst. If the abbreviation
1647 * was never used at all in this zone, returns false.
1649 * Note: abbrev is matched case-sensitively; it should be all-upper-case.
1652 pg_interpret_timezone_abbrev(const char *abbrev,
1653 const pg_time_t *timep,
1658 const struct state *sp;
1660 const struct ttinfo *ttisp;
1664 const pg_time_t t = *timep;
1669 * Locate the abbreviation in the zone's abbreviation list. We assume
1670 * there are not duplicates in the list.
1674 while (abbrind < sp->charcnt)
1676 if (strcmp(abbrev, abbrs + abbrind) == 0)
1678 while (abbrs[abbrind] != '\0')
1682 if (abbrind >= sp->charcnt)
1683 return false; /* not there! */
1686 * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1687 * (goback/goahead zones). Finding the newest or oldest meaning of the
1688 * abbreviation should get us what we want, since extrapolation would just
1689 * be repeating the newest or oldest meanings.
1691 * Use binary search to locate the first transition > cutoff time.
1695 int hi = sp->timecnt;
1699 int mid = (lo + hi) >> 1;
1701 if (t < sp->ats[mid])
1710 * Scan backwards to find the latest interval using the given abbrev
1711 * before the cutoff time.
1713 for (i = cutoff - 1; i >= 0; i--)
1715 ttisp = &sp->ttis[sp->types[i]];
1716 if (ttisp->tt_abbrind == abbrind)
1718 *gmtoff = ttisp->tt_gmtoff;
1719 *isdst = ttisp->tt_isdst;
1725 * Not there, so scan forwards to find the first one after.
1727 for (i = cutoff; i < sp->timecnt; i++)
1729 ttisp = &sp->ttis[sp->types[i]];
1730 if (ttisp->tt_abbrind == abbrind)
1732 *gmtoff = ttisp->tt_gmtoff;
1733 *isdst = ttisp->tt_isdst;
1738 return false; /* hm, not actually used in any interval? */
1742 * If the given timezone uses only one GMT offset, store that offset
1743 * into *gmtoff and return true, else return false.
1746 pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
1749 * The zone could have more than one ttinfo, if it's historically used
1750 * more than one abbreviation. We return true as long as they all have
1753 const struct state *sp;
1757 for (i = 1; i < sp->typecnt; i++)
1759 if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
1762 *gmtoff = sp->ttis[0].tt_gmtoff;
1767 * Return the name of the current timezone
1770 pg_get_timezone_name(pg_tz *tz)
1778 * Check whether timezone is acceptable.
1780 * What we are doing here is checking for leap-second-aware timekeeping.
1781 * We need to reject such TZ settings because they'll wreak havoc with our
1782 * date/time arithmetic.
1785 pg_tz_acceptable(pg_tz *tz)
1791 * To detect leap-second timekeeping, run pg_localtime for what should be
1792 * GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
1793 * other result has to be due to leap seconds.
1795 time2000 = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;
1796 tt = pg_localtime(&time2000, tz);
1797 if (!tt || tt->tm_sec != 0)