diff --git a/src/timezone/README b/src/timezone/README
index db39d5347c704c86fb341845aedc2ad923d0a7b1..a4ba7053c4eef8d3e6d36dc4911a730f134bc116 100644
--- a/src/timezone/README
+++ b/src/timezone/README
@@ -1,4 +1,4 @@
-$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.
 
diff --git a/src/timezone/localtime.c b/src/timezone/localtime.c
index 869b44620924c5b6d49b1542c97f7857a7bcdce2..da1646c25d946c652e0800374dfeca6a1d406865 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;
 }
 
diff --git a/src/timezone/strftime.c b/src/timezone/strftime.c
index 39443af9d5a05d3181deb02f254c4eb5ef2eb6a8..4400af53d0ca2b871a588d0456153ca0c888b4a6 100644
--- a/src/timezone/strftime.c
+++ b/src/timezone/strftime.c
@@ -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)
diff --git a/src/timezone/zic.c b/src/timezone/zic.c
index 2f03f558fc6880384e15b281a94d3f4a8c5d265a..50ce774535ee48654f4e3249d6fedc371dbb538f 100644
--- a/src/timezone/zic.c
+++ b/src/timezone/zic.c
@@ -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)
 	{