Commit b45f6613 authored by Tom Lane's avatar Tom Lane

Sync our copy of the timezone library with IANA release tzcode2018e.

The non-cosmetic changes involve teaching the "zic" tzdata compiler about
negative DST.  While I'm not currently intending that we start using
negative-DST data right away, it seems possible that somebody would try
to use our copy of zic with bleeding-edge IANA data.  So we'd better be
out in front of this change code-wise, even though it doesn't matter for
the data file we're shipping.

Discussion: https://postgr.es/m/30996.1525445902@sss.pgh.pa.us
parent 59cb3230
...@@ -55,7 +55,7 @@ match properly on the old version. ...@@ -55,7 +55,7 @@ match properly on the old version.
Time Zone code Time Zone code
============== ==============
The code in this directory is currently synced with tzcode release 2017c. The code in this directory is currently synced with tzcode release 2018e.
There are many cosmetic (and not so cosmetic) differences from the There are many cosmetic (and not so cosmetic) differences from the
original tzcode library, but diffs in the upstream version should usually original tzcode library, but diffs in the upstream version should usually
be propagated to our version. Here are some notes about that. be propagated to our version. Here are some notes about that.
......
...@@ -60,9 +60,8 @@ static int tzdefrules_loaded = 0; ...@@ -60,9 +60,8 @@ static int tzdefrules_loaded = 0;
/* /*
* The DST rules to use if TZ has no rules and we can't load TZDEFRULES. * The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
* Default to US rules as of 2017-05-07. * Default to US rules as of 2017-05-07.
* POSIX 1003.1 section 8.1.1 says that the default DST rules are * POSIX does not specify the default DST rules;
* implementation dependent; for historical reasons, US rules are a * for historical reasons, US rules are a common default.
* common default.
*/ */
#define TZDEFRULESTRING ",M3.2.0,M11.1.0" #define TZDEFRULESTRING ",M3.2.0,M11.1.0"
...@@ -1158,10 +1157,11 @@ tzparse(const char *name, struct state *sp, bool lastditch) ...@@ -1158,10 +1157,11 @@ tzparse(const char *name, struct state *sp, bool lastditch)
else else
{ {
/* /*
* If summer time is in effect, and the transition time * If daylight saving time is in effect, and the
* was not specified as standard time, add the summer time * transition time was not specified as standard time, add
* offset to the transition time; otherwise, add the * the daylight saving time offset to the transition time;
* standard time offset to the transition time. * otherwise, add the standard time offset to the
* transition time.
*/ */
/* /*
......
...@@ -203,7 +203,7 @@ _fmt(const char *format, const struct pg_tm *t, char *pt, ...@@ -203,7 +203,7 @@ _fmt(const char *format, const struct pg_tm *t, char *pt,
/* /*
* Locale modifiers of C99 and later. The sequences %Ec * Locale modifiers of C99 and later. The sequences %Ec
* %EC %Ex %EX %Ey %EY %Od %oe %OH %OI %Om %OM %OS %Ou %OU * %EC %Ex %EX %Ey %EY %Od %oe %OH %OI %Om %OM %OS %Ou %OU
* %OV %Ow %OW %Oy are supposed to provide alternate * %OV %Ow %OW %Oy are supposed to provide alternative
* representations. * representations.
*/ */
goto label; goto label;
......
...@@ -39,6 +39,10 @@ typedef int64 zic_t; ...@@ -39,6 +39,10 @@ typedef int64 zic_t;
#define linkat(fromdir, from, todir, to, flag) \ #define linkat(fromdir, from, todir, to, flag) \
(itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to)) (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to))
#endif #endif
/* Port to native MS-Windows and to ancient UNIX. */
#if !defined S_ISDIR && defined S_IFDIR && defined S_IFMT
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
/* The maximum ptrdiff_t value, for pre-C99 platforms. */ /* The maximum ptrdiff_t value, for pre-C99 platforms. */
#ifndef PTRDIFF_MAX #ifndef PTRDIFF_MAX
...@@ -74,7 +78,9 @@ struct rule ...@@ -74,7 +78,9 @@ struct rule
bool r_todisstd; /* above is standard time if 1 or wall clock bool r_todisstd; /* above is standard time if 1 or wall clock
* time if 0 */ * time if 0 */
bool r_todisgmt; /* above is GMT if 1 or local time if 0 */ bool r_todisgmt; /* above is GMT if 1 or local time if 0 */
zic_t r_stdoff; /* offset from standard time */ bool r_isdst; /* is this daylight saving time? */
zic_t r_stdoff; /* offset from default time (which is usually
* standard time) */
const char *r_abbrvar; /* variable part of abbreviation */ const char *r_abbrvar; /* variable part of abbreviation */
bool r_todo; /* a rule to do (used in outzone) */ bool r_todo; /* a rule to do (used in outzone) */
...@@ -96,10 +102,11 @@ struct zone ...@@ -96,10 +102,11 @@ struct zone
const char *z_name; const char *z_name;
zic_t z_gmtoff; zic_t z_gmtoff;
const char *z_rule; char *z_rule;
const char *z_format; const char *z_format;
char z_format_specifier; char z_format_specifier;
bool z_isdst;
zic_t z_stdoff; zic_t z_stdoff;
struct rule *z_rules; struct rule *z_rules;
...@@ -125,6 +132,7 @@ static void dolink(const char *, const char *, bool); ...@@ -125,6 +132,7 @@ static void dolink(const char *, const char *, bool);
static char **getfields(char *buf); static char **getfields(char *buf);
static zic_t gethms(const char *string, const char *errstring, static zic_t gethms(const char *string, const char *errstring,
bool); bool);
static zic_t getstdoff(char *, bool *);
static void infile(const char *filename); static void infile(const char *filename);
static void inleap(char **fields, int nfields); static void inleap(char **fields, int nfields);
static void inlink(char **fields, int nfields); static void inlink(char **fields, int nfields);
...@@ -530,7 +538,7 @@ usage(FILE *stream, int status) ...@@ -530,7 +538,7 @@ usage(FILE *stream, int status)
fprintf(stream, fprintf(stream,
_("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -P ] \\\n" _("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -P ] \\\n"
"\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n" "\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n"
"\t[ -L leapseconds ] [ filename ... ]\n\n" "\t[ -t localtime-link ] [ -L leapseconds ] [ filename ... ]\n\n"
"Report bugs to %s.\n"), "Report bugs to %s.\n"),
progname, progname, PACKAGE_BUGREPORT); progname, progname, PACKAGE_BUGREPORT);
if (status == EXIT_SUCCESS) if (status == EXIT_SUCCESS)
...@@ -566,6 +574,7 @@ static const char *psxrules; ...@@ -566,6 +574,7 @@ static const char *psxrules;
static const char *lcltime; static const char *lcltime;
static const char *directory; static const char *directory;
static const char *leapsec; static const char *leapsec;
static const char *tzdefault;
static const char *yitcommand; static const char *yitcommand;
int int
...@@ -597,7 +606,7 @@ main(int argc, char **argv) ...@@ -597,7 +606,7 @@ main(int argc, char **argv)
{ {
usage(stdout, EXIT_SUCCESS); usage(stdout, EXIT_SUCCESS);
} }
while ((c = getopt(argc, argv, "d:l:p:L:vPsy:")) != EOF && c != -1) while ((c = getopt(argc, argv, "d:l:L:p:Pst:vy:")) != EOF && c != -1)
switch (c) switch (c)
{ {
default: default:
...@@ -635,6 +644,17 @@ main(int argc, char **argv) ...@@ -635,6 +644,17 @@ main(int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
break; break;
case 't':
if (tzdefault != NULL)
{
fprintf(stderr,
_("%s: More than one -t option"
" specified\n"),
progname);
return EXIT_FAILURE;
}
tzdefault = optarg;
break;
case 'y': case 'y':
if (yitcommand == NULL) if (yitcommand == NULL)
{ {
...@@ -675,6 +695,8 @@ main(int argc, char **argv) ...@@ -675,6 +695,8 @@ main(int argc, char **argv)
usage(stderr, EXIT_FAILURE); /* usage message by request */ usage(stderr, EXIT_FAILURE); /* usage message by request */
if (directory == NULL) if (directory == NULL)
directory = "data"; directory = "data";
if (tzdefault == NULL)
tzdefault = TZDEFAULT;
if (yitcommand == NULL) if (yitcommand == NULL)
yitcommand = "yearistype"; yitcommand = "yearistype";
...@@ -716,7 +738,7 @@ main(int argc, char **argv) ...@@ -716,7 +738,7 @@ main(int argc, char **argv)
if (lcltime != NULL) if (lcltime != NULL)
{ {
eat(_("command line"), 1); eat(_("command line"), 1);
dolink(lcltime, TZDEFAULT, true); dolink(lcltime, tzdefault, true);
} }
if (psxrules != NULL) if (psxrules != NULL)
{ {
...@@ -916,10 +938,12 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink) ...@@ -916,10 +938,12 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink)
char const *contents = absolute ? fromfield : linkalloc; char const *contents = absolute ? fromfield : linkalloc;
int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno; int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
if (symlink_errno == ENOENT && !todirs_made) if (!todirs_made
&& (symlink_errno == ENOENT || symlink_errno == ENOTSUP))
{ {
mkdirs(tofield, true); mkdirs(tofield, true);
symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno; if (symlink_errno == ENOENT)
symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
} }
free(linkalloc); free(linkalloc);
if (symlink_errno == 0) if (symlink_errno == 0)
...@@ -1140,8 +1164,7 @@ associate(void) ...@@ -1140,8 +1164,7 @@ associate(void)
* Maybe we have a local standard time offset. * Maybe we have a local standard time offset.
*/ */
eat(zp->z_filename, zp->z_linenum); eat(zp->z_filename, zp->z_linenum);
zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), zp->z_stdoff = getstdoff(zp->z_rule, &zp->z_isdst);
true);
/* /*
* Note, though, that if there's no rule, a '%s' in the format is * Note, though, that if there's no rule, a '%s' in the format is
...@@ -1263,10 +1286,16 @@ gethms(char const *string, char const *errstring, bool signable) ...@@ -1263,10 +1286,16 @@ gethms(char const *string, char const *errstring, bool signable)
{ {
/* PG: make hh be int not zic_t to avoid sscanf portability issues */ /* PG: make hh be int not zic_t to avoid sscanf portability issues */
int hh; int hh;
int mm, int sign,
ss, mm = 0,
sign; ss = 0;
char xs; char hhx,
mmx,
ssx,
xr = '0',
xs;
int tenths = 0;
bool ok = true;
if (string == NULL || *string == '\0') if (string == NULL || *string == '\0')
return 0; return 0;
...@@ -1279,12 +1308,32 @@ gethms(char const *string, char const *errstring, bool signable) ...@@ -1279,12 +1308,32 @@ gethms(char const *string, char const *errstring, bool signable)
} }
else else
sign = 1; sign = 1;
if (sscanf(string, "%d%c", &hh, &xs) == 1) switch (sscanf(string,
mm = ss = 0; "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
else if (sscanf(string, "%d:%d%c", &hh, &mm, &xs) == 2) &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs))
ss = 0; {
else if (sscanf(string, "%d:%d:%d%c", &hh, &mm, &ss, &xs) default:
!= 3) ok = false;
break;
case 8:
ok = '0' <= xr && xr <= '9';
/* fallthrough */
case 7:
ok &= ssx == '.';
if (ok && noise)
warning(_("fractional seconds rejected by"
" pre-2018 versions of zic"));
/* fallthrough */
case 5:
ok &= mmx == ':';
/* fallthrough */
case 3:
ok &= hhx == ':';
/* fallthrough */
case 1:
break;
}
if (!ok)
{ {
error("%s", errstring); error("%s", errstring);
return 0; return 0;
...@@ -1304,6 +1353,7 @@ gethms(char const *string, char const *errstring, bool signable) ...@@ -1304,6 +1353,7 @@ gethms(char const *string, char const *errstring, bool signable)
return 0; return 0;
} }
#endif #endif
ss += 5 + ((ss ^ 1) & (xr == '0')) <= tenths; /* Round to even. */
if (noise && (hh > HOURSPERDAY || if (noise && (hh > HOURSPERDAY ||
(hh == HOURSPERDAY && (mm != 0 || ss != 0)))) (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
warning(_("values over 24 hours not handled by pre-2007 versions of zic")); warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
...@@ -1311,6 +1361,34 @@ gethms(char const *string, char const *errstring, bool signable) ...@@ -1311,6 +1361,34 @@ gethms(char const *string, char const *errstring, bool signable)
sign * (mm * SECSPERMIN + ss)); sign * (mm * SECSPERMIN + ss));
} }
static zic_t
getstdoff(char *field, bool *isdst)
{
int dst = -1;
zic_t stdoff;
size_t fieldlen = strlen(field);
if (fieldlen != 0)
{
char *ep = field + fieldlen - 1;
switch (*ep)
{
case 'd':
dst = 1;
*ep = '\0';
break;
case 's':
dst = 0;
*ep = '\0';
break;
}
}
stdoff = gethms(field, _("invalid saved time"), true);
*isdst = dst < 0 ? stdoff != 0 : dst;
return stdoff;
}
static void static void
inrule(char **fields, int nfields) inrule(char **fields, int nfields)
{ {
...@@ -1328,7 +1406,7 @@ inrule(char **fields, int nfields) ...@@ -1328,7 +1406,7 @@ inrule(char **fields, int nfields)
} }
r.r_filename = filename; r.r_filename = filename;
r.r_linenum = linenum; r.r_linenum = linenum;
r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), true); r.r_stdoff = getstdoff(fields[RF_STDOFF], &r.r_isdst);
rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND], rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
r.r_name = ecpyalloc(fields[RF_NAME]); r.r_name = ecpyalloc(fields[RF_NAME]);
...@@ -1349,11 +1427,11 @@ inzone(char **fields, int nfields) ...@@ -1349,11 +1427,11 @@ inzone(char **fields, int nfields)
error(_("wrong number of fields on Zone line")); error(_("wrong number of fields on Zone line"));
return false; return false;
} }
if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0)
{ {
error( error(
_("\"Zone %s\" line and -l option are mutually exclusive"), _("\"Zone %s\" line and -l option are mutually exclusive"),
TZDEFAULT); tzdefault);
return false; return false;
} }
if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL)
...@@ -2171,7 +2249,7 @@ writezone(const char *const name, const char *const string, char version) ...@@ -2171,7 +2249,7 @@ writezone(const char *const name, const char *const string, char version)
} }
#define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp) #define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp)
tzh = tzh0; tzh = tzh0;
strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); memcpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
tzh.tzh_version[0] = version; tzh.tzh_version[0] = version;
convert(thistypecnt, tzh.tzh_ttisgmtcnt); convert(thistypecnt, tzh.tzh_ttisgmtcnt);
convert(thistypecnt, tzh.tzh_ttisstdcnt); convert(thistypecnt, tzh.tzh_ttisstdcnt);
...@@ -2299,7 +2377,7 @@ abbroffset(char *buf, zic_t offset) ...@@ -2299,7 +2377,7 @@ abbroffset(char *buf, zic_t offset)
offset /= MINSPERHOUR; offset /= MINSPERHOUR;
if (100 <= offset) if (100 <= offset)
{ {
error(_("%%z UTC offset magnitude exceeds 99:59:59")); error(_("%%z UT offset magnitude exceeds 99:59:59"));
return "%z"; return "%z";
} }
else else
...@@ -2326,7 +2404,7 @@ abbroffset(char *buf, zic_t offset) ...@@ -2326,7 +2404,7 @@ abbroffset(char *buf, zic_t offset)
static size_t static size_t
doabbr(char *abbr, struct zone const *zp, char const *letters, doabbr(char *abbr, struct zone const *zp, char const *letters,
zic_t stdoff, bool doquotes) bool isdst, zic_t stdoff, bool doquotes)
{ {
char *cp; char *cp;
char *slashp; char *slashp;
...@@ -2344,7 +2422,7 @@ doabbr(char *abbr, struct zone const *zp, char const *letters, ...@@ -2344,7 +2422,7 @@ doabbr(char *abbr, struct zone const *zp, char const *letters,
letters = "%s"; letters = "%s";
sprintf(abbr, format, letters); sprintf(abbr, format, letters);
} }
else if (stdoff != 0) else if (isdst)
{ {
strcpy(abbr, slashp + 1); strcpy(abbr, slashp + 1);
} }
...@@ -2471,7 +2549,7 @@ stringrule(char *result, const struct rule *const rp, const zic_t dstoff, ...@@ -2471,7 +2549,7 @@ stringrule(char *result, const struct rule *const rp, const zic_t dstoff,
} }
if (rp->r_todisgmt) if (rp->r_todisgmt)
tod += gmtoff; tod += gmtoff;
if (rp->r_todisstd && rp->r_stdoff == 0) if (rp->r_todisstd && !rp->r_isdst)
tod += dstoff; tod += dstoff;
if (tod != 2 * SECSPERMIN * MINSPERHOUR) if (tod != 2 * SECSPERMIN * MINSPERHOUR)
{ {
...@@ -2536,7 +2614,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) ...@@ -2536,7 +2614,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
continue; continue;
if (rp->r_yrtype != NULL) if (rp->r_yrtype != NULL)
continue; continue;
if (rp->r_stdoff == 0) if (!rp->r_isdst)
{ {
if (stdrp == NULL) if (stdrp == NULL)
stdrp = rp; stdrp = rp;
...@@ -2562,7 +2640,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) ...@@ -2562,7 +2640,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
for (i = 0; i < zp->z_nrules; ++i) for (i = 0; i < zp->z_nrules; ++i)
{ {
rp = &zp->z_rules[i]; rp = &zp->z_rules[i];
if (rp->r_stdoff == 0 && rule_cmp(stdabbrrp, rp) < 0) if (!rp->r_isdst && rule_cmp(stdabbrrp, rp) < 0)
stdabbrrp = rp; stdabbrrp = rp;
if (rule_cmp(stdrp, rp) < 0) if (rule_cmp(stdrp, rp) < 0)
stdrp = rp; stdrp = rp;
...@@ -2576,7 +2654,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) ...@@ -2576,7 +2654,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
if (stdrp != NULL && stdrp->r_hiyear == 2037) if (stdrp != NULL && stdrp->r_hiyear == 2037)
return YEAR_BY_YEAR_ZONE; return YEAR_BY_YEAR_ZONE;
if (stdrp != NULL && stdrp->r_stdoff != 0) if (stdrp != NULL && stdrp->r_isdst)
{ {
/* Perpetual DST. */ /* Perpetual DST. */
dstr.r_month = TM_JANUARY; dstr.r_month = TM_JANUARY;
...@@ -2584,6 +2662,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) ...@@ -2584,6 +2662,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
dstr.r_dayofmonth = 1; dstr.r_dayofmonth = 1;
dstr.r_tod = 0; dstr.r_tod = 0;
dstr.r_todisstd = dstr.r_todisgmt = false; dstr.r_todisstd = dstr.r_todisgmt = false;
dstr.r_isdst = stdrp->r_isdst;
dstr.r_stdoff = stdrp->r_stdoff; dstr.r_stdoff = stdrp->r_stdoff;
dstr.r_abbrvar = stdrp->r_abbrvar; dstr.r_abbrvar = stdrp->r_abbrvar;
stdr.r_month = TM_DECEMBER; stdr.r_month = TM_DECEMBER;
...@@ -2591,6 +2670,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) ...@@ -2591,6 +2670,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
stdr.r_dayofmonth = 31; stdr.r_dayofmonth = 31;
stdr.r_tod = SECSPERDAY + stdrp->r_stdoff; stdr.r_tod = SECSPERDAY + stdrp->r_stdoff;
stdr.r_todisstd = stdr.r_todisgmt = false; stdr.r_todisstd = stdr.r_todisgmt = false;
stdr.r_isdst = false;
stdr.r_stdoff = 0; stdr.r_stdoff = 0;
stdr.r_abbrvar stdr.r_abbrvar
= (stdabbrrp ? stdabbrrp->r_abbrvar : ""); = (stdabbrrp ? stdabbrrp->r_abbrvar : "");
...@@ -2598,10 +2678,10 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) ...@@ -2598,10 +2678,10 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
stdrp = &stdr; stdrp = &stdr;
} }
} }
if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_stdoff != 0)) if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_isdst))
return -1; return -1;
abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar; abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
len = doabbr(result, zp, abbrvar, 0, true); len = doabbr(result, zp, abbrvar, false, 0, true);
offsetlen = stringoffset(result + len, -zp->z_gmtoff); offsetlen = stringoffset(result + len, -zp->z_gmtoff);
if (!offsetlen) if (!offsetlen)
{ {
...@@ -2611,7 +2691,8 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) ...@@ -2611,7 +2691,8 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
len += offsetlen; len += offsetlen;
if (dstrp == NULL) if (dstrp == NULL)
return compat; return compat;
len += doabbr(result + len, zp, dstrp->r_abbrvar, dstrp->r_stdoff, true); len += doabbr(result + len, zp, dstrp->r_abbrvar,
dstrp->r_isdst, dstrp->r_stdoff, true);
if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR)
{ {
offsetlen = stringoffset(result + len, offsetlen = stringoffset(result + len,
...@@ -2810,9 +2891,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) ...@@ -2810,9 +2891,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
if (zp->z_nrules == 0) if (zp->z_nrules == 0)
{ {
stdoff = zp->z_stdoff; stdoff = zp->z_stdoff;
doabbr(startbuf, zp, NULL, stdoff, false); doabbr(startbuf, zp, NULL, zp->z_isdst, stdoff, false);
type = addtype(oadd(zp->z_gmtoff, stdoff), type = addtype(oadd(zp->z_gmtoff, stdoff),
startbuf, stdoff != 0, startttisstd, startbuf, zp->z_isdst, startttisstd,
startttisgmt); startttisgmt);
if (usestart) if (usestart)
{ {
...@@ -2927,6 +3008,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) ...@@ -2927,6 +3008,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
stdoff); stdoff);
doabbr(startbuf, zp, doabbr(startbuf, zp,
rp->r_abbrvar, rp->r_abbrvar,
rp->r_isdst,
rp->r_stdoff, rp->r_stdoff,
false); false);
continue; continue;
...@@ -2938,6 +3020,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) ...@@ -2938,6 +3020,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
doabbr(startbuf, doabbr(startbuf,
zp, zp,
rp->r_abbrvar, rp->r_abbrvar,
rp->r_isdst,
rp->r_stdoff, rp->r_stdoff,
false); false);
} }
...@@ -2945,9 +3028,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) ...@@ -2945,9 +3028,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
eats(zp->z_filename, zp->z_linenum, eats(zp->z_filename, zp->z_linenum,
rp->r_filename, rp->r_linenum); rp->r_filename, rp->r_linenum);
doabbr(ab, zp, rp->r_abbrvar, doabbr(ab, zp, rp->r_abbrvar,
rp->r_stdoff, false); rp->r_isdst, rp->r_stdoff, false);
offset = oadd(zp->z_gmtoff, rp->r_stdoff); offset = oadd(zp->z_gmtoff, rp->r_stdoff);
type = addtype(offset, ab, rp->r_stdoff != 0, type = addtype(offset, ab, rp->r_isdst,
rp->r_todisstd, rp->r_todisgmt); rp->r_todisstd, rp->r_todisgmt);
if (rp->r_hiyear == ZIC_MAX if (rp->r_hiyear == ZIC_MAX
&& !(0 <= lastatmax && !(0 <= lastatmax
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment