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