diff --git a/src/timezone/pgtz.c b/src/timezone/pgtz.c
index b951830b026c1e80303efdd11fe4db98fe8052b7..bdd2250667229fa326f258e855b70827c80eb357 100644
--- a/src/timezone/pgtz.c
+++ b/src/timezone/pgtz.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.59 2008/02/16 21:16:04 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.60 2008/07/01 03:40:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -198,7 +198,7 @@ scan_directory_ci(const char *dirname, const char *fname, int fnamelen,
 #define T_WEEK	((time_t) (60*60*24*7))
 #define T_MONTH ((time_t) (60*60*24*31))
 
-#define MAX_TEST_TIMES (52*100) /* 100 years, or 1904..2004 */
+#define MAX_TEST_TIMES (52*100) /* 100 years */
 
 struct tztry
 {
@@ -367,6 +367,7 @@ identify_system_timezone(void)
 	time_t		t;
 	struct tztry tt;
 	struct tm  *tm;
+	int			thisyear;
 	int			bestscore;
 	char		tmptzdir[MAXPGPATH];
 	int			std_ofs;
@@ -379,11 +380,14 @@ identify_system_timezone(void)
 
 	/*
 	 * Set up the list of dates to be probed to see how well our timezone
-	 * matches the system zone.  We first probe January and July of 2004; this
-	 * serves to quickly eliminate the vast majority of the TZ database
-	 * entries.  If those dates match, we probe every week from 2004 backwards
-	 * to late 1904.  (Weekly resolution is good enough to identify DST
-	 * transition rules, since everybody switches on Sundays.)	The further
+	 * matches the system zone.  We first probe January and July of the
+	 * current year; this serves to quickly eliminate the vast majority of the
+	 * TZ database entries.  If those dates match, we probe every week for 100
+	 * years backwards from the current July.  (Weekly resolution is good
+	 * enough to identify DST transition rules, since everybody switches on
+	 * Sundays.)  This is sufficient to cover most of the Unix time_t range,
+	 * and we don't want to look further than that since many systems won't
+	 * have sane TZ behavior further back anyway.  The further
 	 * back the zone matches, the better we score it.  This may seem like a
 	 * rather random way of doing things, but experience has shown that
 	 * system-supplied timezone definitions are likely to have DST behavior
@@ -393,9 +397,29 @@ identify_system_timezone(void)
 	 * (Note: we probe Thursdays, not Sundays, to avoid triggering
 	 * DST-transition bugs in localtime itself.)
 	 */
+	tnow = time(NULL);
+	tm = localtime(&tnow);
+	if (!tm)
+		return NULL;			/* give up if localtime is broken... */
+	thisyear = tm->tm_year + 1900;
+
+	t = build_time_t(thisyear, 1, 15);
+	/*
+	 * Round back to GMT midnight Thursday.  This depends on the knowledge
+	 * that the time_t origin is Thu Jan 01 1970.  (With a different origin
+	 * we'd be probing some other day of the week, but it wouldn't matter
+	 * anyway unless localtime() had DST-transition bugs.)
+	 */
+	t -= (t % T_WEEK);
+
 	tt.n_test_times = 0;
-	tt.test_times[tt.n_test_times++] = build_time_t(2004, 1, 15);
-	tt.test_times[tt.n_test_times++] = t = build_time_t(2004, 7, 15);
+	tt.test_times[tt.n_test_times++] = t;
+
+	t = build_time_t(thisyear, 7, 15);
+	t -= (t % T_WEEK);
+
+	tt.test_times[tt.n_test_times++] = t;
+
 	while (tt.n_test_times < MAX_TEST_TIMES)
 	{
 		t -= T_WEEK;
@@ -410,7 +434,12 @@ identify_system_timezone(void)
 							 &tt,
 							 &bestscore, resultbuf);
 	if (bestscore > 0)
+	{
+		/* Ignore zic's rather silly "Factory" time zone; use GMT instead */
+		if (strcmp(resultbuf, "Factory") == 0)
+			return NULL;
 		return resultbuf;
+	}
 
 	/*
 	 * Couldn't find a match in the database, so next we try constructed zone