mirror of
https://github.com/postgres/postgres.git
synced 2025-05-11 05:41:32 +03:00
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
This commit is contained in:
parent
d9b3bc5520
commit
7a83323f2d
@ -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;
|
|||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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,
|
|||||||
/*
|
/*
|
||||||
* 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;
|
|||||||
#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
|
|||||||
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
|
|||||||
|
|
||||||
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);
|
|||||||
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)
|
|||||||
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;
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,9 +938,11 @@ 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);
|
||||||
|
if (symlink_errno == ENOENT)
|
||||||
symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
|
symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
|
||||||
}
|
}
|
||||||
free(linkalloc);
|
free(linkalloc);
|
||||||
@ -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)
|
|||||||
{
|
{
|
||||||
/* 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)
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
#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)
|
|||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user