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