From f4898c945fb18c3ced03101adecb6c58e4128ad5 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 11 Mar 2010 18:43:24 +0000 Subject: 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. --- src/timezone/localtime.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'src/timezone/localtime.c') diff --git a/src/timezone/localtime.c b/src/timezone/localtime.c index 869b4462092..da1646c25d9 100644 --- a/src/timezone/localtime.c +++ b/src/timezone/localtime.c @@ -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; } -- cgit v1.2.3