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