1 /* Convert timestamp from pg_time_t to struct pg_tm. */
4 * This file is in the public domain, so clarified as of
5 * 1996-06-05 by Arthur David Olson.
8 * src/timezone/localtime.c
12 * Leap second handling from Bradley White.
13 * POSIX-style TZ environment variable handling from Guy Harris.
16 /* this file needs to build in both frontend and backend contexts */
21 #include "datatype/timestamp.h"
30 * Someone might make incorrect use of a time zone abbreviation:
31 * 1. They might reference tzname[0] before calling tzset (explicitly
33 * 2. They might reference tzname[1] before calling tzset (explicitly
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).
49 #endif /* !defined WILDABBR */
51 static const char wildabbr
[] = WILDABBR
;
53 static const char gmt
[] = "GMT";
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.
61 #define TZDEFRULESTRING ",M3.2.0,M11.1.0"
63 /* structs ttinfo, lsinfo, state have been moved to pgtz.h */
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 */
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 */
82 * Prototypes for static functions.
85 static struct pg_tm
*gmtsub(pg_time_t
const *timep
, int32 offset
,
87 static bool increment_overflow(int *ip
, int j
);
88 static bool increment_overflow_time(pg_time_t
*tp
, int32 j
);
89 static int64
leapcorr(struct state
const *sp
, pg_time_t t
);
90 static struct pg_tm
*timesub(pg_time_t
const *timep
,
91 int32 offset
, struct state
const *sp
,
93 static bool typesequiv(struct state
const *sp
, int a
, int b
);
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.
104 static struct pg_tm tm
;
106 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
108 init_ttinfo(struct ttinfo
*s
, int32 utoff
, bool isdst
, int desigidx
)
112 s
->tt_desigidx
= desigidx
;
113 s
->tt_ttisstd
= false;
114 s
->tt_ttisut
= false;
118 detzcode(const char *const codep
)
123 int32 halfmaxval
= one
<< (32 - 2);
124 int32 maxval
= halfmaxval
- 1 + halfmaxval
;
125 int32 minval
= -1 - maxval
;
127 result
= codep
[0] & 0x7f;
128 for (i
= 1; i
< 4; ++i
)
129 result
= (result
<< 8) | (codep
[i
] & 0xff);
134 * Do two's-complement negation even on non-two's-complement machines.
135 * If the result would be minval - 1, return minval.
137 result
-= !TWOS_COMPLEMENT(int32
) && result
!= 0;
144 detzcode64(const char *const codep
)
149 int64 halfmaxval
= one
<< (64 - 2);
150 int64 maxval
= halfmaxval
- 1 + halfmaxval
;
151 int64 minval
= -TWOS_COMPLEMENT(int64
) - maxval
;
153 result
= codep
[0] & 0x7f;
154 for (i
= 1; i
< 8; ++i
)
155 result
= (result
<< 8) | (codep
[i
] & 0xff);
160 * Do two's-complement negation even on non-two's-complement machines.
161 * If the result would be minval - 1, return minval.
163 result
-= !TWOS_COMPLEMENT(int64
) && result
!= 0;
170 differ_by_repeat(const pg_time_t t1
, const pg_time_t t0
)
172 if (TYPE_BIT(pg_time_t
) - TYPE_SIGNED(pg_time_t
) < SECSPERREPEAT_BITS
)
174 return t1
- t0
== SECSPERREPEAT
;
177 /* Input buffer for data read from a compiled tz file. */
180 /* The first part of the buffer, interpreted as a header. */
181 struct tzhead tzhead
;
183 /* The entire buffer. */
184 char buf
[2 * sizeof(struct tzhead
) + 2 * sizeof(struct state
)
188 /* Local storage needed for 'tzloadbody'. */
191 /* The results of analyzing the file's contents after it is opened. */
194 /* The input buffer. */
195 union input_buffer u
;
197 /* A temporary state used for parsing a TZ string in the file. */
201 /* We don't need the "fullname" member */
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!).
211 tzloadbody(char const *name
, char *canonname
, struct state
*sp
, bool doextend
,
212 union local_storage
*lsp
)
218 union input_buffer
*up
= &lsp
->u
.u
;
219 int tzheadsize
= sizeof(struct tzhead
);
221 sp
->goback
= sp
->goahead
= false;
233 fid
= pg_open_tzfile(name
, canonname
);
235 return ENOENT
; /* pg_open_tzfile may not set errno */
237 nread
= read(fid
, up
->buf
, sizeof up
->buf
);
238 if (nread
< tzheadsize
)
240 int err
= nread
< 0 ? errno
: EINVAL
;
247 for (stored
= 4; stored
<= 8; stored
*= 2)
249 int32 ttisstdcnt
= detzcode(up
->tzhead
.tzh_ttisstdcnt
);
250 int32 ttisutcnt
= detzcode(up
->tzhead
.tzh_ttisutcnt
);
253 int32 leapcnt
= detzcode(up
->tzhead
.tzh_leapcnt
);
254 int32 timecnt
= detzcode(up
->tzhead
.tzh_timecnt
);
255 int32 typecnt
= detzcode(up
->tzhead
.tzh_typecnt
);
256 int32 charcnt
= detzcode(up
->tzhead
.tzh_charcnt
);
257 char const *p
= up
->buf
+ tzheadsize
;
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.
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)))
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 */
281 sp
->leapcnt
= leapcnt
;
282 sp
->timecnt
= timecnt
;
283 sp
->typecnt
= typecnt
;
284 sp
->charcnt
= charcnt
;
287 * Read transitions, discarding those out of pg_time_t range. But
288 * pretend the last transition before TIME_T_MIN occurred at
292 for (i
= 0; i
< sp
->timecnt
; ++i
)
295 = stored
== 4 ? detzcode(p
) : detzcode64(p
);
297 sp
->types
[i
] = at
<= TIME_T_MAX
;
301 = ((TYPE_SIGNED(pg_time_t
) ? at
< TIME_T_MIN
: at
< 0)
304 if (timecnt
&& attime
<= sp
->ats
[timecnt
- 1])
306 if (attime
< sp
->ats
[timecnt
- 1])
308 sp
->types
[i
- 1] = 0;
311 sp
->ats
[timecnt
++] = attime
;
317 for (i
= 0; i
< sp
->timecnt
; ++i
)
319 unsigned char typ
= *p
++;
321 if (sp
->typecnt
<= typ
)
324 sp
->types
[timecnt
++] = typ
;
326 sp
->timecnt
= timecnt
;
327 for (i
= 0; i
< sp
->typecnt
; ++i
)
329 struct ttinfo
*ttisp
;
333 ttisp
= &sp
->ttis
[i
];
334 ttisp
->tt_utoff
= detzcode(p
);
339 ttisp
->tt_isdst
= isdst
;
341 if (!(desigidx
< sp
->charcnt
))
343 ttisp
->tt_desigidx
= desigidx
;
345 for (i
= 0; i
< sp
->charcnt
; ++i
)
347 sp
->chars
[i
] = '\0'; /* ensure '\0' at end */
349 /* Read leap seconds, discarding those out of pg_time_t range. */
351 for (i
= 0; i
< sp
->leapcnt
; ++i
)
353 int64 tr
= stored
== 4 ? detzcode(p
) : detzcode64(p
);
354 int32 corr
= detzcode(p
+ stored
);
357 /* Leap seconds cannot occur before the Epoch. */
360 if (tr
<= TIME_T_MAX
)
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.
368 if (tr
- prevtr
< 28 * SECSPERDAY
- 1
369 || (corr
!= prevcorr
- 1 && corr
!= prevcorr
+ 1))
371 sp
->lsis
[leapcnt
].ls_trans
= prevtr
= tr
;
372 sp
->lsis
[leapcnt
].ls_corr
= prevcorr
= corr
;
376 sp
->leapcnt
= leapcnt
;
378 for (i
= 0; i
< sp
->typecnt
; ++i
)
380 struct ttinfo
*ttisp
;
382 ttisp
= &sp
->ttis
[i
];
384 ttisp
->tt_ttisstd
= false;
387 if (*p
!= true && *p
!= false)
389 ttisp
->tt_ttisstd
= *p
++;
392 for (i
= 0; i
< sp
->typecnt
; ++i
)
394 struct ttinfo
*ttisp
;
396 ttisp
= &sp
->ttis
[i
];
398 ttisp
->tt_ttisut
= false;
401 if (*p
!= true && *p
!= false)
403 ttisp
->tt_ttisut
= *p
++;
408 * If this is an old file, we're done.
410 if (up
->tzhead
.tzh_version
[0] == '\0')
412 nread
-= p
- up
->buf
;
413 memmove(up
->buf
, p
, nread
);
415 if (doextend
&& nread
> 2 &&
416 up
->buf
[0] == '\n' && up
->buf
[nread
- 1] == '\n' &&
417 sp
->typecnt
+ 2 <= TZ_MAX_TYPES
)
419 struct state
*ts
= &lsp
->u
.st
;
421 up
->buf
[nread
- 1] = '\0';
422 if (tzparse(&up
->buf
[1], ts
, false))
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
433 int charcnt
= sp
->charcnt
;
435 for (i
= 0; i
< ts
->typecnt
; i
++)
437 char *tsabbr
= ts
->chars
+ ts
->ttis
[i
].tt_desigidx
;
440 for (j
= 0; j
< charcnt
; j
++)
441 if (strcmp(sp
->chars
+ j
, tsabbr
) == 0)
443 ts
->ttis
[i
].tt_desigidx
= j
;
449 int tsabbrlen
= strlen(tsabbr
);
451 if (j
+ tsabbrlen
< TZ_MAX_CHARS
)
453 strcpy(sp
->chars
+ j
, tsabbr
);
454 charcnt
= j
+ tsabbrlen
+ 1;
455 ts
->ttis
[i
].tt_desigidx
= j
;
460 if (gotabbr
== ts
->typecnt
)
462 sp
->charcnt
= charcnt
;
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
469 while (1 < sp
->timecnt
470 && (sp
->types
[sp
->timecnt
- 1]
471 == sp
->types
[sp
->timecnt
- 2]))
474 for (i
= 0; i
< ts
->timecnt
; i
++)
476 || (sp
->ats
[sp
->timecnt
- 1]
477 < ts
->ats
[i
] + leapcorr(sp
, ts
->ats
[i
])))
479 while (i
< ts
->timecnt
480 && sp
->timecnt
< TZ_MAX_TIMES
)
483 = ts
->ats
[i
] + leapcorr(sp
, ts
->ats
[i
]);
484 sp
->types
[sp
->timecnt
] = (sp
->typecnt
489 for (i
= 0; i
< ts
->typecnt
; i
++)
490 sp
->ttis
[sp
->typecnt
++] = ts
->ttis
[i
];
494 if (sp
->typecnt
== 0)
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]))
505 for (i
= sp
->timecnt
- 2; i
>= 0; --i
)
506 if (typesequiv(sp
, sp
->types
[sp
->timecnt
- 1],
508 differ_by_repeat(sp
->ats
[sp
->timecnt
- 1],
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.
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
529 * If type 0 is unused in transitions, it's the type to use for early
532 for (i
= 0; i
< sp
->timecnt
; ++i
)
533 if (sp
->types
[i
] == 0)
535 i
= i
< sp
->timecnt
? -1 : 0;
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.
542 if (i
< 0 && sp
->timecnt
> 0 && sp
->ttis
[sp
->types
[0]].tt_isdst
)
546 if (!sp
->ttis
[i
].tt_isdst
)
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.
556 * If no result yet, find the first standard type. If there is none, punt
562 while (sp
->ttis
[i
].tt_isdst
)
563 if (++i
>= sp
->typecnt
)
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.
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!).
586 tzload(const char *name
, char *canonname
, struct state
*sp
, bool doextend
)
588 union local_storage
*lsp
= malloc(sizeof *lsp
);
594 int err
= tzloadbody(name
, canonname
, sp
, doextend
, lsp
);
602 typesequiv(const struct state
*sp
, int a
, int b
)
607 a
< 0 || a
>= sp
->typecnt
||
608 b
< 0 || b
>= sp
->typecnt
)
612 const struct ttinfo
*ap
= &sp
->ttis
[a
];
613 const struct ttinfo
*bp
= &sp
->ttis
[b
];
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
])
626 static 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}
631 static const int year_lengths
[2] = {
632 DAYSPERNYEAR
, DAYSPERLYEAR
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.
642 getzname(const char *strp
)
646 while ((c
= *strp
) != '\0' && !is_digit(c
) && c
!= ',' && c
!= '-' &&
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.
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.
663 getqzname(const char *strp
, const int delim
)
667 while ((c
= *strp
) != '\0' && c
!= delim
)
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
676 * Otherwise, return a pointer to the first character not part of the number.
680 getnum(const char *strp
, int *const nump
, const int min
, const int max
)
685 if (strp
== NULL
|| !is_digit(c
= *strp
))
690 num
= num
* 10 + (c
- '0');
692 return NULL
; /* illegal value */
694 } while (is_digit(c
));
696 return NULL
; /* illegal value */
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
710 getsecs(const char *strp
, int32
*const secsp
)
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".
719 strp
= getnum(strp
, &num
, 0, HOURSPERDAY
* DAYSPERWEEK
- 1);
722 *secsp
= num
* (int32
) SECSPERHOUR
;
726 strp
= getnum(strp
, &num
, 0, MINSPERHOUR
- 1);
729 *secsp
+= num
* SECSPERMIN
;
733 /* 'SECSPERMIN' allows for leap seconds. */
734 strp
= getnum(strp
, &num
, 0, SECSPERMIN
);
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.
751 getoffset(const char *strp
, int32
*const offsetp
)
760 else if (*strp
== '+')
762 strp
= getsecs(strp
, offsetp
);
764 return NULL
; /* illegal time */
766 *offsetp
= -*offsetp
;
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.
778 getrule(const char *strp
, struct rule
*const rulep
)
785 rulep
->r_type
= JULIAN_DAY
;
787 strp
= getnum(strp
, &rulep
->r_day
, 1, DAYSPERNYEAR
);
789 else if (*strp
== 'M')
794 rulep
->r_type
= MONTH_NTH_DAY_OF_WEEK
;
796 strp
= getnum(strp
, &rulep
->r_mon
, 1, MONSPERYEAR
);
801 strp
= getnum(strp
, &rulep
->r_week
, 1, 5);
806 strp
= getnum(strp
, &rulep
->r_day
, 0, DAYSPERWEEK
- 1);
808 else if (is_digit(*strp
))
813 rulep
->r_type
= DAY_OF_YEAR
;
814 strp
= getnum(strp
, &rulep
->r_day
, 0, DAYSPERLYEAR
- 1);
817 return NULL
; /* invalid format */
826 strp
= getoffset(strp
, &rulep
->r_time
);
829 rulep
->r_time
= 2 * SECSPERHOUR
; /* default = 2:00:00 */
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.
839 transtime(const int year
, const struct rule
*const rulep
,
853 leapyear
= isleap(year
);
854 switch (rulep
->r_type
)
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.
865 value
= (rulep
->r_day
- 1) * SECSPERDAY
;
866 if (leapyear
&& rulep
->r_day
>= 60)
873 * n - day of year. Just add SECSPERDAY times the day number to
874 * the time of January 1, midnight, to get the day.
876 value
= rulep
->r_day
* SECSPERDAY
;
879 case MONTH_NTH_DAY_OF_WEEK
:
882 * Mm.n.d - nth "dth day" of month m.
886 * Use Zeller's Congruence to get day-of-week of first day of
889 m1
= (rulep
->r_mon
+ 9) % 12 + 1;
890 yy0
= (rulep
->r_mon
<= 2) ? (year
- 1) : year
;
893 dow
= ((26 * m1
- 2) / 10 +
894 1 + yy2
+ yy2
/ 4 + yy1
/ 4 - 2 * yy1
) % 7;
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.
902 d
= rulep
->r_day
- dow
;
905 for (i
= 1; i
< rulep
->r_week
; ++i
)
907 if (d
+ DAYSPERWEEK
>=
908 mon_lengths
[(int) leapyear
][rulep
->r_mon
- 1])
914 * "d" is the day-of-month (zero-origin) of the day we want.
916 value
= d
* SECSPERDAY
;
917 for (i
= 0; i
< rulep
->r_mon
- 1; ++i
)
918 value
+= mon_lengths
[(int) leapyear
][i
] * SECSPERDAY
;
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.
927 return value
+ rulep
->r_time
+ offset
;
931 * Given a POSIX section 8-style TZ string, fill in the rule tables as
933 * Returns true on success, false on failure.
936 tzparse(const char *name
, struct state
*sp
, bool lastditch
)
939 const char *dstname
= NULL
;
951 /* Unlike IANA, don't assume name is exactly "GMT" */
952 stdlen
= strlen(name
); /* length of standard zone name */
962 name
= getqzname(name
, '>');
965 stdlen
= name
- stdname
;
970 name
= getzname(name
);
971 stdlen
= name
- stdname
;
973 if (*name
== '\0') /* we allow empty STD abbrev, unlike IANA */
975 name
= getoffset(name
, &stdoffset
);
979 charcnt
= stdlen
+ 1;
980 if (sizeof sp
->chars
< charcnt
)
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
993 sp
->goback
= sp
->goahead
= false; /* simulate failed tzload() */
994 sp
->leapcnt
= 0; /* intentionally assume no leap seconds */
1001 name
= getqzname(name
, '>');
1004 dstlen
= name
- dstname
;
1010 name
= getzname(name
);
1011 dstlen
= name
- dstname
; /* length of DST abbr. */
1015 charcnt
+= dstlen
+ 1;
1016 if (sizeof sp
->chars
< charcnt
)
1018 if (*name
!= '\0' && *name
!= ',' && *name
!= ';')
1020 name
= getoffset(name
, &dstoffset
);
1025 dstoffset
= stdoffset
- SECSPERHOUR
;
1026 if (*name
== '\0' && !load_ok
)
1027 name
= TZDEFRULESTRING
;
1028 if (*name
== ',' || *name
== ';')
1036 int32 janoffset
= 0;
1040 if ((name
= getrule(name
, &start
)) == NULL
)
1044 if ((name
= getrule(name
, &end
)) == NULL
)
1048 sp
->typecnt
= 2; /* standard time and DST */
1051 * Two transitions per year, from EPOCH_YEAR forward.
1053 init_ttinfo(&sp
->ttis
[0], -stdoffset
, false, 0);
1054 init_ttinfo(&sp
->ttis
[1], -dstoffset
, true, stdlen
+ 1);
1055 sp
->defaulttype
= 0;
1058 yearbeg
= EPOCH_YEAR
;
1063 = year_lengths
[isleap(yearbeg
- 1)] * SECSPERDAY
;
1066 if (increment_overflow_time(&janfirst
, -yearsecs
))
1068 janoffset
= -yearsecs
;
1071 } while (EPOCH_YEAR
- YEARSPERREPEAT
/ 2 < yearbeg
);
1073 yearlim
= yearbeg
+ YEARSPERREPEAT
+ 1;
1074 for (year
= yearbeg
; year
< yearlim
; year
++)
1077 starttime
= transtime(year
, &start
, stdoffset
),
1078 endtime
= transtime(year
, &end
, dstoffset
);
1080 yearsecs
= (year_lengths
[isleap(year
)]
1082 bool reversed
= endtime
< starttime
;
1086 int32 swap
= starttime
;
1088 starttime
= endtime
;
1092 || (starttime
< endtime
1093 && (endtime
- starttime
1095 + (stdoffset
- dstoffset
)))))
1097 if (TZ_MAX_TIMES
- 2 < timecnt
)
1099 sp
->ats
[timecnt
] = janfirst
;
1100 if (!increment_overflow_time
1102 janoffset
+ starttime
))
1103 sp
->types
[timecnt
++] = !reversed
;
1104 sp
->ats
[timecnt
] = janfirst
;
1105 if (!increment_overflow_time
1107 janoffset
+ endtime
))
1109 sp
->types
[timecnt
++] = reversed
;
1110 yearlim
= year
+ YEARSPERREPEAT
+ 1;
1113 if (increment_overflow_time
1114 (&janfirst
, janoffset
+ yearsecs
))
1118 sp
->timecnt
= timecnt
;
1121 sp
->ttis
[0] = sp
->ttis
[1];
1122 sp
->typecnt
= 1; /* Perpetual DST. */
1124 else if (YEARSPERREPEAT
< year
- yearbeg
)
1125 sp
->goback
= sp
->goahead
= true;
1129 int32 theirstdoffset
;
1130 int32 theirdstoffset
;
1140 * Initial values of theirstdoffset and theirdstoffset.
1143 for (i
= 0; i
< sp
->timecnt
; ++i
)
1146 if (!sp
->ttis
[j
].tt_isdst
)
1149 -sp
->ttis
[j
].tt_utoff
;
1154 for (i
= 0; i
< sp
->timecnt
; ++i
)
1157 if (sp
->ttis
[j
].tt_isdst
)
1160 -sp
->ttis
[j
].tt_utoff
;
1166 * Initially we're assumed to be in standard time.
1169 theiroffset
= theirstdoffset
;
1172 * Now juggle transition times and types tracking offsets as you
1175 for (i
= 0; i
< sp
->timecnt
; ++i
)
1178 sp
->types
[i
] = sp
->ttis
[j
].tt_isdst
;
1179 if (sp
->ttis
[j
].tt_ttisut
)
1181 /* No adjustment to transition time */
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
1193 * Transitions from DST to DDST will effectively disappear
1194 * since POSIX provides for only one DST offset.
1196 if (isdst
&& !sp
->ttis
[j
].tt_ttisstd
)
1198 sp
->ats
[i
] += dstoffset
-
1203 sp
->ats
[i
] += stdoffset
-
1207 theiroffset
= -sp
->ttis
[j
].tt_utoff
;
1208 if (sp
->ttis
[j
].tt_isdst
)
1209 theirdstoffset
= theiroffset
;
1211 theirstdoffset
= theiroffset
;
1215 * Finally, fill in ttis.
1217 init_ttinfo(&sp
->ttis
[0], -stdoffset
, false, 0);
1218 init_ttinfo(&sp
->ttis
[1], -dstoffset
, true, stdlen
+ 1);
1220 sp
->defaulttype
= 0;
1226 sp
->typecnt
= 1; /* only standard time */
1228 init_ttinfo(&sp
->ttis
[0], -stdoffset
, false, 0);
1229 sp
->defaulttype
= 0;
1231 sp
->charcnt
= charcnt
;
1233 memcpy(cp
, stdname
, stdlen
);
1238 memcpy(cp
, dstname
, dstlen
);
1239 *(cp
+ dstlen
) = '\0';
1245 gmtload(struct state
*const sp
)
1247 if (tzload(gmt
, NULL
, sp
, true) != 0)
1248 tzparse(gmt
, sp
, true);
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.)
1258 static struct pg_tm
*
1259 localsub(struct state
const *sp
, pg_time_t
const *timep
,
1260 struct pg_tm
*const tmp
)
1262 const struct ttinfo
*ttisp
;
1264 struct pg_tm
*result
;
1265 const pg_time_t t
= *timep
;
1268 return gmtsub(timep
, 0, tmp
);
1269 if ((sp
->goback
&& t
< sp
->ats
[0]) ||
1270 (sp
->goahead
&& t
> sp
->ats
[sp
->timecnt
- 1]))
1277 seconds
= sp
->ats
[0] - t
;
1279 seconds
= t
- sp
->ats
[sp
->timecnt
- 1];
1281 years
= (seconds
/ SECSPERREPEAT
+ 1) * YEARSPERREPEAT
;
1282 seconds
= years
* AVGSECSPERYEAR
;
1287 if (newt
< sp
->ats
[0] ||
1288 newt
> sp
->ats
[sp
->timecnt
- 1])
1289 return NULL
; /* "cannot happen" */
1290 result
= localsub(sp
, &newt
, tmp
);
1295 newy
= result
->tm_year
;
1300 if (!(INT_MIN
<= newy
&& newy
<= INT_MAX
))
1302 result
->tm_year
= newy
;
1306 if (sp
->timecnt
== 0 || t
< sp
->ats
[0])
1308 i
= sp
->defaulttype
;
1313 int hi
= sp
->timecnt
;
1317 int mid
= (lo
+ hi
) >> 1;
1319 if (t
< sp
->ats
[mid
])
1324 i
= (int) sp
->types
[lo
- 1];
1326 ttisp
= &sp
->ttis
[i
];
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);
1333 result
= timesub(&t
, ttisp
->tt_utoff
, sp
, tmp
);
1336 result
->tm_isdst
= ttisp
->tt_isdst
;
1337 result
->tm_zone
= unconstify(char *, &sp
->chars
[ttisp
->tt_desigidx
]);
1344 pg_localtime(const pg_time_t
*timep
, const pg_tz
*tz
)
1346 return localsub(&tz
->state
, timep
, &tm
);
1351 * gmtsub is to gmtime as localsub is to localtime.
1353 * Except we have a private "struct state" for GMT, so no sp is passed in.
1356 static struct pg_tm
*
1357 gmtsub(pg_time_t
const *timep
, int32 offset
,
1360 struct pg_tm
*result
;
1362 /* GMT timezone state data is kept here */
1363 static struct state
*gmtptr
= NULL
;
1367 /* Allocate on first use */
1368 gmtptr
= (struct state
*) malloc(sizeof(struct state
));
1370 return NULL
; /* errno should be set by malloc */
1374 result
= timesub(timep
, offset
, gmtptr
, tmp
);
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.
1381 tmp
->tm_zone
= wildabbr
;
1383 tmp
->tm_zone
= gmtptr
->chars
;
1389 pg_gmtime(const pg_time_t
*timep
)
1391 return gmtsub(timep
, 0, &tm
);
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.
1400 leaps_thru_end_of_nonneg(int y
)
1402 return y
/ 4 - y
/ 100 + y
/ 400;
1406 leaps_thru_end_of(const int y
)
1409 ? -1 - leaps_thru_end_of_nonneg(-1 - y
)
1410 : leaps_thru_end_of_nonneg(y
));
1413 static struct pg_tm
*
1414 timesub(const pg_time_t
*timep
, int32 offset
,
1415 const struct state
*sp
, struct pg_tm
*tmp
)
1417 const struct lsinfo
*lp
;
1419 int idays
; /* unsigned would be so 2003 */
1429 i
= (sp
== NULL
) ? 0 : sp
->leapcnt
;
1433 if (*timep
>= lp
->ls_trans
)
1436 hit
= (*timep
== lp
->ls_trans
1437 && (i
== 0 ? 0 : lp
[-1].ls_corr
) < corr
);
1442 tdays
= *timep
/ SECSPERDAY
;
1443 rem
= *timep
% SECSPERDAY
;
1444 while (tdays
< 0 || tdays
>= year_lengths
[isleap(y
)])
1451 tdelta
= tdays
/ DAYSPERLYEAR
;
1452 if (!((!TYPE_SIGNED(pg_time_t
) || INT_MIN
<= tdelta
)
1453 && tdelta
<= INT_MAX
))
1457 idelta
= (tdays
< 0) ? -1 : 1;
1459 if (increment_overflow(&newy
, idelta
))
1461 leapdays
= leaps_thru_end_of(newy
- 1) -
1462 leaps_thru_end_of(y
- 1);
1463 tdays
-= ((pg_time_t
) newy
- y
) * DAYSPERNYEAR
;
1469 * Given the range, we can now fearlessly cast...
1472 rem
+= offset
- corr
;
1478 while (rem
>= SECSPERDAY
)
1485 if (increment_overflow(&y
, -1))
1487 idays
+= year_lengths
[isleap(y
)];
1489 while (idays
>= year_lengths
[isleap(y
)])
1491 idays
-= year_lengths
[isleap(y
)];
1492 if (increment_overflow(&y
, 1))
1496 if (increment_overflow(&tmp
->tm_year
, -TM_YEAR_BASE
))
1498 tmp
->tm_yday
= idays
;
1501 * The "extra" mods below avoid overflow problems.
1503 tmp
->tm_wday
= EPOCH_WDAY
+
1504 ((y
- EPOCH_YEAR
) % DAYSPERWEEK
) *
1505 (DAYSPERNYEAR
% DAYSPERWEEK
) +
1506 leaps_thru_end_of(y
- 1) -
1507 leaps_thru_end_of(EPOCH_YEAR
- 1) +
1509 tmp
->tm_wday
%= DAYSPERWEEK
;
1510 if (tmp
->tm_wday
< 0)
1511 tmp
->tm_wday
+= DAYSPERWEEK
;
1512 tmp
->tm_hour
= (int) (rem
/ SECSPERHOUR
);
1514 tmp
->tm_min
= (int) (rem
/ SECSPERMIN
);
1517 * A positive leap second requires a special representation. This uses
1518 * "... ??:59:60" et seq.
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);
1526 tmp
->tm_gmtoff
= offset
;
1535 * Normalize logic courtesy Paul Eggert.
1539 increment_overflow(int *ip
, int j
)
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.
1550 if ((i
>= 0) ? (j
> INT_MAX
- i
) : (j
< INT_MIN
- i
))
1557 increment_overflow_time(pg_time_t
*tp
, int32 j
)
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.
1566 ? (TYPE_SIGNED(pg_time_t
) ? TIME_T_MIN
- j
<= *tp
: -1 - j
< *tp
)
1567 : *tp
<= TIME_T_MAX
- j
))
1574 leapcorr(struct state
const *sp
, pg_time_t t
)
1576 struct lsinfo
const *lp
;
1583 if (t
>= lp
->ls_trans
)
1590 * Find the next DST transition time in the given zone after the given time
1592 * *timep and *tz are input arguments, the other parameters are output values.
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.
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.)
1606 * A function result of -1 indicates failure (this case does not actually
1607 * occur in our current implementation).
1610 pg_next_dst_boundary(const pg_time_t
*timep
,
1611 long int *before_gmtoff
,
1613 pg_time_t
*boundary
,
1614 long int *after_gmtoff
,
1618 const struct state
*sp
;
1619 const struct ttinfo
*ttisp
;
1622 const pg_time_t t
= *timep
;
1625 if (sp
->timecnt
== 0)
1627 /* non-DST zone, use lowest-numbered standard type */
1629 while (sp
->ttis
[i
].tt_isdst
)
1630 if (++i
>= sp
->typecnt
)
1635 ttisp
= &sp
->ttis
[i
];
1636 *before_gmtoff
= ttisp
->tt_utoff
;
1637 *before_isdst
= ttisp
->tt_isdst
;
1640 if ((sp
->goback
&& t
< sp
->ats
[0]) ||
1641 (sp
->goahead
&& t
> sp
->ats
[sp
->timecnt
- 1]))
1643 /* For values outside the transition table, extrapolate */
1651 seconds
= sp
->ats
[0] - t
;
1653 seconds
= t
- sp
->ats
[sp
->timecnt
- 1];
1655 tcycles
= seconds
/ YEARSPERREPEAT
/ AVGSECSPERYEAR
;
1658 if (tcycles
- icycles
>= 1 || icycles
- tcycles
>= 1)
1661 seconds
*= YEARSPERREPEAT
;
1662 seconds
*= AVGSECSPERYEAR
;
1667 if (newt
< sp
->ats
[0] ||
1668 newt
> sp
->ats
[sp
->timecnt
- 1])
1669 return -1; /* "cannot happen" */
1671 result
= pg_next_dst_boundary(&newt
, before_gmtoff
,
1678 *boundary
-= seconds
;
1680 *boundary
+= seconds
;
1684 if (t
>= sp
->ats
[sp
->timecnt
- 1])
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
;
1695 /* For "before", use lowest-numbered standard type */
1697 while (sp
->ttis
[i
].tt_isdst
)
1698 if (++i
>= sp
->typecnt
)
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 */
1709 ttisp
= &sp
->ttis
[i
];
1710 *after_gmtoff
= ttisp
->tt_utoff
;
1711 *after_isdst
= ttisp
->tt_isdst
;
1714 /* Else search to find the boundary following t */
1717 int hi
= sp
->timecnt
- 1;
1721 int mid
= (lo
+ hi
) >> 1;
1723 if (t
< sp
->ats
[mid
])
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
];
1736 ttisp
= &sp
->ttis
[j
];
1737 *after_gmtoff
= ttisp
->tt_utoff
;
1738 *after_isdst
= ttisp
->tt_isdst
;
1743 * Identify a timezone abbreviation's meaning in the given zone
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.
1751 * On success, returns true and sets *gmtoff and *isdst. If the abbreviation
1752 * was never used at all in this zone, returns false.
1754 * Note: abbrev is matched case-sensitively; it should be all-upper-case.
1757 pg_interpret_timezone_abbrev(const char *abbrev
,
1758 const pg_time_t
*timep
,
1763 const struct state
*sp
;
1765 const struct ttinfo
*ttisp
;
1769 const pg_time_t t
= *timep
;
1774 * Locate the abbreviation in the zone's abbreviation list. We assume
1775 * there are not duplicates in the list.
1779 while (abbrind
< sp
->charcnt
)
1781 if (strcmp(abbrev
, abbrs
+ abbrind
) == 0)
1783 while (abbrs
[abbrind
] != '\0')
1787 if (abbrind
>= sp
->charcnt
)
1788 return false; /* not there! */
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.
1796 * Use binary search to locate the first transition > cutoff time.
1800 int hi
= sp
->timecnt
;
1804 int mid
= (lo
+ hi
) >> 1;
1806 if (t
< sp
->ats
[mid
])
1815 * Scan backwards to find the latest interval using the given abbrev
1816 * before the cutoff time.
1818 for (i
= cutoff
- 1; i
>= 0; i
--)
1820 ttisp
= &sp
->ttis
[sp
->types
[i
]];
1821 if (ttisp
->tt_desigidx
== abbrind
)
1823 *gmtoff
= ttisp
->tt_utoff
;
1824 *isdst
= ttisp
->tt_isdst
;
1830 * Not there, so scan forwards to find the first one after.
1832 for (i
= cutoff
; i
< sp
->timecnt
; i
++)
1834 ttisp
= &sp
->ttis
[sp
->types
[i
]];
1835 if (ttisp
->tt_desigidx
== abbrind
)
1837 *gmtoff
= ttisp
->tt_utoff
;
1838 *isdst
= ttisp
->tt_isdst
;
1843 return false; /* hm, not actually used in any interval? */
1847 * If the given timezone uses only one GMT offset, store that offset
1848 * into *gmtoff and return true, else return false.
1851 pg_get_timezone_offset(const pg_tz
*tz
, long int *gmtoff
)
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
1858 const struct state
*sp
;
1862 for (i
= 1; i
< sp
->typecnt
; i
++)
1864 if (sp
->ttis
[i
].tt_utoff
!= sp
->ttis
[0].tt_utoff
)
1867 *gmtoff
= sp
->ttis
[0].tt_utoff
;
1872 * Return the name of the current timezone
1875 pg_get_timezone_name(pg_tz
*tz
)
1883 * Check whether timezone is acceptable.
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.
1890 pg_tz_acceptable(pg_tz
*tz
)
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.
1900 time2000
= (POSTGRES_EPOCH_JDATE
- UNIX_EPOCH_JDATE
) * SECS_PER_DAY
;
1901 tt
= pg_localtime(&time2000
, tz
);
1902 if (!tt
|| tt
->tm_sec
!= 0)