Commit f4898c94 authored by Tom Lane's avatar Tom Lane

Sync timezone code with tzcode 2010c from the Olson group. This fixes some

corner cases that come up in certain timezones (apparently, only those with
lots and lots of distinct TZ transition rules, as far as I can gather from
a quick scan of their archives).  Per suggestion from Jeevan Chalke.

Back-patch to 8.4.  Possibly we need to push this into earlier releases
as well, but I'm hesitant to update them to the 64-bit tzcode without
more thought and testing.
parent e0f9e2b6
$PostgreSQL: pgsql/src/timezone/README,v 1.7 2008/03/21 13:23:29 momjian Exp $
$PostgreSQL: pgsql/src/timezone/README,v 1.8 2010/03/11 18:43:24 tgl Exp $
Timezone
========
......@@ -7,7 +7,7 @@ This is a PostgreSQL adapted version of the timezone library from:
ftp://elsie.nci.nih.gov/pub/tzcode*.tar.gz
The code is currently synced with release 2007k. There are many cosmetic
The code is currently synced with release 2010c. There are many cosmetic
(and not so cosmetic) differences from the original tzcode library, but
diffs in the upstream version should usually be propagated to our version.
......
......@@ -3,7 +3,7 @@
* 1996-06-05 by Arthur David Olson.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/localtime.c,v 1.21 2009/06/11 14:49:15 momjian Exp $
* $PostgreSQL: pgsql/src/timezone/localtime.c,v 1.22 2010/03/11 18:43:24 tgl Exp $
*/
/*
......@@ -164,6 +164,7 @@ tzload(const char *name, char *canonname, struct state * sp, int doextend)
4 * TZ_MAX_TIMES];
} u;
sp->goback = sp->goahead = FALSE;
if (name == NULL && (name = TZDEFAULT) == NULL)
return -1;
if (name[0] == ':')
......@@ -357,16 +358,25 @@ tzload(const char *name, char *canonname, struct state * sp, int doextend)
sp->ttis[sp->typecnt++] = ts.ttis[1];
}
}
i = 2 * YEARSPERREPEAT;
sp->goback = sp->goahead = sp->timecnt > i;
sp->goback = sp->goback &&
typesequiv(sp, sp->types[i], sp->types[0]) &&
differ_by_repeat(sp->ats[i], sp->ats[0]);
sp->goahead = sp->goahead &&
typesequiv(sp, sp->types[sp->timecnt - 1],
sp->types[sp->timecnt - 1 - i]) &&
differ_by_repeat(sp->ats[sp->timecnt - 1],
sp->ats[sp->timecnt - 1 - i]);
if (sp->timecnt > 1)
{
for (i = 1; i < sp->timecnt; ++i)
if (typesequiv(sp, sp->types[i], sp->types[0]) &&
differ_by_repeat(sp->ats[i], sp->ats[0]))
{
sp->goback = TRUE;
break;
}
for (i = sp->timecnt - 2; i >= 0; --i)
if (typesequiv(sp, sp->types[sp->timecnt - 1],
sp->types[i]) &&
differ_by_repeat(sp->ats[sp->timecnt - 1],
sp->ats[i]))
{
sp->goahead = TRUE;
break;
}
}
return 0;
}
......
......@@ -15,7 +15,7 @@
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/strftime.c,v 1.14 2009/06/11 14:49:15 momjian Exp $
* $PostgreSQL: pgsql/src/timezone/strftime.c,v 1.15 2010/03/11 18:43:24 tgl Exp $
*/
#include "postgres.h"
......@@ -169,7 +169,7 @@ _fmt(const char *format, const struct pg_tm * t, char *pt, const char *ptlim,
{
int warn2 = IN_SOME;
pt = _fmt(Locale->c_fmt, t, pt, ptlim, warnp);
pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
if (warn2 == IN_ALL)
warn2 = IN_THIS;
if (warn2 > *warnp)
......
......@@ -3,7 +3,7 @@
* 2006-07-17 by Arthur David Olson.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/zic.c,v 1.24 2009/06/11 14:49:15 momjian Exp $
* $PostgreSQL: pgsql/src/timezone/zic.c,v 1.25 2010/03/11 18:43:24 tgl Exp $
*/
#include "postgres_fe.h"
......@@ -41,7 +41,7 @@ typedef int64 zic_t;
#endif
#endif
static char elsieid[] = "@(#)zic.c 8.17";
static char elsieid[] = "@(#)zic.c 8.20";
/*
* On some ancient hosts, predicates like `isspace(C)' are defined
......@@ -162,7 +162,7 @@ static void rulesub(struct rule * rp,
const char *dayp, const char *timep);
static void setboundaries(void);
static pg_time_t tadd(const pg_time_t t1, long t2);
static void usage(void);
static void usage(FILE *stream, int status);
static void writezone(const char *name, const char *string);
static int yearistype(int year, const char *type);
......@@ -454,13 +454,15 @@ warning(const char *string)
}
static void
usage(void)
usage(FILE *stream, int status)
{
(void) fprintf(stderr, _("%s: usage is %s \
[ --version ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"),
(void) fprintf(stream, _("%s: usage is %s \
[ --version ] [ --help ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\
\n\
Report bugs to tz@elsie.nci.nih.gov.\n"),
progname, progname);
exit(EXIT_FAILURE);
exit(status);
}
static const char *psxrules;
......@@ -492,11 +494,15 @@ main(int argc, char *argv[])
(void) printf("%s\n", elsieid);
exit(EXIT_SUCCESS);
}
else if (strcmp(argv[i], "--help") == 0)
{
usage(stdout, EXIT_SUCCESS);
}
while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1)
switch (c)
{
default:
usage();
usage(stderr, EXIT_FAILURE);
case 'd':
if (directory == NULL)
directory = optarg;
......@@ -560,7 +566,7 @@ main(int argc, char *argv[])
break;
}
if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
usage(); /* usage message by request */
usage(stderr, EXIT_FAILURE); /* usage message by request */
if (directory == NULL)
directory = "data";
if (yitcommand == NULL)
......@@ -2035,7 +2041,7 @@ stringzone(char *result, const struct zone * zpfirst, int zonecount)
if (stdrp != NULL && stdrp->r_hiyear == 2037)
return;
}
if (stdrp == NULL && zp->z_nrules != 0)
if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_stdoff != 0))
return;
abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
doabbr(result, zp->z_format, abbrvar, FALSE, TRUE);
......@@ -2115,7 +2121,7 @@ outzone(const struct zone * zpfirst, int zonecount)
if (leapseen)
{
updateminmax(leapminyear);
updateminmax(leapmaxyear);
updateminmax(leapmaxyear + (leapmaxyear < INT_MAX));
}
for (i = 0; i < zonecount; ++i)
{
......
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