diff --git a/src/bin/initdb/findtimezone.c b/src/bin/initdb/findtimezone.c
index b14f0f8922a9305c66a07412af9c833f2d3b7230..1e6569a4da1543373b9eac1e100857eee0ec7e58 100644
--- a/src/bin/initdb/findtimezone.c
+++ b/src/bin/initdb/findtimezone.c
@@ -128,8 +128,11 @@ pg_load_tz(const char *name)
  * the C library's localtime() function.  The database zone that matches
  * furthest into the past is the one to use.  Often there will be several
  * zones with identical rankings (since the IANA database assigns multiple
- * names to many zones).  We break ties arbitrarily by preferring shorter,
- * then alphabetically earlier zone names.
+ * names to many zones).  We break ties by first checking for "preferred"
+ * names (such as "UTC"), and then arbitrarily by preferring shorter, then
+ * alphabetically earlier zone names.  (If we did not explicitly prefer
+ * "UTC", we would get the alias name "UCT" instead due to alphabetic
+ * ordering.)
  *
  * Many modern systems use the IANA database, so if we can determine the
  * system's idea of which zone it is using and its behavior matches our zone
@@ -602,6 +605,28 @@ check_system_link_file(const char *linkname, struct tztry *tt,
 #endif
 }
 
+/*
+ * Given a timezone name, determine whether it should be preferred over other
+ * names which are equally good matches. The output is arbitrary but we will
+ * use 0 for "neutral" default preference.
+ *
+ * Ideally we'd prefer the zone.tab/zone1970.tab names, since in general those
+ * are the ones offered to the user to select from. But for the moment, to
+ * minimize changes in behaviour, simply prefer UTC over alternative spellings
+ * such as UCT that otherwise cause confusion. The existing "shortest first"
+ * rule would prefer "UTC" over "Etc/UTC" so keep that the same way (while
+ * still preferring Etc/UTC over Etc/UCT).
+ */
+static int
+zone_name_pref(const char *zonename)
+{
+	if (strcmp(zonename, "UTC") == 0)
+		return 50;
+	if (strcmp(zonename, "Etc/UTC") == 0)
+		return 40;
+	return 0;
+}
+
 /*
  * Recursively scan the timezone database looking for the best match to
  * the system timezone behavior.
@@ -674,9 +699,13 @@ scan_available_timezones(char *tzdir, char *tzdirsub, struct tztry * tt,
 			else if (score == *bestscore)
 			{
 				/* Consider how to break a tie */
-				if (strlen(tzdirsub) < strlen(bestzonename) ||
-					(strlen(tzdirsub) == strlen(bestzonename) &&
-					 strcmp(tzdirsub, bestzonename) < 0))
+				int		namepref = (zone_name_pref(tzdirsub) -
+									zone_name_pref(bestzonename));
+				if (namepref > 0 ||
+					(namepref == 0 &&
+					 (strlen(tzdirsub) < strlen(bestzonename) ||
+					  (strlen(tzdirsub) == strlen(bestzonename) &&
+					   strcmp(tzdirsub, bestzonename) < 0))))
 					strlcpy(bestzonename, tzdirsub, TZ_STRLEN_MAX + 1);
 			}
 		}