mirror of
https://github.com/postgres/postgres.git
synced 2025-06-23 14:01:44 +03:00
Sync our copy of the timezone library with IANA release tzcode2018f.
About half of this is purely cosmetic changes to reduce the diff between our code and theirs, like inserting "const" markers where they have them. The other half is tracking actual code changes in zic.c and localtime.c. I don't think any of these represent near-term compatibility hazards, but it seems best to stay up to date. I also fixed longstanding bugs in our code for producing the known_abbrevs.txt list, which by chance hadn't been exposed before, but which resulted in some garbage output after applying the upstream changes in zic.c. Notably, because upstream removed their old phony transitions at the Big Bang, it's now necessary to cope with TZif files containing no DST transition times at all.
This commit is contained in:
@ -1,3 +1,5 @@
|
||||
/* Compile .zi time zone data into TZif binary files. */
|
||||
|
||||
/*
|
||||
* This file is in the public domain, so clarified as of
|
||||
* 2006-07-17 by Arthur David Olson.
|
||||
@ -130,8 +132,7 @@ static void adjleap(void);
|
||||
static void associate(void);
|
||||
static void dolink(const char *, const char *, bool);
|
||||
static char **getfields(char *buf);
|
||||
static zic_t gethms(const char *string, const char *errstring,
|
||||
bool);
|
||||
static zic_t gethms(const char *string, const char *errstring);
|
||||
static zic_t getstdoff(char *, bool *);
|
||||
static void infile(const char *filename);
|
||||
static void inleap(char **fields, int nfields);
|
||||
@ -162,7 +163,7 @@ enum
|
||||
PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};
|
||||
|
||||
/* If true, work around a bug in Qt 5.6.1 and earlier, which mishandles
|
||||
tz binary files whose POSIX-TZ-style strings contain '<'; see
|
||||
TZif files whose POSIX-TZ-style strings contain '<'; see
|
||||
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
|
||||
workaround will no longer be needed when Qt 5.6.1 and earlier are
|
||||
obsolete, say in the year 2021. */
|
||||
@ -211,7 +212,7 @@ static int typecnt;
|
||||
#define ZF_RULE 3
|
||||
#define ZF_FORMAT 4
|
||||
#define ZF_TILYEAR 5
|
||||
#define ZF_TILMONTH 6
|
||||
#define ZF_TILMONTH 6
|
||||
#define ZF_TILDAY 7
|
||||
#define ZF_TILTIME 8
|
||||
#define ZONE_MINFIELDS 5
|
||||
@ -224,12 +225,12 @@ static int typecnt;
|
||||
#define ZFC_GMTOFF 0
|
||||
#define ZFC_RULE 1
|
||||
#define ZFC_FORMAT 2
|
||||
#define ZFC_TILYEAR 3
|
||||
#define ZFC_TILYEAR 3
|
||||
#define ZFC_TILMONTH 4
|
||||
#define ZFC_TILDAY 5
|
||||
#define ZFC_TILTIME 6
|
||||
#define ZONEC_MINFIELDS 3
|
||||
#define ZONEC_MAXFIELDS 7
|
||||
#define ZFC_TILTIME 6
|
||||
#define ZONEC_MINFIELDS 3
|
||||
#define ZONEC_MAXFIELDS 7
|
||||
|
||||
/*
|
||||
* Which files are which on a Rule line.
|
||||
@ -244,7 +245,7 @@ static int typecnt;
|
||||
#define RF_TOD 7
|
||||
#define RF_STDOFF 8
|
||||
#define RF_ABBRVAR 9
|
||||
#define RULE_FIELDS 10
|
||||
#define RULE_FIELDS 10
|
||||
|
||||
/*
|
||||
* Which fields are which on a Link line.
|
||||
@ -252,7 +253,7 @@ static int typecnt;
|
||||
|
||||
#define LF_FROM 1
|
||||
#define LF_TO 2
|
||||
#define LINK_FIELDS 3
|
||||
#define LINK_FIELDS 3
|
||||
|
||||
/*
|
||||
* Which fields are which on a Leap line.
|
||||
@ -264,7 +265,7 @@ static int typecnt;
|
||||
#define LP_TIME 4
|
||||
#define LP_CORR 5
|
||||
#define LP_ROLL 6
|
||||
#define LEAP_FIELDS 7
|
||||
#define LEAP_FIELDS 7
|
||||
|
||||
/*
|
||||
* Year synonyms.
|
||||
@ -998,48 +999,6 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink)
|
||||
static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
|
||||
static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
|
||||
|
||||
/*
|
||||
* Estimated time of the Big Bang, in seconds since the POSIX epoch.
|
||||
* rounded downward to the negation of a power of two that is
|
||||
* comfortably outside the error bounds.
|
||||
*
|
||||
* For the time of the Big Bang, see:
|
||||
*
|
||||
* Ade PAR, Aghanim N, Armitage-Caplan C et al. Planck 2013 results.
|
||||
* I. Overview of products and scientific results.
|
||||
* arXiv:1303.5062 2013-03-20 20:10:01 UTC
|
||||
* <https://arxiv.org/pdf/1303.5062v1> [PDF]
|
||||
*
|
||||
* Page 36, Table 9, row Age/Gyr, column Planck+WP+highL+BAO 68% limits
|
||||
* gives the value 13.798 plus-or-minus 0.037 billion years.
|
||||
* Multiplying this by 1000000000 and then by 31557600 (the number of
|
||||
* seconds in an astronomical year) gives a value that is comfortably
|
||||
* less than 2**59, so BIG_BANG is - 2**59.
|
||||
*
|
||||
* BIG_BANG is approximate, and may change in future versions.
|
||||
* Please do not rely on its exact value.
|
||||
*/
|
||||
|
||||
#ifndef BIG_BANG
|
||||
#define BIG_BANG (- (((zic_t) 1) << 59))
|
||||
#endif
|
||||
|
||||
/* If true, work around GNOME bug 730332
|
||||
<https://bugzilla.gnome.org/show_bug.cgi?id=730332>
|
||||
by refusing to output time stamps before BIG_BANG.
|
||||
Such time stamps are physically suspect anyway.
|
||||
|
||||
The GNOME bug is scheduled to be fixed in GNOME 3.22, and if so
|
||||
this workaround will no longer be needed when GNOME 3.21 and
|
||||
earlier are obsolete, say in the year 2021. */
|
||||
enum
|
||||
{
|
||||
WORK_AROUND_GNOME_BUG_730332 = true};
|
||||
|
||||
static const zic_t early_time = (WORK_AROUND_GNOME_BUG_730332
|
||||
? BIG_BANG
|
||||
: MINVAL(zic_t, TIME_T_BITS_IN_FILE));
|
||||
|
||||
/* Return true if NAME is a directory. */
|
||||
static bool
|
||||
itsdir(char const *name)
|
||||
@ -1281,8 +1240,9 @@ infile(const char *name)
|
||||
* A null string maps to zero.
|
||||
* Call error with errstring and return zero on errors.
|
||||
*/
|
||||
|
||||
static zic_t
|
||||
gethms(char const *string, char const *errstring, bool signable)
|
||||
gethms(char const *string, char const *errstring)
|
||||
{
|
||||
/* PG: make hh be int not zic_t to avoid sscanf portability issues */
|
||||
int hh;
|
||||
@ -1299,9 +1259,7 @@ gethms(char const *string, char const *errstring, bool signable)
|
||||
|
||||
if (string == NULL || *string == '\0')
|
||||
return 0;
|
||||
if (!signable)
|
||||
sign = 1;
|
||||
else if (*string == '-')
|
||||
if (*string == '-')
|
||||
{
|
||||
sign = -1;
|
||||
++string;
|
||||
@ -1384,7 +1342,7 @@ getstdoff(char *field, bool *isdst)
|
||||
break;
|
||||
}
|
||||
}
|
||||
stdoff = gethms(field, _("invalid saved time"), true);
|
||||
stdoff = gethms(field, _("invalid saved time"));
|
||||
*isdst = dst < 0 ? stdoff != 0 : dst;
|
||||
return stdoff;
|
||||
}
|
||||
@ -1399,10 +1357,29 @@ inrule(char **fields, int nfields)
|
||||
error(_("wrong number of fields on Rule line"));
|
||||
return;
|
||||
}
|
||||
if (*fields[RF_NAME] == '\0')
|
||||
switch (*fields[RF_NAME])
|
||||
{
|
||||
error(_("nameless rule"));
|
||||
return;
|
||||
case '\0':
|
||||
case ' ':
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\v':
|
||||
case '+':
|
||||
case '-':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
error(_("Invalid rule name \"%s\""), fields[RF_NAME]);
|
||||
return;
|
||||
}
|
||||
r.r_filename = filename;
|
||||
r.r_linenum = linenum;
|
||||
@ -1507,7 +1484,7 @@ inzsub(char **fields, int nfields, bool iscont)
|
||||
}
|
||||
z.z_filename = filename;
|
||||
z.z_linenum = linenum;
|
||||
z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"), true);
|
||||
z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"));
|
||||
if ((cp = strchr(fields[i_format], '%')) != NULL)
|
||||
{
|
||||
if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
|
||||
@ -1649,7 +1626,7 @@ inleap(char **fields, int nfields)
|
||||
return;
|
||||
}
|
||||
t = dayoff * SECSPERDAY;
|
||||
tod = gethms(fields[LP_TIME], _("invalid time of day"), false);
|
||||
tod = gethms(fields[LP_TIME], _("invalid time of day"));
|
||||
cp = fields[LP_CORR];
|
||||
{
|
||||
bool positive;
|
||||
@ -1757,7 +1734,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
|
||||
break;
|
||||
}
|
||||
}
|
||||
rp->r_tod = gethms(dp, _("invalid time of day"), false);
|
||||
rp->r_tod = gethms(dp, _("invalid time of day"));
|
||||
free(dp);
|
||||
|
||||
/*
|
||||
@ -1942,7 +1919,43 @@ is32(const zic_t x)
|
||||
}
|
||||
|
||||
static void
|
||||
writezone(const char *const name, const char *const string, char version)
|
||||
swaptypes(int i, int j)
|
||||
{
|
||||
{
|
||||
zic_t t = gmtoffs[i];
|
||||
|
||||
gmtoffs[i] = gmtoffs[j];
|
||||
gmtoffs[j] = t;
|
||||
}
|
||||
{
|
||||
char t = isdsts[i];
|
||||
|
||||
isdsts[i] = isdsts[j];
|
||||
isdsts[j] = t;
|
||||
}
|
||||
{
|
||||
unsigned char t = abbrinds[i];
|
||||
|
||||
abbrinds[i] = abbrinds[j];
|
||||
abbrinds[j] = t;
|
||||
}
|
||||
{
|
||||
bool t = ttisstds[i];
|
||||
|
||||
ttisstds[i] = ttisstds[j];
|
||||
ttisstds[j] = t;
|
||||
}
|
||||
{
|
||||
bool t = ttisgmts[i];
|
||||
|
||||
ttisgmts[i] = ttisgmts[j];
|
||||
ttisgmts[j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
writezone(const char *const name, const char *const string, char version,
|
||||
int defaulttype)
|
||||
{
|
||||
FILE *fp;
|
||||
ptrdiff_t i,
|
||||
@ -1977,14 +1990,12 @@ writezone(const char *const name, const char *const string, char version)
|
||||
|
||||
toi = 0;
|
||||
fromi = 0;
|
||||
while (fromi < timecnt && attypes[fromi].at < early_time)
|
||||
++fromi;
|
||||
for (; fromi < timecnt; ++fromi)
|
||||
{
|
||||
if (toi > 1 && ((attypes[fromi].at +
|
||||
gmtoffs[attypes[toi - 1].type]) <=
|
||||
(attypes[toi - 1].at +
|
||||
gmtoffs[attypes[toi - 2].type])))
|
||||
if (toi != 0 && ((attypes[fromi].at +
|
||||
gmtoffs[attypes[toi - 1].type]) <=
|
||||
(attypes[toi - 1].at + gmtoffs[toi == 1 ? 0
|
||||
: attypes[toi - 2].type])))
|
||||
{
|
||||
attypes[toi - 1].type =
|
||||
attypes[fromi].type;
|
||||
@ -2019,8 +2030,8 @@ writezone(const char *const name, const char *const string, char version)
|
||||
}
|
||||
|
||||
/*
|
||||
* Work around QTBUG-53071 for time stamps less than y2038_boundary - 1,
|
||||
* by inserting a no-op transition at time y2038_boundary - 1. This works
|
||||
* Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by
|
||||
* inserting a no-op transition at time y2038_boundary - 1. This works
|
||||
* only for timestamps before the boundary, which should be good enough in
|
||||
* practice as QTBUG-53071 should be long-dead by 2038.
|
||||
*/
|
||||
@ -2116,7 +2127,8 @@ writezone(const char *const name, const char *const string, char version)
|
||||
int thisleapi,
|
||||
thisleapcnt,
|
||||
thisleaplim;
|
||||
int writetype[TZ_MAX_TYPES];
|
||||
int old0;
|
||||
char omittype[TZ_MAX_TYPES];
|
||||
int typemap[TZ_MAX_TYPES];
|
||||
int thistypecnt;
|
||||
char thischars[TZ_MAX_CHARS];
|
||||
@ -2144,28 +2156,19 @@ writezone(const char *const name, const char *const string, char version)
|
||||
error(_("too many transition times"));
|
||||
thistimelim = thistimei + thistimecnt;
|
||||
thisleaplim = thisleapi + thisleapcnt;
|
||||
for (i = 0; i < typecnt; ++i)
|
||||
writetype[i] = thistimecnt == timecnt;
|
||||
if (thistimecnt == 0)
|
||||
{
|
||||
/*
|
||||
* No transition times fall in the current (32- or 64-bit) window.
|
||||
*/
|
||||
if (typecnt != 0)
|
||||
writetype[typecnt - 1] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = thistimei - 1; i < thistimelim; ++i)
|
||||
if (i >= 0)
|
||||
writetype[types[i]] = true;
|
||||
memset(omittype, true, typecnt);
|
||||
omittype[defaulttype] = false;
|
||||
for (i = thistimei; i < thistimelim; i++)
|
||||
omittype[types[i]] = false;
|
||||
|
||||
/*
|
||||
* Reorder types to make DEFAULTTYPE type 0. Use TYPEMAP to swap OLD0
|
||||
* and DEFAULTTYPE so that DEFAULTTYPE appears as type 0 in the output
|
||||
* instead of OLD0. TYPEMAP also omits unused types.
|
||||
*/
|
||||
old0 = strlen(omittype);
|
||||
swaptypes(old0, defaulttype);
|
||||
|
||||
/*
|
||||
* For America/Godthab and Antarctica/Palmer
|
||||
*/
|
||||
if (thistimei == 0)
|
||||
writetype[0] = true;
|
||||
}
|
||||
#ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
|
||||
|
||||
/*
|
||||
@ -2187,8 +2190,8 @@ writezone(const char *const name, const char *const string, char version)
|
||||
mrudst = types[i];
|
||||
else
|
||||
mrustd = types[i];
|
||||
for (i = 0; i < typecnt; ++i)
|
||||
if (writetype[i])
|
||||
for (i = old0; i < typecnt; i++)
|
||||
if (!omittype[i])
|
||||
{
|
||||
if (isdsts[i])
|
||||
hidst = i;
|
||||
@ -2205,7 +2208,7 @@ writezone(const char *const name, const char *const string, char version)
|
||||
ttisstds[mrudst],
|
||||
ttisgmts[mrudst]);
|
||||
isdsts[mrudst] = 1;
|
||||
writetype[type] = true;
|
||||
omittype[type] = false;
|
||||
}
|
||||
if (histd >= 0 && mrustd >= 0 && histd != mrustd &&
|
||||
gmtoffs[histd] != gmtoffs[mrustd])
|
||||
@ -2217,22 +2220,26 @@ writezone(const char *const name, const char *const string, char version)
|
||||
ttisstds[mrustd],
|
||||
ttisgmts[mrustd]);
|
||||
isdsts[mrustd] = 0;
|
||||
writetype[type] = true;
|
||||
omittype[type] = false;
|
||||
}
|
||||
}
|
||||
#endif /* !defined
|
||||
* LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */
|
||||
thistypecnt = 0;
|
||||
for (i = 0; i < typecnt; ++i)
|
||||
typemap[i] = writetype[i] ? thistypecnt++ : -1;
|
||||
for (i = old0; i < typecnt; i++)
|
||||
if (!omittype[i])
|
||||
typemap[i == old0 ? defaulttype
|
||||
: i == defaulttype ? old0 : i]
|
||||
= thistypecnt++;
|
||||
|
||||
for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
|
||||
indmap[i] = -1;
|
||||
thischarcnt = 0;
|
||||
for (i = 0; i < typecnt; ++i)
|
||||
for (i = old0; i < typecnt; i++)
|
||||
{
|
||||
char *thisabbr;
|
||||
|
||||
if (!writetype[i])
|
||||
if (omittype[i])
|
||||
continue;
|
||||
if (indmap[abbrinds[i]] >= 0)
|
||||
continue;
|
||||
@ -2267,23 +2274,16 @@ writezone(const char *const name, const char *const string, char version)
|
||||
DO(tzh_typecnt);
|
||||
DO(tzh_charcnt);
|
||||
#undef DO
|
||||
for (i = thistimei; i < thistimelim; ++i)
|
||||
if (pass == 1)
|
||||
|
||||
/*
|
||||
* Output an INT32_MIN "transition" if appropriate; see above.
|
||||
*/
|
||||
puttzcode(((ats[i] < PG_INT32_MIN) ?
|
||||
PG_INT32_MIN : ats[i]), fp);
|
||||
else
|
||||
/* PG: print current timezone abbreviations if requested */
|
||||
if (print_abbrevs && pass == 2)
|
||||
{
|
||||
/* Print "type" data for periods ending after print_cutoff */
|
||||
for (i = thistimei; i < thistimelim; ++i)
|
||||
{
|
||||
puttzcode64(ats[i], fp);
|
||||
|
||||
/* Print current timezone abbreviations if requested */
|
||||
if (print_abbrevs &&
|
||||
(i == thistimelim - 1 || ats[i + 1] > print_cutoff))
|
||||
if (i == thistimelim - 1 || ats[i + 1] > print_cutoff)
|
||||
{
|
||||
unsigned char tm = typemap[types[i]];
|
||||
unsigned char tm = types[i];
|
||||
char *thisabbrev = &thischars[indmap[abbrinds[tm]]];
|
||||
|
||||
/* filter out assorted junk entries */
|
||||
@ -2295,6 +2295,32 @@ writezone(const char *const name, const char *const string, char version)
|
||||
isdsts[tm] ? "\tD" : "");
|
||||
}
|
||||
}
|
||||
/* Print the default type if we have no transitions at all */
|
||||
if (thistimei >= thistimelim)
|
||||
{
|
||||
unsigned char tm = defaulttype;
|
||||
char *thisabbrev = &thischars[indmap[abbrinds[tm]]];
|
||||
|
||||
/* filter out assorted junk entries */
|
||||
if (strcmp(thisabbrev, GRANDPARENTED) != 0 &&
|
||||
strcmp(thisabbrev, "zzz") != 0)
|
||||
fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
|
||||
thisabbrev,
|
||||
gmtoffs[tm],
|
||||
isdsts[tm] ? "\tD" : "");
|
||||
}
|
||||
}
|
||||
|
||||
for (i = thistimei; i < thistimelim; ++i)
|
||||
if (pass == 1)
|
||||
|
||||
/*
|
||||
* Output an INT32_MIN "transition" if appropriate; see above.
|
||||
*/
|
||||
puttzcode(((ats[i] < PG_INT32_MIN) ?
|
||||
PG_INT32_MIN : ats[i]), fp);
|
||||
else
|
||||
puttzcode64(ats[i], fp);
|
||||
for (i = thistimei; i < thistimelim; ++i)
|
||||
{
|
||||
unsigned char uc;
|
||||
@ -2302,8 +2328,8 @@ writezone(const char *const name, const char *const string, char version)
|
||||
uc = typemap[types[i]];
|
||||
fwrite(&uc, sizeof uc, 1, fp);
|
||||
}
|
||||
for (i = 0; i < typecnt; ++i)
|
||||
if (writetype[i])
|
||||
for (i = old0; i < typecnt; i++)
|
||||
if (!omittype[i])
|
||||
{
|
||||
puttzcode(gmtoffs[i], fp);
|
||||
putc(isdsts[i], fp);
|
||||
@ -2346,12 +2372,13 @@ writezone(const char *const name, const char *const string, char version)
|
||||
puttzcode64(todo, fp);
|
||||
puttzcode(corr[i], fp);
|
||||
}
|
||||
for (i = 0; i < typecnt; ++i)
|
||||
if (writetype[i])
|
||||
for (i = old0; i < typecnt; i++)
|
||||
if (!omittype[i])
|
||||
putc(ttisstds[i], fp);
|
||||
for (i = 0; i < typecnt; ++i)
|
||||
if (writetype[i])
|
||||
for (i = old0; i < typecnt; i++)
|
||||
if (!omittype[i])
|
||||
putc(ttisgmts[i], fp);
|
||||
swaptypes(old0, defaulttype);
|
||||
}
|
||||
fprintf(fp, "\n%s\n", string);
|
||||
close_file(fp, directory, name);
|
||||
@ -2757,6 +2784,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
zic_t one = 1;
|
||||
zic_t y2038_boundary = one << 31;
|
||||
zic_t max_year0;
|
||||
int defaulttype = -1;
|
||||
|
||||
max_abbr_len = 2 + max_format_len + max_abbrvar_len;
|
||||
max_envvar_len = 2 * max_abbr_len + 5 * 9;
|
||||
@ -2880,9 +2908,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
*/
|
||||
stdoff = 0;
|
||||
zp = &zpfirst[i];
|
||||
usestart = i > 0 && (zp - 1)->z_untiltime > early_time;
|
||||
usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
|
||||
useuntil = i < (zonecount - 1);
|
||||
if (useuntil && zp->z_untiltime <= early_time)
|
||||
if (useuntil && zp->z_untiltime <= min_time)
|
||||
continue;
|
||||
gmtoff = zp->z_gmtoff;
|
||||
eat(zp->z_filename, zp->z_linenum);
|
||||
@ -2901,7 +2929,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
usestart = false;
|
||||
}
|
||||
else
|
||||
addtt(early_time, type);
|
||||
defaulttype = type;
|
||||
}
|
||||
else
|
||||
for (year = min_year; year <= max_year; ++year)
|
||||
@ -3032,6 +3060,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
offset = oadd(zp->z_gmtoff, rp->r_stdoff);
|
||||
type = addtype(offset, ab, rp->r_isdst,
|
||||
rp->r_todisstd, rp->r_todisgmt);
|
||||
if (defaulttype < 0 && !rp->r_isdst)
|
||||
defaulttype = type;
|
||||
if (rp->r_hiyear == ZIC_MAX
|
||||
&& !(0 <= lastatmax
|
||||
&& ktime < attypes[lastatmax].at))
|
||||
@ -3050,11 +3080,15 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
if (*startbuf == '\0')
|
||||
error(_("cannot determine time zone abbreviation to use just after until time"));
|
||||
else
|
||||
addtt(starttime,
|
||||
addtype(startoff, startbuf,
|
||||
startoff != zp->z_gmtoff,
|
||||
startttisstd,
|
||||
startttisgmt));
|
||||
{
|
||||
bool isdst = startoff != zp->z_gmtoff;
|
||||
|
||||
type = addtype(startoff, startbuf, isdst,
|
||||
startttisstd, startttisgmt);
|
||||
if (defaulttype < 0 && !isdst)
|
||||
defaulttype = type;
|
||||
addtt(starttime, type);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3071,6 +3105,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
starttime = tadd(starttime, -gmtoff);
|
||||
}
|
||||
}
|
||||
if (defaulttype < 0)
|
||||
defaulttype = 0;
|
||||
if (0 <= lastatmax)
|
||||
attypes[lastatmax].dontmerge = true;
|
||||
if (do_extend)
|
||||
@ -3100,7 +3136,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
attypes[timecnt - 1].dontmerge = true;
|
||||
}
|
||||
}
|
||||
writezone(zpfirst->z_name, envvar, version);
|
||||
writezone(zpfirst->z_name, envvar, version, defaulttype);
|
||||
free(startbuf);
|
||||
free(ab);
|
||||
free(envvar);
|
||||
@ -3109,21 +3145,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
static void
|
||||
addtt(zic_t starttime, int type)
|
||||
{
|
||||
if (starttime <= early_time
|
||||
|| (timecnt == 1 && attypes[0].at < early_time))
|
||||
{
|
||||
gmtoffs[0] = gmtoffs[type];
|
||||
isdsts[0] = isdsts[type];
|
||||
ttisstds[0] = ttisstds[type];
|
||||
ttisgmts[0] = ttisgmts[type];
|
||||
if (abbrinds[type] != 0)
|
||||
strcpy(chars, &chars[abbrinds[type]]);
|
||||
abbrinds[0] = 0;
|
||||
charcnt = strlen(chars) + 1;
|
||||
typecnt = 1;
|
||||
timecnt = 0;
|
||||
type = 0;
|
||||
}
|
||||
attypes = growalloc(attypes, sizeof *attypes, timecnt, &timecnt_alloc);
|
||||
attypes[timecnt].at = starttime;
|
||||
attypes[timecnt].dontmerge = false;
|
||||
@ -3361,7 +3382,7 @@ is_alpha(char a)
|
||||
}
|
||||
|
||||
/* If A is an uppercase character in the C locale, return its lowercase
|
||||
* counterpart. Otherwise, return A. */
|
||||
counterpart. Otherwise, return A. */
|
||||
static char
|
||||
lowerit(char a)
|
||||
{
|
||||
@ -3628,6 +3649,18 @@ rpytime(const struct rule *rp, zic_t wantedy)
|
||||
dayoff = 0;
|
||||
m = TM_JANUARY;
|
||||
y = EPOCH_YEAR;
|
||||
if (y < wantedy)
|
||||
{
|
||||
wantedy -= y;
|
||||
dayoff = (wantedy / YEARSPERREPEAT) * (SECSPERREPEAT / SECSPERDAY);
|
||||
wantedy %= YEARSPERREPEAT;
|
||||
wantedy += y;
|
||||
}
|
||||
else if (wantedy < 0)
|
||||
{
|
||||
dayoff = (wantedy / YEARSPERREPEAT) * (SECSPERREPEAT / SECSPERDAY);
|
||||
wantedy %= YEARSPERREPEAT;
|
||||
}
|
||||
while (wantedy != y)
|
||||
{
|
||||
if (wantedy > y)
|
||||
@ -3706,7 +3739,6 @@ will not work with pre-2004 versions of zic"));
|
||||
if (dayoff > max_time / SECSPERDAY)
|
||||
return max_time;
|
||||
t = (zic_t) dayoff * SECSPERDAY;
|
||||
|
||||
return tadd(t, rp->r_tod);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user