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