mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
Sync our copy of the timezone library with IANA release tzcode2017b.
zic no longer mishandles some transitions in January 2038 when it attempts to work around Qt bug 53071. This fixes a bug affecting Pacific/Tongatapu that was introduced in zic 2016e. localtime.c now contains a workaround, useful when loading a file generated by a buggy zic. There are assorted cosmetic changes as well, notably relocation of a bunch of #defines.
This commit is contained in:
@ -17,8 +17,9 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "datatype/timestamp.h"
|
||||
#include "private.h"
|
||||
#include "pgtz.h"
|
||||
|
||||
#include "private.h"
|
||||
#include "tzfile.h"
|
||||
|
||||
|
||||
@ -414,10 +415,10 @@ tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
|
||||
{
|
||||
/*
|
||||
* Attempt to reuse existing abbreviations. Without this,
|
||||
* America/Anchorage would stop working after 2037 when
|
||||
* TZ_MAX_CHARS is 50, as sp->charcnt equals 42 (for LMT CAT CAWT
|
||||
* CAPT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
|
||||
* AKST AKDT). Reusing means sp->charcnt can stay 42 in this
|
||||
* America/Anchorage would be right on the edge after 2037 when
|
||||
* TZ_MAX_CHARS is 50, as sp->charcnt equals 40 (for LMT AST AWT
|
||||
* APT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
|
||||
* AKST AKDT). Reusing means sp->charcnt can stay 40 in this
|
||||
* example.
|
||||
*/
|
||||
int gotabbr = 0;
|
||||
@ -451,6 +452,17 @@ tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
|
||||
if (gotabbr == 2)
|
||||
{
|
||||
sp->charcnt = charcnt;
|
||||
|
||||
/*
|
||||
* Ignore any trailing, no-op transitions generated by zic as
|
||||
* they don't help here and can run afoul of bugs in zic 2016j
|
||||
* or earlier.
|
||||
*/
|
||||
while (1 < sp->timecnt
|
||||
&& (sp->types[sp->timecnt - 1]
|
||||
== sp->types[sp->timecnt - 2]))
|
||||
sp->timecnt--;
|
||||
|
||||
for (i = 0; i < ts->timecnt; i++)
|
||||
if (sp->ats[sp->timecnt - 1] < ts->ats[i])
|
||||
break;
|
||||
@ -974,6 +986,8 @@ tzparse(const char *name, struct state * sp, bool lastditch)
|
||||
int yearlim;
|
||||
int timecnt;
|
||||
pg_time_t janfirst;
|
||||
int32 janoffset = 0;
|
||||
int yearbeg;
|
||||
|
||||
++name;
|
||||
if ((name = getrule(name, &start)) == NULL)
|
||||
@ -994,8 +1008,23 @@ tzparse(const char *name, struct state * sp, bool lastditch)
|
||||
sp->defaulttype = 0;
|
||||
timecnt = 0;
|
||||
janfirst = 0;
|
||||
yearlim = EPOCH_YEAR + YEARSPERREPEAT;
|
||||
for (year = EPOCH_YEAR; year < yearlim; year++)
|
||||
yearbeg = EPOCH_YEAR;
|
||||
|
||||
do
|
||||
{
|
||||
int32 yearsecs
|
||||
= year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
|
||||
|
||||
yearbeg--;
|
||||
if (increment_overflow_time(&janfirst, -yearsecs))
|
||||
{
|
||||
janoffset = -yearsecs;
|
||||
break;
|
||||
}
|
||||
} while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
|
||||
|
||||
yearlim = yearbeg + YEARSPERREPEAT + 1;
|
||||
for (year = yearbeg; year < yearlim; year++)
|
||||
{
|
||||
int32
|
||||
starttime = transtime(year, &start, stdoffset),
|
||||
@ -1020,24 +1049,34 @@ tzparse(const char *name, struct state * sp, bool lastditch)
|
||||
{
|
||||
if (TZ_MAX_TIMES - 2 < timecnt)
|
||||
break;
|
||||
yearlim = year + YEARSPERREPEAT + 1;
|
||||
sp->ats[timecnt] = janfirst;
|
||||
if (increment_overflow_time
|
||||
(&sp->ats[timecnt], starttime))
|
||||
break;
|
||||
sp->types[timecnt++] = reversed;
|
||||
if (!increment_overflow_time
|
||||
(&sp->ats[timecnt],
|
||||
janoffset + starttime))
|
||||
sp->types[timecnt++] = reversed;
|
||||
else if (janoffset)
|
||||
sp->defaulttype = reversed;
|
||||
sp->ats[timecnt] = janfirst;
|
||||
if (increment_overflow_time
|
||||
(&sp->ats[timecnt], endtime))
|
||||
break;
|
||||
sp->types[timecnt++] = !reversed;
|
||||
if (!increment_overflow_time
|
||||
(&sp->ats[timecnt],
|
||||
janoffset + endtime))
|
||||
{
|
||||
sp->types[timecnt++] = !reversed;
|
||||
yearlim = year + YEARSPERREPEAT + 1;
|
||||
}
|
||||
else if (janoffset)
|
||||
sp->defaulttype = !reversed;
|
||||
}
|
||||
if (increment_overflow_time(&janfirst, yearsecs))
|
||||
if (increment_overflow_time
|
||||
(&janfirst, janoffset + yearsecs))
|
||||
break;
|
||||
janoffset = 0;
|
||||
}
|
||||
sp->timecnt = timecnt;
|
||||
if (!timecnt)
|
||||
sp->typecnt = 1; /* Perpetual DST. */
|
||||
else if (YEARSPERREPEAT < year - yearbeg)
|
||||
sp->goback = sp->goahead = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user