PostgreSQL Source Code  git master
localtime.c
Go to the documentation of this file.
1 /*
2  * This file is in the public domain, so clarified as of
3  * 1996-06-05 by Arthur David Olson.
4  *
5  * IDENTIFICATION
6  * src/timezone/localtime.c
7  */
8 
9 /*
10  * Leap second handling from Bradley White.
11  * POSIX-style TZ environment variable handling from Guy Harris.
12  */
13 
14 /* this file needs to build in both frontend and backend contexts */
15 #include "c.h"
16 
17 #include <fcntl.h>
18 
19 #include "datatype/timestamp.h"
20 #include "pgtz.h"
21 
22 #include "private.h"
23 #include "tzfile.h"
24 
25 
26 #ifndef WILDABBR
27 /*
28  * Someone might make incorrect use of a time zone abbreviation:
29  * 1. They might reference tzname[0] before calling tzset (explicitly
30  * or implicitly).
31  * 2. They might reference tzname[1] before calling tzset (explicitly
32  * or implicitly).
33  * 3. They might reference tzname[1] after setting to a time zone
34  * in which Daylight Saving Time is never observed.
35  * 4. They might reference tzname[0] after setting to a time zone
36  * in which Standard Time is never observed.
37  * 5. They might reference tm.TM_ZONE after calling offtime.
38  * What's best to do in the above cases is open to debate;
39  * for now, we just set things up so that in any of the five cases
40  * WILDABBR is used. Another possibility: initialize tzname[0] to the
41  * string "tzname[0] used before set", and similarly for the other cases.
42  * And another: initialize tzname[0] to "ERA", with an explanation in the
43  * manual page of what this "time zone abbreviation" means (doing this so
44  * that tzname[0] has the "normal" length of three characters).
45  */
46 #define WILDABBR " "
47 #endif /* !defined WILDABBR */
48 
49 static const char wildabbr[] = WILDABBR;
50 
51 static const char gmt[] = "GMT";
52 
53 /*
54  * PG: We cache the result of trying to load the TZDEFRULES zone here.
55  * tzdefrules_loaded is 0 if not tried yet, +1 if good, -1 if failed.
56  */
57 static struct state tzdefrules_s;
58 static int tzdefrules_loaded = 0;
59 
60 /*
61  * The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
62  * Default to US rules as of 2017-05-07.
63  * POSIX does not specify the default DST rules;
64  * for historical reasons, US rules are a common default.
65  */
66 #define TZDEFRULESTRING ",M3.2.0,M11.1.0"
67 
68 /* structs ttinfo, lsinfo, state have been moved to pgtz.h */
69 
70 enum r_type
71 {
72  JULIAN_DAY, /* Jn = Julian day */
73  DAY_OF_YEAR, /* n = day of year */
74  MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
75 };
76 
77 struct rule
78 {
79  enum r_type r_type; /* type of rule */
80  int r_day; /* day number of rule */
81  int r_week; /* week number of rule */
82  int r_mon; /* month number of rule */
83  int32 r_time; /* transition time of rule */
84 };
85 
86 /*
87  * Prototypes for static functions.
88  */
89 
90 static struct pg_tm *gmtsub(pg_time_t const *, int32, struct pg_tm *);
91 static bool increment_overflow(int *, int);
93 static struct pg_tm *timesub(pg_time_t const *, int32, struct state const *,
94  struct pg_tm *);
95 static bool typesequiv(struct state const *, int, int);
96 
97 
98 /*
99  * Section 4.12.3 of X3.159-1989 requires that
100  * Except for the strftime function, these functions [asctime,
101  * ctime, gmtime, localtime] return values in one of two static
102  * objects: a broken-down time structure and an array of char.
103  * Thanks to Paul Eggert for noting this.
104  */
105 
106 static struct pg_tm tm;
107 
108 /* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
109 static void
110 init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
111 {
112  s->tt_gmtoff = gmtoff;
113  s->tt_isdst = isdst;
114  s->tt_abbrind = abbrind;
115  s->tt_ttisstd = false;
116  s->tt_ttisgmt = false;
117 }
118 
119 static int32
120 detzcode(const char *codep)
121 {
122  int32 result;
123  int i;
124  int32 one = 1;
125  int32 halfmaxval = one << (32 - 2);
126  int32 maxval = halfmaxval - 1 + halfmaxval;
127  int32 minval = -1 - maxval;
128 
129  result = codep[0] & 0x7f;
130  for (i = 1; i < 4; ++i)
131  result = (result << 8) | (codep[i] & 0xff);
132 
133  if (codep[0] & 0x80)
134  {
135  /*
136  * Do two's-complement negation even on non-two's-complement machines.
137  * If the result would be minval - 1, return minval.
138  */
139  result -= !TWOS_COMPLEMENT(int32) &&result != 0;
140  result += minval;
141  }
142  return result;
143 }
144 
145 static int64
146 detzcode64(const char *codep)
147 {
148  uint64 result;
149  int i;
150  int64 one = 1;
151  int64 halfmaxval = one << (64 - 2);
152  int64 maxval = halfmaxval - 1 + halfmaxval;
153  int64 minval = -TWOS_COMPLEMENT(int64) -maxval;
154 
155  result = codep[0] & 0x7f;
156  for (i = 1; i < 8; ++i)
157  result = (result << 8) | (codep[i] & 0xff);
158 
159  if (codep[0] & 0x80)
160  {
161  /*
162  * Do two's-complement negation even on non-two's-complement machines.
163  * If the result would be minval - 1, return minval.
164  */
165  result -= !TWOS_COMPLEMENT(int64) &&result != 0;
166  result += minval;
167  }
168  return result;
169 }
170 
171 static bool
173 {
175  return 0;
176  return t1 - t0 == SECSPERREPEAT;
177 }
178 
179 /* Input buffer for data read from a compiled tz file. */
181 {
182  /* The first part of the buffer, interpreted as a header. */
183  struct tzhead tzhead;
184 
185  /* The entire buffer. */
186  char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
187  + 4 * TZ_MAX_TIMES];
188 };
189 
190 /* Local storage needed for 'tzloadbody'. */
192 {
193  /* The results of analyzing the file's contents after it is opened. */
195  {
196  /* The input buffer. */
197  union input_buffer u;
198 
199  /* A temporary state used for parsing a TZ string in the file. */
200  struct state st;
201  } u;
202 
203  /* We don't need the "fullname" member */
204 };
205 
206 /* Load tz data from the file named NAME into *SP. Read extended
207  * format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
208  * success, an errno value on failure.
209  * PG: If "canonname" is not NULL, then on success the canonical spelling of
210  * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
211  */
212 static int
213 tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
214  union local_storage *lsp)
215 {
216  int i;
217  int fid;
218  int stored;
219  ssize_t nread;
220  union input_buffer *up = &lsp->u.u;
221  int tzheadsize = sizeof(struct tzhead);
222 
223  sp->goback = sp->goahead = false;
224 
225  if (!name)
226  {
227  name = TZDEFAULT;
228  if (!name)
229  return EINVAL;
230  }
231 
232  if (name[0] == ':')
233  ++name;
234 
235  fid = pg_open_tzfile(name, canonname);
236  if (fid < 0)
237  return ENOENT; /* pg_open_tzfile may not set errno */
238 
239  nread = read(fid, up->buf, sizeof up->buf);
240  if (nread < tzheadsize)
241  {
242  int err = nread < 0 ? errno : EINVAL;
243 
244  close(fid);
245  return err;
246  }
247  if (close(fid) < 0)
248  return errno;
249  for (stored = 4; stored <= 8; stored *= 2)
250  {
251  int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
252  int32 ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
253  int64 prevtr = 0;
254  int32 prevcorr = 0;
259  char const *p = up->buf + tzheadsize;
260 
261  if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
262  && 0 < typecnt && typecnt < TZ_MAX_TYPES
263  && 0 <= timecnt && timecnt < TZ_MAX_TIMES
264  && 0 <= charcnt && charcnt < TZ_MAX_CHARS
265  && (ttisstdcnt == typecnt || ttisstdcnt == 0)
266  && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
267  return EINVAL;
268  if (nread
269  < (tzheadsize /* struct tzhead */
270  + timecnt * stored /* ats */
271  + timecnt /* types */
272  + typecnt * 6 /* ttinfos */
273  + charcnt /* chars */
274  + leapcnt * (stored + 4) /* lsinfos */
275  + ttisstdcnt /* ttisstds */
276  + ttisgmtcnt)) /* ttisgmts */
277  return EINVAL;
278  sp->leapcnt = leapcnt;
279  sp->timecnt = timecnt;
280  sp->typecnt = typecnt;
281  sp->charcnt = charcnt;
282 
283  /*
284  * Read transitions, discarding those out of pg_time_t range. But
285  * pretend the last transition before TIME_T_MIN occurred at
286  * TIME_T_MIN.
287  */
288  timecnt = 0;
289  for (i = 0; i < sp->timecnt; ++i)
290  {
291  int64 at
292  = stored == 4 ? detzcode(p) : detzcode64(p);
293 
294  sp->types[i] = at <= TIME_T_MAX;
295  if (sp->types[i])
296  {
297  pg_time_t attime
298  = ((TYPE_SIGNED(pg_time_t) ? at < TIME_T_MIN : at < 0)
299  ? TIME_T_MIN : at);
300 
301  if (timecnt && attime <= sp->ats[timecnt - 1])
302  {
303  if (attime < sp->ats[timecnt - 1])
304  return EINVAL;
305  sp->types[i - 1] = 0;
306  timecnt--;
307  }
308  sp->ats[timecnt++] = attime;
309  }
310  p += stored;
311  }
312 
313  timecnt = 0;
314  for (i = 0; i < sp->timecnt; ++i)
315  {
316  unsigned char typ = *p++;
317 
318  if (sp->typecnt <= typ)
319  return EINVAL;
320  if (sp->types[i])
321  sp->types[timecnt++] = typ;
322  }
323  sp->timecnt = timecnt;
324  for (i = 0; i < sp->typecnt; ++i)
325  {
326  struct ttinfo *ttisp;
327  unsigned char isdst,
328  abbrind;
329 
330  ttisp = &sp->ttis[i];
331  ttisp->tt_gmtoff = detzcode(p);
332  p += 4;
333  isdst = *p++;
334  if (!(isdst < 2))
335  return EINVAL;
336  ttisp->tt_isdst = isdst;
337  abbrind = *p++;
338  if (!(abbrind < sp->charcnt))
339  return EINVAL;
340  ttisp->tt_abbrind = abbrind;
341  }
342  for (i = 0; i < sp->charcnt; ++i)
343  sp->chars[i] = *p++;
344  sp->chars[i] = '\0'; /* ensure '\0' at end */
345 
346  /* Read leap seconds, discarding those out of pg_time_t range. */
347  leapcnt = 0;
348  for (i = 0; i < sp->leapcnt; ++i)
349  {
350  int64 tr = stored == 4 ? detzcode(p) : detzcode64(p);
351  int32 corr = detzcode(p + stored);
352 
353  p += stored + 4;
354  /* Leap seconds cannot occur before the Epoch. */
355  if (tr < 0)
356  return EINVAL;
357  if (tr <= TIME_T_MAX)
358  {
359  /*
360  * Leap seconds cannot occur more than once per UTC month, and
361  * UTC months are at least 28 days long (minus 1 second for a
362  * negative leap second). Each leap second's correction must
363  * differ from the previous one's by 1 second.
364  */
365  if (tr - prevtr < 28 * SECSPERDAY - 1
366  || (corr != prevcorr - 1 && corr != prevcorr + 1))
367  return EINVAL;
368  sp->lsis[leapcnt].ls_trans = prevtr = tr;
369  sp->lsis[leapcnt].ls_corr = prevcorr = corr;
370  leapcnt++;
371  }
372  }
373  sp->leapcnt = leapcnt;
374 
375  for (i = 0; i < sp->typecnt; ++i)
376  {
377  struct ttinfo *ttisp;
378 
379  ttisp = &sp->ttis[i];
380  if (ttisstdcnt == 0)
381  ttisp->tt_ttisstd = false;
382  else
383  {
384  if (*p != true && *p != false)
385  return EINVAL;
386  ttisp->tt_ttisstd = *p++;
387  }
388  }
389  for (i = 0; i < sp->typecnt; ++i)
390  {
391  struct ttinfo *ttisp;
392 
393  ttisp = &sp->ttis[i];
394  if (ttisgmtcnt == 0)
395  ttisp->tt_ttisgmt = false;
396  else
397  {
398  if (*p != true && *p != false)
399  return EINVAL;
400  ttisp->tt_ttisgmt = *p++;
401  }
402  }
403 
404  /*
405  * If this is an old file, we're done.
406  */
407  if (up->tzhead.tzh_version[0] == '\0')
408  break;
409  nread -= p - up->buf;
410  memmove(up->buf, p, nread);
411  }
412  if (doextend && nread > 2 &&
413  up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
414  sp->typecnt + 2 <= TZ_MAX_TYPES)
415  {
416  struct state *ts = &lsp->u.st;
417 
418  up->buf[nread - 1] = '\0';
419  if (tzparse(&up->buf[1], ts, false)
420  && ts->typecnt == 2)
421  {
422  /*
423  * Attempt to reuse existing abbreviations. Without this,
424  * America/Anchorage would be right on the edge after 2037 when
425  * TZ_MAX_CHARS is 50, as sp->charcnt equals 40 (for LMT AST AWT
426  * APT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
427  * AKST AKDT). Reusing means sp->charcnt can stay 40 in this
428  * example.
429  */
430  int gotabbr = 0;
431  int charcnt = sp->charcnt;
432 
433  for (i = 0; i < 2; i++)
434  {
435  char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
436  int j;
437 
438  for (j = 0; j < charcnt; j++)
439  if (strcmp(sp->chars + j, tsabbr) == 0)
440  {
441  ts->ttis[i].tt_abbrind = j;
442  gotabbr++;
443  break;
444  }
445  if (!(j < charcnt))
446  {
447  int tsabbrlen = strlen(tsabbr);
448 
449  if (j + tsabbrlen < TZ_MAX_CHARS)
450  {
451  strcpy(sp->chars + j, tsabbr);
452  charcnt = j + tsabbrlen + 1;
453  ts->ttis[i].tt_abbrind = j;
454  gotabbr++;
455  }
456  }
457  }
458  if (gotabbr == 2)
459  {
460  sp->charcnt = charcnt;
461 
462  /*
463  * Ignore any trailing, no-op transitions generated by zic as
464  * they don't help here and can run afoul of bugs in zic 2016j
465  * or earlier.
466  */
467  while (1 < sp->timecnt
468  && (sp->types[sp->timecnt - 1]
469  == sp->types[sp->timecnt - 2]))
470  sp->timecnt--;
471 
472  for (i = 0; i < ts->timecnt; i++)
473  if (sp->ats[sp->timecnt - 1] < ts->ats[i])
474  break;
475  while (i < ts->timecnt
476  && sp->timecnt < TZ_MAX_TIMES)
477  {
478  sp->ats[sp->timecnt] = ts->ats[i];
479  sp->types[sp->timecnt] = (sp->typecnt
480  + ts->types[i]);
481  sp->timecnt++;
482  i++;
483  }
484  sp->ttis[sp->typecnt++] = ts->ttis[0];
485  sp->ttis[sp->typecnt++] = ts->ttis[1];
486  }
487  }
488  }
489  if (sp->timecnt > 1)
490  {
491  for (i = 1; i < sp->timecnt; ++i)
492  if (typesequiv(sp, sp->types[i], sp->types[0]) &&
493  differ_by_repeat(sp->ats[i], sp->ats[0]))
494  {
495  sp->goback = true;
496  break;
497  }
498  for (i = sp->timecnt - 2; i >= 0; --i)
499  if (typesequiv(sp, sp->types[sp->timecnt - 1],
500  sp->types[i]) &&
501  differ_by_repeat(sp->ats[sp->timecnt - 1],
502  sp->ats[i]))
503  {
504  sp->goahead = true;
505  break;
506  }
507  }
508 
509  /*
510  * If type 0 is unused in transitions, it's the type to use for early
511  * times.
512  */
513  for (i = 0; i < sp->timecnt; ++i)
514  if (sp->types[i] == 0)
515  break;
516  i = i < sp->timecnt ? -1 : 0;
517 
518  /*
519  * Absent the above, if there are transition times and the first
520  * transition is to a daylight time find the standard type less than and
521  * closest to the type of the first transition.
522  */
523  if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst)
524  {
525  i = sp->types[0];
526  while (--i >= 0)
527  if (!sp->ttis[i].tt_isdst)
528  break;
529  }
530 
531  /*
532  * If no result yet, find the first standard type. If there is none, punt
533  * to type zero.
534  */
535  if (i < 0)
536  {
537  i = 0;
538  while (sp->ttis[i].tt_isdst)
539  if (++i >= sp->typecnt)
540  {
541  i = 0;
542  break;
543  }
544  }
545  sp->defaulttype = i;
546  return 0;
547 }
548 
549 /* Load tz data from the file named NAME into *SP. Read extended
550  * format if DOEXTEND. Return 0 on success, an errno value on failure.
551  * PG: If "canonname" is not NULL, then on success the canonical spelling of
552  * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
553  */
554 int
555 tzload(const char *name, char *canonname, struct state *sp, bool doextend)
556 {
557  union local_storage *lsp = malloc(sizeof *lsp);
558 
559  if (!lsp)
560  return errno;
561  else
562  {
563  int err = tzloadbody(name, canonname, sp, doextend, lsp);
564 
565  free(lsp);
566  return err;
567  }
568 }
569 
570 static bool
571 typesequiv(const struct state *sp, int a, int b)
572 {
573  bool result;
574 
575  if (sp == NULL ||
576  a < 0 || a >= sp->typecnt ||
577  b < 0 || b >= sp->typecnt)
578  result = false;
579  else
580  {
581  const struct ttinfo *ap = &sp->ttis[a];
582  const struct ttinfo *bp = &sp->ttis[b];
583 
584  result = ap->tt_gmtoff == bp->tt_gmtoff &&
585  ap->tt_isdst == bp->tt_isdst &&
586  ap->tt_ttisstd == bp->tt_ttisstd &&
587  ap->tt_ttisgmt == bp->tt_ttisgmt &&
588  strcmp(&sp->chars[ap->tt_abbrind],
589  &sp->chars[bp->tt_abbrind]) == 0;
590  }
591  return result;
592 }
593 
594 static const int mon_lengths[2][MONSPERYEAR] = {
595  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
596  {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
597 };
598 
599 static const int year_lengths[2] = {
601 };
602 
603 /*
604  * Given a pointer into a time zone string, scan until a character that is not
605  * a valid character in a zone name is found. Return a pointer to that
606  * character.
607  */
608 static const char *
609 getzname(const char *strp)
610 {
611  char c;
612 
613  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
614  c != '+')
615  ++strp;
616  return strp;
617 }
618 
619 /*
620  * Given a pointer into an extended time zone string, scan until the ending
621  * delimiter of the zone name is located. Return a pointer to the delimiter.
622  *
623  * As with getzname above, the legal character set is actually quite
624  * restricted, with other characters producing undefined results.
625  * We don't do any checking here; checking is done later in common-case code.
626  */
627 static const char *
628 getqzname(const char *strp, int delim)
629 {
630  int c;
631 
632  while ((c = *strp) != '\0' && c != delim)
633  ++strp;
634  return strp;
635 }
636 
637 /*
638  * Given a pointer into a time zone string, extract a number from that string.
639  * Check that the number is within a specified range; if it is not, return
640  * NULL.
641  * Otherwise, return a pointer to the first character not part of the number.
642  */
643 static const char *
644 getnum(const char *strp, int *nump, int min, int max)
645 {
646  char c;
647  int num;
648 
649  if (strp == NULL || !is_digit(c = *strp))
650  return NULL;
651  num = 0;
652  do
653  {
654  num = num * 10 + (c - '0');
655  if (num > max)
656  return NULL; /* illegal value */
657  c = *++strp;
658  } while (is_digit(c));
659  if (num < min)
660  return NULL; /* illegal value */
661  *nump = num;
662  return strp;
663 }
664 
665 /*
666  * Given a pointer into a time zone string, extract a number of seconds,
667  * in hh[:mm[:ss]] form, from the string.
668  * If any error occurs, return NULL.
669  * Otherwise, return a pointer to the first character not part of the number
670  * of seconds.
671  */
672 static const char *
673 getsecs(const char *strp, int32 *secsp)
674 {
675  int num;
676 
677  /*
678  * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
679  * "M10.4.6/26", which does not conform to Posix, but which specifies the
680  * equivalent of "02:00 on the first Sunday on or after 23 Oct".
681  */
682  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
683  if (strp == NULL)
684  return NULL;
685  *secsp = num * (int32) SECSPERHOUR;
686  if (*strp == ':')
687  {
688  ++strp;
689  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
690  if (strp == NULL)
691  return NULL;
692  *secsp += num * SECSPERMIN;
693  if (*strp == ':')
694  {
695  ++strp;
696  /* 'SECSPERMIN' allows for leap seconds. */
697  strp = getnum(strp, &num, 0, SECSPERMIN);
698  if (strp == NULL)
699  return NULL;
700  *secsp += num;
701  }
702  }
703  return strp;
704 }
705 
706 /*
707  * Given a pointer into a time zone string, extract an offset, in
708  * [+-]hh[:mm[:ss]] form, from the string.
709  * If any error occurs, return NULL.
710  * Otherwise, return a pointer to the first character not part of the time.
711  */
712 static const char *
713 getoffset(const char *strp, int32 *offsetp)
714 {
715  bool neg = false;
716 
717  if (*strp == '-')
718  {
719  neg = true;
720  ++strp;
721  }
722  else if (*strp == '+')
723  ++strp;
724  strp = getsecs(strp, offsetp);
725  if (strp == NULL)
726  return NULL; /* illegal time */
727  if (neg)
728  *offsetp = -*offsetp;
729  return strp;
730 }
731 
732 /*
733  * Given a pointer into a time zone string, extract a rule in the form
734  * date[/time]. See POSIX section 8 for the format of "date" and "time".
735  * If a valid rule is not found, return NULL.
736  * Otherwise, return a pointer to the first character not part of the rule.
737  */
738 static const char *
739 getrule(const char *strp, struct rule *rulep)
740 {
741  if (*strp == 'J')
742  {
743  /*
744  * Julian day.
745  */
746  rulep->r_type = JULIAN_DAY;
747  ++strp;
748  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
749  }
750  else if (*strp == 'M')
751  {
752  /*
753  * Month, week, day.
754  */
755  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
756  ++strp;
757  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
758  if (strp == NULL)
759  return NULL;
760  if (*strp++ != '.')
761  return NULL;
762  strp = getnum(strp, &rulep->r_week, 1, 5);
763  if (strp == NULL)
764  return NULL;
765  if (*strp++ != '.')
766  return NULL;
767  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
768  }
769  else if (is_digit(*strp))
770  {
771  /*
772  * Day of year.
773  */
774  rulep->r_type = DAY_OF_YEAR;
775  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
776  }
777  else
778  return NULL; /* invalid format */
779  if (strp == NULL)
780  return NULL;
781  if (*strp == '/')
782  {
783  /*
784  * Time specified.
785  */
786  ++strp;
787  strp = getoffset(strp, &rulep->r_time);
788  }
789  else
790  rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
791  return strp;
792 }
793 
794 /*
795  * Given a year, a rule, and the offset from UT at the time that rule takes
796  * effect, calculate the year-relative time that rule takes effect.
797  */
798 static int32
799 transtime(int year, const struct rule *rulep,
800  int32 offset)
801 {
802  bool leapyear;
803  int32 value;
804  int i;
805  int d,
806  m1,
807  yy0,
808  yy1,
809  yy2,
810  dow;
811 
812  INITIALIZE(value);
813  leapyear = isleap(year);
814  switch (rulep->r_type)
815  {
816 
817  case JULIAN_DAY:
818 
819  /*
820  * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
821  * years. In non-leap years, or if the day number is 59 or less,
822  * just add SECSPERDAY times the day number-1 to the time of
823  * January 1, midnight, to get the day.
824  */
825  value = (rulep->r_day - 1) * SECSPERDAY;
826  if (leapyear && rulep->r_day >= 60)
827  value += SECSPERDAY;
828  break;
829 
830  case DAY_OF_YEAR:
831 
832  /*
833  * n - day of year. Just add SECSPERDAY times the day number to
834  * the time of January 1, midnight, to get the day.
835  */
836  value = rulep->r_day * SECSPERDAY;
837  break;
838 
840 
841  /*
842  * Mm.n.d - nth "dth day" of month m.
843  */
844 
845  /*
846  * Use Zeller's Congruence to get day-of-week of first day of
847  * month.
848  */
849  m1 = (rulep->r_mon + 9) % 12 + 1;
850  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
851  yy1 = yy0 / 100;
852  yy2 = yy0 % 100;
853  dow = ((26 * m1 - 2) / 10 +
854  1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
855  if (dow < 0)
856  dow += DAYSPERWEEK;
857 
858  /*
859  * "dow" is the day-of-week of the first day of the month. Get the
860  * day-of-month (zero-origin) of the first "dow" day of the month.
861  */
862  d = rulep->r_day - dow;
863  if (d < 0)
864  d += DAYSPERWEEK;
865  for (i = 1; i < rulep->r_week; ++i)
866  {
867  if (d + DAYSPERWEEK >=
868  mon_lengths[(int) leapyear][rulep->r_mon - 1])
869  break;
870  d += DAYSPERWEEK;
871  }
872 
873  /*
874  * "d" is the day-of-month (zero-origin) of the day we want.
875  */
876  value = d * SECSPERDAY;
877  for (i = 0; i < rulep->r_mon - 1; ++i)
878  value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
879  break;
880  }
881 
882  /*
883  * "value" is the year-relative time of 00:00:00 UT on the day in
884  * question. To get the year-relative time of the specified local time on
885  * that day, add the transition time and the current offset from UT.
886  */
887  return value + rulep->r_time + offset;
888 }
889 
890 /*
891  * Given a POSIX section 8-style TZ string, fill in the rule tables as
892  * appropriate.
893  * Returns true on success, false on failure.
894  */
895 bool
896 tzparse(const char *name, struct state *sp, bool lastditch)
897 {
898  const char *stdname;
899  const char *dstname = NULL;
900  size_t stdlen;
901  size_t dstlen;
902  size_t charcnt;
903  int32 stdoffset;
904  int32 dstoffset;
905  char *cp;
906  bool load_ok;
907 
908  stdname = name;
909  if (lastditch)
910  {
911  /*
912  * This is intentionally somewhat different from the IANA code. We do
913  * not want to invoke tzload() in the lastditch case: we can't assume
914  * pg_open_tzfile() is sane yet, and we don't care about leap seconds
915  * anyway.
916  */
917  stdlen = strlen(name); /* length of standard zone name */
918  name += stdlen;
919  if (stdlen >= sizeof sp->chars)
920  stdlen = (sizeof sp->chars) - 1;
921  charcnt = stdlen + 1;
922  stdoffset = 0;
923  sp->goback = sp->goahead = false; /* simulate failed tzload() */
924  load_ok = false;
925  }
926  else
927  {
928  if (*name == '<')
929  {
930  name++;
931  stdname = name;
932  name = getqzname(name, '>');
933  if (*name != '>')
934  return false;
935  stdlen = name - stdname;
936  name++;
937  }
938  else
939  {
940  name = getzname(name);
941  stdlen = name - stdname;
942  }
943  if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
944  return false;
945  name = getoffset(name, &stdoffset);
946  if (name == NULL)
947  return false;
948  charcnt = stdlen + 1;
949  if (sizeof sp->chars < charcnt)
950  return false;
951 
952  /*
953  * This bit also differs from the IANA code, which doesn't make any
954  * attempt to avoid repetitive loadings of the TZDEFRULES zone.
955  */
956  if (tzdefrules_loaded == 0)
957  {
958  if (tzload(TZDEFRULES, NULL, &tzdefrules_s, false) == 0)
959  tzdefrules_loaded = 1;
960  else
961  tzdefrules_loaded = -1;
962  }
963  load_ok = (tzdefrules_loaded > 0);
964  if (load_ok)
965  memcpy(sp, &tzdefrules_s, sizeof(struct state));
966  }
967  if (!load_ok)
968  sp->leapcnt = 0; /* so, we're off a little */
969  if (*name != '\0')
970  {
971  if (*name == '<')
972  {
973  dstname = ++name;
974  name = getqzname(name, '>');
975  if (*name != '>')
976  return false;
977  dstlen = name - dstname;
978  name++;
979  }
980  else
981  {
982  dstname = name;
983  name = getzname(name);
984  dstlen = name - dstname; /* length of DST zone name */
985  }
986  if (!dstlen)
987  return false;
988  charcnt += dstlen + 1;
989  if (sizeof sp->chars < charcnt)
990  return false;
991  if (*name != '\0' && *name != ',' && *name != ';')
992  {
993  name = getoffset(name, &dstoffset);
994  if (name == NULL)
995  return false;
996  }
997  else
998  dstoffset = stdoffset - SECSPERHOUR;
999  if (*name == '\0' && !load_ok)
1000  name = TZDEFRULESTRING;
1001  if (*name == ',' || *name == ';')
1002  {
1003  struct rule start;
1004  struct rule end;
1005  int year;
1006  int yearlim;
1007  int timecnt;
1008  pg_time_t janfirst;
1009  int32 janoffset = 0;
1010  int yearbeg;
1011 
1012  ++name;
1013  if ((name = getrule(name, &start)) == NULL)
1014  return false;
1015  if (*name++ != ',')
1016  return false;
1017  if ((name = getrule(name, &end)) == NULL)
1018  return false;
1019  if (*name != '\0')
1020  return false;
1021  sp->typecnt = 2; /* standard time and DST */
1022 
1023  /*
1024  * Two transitions per year, from EPOCH_YEAR forward.
1025  */
1026  init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
1027  init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
1028  sp->defaulttype = 0;
1029  timecnt = 0;
1030  janfirst = 0;
1031  yearbeg = EPOCH_YEAR;
1032 
1033  do
1034  {
1035  int32 yearsecs
1036  = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
1037 
1038  yearbeg--;
1039  if (increment_overflow_time(&janfirst, -yearsecs))
1040  {
1041  janoffset = -yearsecs;
1042  break;
1043  }
1044  } while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1045 
1046  yearlim = yearbeg + YEARSPERREPEAT + 1;
1047  for (year = yearbeg; year < yearlim; year++)
1048  {
1049  int32
1050  starttime = transtime(year, &start, stdoffset),
1051  endtime = transtime(year, &end, dstoffset);
1052  int32
1053  yearsecs = (year_lengths[isleap(year)]
1054  * SECSPERDAY);
1055  bool reversed = endtime < starttime;
1056 
1057  if (reversed)
1058  {
1059  int32 swap = starttime;
1060 
1061  starttime = endtime;
1062  endtime = swap;
1063  }
1064  if (reversed
1065  || (starttime < endtime
1066  && (endtime - starttime
1067  < (yearsecs
1068  + (stdoffset - dstoffset)))))
1069  {
1070  if (TZ_MAX_TIMES - 2 < timecnt)
1071  break;
1072  sp->ats[timecnt] = janfirst;
1074  (&sp->ats[timecnt],
1075  janoffset + starttime))
1076  sp->types[timecnt++] = reversed;
1077  else if (janoffset)
1078  sp->defaulttype = reversed;
1079  sp->ats[timecnt] = janfirst;
1081  (&sp->ats[timecnt],
1082  janoffset + endtime))
1083  {
1084  sp->types[timecnt++] = !reversed;
1085  yearlim = year + YEARSPERREPEAT + 1;
1086  }
1087  else if (janoffset)
1088  sp->defaulttype = !reversed;
1089  }
1091  (&janfirst, janoffset + yearsecs))
1092  break;
1093  janoffset = 0;
1094  }
1095  sp->timecnt = timecnt;
1096  if (!timecnt)
1097  sp->typecnt = 1; /* Perpetual DST. */
1098  else if (YEARSPERREPEAT < year - yearbeg)
1099  sp->goback = sp->goahead = true;
1100  }
1101  else
1102  {
1103  int32 theirstdoffset;
1104  int32 theirdstoffset;
1105  int32 theiroffset;
1106  bool isdst;
1107  int i;
1108  int j;
1109 
1110  if (*name != '\0')
1111  return false;
1112 
1113  /*
1114  * Initial values of theirstdoffset and theirdstoffset.
1115  */
1116  theirstdoffset = 0;
1117  for (i = 0; i < sp->timecnt; ++i)
1118  {
1119  j = sp->types[i];
1120  if (!sp->ttis[j].tt_isdst)
1121  {
1122  theirstdoffset =
1123  -sp->ttis[j].tt_gmtoff;
1124  break;
1125  }
1126  }
1127  theirdstoffset = 0;
1128  for (i = 0; i < sp->timecnt; ++i)
1129  {
1130  j = sp->types[i];
1131  if (sp->ttis[j].tt_isdst)
1132  {
1133  theirdstoffset =
1134  -sp->ttis[j].tt_gmtoff;
1135  break;
1136  }
1137  }
1138 
1139  /*
1140  * Initially we're assumed to be in standard time.
1141  */
1142  isdst = false;
1143  theiroffset = theirstdoffset;
1144 
1145  /*
1146  * Now juggle transition times and types tracking offsets as you
1147  * do.
1148  */
1149  for (i = 0; i < sp->timecnt; ++i)
1150  {
1151  j = sp->types[i];
1152  sp->types[i] = sp->ttis[j].tt_isdst;
1153  if (sp->ttis[j].tt_ttisgmt)
1154  {
1155  /* No adjustment to transition time */
1156  }
1157  else
1158  {
1159  /*
1160  * If daylight saving time is in effect, and the
1161  * transition time was not specified as standard time, add
1162  * the daylight saving time offset to the transition time;
1163  * otherwise, add the standard time offset to the
1164  * transition time.
1165  */
1166 
1167  /*
1168  * Transitions from DST to DDST will effectively disappear
1169  * since POSIX provides for only one DST offset.
1170  */
1171  if (isdst && !sp->ttis[j].tt_ttisstd)
1172  {
1173  sp->ats[i] += dstoffset -
1174  theirdstoffset;
1175  }
1176  else
1177  {
1178  sp->ats[i] += stdoffset -
1179  theirstdoffset;
1180  }
1181  }
1182  theiroffset = -sp->ttis[j].tt_gmtoff;
1183  if (sp->ttis[j].tt_isdst)
1184  theirdstoffset = theiroffset;
1185  else
1186  theirstdoffset = theiroffset;
1187  }
1188 
1189  /*
1190  * Finally, fill in ttis.
1191  */
1192  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1193  init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1194  sp->typecnt = 2;
1195  sp->defaulttype = 0;
1196  }
1197  }
1198  else
1199  {
1200  dstlen = 0;
1201  sp->typecnt = 1; /* only standard time */
1202  sp->timecnt = 0;
1203  init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1204  sp->defaulttype = 0;
1205  }
1206  sp->charcnt = charcnt;
1207  cp = sp->chars;
1208  memcpy(cp, stdname, stdlen);
1209  cp += stdlen;
1210  *cp++ = '\0';
1211  if (dstlen != 0)
1212  {
1213  memcpy(cp, dstname, dstlen);
1214  *(cp + dstlen) = '\0';
1215  }
1216  return true;
1217 }
1218 
1219 static void
1220 gmtload(struct state *sp)
1221 {
1222  if (tzload(gmt, NULL, sp, true) != 0)
1223  tzparse(gmt, sp, true);
1224 }
1225 
1226 
1227 /*
1228  * The easy way to behave "as if no library function calls" localtime
1229  * is to not call it, so we drop its guts into "localsub", which can be
1230  * freely called. (And no, the PANS doesn't require the above behavior,
1231  * but it *is* desirable.)
1232  */
1233 static struct pg_tm *
1234 localsub(struct state const *sp, pg_time_t const *timep,
1235  struct pg_tm *tmp)
1236 {
1237  const struct ttinfo *ttisp;
1238  int i;
1239  struct pg_tm *result;
1240  const pg_time_t t = *timep;
1241 
1242  if (sp == NULL)
1243  return gmtsub(timep, 0, tmp);
1244  if ((sp->goback && t < sp->ats[0]) ||
1245  (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1246  {
1247  pg_time_t newt = t;
1248  pg_time_t seconds;
1249  pg_time_t years;
1250 
1251  if (t < sp->ats[0])
1252  seconds = sp->ats[0] - t;
1253  else
1254  seconds = t - sp->ats[sp->timecnt - 1];
1255  --seconds;
1256  years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1257  seconds = years * AVGSECSPERYEAR;
1258  if (t < sp->ats[0])
1259  newt += seconds;
1260  else
1261  newt -= seconds;
1262  if (newt < sp->ats[0] ||
1263  newt > sp->ats[sp->timecnt - 1])
1264  return NULL; /* "cannot happen" */
1265  result = localsub(sp, &newt, tmp);
1266  if (result)
1267  {
1268  int64 newy;
1269 
1270  newy = result->tm_year;
1271  if (t < sp->ats[0])
1272  newy -= years;
1273  else
1274  newy += years;
1275  if (!(INT_MIN <= newy && newy <= INT_MAX))
1276  return NULL;
1277  result->tm_year = newy;
1278  }
1279  return result;
1280  }
1281  if (sp->timecnt == 0 || t < sp->ats[0])
1282  {
1283  i = sp->defaulttype;
1284  }
1285  else
1286  {
1287  int lo = 1;
1288  int hi = sp->timecnt;
1289 
1290  while (lo < hi)
1291  {
1292  int mid = (lo + hi) >> 1;
1293 
1294  if (t < sp->ats[mid])
1295  hi = mid;
1296  else
1297  lo = mid + 1;
1298  }
1299  i = (int) sp->types[lo - 1];
1300  }
1301  ttisp = &sp->ttis[i];
1302 
1303  result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1304  if (result)
1305  {
1306  result->tm_isdst = ttisp->tt_isdst;
1307  result->tm_zone = (char *) &sp->chars[ttisp->tt_abbrind];
1308  }
1309  return result;
1310 }
1311 
1312 
1313 struct pg_tm *
1314 pg_localtime(const pg_time_t *timep, const pg_tz *tz)
1315 {
1316  return localsub(&tz->state, timep, &tm);
1317 }
1318 
1319 
1320 /*
1321  * gmtsub is to gmtime as localsub is to localtime.
1322  *
1323  * Except we have a private "struct state" for GMT, so no sp is passed in.
1324  */
1325 static struct pg_tm *
1326 gmtsub(pg_time_t const *timep, int32 offset, struct pg_tm *tmp)
1327 {
1328  struct pg_tm *result;
1329 
1330  /* GMT timezone state data is kept here */
1331  static struct state gmtmem;
1332  static bool gmt_is_set = false;
1333 #define gmtptr (&gmtmem)
1334 
1335  if (!gmt_is_set)
1336  {
1337  gmt_is_set = true;
1338  gmtload(gmtptr);
1339  }
1340  result = timesub(timep, offset, gmtptr, tmp);
1341 
1342  /*
1343  * Could get fancy here and deliver something such as "+xx" or "-xx" if
1344  * offset is non-zero, but this is no time for a treasure hunt.
1345  */
1346  if (offset != 0)
1347  tmp->tm_zone = wildabbr;
1348  else
1349  tmp->tm_zone = gmtptr->chars;
1350 
1351  return result;
1352 }
1353 
1354 struct pg_tm *
1355 pg_gmtime(const pg_time_t *timep)
1356 {
1357  return gmtsub(timep, 0, &tm);
1358 }
1359 
1360 /*
1361  * Return the number of leap years through the end of the given year
1362  * where, to make the math easy, the answer for year zero is defined as zero.
1363  */
1364 static int
1366 {
1367  return y / 4 - y / 100 + y / 400;
1368 }
1369 
1370 static int
1371 leaps_thru_end_of(const int y)
1372 {
1373  return (y < 0
1374  ? -1 - leaps_thru_end_of_nonneg(-1 - y)
1376 }
1377 
1378 static struct pg_tm *
1379 timesub(const pg_time_t *timep, int32 offset,
1380  const struct state *sp, struct pg_tm *tmp)
1381 {
1382  const struct lsinfo *lp;
1383  pg_time_t tdays;
1384  int idays; /* unsigned would be so 2003 */
1385  int64 rem;
1386  int y;
1387  const int *ip;
1388  int64 corr;
1389  bool hit;
1390  int i;
1391 
1392  corr = 0;
1393  hit = false;
1394  i = (sp == NULL) ? 0 : sp->leapcnt;
1395  while (--i >= 0)
1396  {
1397  lp = &sp->lsis[i];
1398  if (*timep >= lp->ls_trans)
1399  {
1400  corr = lp->ls_corr;
1401  hit = (*timep == lp->ls_trans
1402  && (i == 0 ? 0 : lp[-1].ls_corr) < corr);
1403  break;
1404  }
1405  }
1406  y = EPOCH_YEAR;
1407  tdays = *timep / SECSPERDAY;
1408  rem = *timep % SECSPERDAY;
1409  while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1410  {
1411  int newy;
1412  pg_time_t tdelta;
1413  int idelta;
1414  int leapdays;
1415 
1416  tdelta = tdays / DAYSPERLYEAR;
1417  if (!((!TYPE_SIGNED(pg_time_t) ||INT_MIN <= tdelta)
1418  && tdelta <= INT_MAX))
1419  goto out_of_range;
1420  idelta = tdelta;
1421  if (idelta == 0)
1422  idelta = (tdays < 0) ? -1 : 1;
1423  newy = y;
1424  if (increment_overflow(&newy, idelta))
1425  goto out_of_range;
1426  leapdays = leaps_thru_end_of(newy - 1) -
1427  leaps_thru_end_of(y - 1);
1428  tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1429  tdays -= leapdays;
1430  y = newy;
1431  }
1432 
1433  /*
1434  * Given the range, we can now fearlessly cast...
1435  */
1436  idays = tdays;
1437  rem += offset - corr;
1438  while (rem < 0)
1439  {
1440  rem += SECSPERDAY;
1441  --idays;
1442  }
1443  while (rem >= SECSPERDAY)
1444  {
1445  rem -= SECSPERDAY;
1446  ++idays;
1447  }
1448  while (idays < 0)
1449  {
1450  if (increment_overflow(&y, -1))
1451  goto out_of_range;
1452  idays += year_lengths[isleap(y)];
1453  }
1454  while (idays >= year_lengths[isleap(y)])
1455  {
1456  idays -= year_lengths[isleap(y)];
1457  if (increment_overflow(&y, 1))
1458  goto out_of_range;
1459  }
1460  tmp->tm_year = y;
1462  goto out_of_range;
1463  tmp->tm_yday = idays;
1464 
1465  /*
1466  * The "extra" mods below avoid overflow problems.
1467  */
1468  tmp->tm_wday = EPOCH_WDAY +
1469  ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1471  leaps_thru_end_of(y - 1) -
1473  idays;
1474  tmp->tm_wday %= DAYSPERWEEK;
1475  if (tmp->tm_wday < 0)
1476  tmp->tm_wday += DAYSPERWEEK;
1477  tmp->tm_hour = (int) (rem / SECSPERHOUR);
1478  rem %= SECSPERHOUR;
1479  tmp->tm_min = (int) (rem / SECSPERMIN);
1480 
1481  /*
1482  * A positive leap second requires a special representation. This uses
1483  * "... ??:59:60" et seq.
1484  */
1485  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1486  ip = mon_lengths[isleap(y)];
1487  for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1488  idays -= ip[tmp->tm_mon];
1489  tmp->tm_mday = (int) (idays + 1);
1490  tmp->tm_isdst = 0;
1491  tmp->tm_gmtoff = offset;
1492  return tmp;
1493 
1494 out_of_range:
1495  errno = EOVERFLOW;
1496  return NULL;
1497 }
1498 
1499 /*
1500  * Normalize logic courtesy Paul Eggert.
1501  */
1502 
1503 static bool
1504 increment_overflow(int *ip, int j)
1505 {
1506  int const i = *ip;
1507 
1508  /*----------
1509  * If i >= 0 there can only be overflow if i + j > INT_MAX
1510  * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1511  * If i < 0 there can only be overflow if i + j < INT_MIN
1512  * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1513  *----------
1514  */
1515  if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1516  return true;
1517  *ip += j;
1518  return false;
1519 }
1520 
1521 static bool
1523 {
1524  /*----------
1525  * This is like
1526  * 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
1527  * except that it does the right thing even if *tp + j would overflow.
1528  *----------
1529  */
1530  if (!(j < 0
1531  ? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
1532  : *tp <= TIME_T_MAX - j))
1533  return true;
1534  *tp += j;
1535  return false;
1536 }
1537 
1538 /*
1539  * Find the next DST transition time in the given zone after the given time
1540  *
1541  * *timep and *tz are input arguments, the other parameters are output values.
1542  *
1543  * When the function result is 1, *boundary is set to the pg_time_t
1544  * representation of the next DST transition time after *timep,
1545  * *before_gmtoff and *before_isdst are set to the GMT offset and isdst
1546  * state prevailing just before that boundary (in particular, the state
1547  * prevailing at *timep), and *after_gmtoff and *after_isdst are set to
1548  * the state prevailing just after that boundary.
1549  *
1550  * When the function result is 0, there is no known DST transition
1551  * after *timep, but *before_gmtoff and *before_isdst indicate the GMT
1552  * offset and isdst state prevailing at *timep. (This would occur in
1553  * DST-less time zones, or if a zone has permanently ceased using DST.)
1554  *
1555  * A function result of -1 indicates failure (this case does not actually
1556  * occur in our current implementation).
1557  */
1558 int
1560  long int *before_gmtoff,
1561  int *before_isdst,
1562  pg_time_t *boundary,
1563  long int *after_gmtoff,
1564  int *after_isdst,
1565  const pg_tz *tz)
1566 {
1567  const struct state *sp;
1568  const struct ttinfo *ttisp;
1569  int i;
1570  int j;
1571  const pg_time_t t = *timep;
1572 
1573  sp = &tz->state;
1574  if (sp->timecnt == 0)
1575  {
1576  /* non-DST zone, use lowest-numbered standard type */
1577  i = 0;
1578  while (sp->ttis[i].tt_isdst)
1579  if (++i >= sp->typecnt)
1580  {
1581  i = 0;
1582  break;
1583  }
1584  ttisp = &sp->ttis[i];
1585  *before_gmtoff = ttisp->tt_gmtoff;
1586  *before_isdst = ttisp->tt_isdst;
1587  return 0;
1588  }
1589  if ((sp->goback && t < sp->ats[0]) ||
1590  (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1591  {
1592  /* For values outside the transition table, extrapolate */
1593  pg_time_t newt = t;
1594  pg_time_t seconds;
1595  pg_time_t tcycles;
1596  int64 icycles;
1597  int result;
1598 
1599  if (t < sp->ats[0])
1600  seconds = sp->ats[0] - t;
1601  else
1602  seconds = t - sp->ats[sp->timecnt - 1];
1603  --seconds;
1604  tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1605  ++tcycles;
1606  icycles = tcycles;
1607  if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1608  return -1;
1609  seconds = icycles;
1610  seconds *= YEARSPERREPEAT;
1611  seconds *= AVGSECSPERYEAR;
1612  if (t < sp->ats[0])
1613  newt += seconds;
1614  else
1615  newt -= seconds;
1616  if (newt < sp->ats[0] ||
1617  newt > sp->ats[sp->timecnt - 1])
1618  return -1; /* "cannot happen" */
1619 
1620  result = pg_next_dst_boundary(&newt, before_gmtoff,
1621  before_isdst,
1622  boundary,
1623  after_gmtoff,
1624  after_isdst,
1625  tz);
1626  if (t < sp->ats[0])
1627  *boundary -= seconds;
1628  else
1629  *boundary += seconds;
1630  return result;
1631  }
1632 
1633  if (t >= sp->ats[sp->timecnt - 1])
1634  {
1635  /* No known transition > t, so use last known segment's type */
1636  i = sp->types[sp->timecnt - 1];
1637  ttisp = &sp->ttis[i];
1638  *before_gmtoff = ttisp->tt_gmtoff;
1639  *before_isdst = ttisp->tt_isdst;
1640  return 0;
1641  }
1642  if (t < sp->ats[0])
1643  {
1644  /* For "before", use lowest-numbered standard type */
1645  i = 0;
1646  while (sp->ttis[i].tt_isdst)
1647  if (++i >= sp->typecnt)
1648  {
1649  i = 0;
1650  break;
1651  }
1652  ttisp = &sp->ttis[i];
1653  *before_gmtoff = ttisp->tt_gmtoff;
1654  *before_isdst = ttisp->tt_isdst;
1655  *boundary = sp->ats[0];
1656  /* And for "after", use the first segment's type */
1657  i = sp->types[0];
1658  ttisp = &sp->ttis[i];
1659  *after_gmtoff = ttisp->tt_gmtoff;
1660  *after_isdst = ttisp->tt_isdst;
1661  return 1;
1662  }
1663  /* Else search to find the boundary following t */
1664  {
1665  int lo = 1;
1666  int hi = sp->timecnt - 1;
1667 
1668  while (lo < hi)
1669  {
1670  int mid = (lo + hi) >> 1;
1671 
1672  if (t < sp->ats[mid])
1673  hi = mid;
1674  else
1675  lo = mid + 1;
1676  }
1677  i = lo;
1678  }
1679  j = sp->types[i - 1];
1680  ttisp = &sp->ttis[j];
1681  *before_gmtoff = ttisp->tt_gmtoff;
1682  *before_isdst = ttisp->tt_isdst;
1683  *boundary = sp->ats[i];
1684  j = sp->types[i];
1685  ttisp = &sp->ttis[j];
1686  *after_gmtoff = ttisp->tt_gmtoff;
1687  *after_isdst = ttisp->tt_isdst;
1688  return 1;
1689 }
1690 
1691 /*
1692  * Identify a timezone abbreviation's meaning in the given zone
1693  *
1694  * Determine the GMT offset and DST flag associated with the abbreviation.
1695  * This is generally used only when the abbreviation has actually changed
1696  * meaning over time; therefore, we also take a UTC cutoff time, and return
1697  * the meaning in use at or most recently before that time, or the meaning
1698  * in first use after that time if the abbrev was never used before that.
1699  *
1700  * On success, returns true and sets *gmtoff and *isdst. If the abbreviation
1701  * was never used at all in this zone, returns false.
1702  *
1703  * Note: abbrev is matched case-sensitively; it should be all-upper-case.
1704  */
1705 bool
1706 pg_interpret_timezone_abbrev(const char *abbrev,
1707  const pg_time_t *timep,
1708  long int *gmtoff,
1709  int *isdst,
1710  const pg_tz *tz)
1711 {
1712  const struct state *sp;
1713  const char *abbrs;
1714  const struct ttinfo *ttisp;
1715  int abbrind;
1716  int cutoff;
1717  int i;
1718  const pg_time_t t = *timep;
1719 
1720  sp = &tz->state;
1721 
1722  /*
1723  * Locate the abbreviation in the zone's abbreviation list. We assume
1724  * there are not duplicates in the list.
1725  */
1726  abbrs = sp->chars;
1727  abbrind = 0;
1728  while (abbrind < sp->charcnt)
1729  {
1730  if (strcmp(abbrev, abbrs + abbrind) == 0)
1731  break;
1732  while (abbrs[abbrind] != '\0')
1733  abbrind++;
1734  abbrind++;
1735  }
1736  if (abbrind >= sp->charcnt)
1737  return false; /* not there! */
1738 
1739  /*
1740  * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1741  * (goback/goahead zones). Finding the newest or oldest meaning of the
1742  * abbreviation should get us what we want, since extrapolation would just
1743  * be repeating the newest or oldest meanings.
1744  *
1745  * Use binary search to locate the first transition > cutoff time.
1746  */
1747  {
1748  int lo = 0;
1749  int hi = sp->timecnt;
1750 
1751  while (lo < hi)
1752  {
1753  int mid = (lo + hi) >> 1;
1754 
1755  if (t < sp->ats[mid])
1756  hi = mid;
1757  else
1758  lo = mid + 1;
1759  }
1760  cutoff = lo;
1761  }
1762 
1763  /*
1764  * Scan backwards to find the latest interval using the given abbrev
1765  * before the cutoff time.
1766  */
1767  for (i = cutoff - 1; i >= 0; i--)
1768  {
1769  ttisp = &sp->ttis[sp->types[i]];
1770  if (ttisp->tt_abbrind == abbrind)
1771  {
1772  *gmtoff = ttisp->tt_gmtoff;
1773  *isdst = ttisp->tt_isdst;
1774  return true;
1775  }
1776  }
1777 
1778  /*
1779  * Not there, so scan forwards to find the first one after.
1780  */
1781  for (i = cutoff; i < sp->timecnt; i++)
1782  {
1783  ttisp = &sp->ttis[sp->types[i]];
1784  if (ttisp->tt_abbrind == abbrind)
1785  {
1786  *gmtoff = ttisp->tt_gmtoff;
1787  *isdst = ttisp->tt_isdst;
1788  return true;
1789  }
1790  }
1791 
1792  return false; /* hm, not actually used in any interval? */
1793 }
1794 
1795 /*
1796  * If the given timezone uses only one GMT offset, store that offset
1797  * into *gmtoff and return true, else return false.
1798  */
1799 bool
1800 pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
1801 {
1802  /*
1803  * The zone could have more than one ttinfo, if it's historically used
1804  * more than one abbreviation. We return true as long as they all have
1805  * the same gmtoff.
1806  */
1807  const struct state *sp;
1808  int i;
1809 
1810  sp = &tz->state;
1811  for (i = 1; i < sp->typecnt; i++)
1812  {
1813  if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
1814  return false;
1815  }
1816  *gmtoff = sp->ttis[0].tt_gmtoff;
1817  return true;
1818 }
1819 
1820 /*
1821  * Return the name of the current timezone
1822  */
1823 const char *
1825 {
1826  if (tz)
1827  return tz->TZname;
1828  return NULL;
1829 }
1830 
1831 /*
1832  * Check whether timezone is acceptable.
1833  *
1834  * What we are doing here is checking for leap-second-aware timekeeping.
1835  * We need to reject such TZ settings because they'll wreak havoc with our
1836  * date/time arithmetic.
1837  */
1838 bool
1840 {
1841  struct pg_tm *tt;
1842  pg_time_t time2000;
1843 
1844  /*
1845  * To detect leap-second timekeeping, run pg_localtime for what should be
1846  * GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
1847  * other result has to be due to leap seconds.
1848  */
1850  tt = pg_localtime(&time2000, tz);
1851  if (!tt || tt->tm_sec != 0)
1852  return false;
1853 
1854  return true;
1855 }
#define AVGSECSPERYEAR
Definition: private.h:147
#define TZDEFAULT
Definition: tzfile.h:24
static void gmtload(struct state *sp)
Definition: localtime.c:1220
struct local_storage::file_analysis u
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1314
#define SECSPERMIN
Definition: private.h:90
static int typecnt
Definition: zic.c:194
#define swap(a, b)
Definition: qsort.c:94
static const char * getoffset(const char *strp, int32 *offsetp)
Definition: localtime.c:713
static void init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
Definition: localtime.c:110
int64 pg_time_t
Definition: pgtime.h:23
int tm_wday
Definition: pgtime.h:33
bool pg_tz_acceptable(pg_tz *tz)
Definition: localtime.c:1839
#define WILDABBR
Definition: localtime.c:46
int tm_isdst
Definition: pgtime.h:35
int tzload(const char *name, char *canonname, struct state *sp, bool doextend)
Definition: localtime.c:555
int charcnt
Definition: pgtz.h:46
static int32 detzcode(const char *codep)
Definition: localtime.c:120
int tm_hour
Definition: pgtime.h:29
static zic_t corr[TZ_MAX_LEAPS]
Definition: zic.c:396
bool goback
Definition: pgtz.h:47
static int tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, union local_storage *lsp)
Definition: localtime.c:213
int32 tt_gmtoff
Definition: pgtz.h:28
#define SECSPERDAY
Definition: private.h:97
static const char * getsecs(const char *strp, int32 *secsp)
Definition: localtime.c:673
#define isleap(y)
Definition: datetime.h:273
int leapcnt
Definition: pgtz.h:43
#define INITIALIZE(x)
Definition: private.h:81
Definition: pgtz.h:26
static const char * getrule(const char *strp, struct rule *rulep)
Definition: localtime.c:739
#define SECSPERHOUR
Definition: private.h:96
static const int mon_lengths[2][MONSPERYEAR]
Definition: localtime.c:594
#define MONSPERYEAR
Definition: private.h:98
#define HOURSPERDAY
Definition: private.h:92
#define TZ_MAX_TIMES
Definition: tzfile.h:93
#define DAYSPERNYEAR
Definition: private.h:94
struct tzhead tzhead
Definition: localtime.c:183
char tzh_timecnt[4]
Definition: tzfile.h:41
long int tm_gmtoff
Definition: pgtime.h:36
Definition: pgtime.h:25
r_type
Definition: localtime.c:70
int r_mon
Definition: localtime.c:82
pg_time_t ats[TZ_MAX_TIMES]
Definition: pgtz.h:49
static int leaps_thru_end_of_nonneg(int y)
Definition: localtime.c:1365
#define TZDEFRULESTRING
Definition: localtime.c:66
#define is_digit(c)
Definition: private.h:42
Definition: localtime.c:77
signed int int32
Definition: c.h:313
#define DAYSPERLYEAR
Definition: private.h:95
static struct pg_tm tm
Definition: localtime.c:106
#define malloc(a)
Definition: header.h:50
#define TZ_MAX_LEAPS
Definition: tzfile.h:101
int r_week
Definition: localtime.c:81
union input_buffer u
Definition: localtime.c:197
bool tt_isdst
Definition: pgtz.h:29
struct lsinfo lsis[TZ_MAX_LEAPS]
Definition: pgtz.h:54
static int64 detzcode64(const char *codep)
Definition: localtime.c:146
#define SECS_PER_DAY
Definition: timestamp.h:86
#define TM_YEAR_BASE
Definition: private.h:121
const char * pg_get_timezone_name(pg_tz *tz)
Definition: localtime.c:1824
#define DAYSPERWEEK
Definition: private.h:93
int64 ls_corr
Definition: pgtz.h:38
char * c
int tm_mday
Definition: pgtime.h:30
static char * buf
Definition: pg_test_fsync.c:67
#define memmove(d, s, c)
Definition: c.h:1135
int tm_mon
Definition: pgtime.h:31
static const char wildabbr[]
Definition: localtime.c:49
static int leapcnt
Definition: zic.c:177
#define SECSPERREPEAT_BITS
Definition: private.h:150
pg_time_t ls_trans
Definition: pgtz.h:37
#define TIME_T_MAX
Definition: private.h:66
char tzh_leapcnt[4]
Definition: tzfile.h:40
static bool typesequiv(struct state const *, int, int)
Definition: localtime.c:571
const char * tm_zone
Definition: pgtime.h:37
static struct state tzdefrules_s
Definition: localtime.c:57
enum r_type r_type
Definition: localtime.c:79
int32 r_time
Definition: localtime.c:83
bool tzparse(const char *name, struct state *sp, bool lastditch)
Definition: localtime.c:896
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS+1, 3),(2 *(TZ_STRLEN_MAX+1)))]
Definition: pgtz.h:53
int r_day
Definition: localtime.c:80
static int32 transtime(int year, const struct rule *rulep, int32 offset)
Definition: localtime.c:799
#define TZ_MAX_CHARS
Definition: tzfile.h:98
#define EPOCH_YEAR
Definition: private.h:123
char buf[2 *sizeof(struct tzhead)+2 *sizeof(struct state)+4 *TZ_MAX_TIMES]
Definition: localtime.c:187
struct state state
Definition: pgtz.h:63
Definition: pgtz.h:59
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: pgtz.h:51
unsigned char types[TZ_MAX_TIMES]
Definition: pgtz.h:50
static struct @131 value
Definition: tzfile.h:33
static int tzdefrules_loaded
Definition: localtime.c:58
int pg_next_dst_boundary(const pg_time_t *timep, long int *before_gmtoff, int *before_isdst, pg_time_t *boundary, long int *after_gmtoff, int *after_isdst, const pg_tz *tz)
Definition: localtime.c:1559
char tzh_typecnt[4]
Definition: tzfile.h:42
#define free(a)
Definition: header.h:65
char tzh_version[1]
Definition: tzfile.h:36
char tzh_charcnt[4]
Definition: tzfile.h:43
Definition: regguts.h:298
#define TZDEFRULES
Definition: tzfile.h:25
static ptrdiff_t timecnt
Definition: zic.c:192
int timecnt
Definition: pgtz.h:44
#define TIME_T_MIN
Definition: private.h:65
bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
Definition: localtime.c:1800
#define gmtptr
Definition: pgtz.h:35
#define EPOCH_WDAY
Definition: private.h:124
static int leaps_thru_end_of(const int y)
Definition: localtime.c:1371
static int charcnt
Definition: zic.c:173
char TZname[TZ_STRLEN_MAX+1]
Definition: pgtz.h:62
bool pg_interpret_timezone_abbrev(const char *abbrev, const pg_time_t *timep, long int *gmtoff, int *isdst, const pg_tz *tz)
Definition: localtime.c:1706
bool tt_ttisstd
Definition: pgtz.h:31
const char * name
Definition: encode.c:521
#define YEARSPERREPEAT
Definition: private.h:88
static bool increment_overflow_time(pg_time_t *, int32)
Definition: localtime.c:1522
static const char * getnum(const char *strp, int *nump, int min, int max)
Definition: localtime.c:644
static const int year_lengths[2]
Definition: localtime.c:599
static bool increment_overflow(int *, int)
Definition: localtime.c:1504
int tm_year
Definition: pgtime.h:32
#define TZ_MAX_TYPES
Definition: tzfile.h:96
int tt_abbrind
Definition: pgtz.h:30
char tzh_ttisstdcnt[4]
Definition: tzfile.h:39
#define TYPE_BIT(type)
Definition: private.h:49
int i
int pg_open_tzfile(const char *name, char *canonname)
Definition: findtimezone.c:64
static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, struct pg_tm *tmp)
Definition: localtime.c:1234
int tm_yday
Definition: pgtime.h:34
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:162
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
struct pg_tm * pg_gmtime(const pg_time_t *timep)
Definition: localtime.c:1355
bool tt_ttisgmt
Definition: pgtz.h:32
bool goahead
Definition: pgtz.h:48
#define SECSPERREPEAT
Definition: private.h:148
static const char * getqzname(const char *strp, int delim)
Definition: localtime.c:628
#define TYPE_SIGNED(type)
Definition: private.h:50
#define close(a)
Definition: win32.h:12
int typecnt
Definition: pgtz.h:45
int tm_sec
Definition: pgtime.h:27
#define EOVERFLOW
Definition: private.h:38
static struct pg_tm * timesub(pg_time_t const *, int32, struct state const *, struct pg_tm *)
Definition: localtime.c:1379
static const char gmt[]
Definition: localtime.c:51
int tm_min
Definition: pgtime.h:28
#define MINSPERHOUR
Definition: private.h:91
#define read(a, b, c)
Definition: win32.h:13
static bool differ_by_repeat(const pg_time_t t1, const pg_time_t t0)
Definition: localtime.c:172
#define TWOS_COMPLEMENT(t)
Definition: private.h:51
static struct pg_tm * gmtsub(pg_time_t const *, int32, struct pg_tm *)
Definition: localtime.c:1326
int defaulttype
Definition: pgtz.h:55
static const char * getzname(const char *strp)
Definition: localtime.c:609
char tzh_ttisgmtcnt[4]
Definition: tzfile.h:38