aboutsummaryrefslogtreecommitdiff
path: root/src/timezone
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-10-16 15:22:10 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2014-10-16 15:22:10 -0400
commitb2cbced9eef20692b51a84d68d469627f4fc43ac (patch)
tree21774c6c010312abd2045c5d7b73f63a6828ec2c /src/timezone
parent90063a7612e2730f7757c2a80ba384bbe7e35c4b (diff)
downloadpostgresql-b2cbced9eef20692b51a84d68d469627f4fc43ac.tar.gz
postgresql-b2cbced9eef20692b51a84d68d469627f4fc43ac.zip
Support timezone abbreviations that sometimes change.
Up to now, PG has assumed that any given timezone abbreviation (such as "EDT") represents a constant GMT offset in the usage of any particular region; we had a way to configure what that offset was, but not for it to be changeable over time. But, as with most things horological, this view of the world is too simplistic: there are numerous regions that have at one time or another switched to a different GMT offset but kept using the same timezone abbreviation. Almost the entire Russian Federation did that a few years ago, and later this month they're going to do it again. And there are similar examples all over the world. To cope with this, invent the notion of a "dynamic timezone abbreviation", which is one that is referenced to a particular underlying timezone (as defined in the IANA timezone database) and means whatever it currently means in that zone. For zones that use or have used daylight-savings time, the standard and DST abbreviations continue to have the property that you can specify standard or DST time and get that time offset whether or not DST was theoretically in effect at the time. However, the abbreviations mean what they meant at the time in question (or most recently before that time) rather than being absolutely fixed. The standard abbreviation-list files have been changed to use this behavior for abbreviations that have actually varied in meaning since 1970. The old simple-numeric definitions are kept for abbreviations that have not changed, since they are a bit faster to resolve. While this is clearly a new feature, it seems necessary to back-patch it into all active branches, because otherwise use of Russian zone abbreviations is going to become even more problematic than it already was. This change supersedes the changes in commit 513d06ded et al to modify the fixed meanings of the Russian abbreviations; since we've not shipped that yet, this will avoid an undesirably incompatible (not to mention incorrect) change in behavior for timestamps between 2011 and 2014. This patch makes some cosmetic changes in ecpglib to keep its usage of datetime lookup tables as similar as possible to the backend code, but doesn't do anything about the increasingly obsolete set of timezone abbreviation definitions that are hard-wired into ecpglib. Whatever we do about that will likely not be appropriate material for back-patching. Also, a potential free() of a garbage pointer after an out-of-memory failure in ecpglib has been fixed. This patch also fixes pre-existing bugs in DetermineTimeZoneOffset() that caused it to produce unexpected results near a timezone transition, if both the "before" and "after" states are marked as standard time. We'd only ever thought about or tested transitions between standard and DST time, but that's not what's happening when a zone simply redefines their base GMT offset. In passing, update the SGML documentation to refer to the Olson/zoneinfo/ zic timezone database as the "IANA" database, since it's now being maintained under the auspices of IANA.
Diffstat (limited to 'src/timezone')
-rw-r--r--src/timezone/known_abbrevs.txt10
-rw-r--r--src/timezone/localtime.c108
-rw-r--r--src/timezone/tznames/America.txt12
-rw-r--r--src/timezone/tznames/Antarctica.txt4
-rw-r--r--src/timezone/tznames/Asia.txt80
-rw-r--r--src/timezone/tznames/Atlantic.txt6
-rw-r--r--src/timezone/tznames/Australia.txt2
-rw-r--r--src/timezone/tznames/Default105
-rw-r--r--src/timezone/tznames/Europe.txt9
-rw-r--r--src/timezone/tznames/Indian.txt2
-rw-r--r--src/timezone/tznames/Pacific.txt18
-rw-r--r--src/timezone/tznames/README25
-rw-r--r--src/timezone/zic.c2
13 files changed, 250 insertions, 133 deletions
diff --git a/src/timezone/known_abbrevs.txt b/src/timezone/known_abbrevs.txt
index f309a48066b..db78cf3492b 100644
--- a/src/timezone/known_abbrevs.txt
+++ b/src/timezone/known_abbrevs.txt
@@ -85,6 +85,7 @@ IDT 10800 D
IOT 21600
IRDT 16200 D
IRKT 28800
+IRKT 32400
IRST 12600
IST 19800
IST 3600 D
@@ -93,11 +94,13 @@ JST 32400
KGT 21600
KOST 39600
KRAT 25200
+KRAT 28800
KST 32400
LHDT 39600 D
LHST 37800
LINT 50400
MAGT 36000
+MAGT 43200
MART -34200
MAWT 18000
MDT -21600 D
@@ -107,6 +110,7 @@ MHT 43200
MIST 39600
MMT 23400
MSK 10800
+MSK 14400
MST -25200
MUT 14400
MVT 18000
@@ -115,6 +119,7 @@ NCT 39600
NDT -9000 D
NFT 41400
NOVT 21600
+NOVT 25200
NPT 20700
NRT 43200
NST -12600
@@ -122,6 +127,7 @@ NUT -39600
NZDT 46800 D
NZST 43200
OMST 21600
+OMST 25200
ORAT 18000
PDT -25200 D
PET -18000
@@ -141,6 +147,7 @@ QYZT 21600
RET 14400
ROTT -10800
SAKT 36000
+SAKT 39600
SAMT 14400
SAST 7200
SBT 39600
@@ -165,6 +172,7 @@ UYT -10800
UZT 18000
VET -16200
VLAT 36000
+VLAT 39600
VOST 21600
VUT 39600
WAKT 43200
@@ -182,4 +190,6 @@ WSDT 50400 D
WSST 46800
XJT 21600
YAKT 32400
+YAKT 36000
YEKT 18000
+YEKT 21600
diff --git a/src/timezone/localtime.c b/src/timezone/localtime.c
index 85b227c9255..19a24e1d960 100644
--- a/src/timezone/localtime.c
+++ b/src/timezone/localtime.c
@@ -1292,9 +1292,9 @@ increment_overflow(int *number, int delta)
}
/*
- * Find the next DST transition time after the given time
+ * Find the next DST transition time in the given zone after the given time
*
- * *timep is the input value, the other parameters are output values.
+ * *timep and *tz are input arguments, the other parameters are output values.
*
* When the function result is 1, *boundary is set to the time_t
* representation of the next DST transition time after *timep,
@@ -1445,6 +1445,110 @@ pg_next_dst_boundary(const pg_time_t *timep,
}
/*
+ * Identify a timezone abbreviation's meaning in the given zone
+ *
+ * Determine the GMT offset and DST flag associated with the abbreviation.
+ * This is generally used only when the abbreviation has actually changed
+ * meaning over time; therefore, we also take a UTC cutoff time, and return
+ * the meaning in use at or most recently before that time, or the meaning
+ * in first use after that time if the abbrev was never used before that.
+ *
+ * On success, returns TRUE and sets *gmtoff and *isdst. If the abbreviation
+ * was never used at all in this zone, returns FALSE.
+ *
+ * Note: abbrev is matched case-sensitively; it should be all-upper-case.
+ */
+bool
+pg_interpret_timezone_abbrev(const char *abbrev,
+ const pg_time_t *timep,
+ long int *gmtoff,
+ int *isdst,
+ const pg_tz *tz)
+{
+ const struct state *sp;
+ const char *abbrs;
+ const struct ttinfo *ttisp;
+ int abbrind;
+ int cutoff;
+ int i;
+ const pg_time_t t = *timep;
+
+ sp = &tz->state;
+
+ /*
+ * Locate the abbreviation in the zone's abbreviation list. We assume
+ * there are not duplicates in the list.
+ */
+ abbrs = sp->chars;
+ abbrind = 0;
+ while (abbrind < sp->charcnt)
+ {
+ if (strcmp(abbrev, abbrs + abbrind) == 0)
+ break;
+ while (abbrs[abbrind] != '\0')
+ abbrind++;
+ abbrind++;
+ }
+ if (abbrind >= sp->charcnt)
+ return FALSE; /* not there! */
+
+ /*
+ * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
+ * (goback/goahead zones). Finding the newest or oldest meaning of the
+ * abbreviation should get us what we want, since extrapolation would just
+ * be repeating the newest or oldest meanings.
+ *
+ * Use binary search to locate the first transition > cutoff time.
+ */
+ {
+ int lo = 0;
+ int hi = sp->timecnt;
+
+ while (lo < hi)
+ {
+ int mid = (lo + hi) >> 1;
+
+ if (t < sp->ats[mid])
+ hi = mid;
+ else
+ lo = mid + 1;
+ }
+ cutoff = lo;
+ }
+
+ /*
+ * Scan backwards to find the latest interval using the given abbrev
+ * before the cutoff time.
+ */
+ for (i = cutoff - 1; i >= 0; i--)
+ {
+ ttisp = &sp->ttis[sp->types[i]];
+ if (ttisp->tt_abbrind == abbrind)
+ {
+ *gmtoff = ttisp->tt_gmtoff;
+ *isdst = ttisp->tt_isdst;
+ return TRUE;
+ }
+ }
+
+ /*
+ * Not there, so scan forwards to find the first one after.
+ */
+ for (i = cutoff; i < sp->timecnt; i++)
+ {
+ ttisp = &sp->ttis[sp->types[i]];
+ if (ttisp->tt_abbrind == abbrind)
+ {
+ *gmtoff = ttisp->tt_gmtoff;
+ *isdst = ttisp->tt_isdst;
+ return TRUE;
+ }
+ }
+
+ return FALSE; /* hm, not actually used in any interval? */
+}
+
+/*
* If the given timezone uses only one GMT offset, store that offset
* into *gmtoff and return TRUE, else return FALSE.
*/
diff --git a/src/timezone/tznames/America.txt b/src/timezone/tznames/America.txt
index 54b51fe0054..9e6273207c1 100644
--- a/src/timezone/tznames/America.txt
+++ b/src/timezone/tznames/America.txt
@@ -47,7 +47,7 @@ AMT -14400 # Amazon Time
# (America/Cuiaba)
# (America/Manaus)
# (America/Porto_Velho)
-ART -10800 # Argentina Time
+ART America/Argentina/Buenos_Aires # Argentina Time
# (America/Argentina/Buenos_Aires)
# (America/Argentina/Cordoba)
# (America/Argentina/Tucuman)
@@ -58,7 +58,7 @@ ART -10800 # Argentina Time
# (America/Argentina/Mendoza)
# (America/Argentina/Rio_Gallegos)
# (America/Argentina/Ushuaia)
-ARST -7200 D # Argentina Summer Time
+ARST America/Argentina/Buenos_Aires # Argentina Summer Time
# CONFLICT! AST is not unique
# Other timezones:
# - AST: Arabic Standard Time (Asia)
@@ -228,7 +228,7 @@ GMT 0 # Greenwich Mean Time
# (Etc/GMT)
# (Europe/Dublin)
# (Europe/London)
-GYT -14400 # Guyana Time
+GYT America/Guyana # Guyana Time
# (America/Guyana)
HADT -32400 D # Hawaii-Aleutian Daylight Time
# (America/Adak)
@@ -285,15 +285,15 @@ PST -28800 # Pacific Standard Time
# (Pacific/Pitcairn)
PYST -10800 D # Paraguay Summer Time
# (America/Asuncion)
-PYT -14400 # Paraguay Time
+PYT America/Asuncion # Paraguay Time
# (America/Asuncion)
-SRT -10800 # Suriname Time
+SRT America/Paramaribo # Suriname Time
# (America/Paramaribo)
UYST -7200 D # Uruguay Summer Time
# (America/Montevideo)
UYT -10800 # Uruguay Time
# (America/Montevideo)
-VET -16200 # Venezuela Time (caution: this used to mean -14400)
+VET America/Caracas # Venezuela Time
# (America/Caracas)
WGST -7200 D # Western Greenland Summer Time
# (America/Godthab)
diff --git a/src/timezone/tznames/Antarctica.txt b/src/timezone/tznames/Antarctica.txt
index 5a032506526..2359020ef87 100644
--- a/src/timezone/tznames/Antarctica.txt
+++ b/src/timezone/tznames/Antarctica.txt
@@ -16,11 +16,11 @@ CLST -10800 D # Chile Summer Time
CLT -14400 # Chile Time
# (America/Santiago)
# (Antarctica/Palmer)
-DAVT 25200 # Davis Time (Antarctica)
+DAVT Antarctica/Davis # Davis Time (Antarctica)
# (Antarctica/Davis)
DDUT 36000 # Dumont-d`Urville Time (Antarctica)
# (Antarctica/DumontDUrville)
-MAWT 18000 # Mawson Time (Antarctica) (caution: this used to mean 21600)
+MAWT Antarctica/Mawson # Mawson Time (Antarctica)
# (Antarctica/Mawson)
MIST 39600 # Macquarie Island Time
# (Antarctica/Macquarie)
diff --git a/src/timezone/tznames/Asia.txt b/src/timezone/tznames/Asia.txt
index 8c3cb354713..bb286464297 100644
--- a/src/timezone/tznames/Asia.txt
+++ b/src/timezone/tznames/Asia.txt
@@ -15,17 +15,19 @@ ALMT 21600 # Alma-Ata Time
# CONFLICT! AMST is not unique
# Other timezones:
# - AMST: Amazon Summer Time (America)
-AMST 18000 D # Armenia Summer Time
+AMST Asia/Yerevan # Armenia Summer Time
# (Asia/Yerevan)
# CONFLICT! AMT is not unique
# Other timezones:
# - AMT: Amazon Time (America)
-AMT 14400 # Armenia Time
+AMT Asia/Yerevan # Armenia Time
# (Asia/Yerevan)
-ANAST 46800 D # Anadyr Summer Time (obsolete)
-ANAT 43200 # Anadyr Time
+ANAST Asia/Anadyr # Anadyr Summer Time (obsolete)
+ANAT Asia/Anadyr # Anadyr Time
# (Asia/Anadyr)
-AQTT 18000 # Aqtau Time (obsolete)
+AQTST Asia/Aqtau # Aqtau Summer Time (obsolete)
+AQTT Asia/Aqtau # Aqtau Time
+ # (Asia/Aqtau)
# CONFLICT! AST is not unique
# Other timezones:
# - AST: Atlantic Standard Time (America)
@@ -41,9 +43,9 @@ AST 10800 # Arabia Standard Time
# (Asia/Kuwait)
# (Asia/Qatar)
# (Asia/Riyadh)
-AZST 18000 D # Azerbaijan Summer Time
+AZST Asia/Baku # Azerbaijan Summer Time
# (Asia/Baku)
-AZT 14400 # Azerbaijan Time
+AZT Asia/Baku # Azerbaijan Time
# (Asia/Baku)
BDT 21600 # Bangladesh Time
# (Asia/Dhaka)
@@ -54,7 +56,7 @@ BTT 21600 # Bhutan Time
# (Asia/Thimphu)
CCT 28800 # China Coastal Time (not in zic)
CHOST 36000 D # Choibalsan Summer Time (obsolete)
-CHOT 28800 # Choibalsan Time (caution: this used to mean 32400)
+CHOT Asia/Choibalsan # Choibalsan Time
# (Asia/Choibalsan)
CIT 28800 # Central Indonesia Time (obsolete, WITA is now preferred)
EEST 10800 D # East-Egypt Summer Time
@@ -105,9 +107,8 @@ EET 7200 # East-Egypt Time
# (Europe/Vilnius)
# (Europe/Zaporozhye)
EIT 32400 # East Indonesia Time (obsolete, WIT is now preferred)
-GEST 14400 D # Georgia Summer Time (obsolete)
- # (Asia/Tbilisi)
-GET 14400 # Georgia Time (caution: this used to mean 10800)
+GEST Asia/Tbilisi # Georgia Summer Time (obsolete)
+GET Asia/Tbilisi # Georgia Time
# (Asia/Tbilisi)
# CONFLICT! GST is not unique
# Other timezones:
@@ -117,7 +118,7 @@ GST 14400 # Gulf Standard Time
# (Asia/Muscat)
HKT 28800 # Hong Kong Time (not in zic)
HOVST 28800 D # Hovd Summer Time (obsolete)
-HOVT 25200 # Hovd Time
+HOVT Asia/Hovd # Hovd Time
# (Asia/Hovd)
ICT 25200 # Indochina Time
# (Asia/Bangkok)
@@ -126,12 +127,12 @@ ICT 25200 # Indochina Time
# (Asia/Vientiane)
IDT 10800 D # Israel Daylight Time
# (Asia/Jerusalem)
-IRDT 16200 D # Iran Daylight Time
+IRDT Asia/Tehran # Iran Daylight Time
# (Asia/Tehran)
-IRKST 32400 D # Irkutsk Summer Time (obsolete)
-IRKT 28800 # Irkutsk Time (caution: this used to mean 32400)
+IRKST Asia/Irkutsk # Irkutsk Summer Time (obsolete)
+IRKT Asia/Irkutsk # Irkutsk Time
# (Asia/Irkutsk)
-IRST 12600 # Iran Standard Time
+IRST Asia/Tehran # Iran Standard Time
# (Asia/Tehran)
IRT 12600 # Iran Time (not in zic)
# CONFLICT! IST is not unique
@@ -151,35 +152,34 @@ JST 32400 # Japan Standard Time
# (Asia/Tokyo)
KDT 36000 D # Korean Daylight Time (not in zic)
KGST 21600 D # Kyrgyzstan Summer Time (obsolete)
+KGT Asia/Bishkek # Kyrgyzstan Time
# (Asia/Bishkek)
-KGT 21600 # Kyrgyzstan Time (caution: this used to mean 18000)
- # (Asia/Bishkek)
-KRAST 28800 D # Krasnoyarsk Summer Time (obsolete)
-KRAT 25200 # Krasnoyarsk Time (caution: this used to mean 28800)
+KRAST Asia/Krasnoyarsk # Krasnoyarsk Summer Time (obsolete)
+KRAT Asia/Krasnoyarsk # Krasnoyarsk Time
# (Asia/Krasnoyarsk)
KST 32400 # Korean Standard Time
# (Asia/Pyongyang)
-LKT 21600 # Lanka Time (obsolete)
-MAGST 43200 D # Magadan Summer Time (obsolete)
-MAGT 36000 # Magadan Time (caution: this used to mean 43200)
+LKT Asia/Colombo # Lanka Time (obsolete)
+MAGST Asia/Magadan # Magadan Summer Time (obsolete)
+MAGT Asia/Magadan # Magadan Time
# (Asia/Magadan)
MMT 23400 # Myanmar Time
# (Asia/Rangoon)
MYT 28800 # Malaysia Time
# (Asia/Kuala_Lumpur)
# (Asia/Kuching)
-NOVST 25200 D # Novosibirsk Summer Time (obsolete)
-NOVT 21600 # Novosibirsk Time (caution: this used to mean 25200)
+NOVST Asia/Novosibirsk # Novosibirsk Summer Time (obsolete)
+NOVT Asia/Novosibirsk # Novosibirsk Time
# (Asia/Novosibirsk)
NPT 20700 # Nepal Time
# (Asia/Katmandu)
-OMSST 25200 D # Omsk Summer Time (obsolete)
-OMST 21600 # Omsk Time (caution: this used to mean 25200)
+OMSST Asia/Omsk # Omsk Summer Time (obsolete)
+OMST Asia/Omsk # Omsk Time
# (Asia/Omsk)
-ORAT 18000 # Oral Time
+ORAT Asia/Oral # Oral Time
# (Asia/Oral)
-PETST 46800 D # Petropavlovsk-Kamchatski Summer Time (obsolete)
-PETT 43200 # Petropavlovsk-Kamchatski Time
+PETST Asia/Kamchatka # Petropavlovsk-Kamchatski Summer Time (obsolete)
+PETT Asia/Kamchatka # Petropavlovsk-Kamchatski Time
# (Asia/Kamchatka)
PHT 28800 # Philippine Time
# (Asia/Manila)
@@ -189,10 +189,10 @@ PKST 21600 D # Pakistan Summer Time
# (Asia/Karachi)
QYZT 21600 # Kizilorda Time
# (Asia/Qyzylorda)
-SAKST 39600 D # Sakhalin Summer Time (obsolete)
-SAKT 36000 # Sakhalin Time (caution: this used to mean 39600)
+SAKST Asia/Sakhalin # Sakhalin Summer Time (obsolete)
+SAKT Asia/Sakhalin # Sakhalin Time
# (Asia/Sakhalin)
-SGT 28800 # Singapore Time
+SGT Asia/Singapore # Singapore Time
# (Asia/Singapore)
SRET 39600 # Srednekolymsk Time
# (Asia/Srednekolymsk)
@@ -200,10 +200,10 @@ TJT 18000 # Tajikistan Time
# (Asia/Dushanbe)
TLT 32400 # East Timor Time
# (Asia/Dili)
-TMT 18000 # Turkmenistan Time
+TMT Asia/Ashgabat # Turkmenistan Time
# (Asia/Ashgabat)
ULAST 32400 D # Ulan Bator Summer Time (obsolete)
-ULAT 28800 # Ulan Bator Time
+ULAT Asia/Ulaanbaatar # Ulan Bator Time
# (Asia/Ulaanbaatar)
UZST 21600 D # Uzbekistan Summer Time
# (Asia/Samarkand)
@@ -211,8 +211,8 @@ UZST 21600 D # Uzbekistan Summer Time
UZT 18000 # Uzbekistan Time
# (Asia/Samarkand)
# (Asia/Tashkent)
-VLAST 39600 D # Vladivostok Summer Time (obsolete)
-VLAT 36000 # Vladivostok Time (caution: this used to mean 39600)
+VLAST Asia/Vladivostok # Vladivostok Summer Time (obsolete)
+VLAT Asia/Vladivostok # Vladivostok Time
# (Asia/Vladivostok)
WIB 25200 # Waktu Indonesia Barat
# (Asia/Jakarta)
@@ -223,9 +223,9 @@ WITA 28800 # Waktu Indonesia Tengah
# (Asia/Makassar)
XJT 21600 # Xinjiang Time
# (Asia/Urumqi)
-YAKST 36000 D # Yakutsk Summer Time (obsolete)
-YAKT 32400 # Yakutsk Time (caution: this used to mean 36000)
+YAKST Asia/Yakutsk # Yakutsk Summer Time (obsolete)
+YAKT Asia/Yakutsk # Yakutsk Time
# (Asia/Yakutsk)
YEKST 21600 D # Yekaterinburg Summer Time (obsolete)
-YEKT 18000 # Yekaterinburg Time (caution: this used to mean 21600)
+YEKT Asia/Yekaterinburg # Yekaterinburg Time
# (Asia/Yekaterinburg)
diff --git a/src/timezone/tznames/Atlantic.txt b/src/timezone/tznames/Atlantic.txt
index c65734b0aee..1d34d1ed4be 100644
--- a/src/timezone/tznames/Atlantic.txt
+++ b/src/timezone/tznames/Atlantic.txt
@@ -48,11 +48,11 @@ AZOST 0 D # Azores Summer Time
# (Atlantic/Azores)
AZOT -3600 # Azores Time
# (Atlantic/Azores)
-CVT -3600 # Cape Verde Time
+CVT Atlantic/Cape_Verde # Cape Verde Time
# (Atlantic/Cape_Verde)
-FKST -10800 # Falkland Islands Summer Time (now used all year round)
+FKST Atlantic/Stanley # Falkland Islands Summer/Standard Time
# (Atlantic/Stanley)
-FKT -14400 # Falkland Islands Time (obsolete)
+FKT Atlantic/Stanley # Falkland Islands Time (obsolete)
GMT 0 # Greenwich Mean Time
# (Africa/Abidjan)
# (Africa/Bamako)
diff --git a/src/timezone/tznames/Australia.txt b/src/timezone/tznames/Australia.txt
index 837309326d3..92c296840f9 100644
--- a/src/timezone/tznames/Australia.txt
+++ b/src/timezone/tznames/Australia.txt
@@ -52,7 +52,7 @@ EAST 36000 # East Australian Standard Time (not in zic)
# Other timezones:
# - EST: Eastern Standard Time (America)
EST 36000 # Eastern Standard Time (not in zic)
-LHDT 39600 D # Lord Howe Daylight Time
+LHDT Australia/Lord_Howe # Lord Howe Daylight Time
# (Australia/Lord_Howe)
LHST 37800 # Lord Howe Standard Time
# (Australia/Lord_Howe)
diff --git a/src/timezone/tznames/Default b/src/timezone/tznames/Default
index 9e5209e779b..a8b8eac5182 100644
--- a/src/timezone/tznames/Default
+++ b/src/timezone/tznames/Default
@@ -54,7 +54,7 @@ AKST -32400 # Alaska Standard Time
# (America/Juneau)
# (America/Nome)
# (America/Yakutat)
-ART -10800 # Argentina Time
+ART America/Argentina/Buenos_Aires # Argentina Time
# (America/Argentina/Buenos_Aires)
# (America/Argentina/Cordoba)
# (America/Argentina/Tucuman)
@@ -65,7 +65,7 @@ ART -10800 # Argentina Time
# (America/Argentina/Mendoza)
# (America/Argentina/Rio_Gallegos)
# (America/Argentina/Ushuaia)
-ARST -7200 D # Argentina Summer Time
+ARST America/Argentina/Buenos_Aires # Argentina Summer Time
BOT -14400 # Bolivia Time
# (America/La_Paz)
BRA -10800 # Brazil Time (not in zic)
@@ -170,7 +170,7 @@ FNST -3600 D # Fernando de Noronha Summer Time (not in zic)
# (America/Noronha)
GFT -10800 # French Guiana Time
# (America/Cayenne)
-GYT -14400 # Guyana Time
+GYT America/Guyana # Guyana Time
# (America/Guyana)
MDT -21600 D # Mexico Mountain Daylight Time
# Mountain Daylight Time
@@ -219,13 +219,13 @@ PST -28800 # Pacific Standard Time
# (Pacific/Pitcairn)
PYST -10800 D # Paraguay Summer Time
# (America/Asuncion)
-PYT -14400 # Paraguay Time
+PYT America/Asuncion # Paraguay Time
# (America/Asuncion)
UYST -7200 D # Uruguay Summer Time
# (America/Montevideo)
UYT -10800 # Uruguay Time
# (America/Montevideo)
-VET -16200 # Venezuela Time (caution: this used to mean -14400)
+VET America/Caracas # Venezuela Time
# (America/Caracas)
WGST -7200 D # Western Greenland Summer Time
# (America/Godthab)
@@ -234,13 +234,13 @@ WGT -10800 # West Greenland Time
#################### ANTARCTICA ####################
-DAVT 25200 # Davis Time (Antarctica)
+DAVT Antarctica/Davis # Davis Time (Antarctica)
# (Antarctica/Davis)
DDUT 36000 # Dumont-d'Urville Time (Antarctica)
# (Antarctica/DumontDUrville)
# (Antarctica/Palmer)
# (America/Santiago)
-MAWT 18000 # Mawson Time (Antarctica) (caution: this used to mean 21600)
+MAWT Antarctica/Mawson # Mawson Time (Antarctica)
# (Antarctica/Mawson)
#################### ASIA ####################
@@ -253,19 +253,19 @@ ALMST 25200 D # Alma-Ata Summer Time (obsolete)
# CONFLICT! AMST is not unique
# Other timezones:
# - AMST: Amazon Summer Time (America)
-AMST 18000 D # Armenia Summer Time
+AMST Asia/Yerevan # Armenia Summer Time
# (Asia/Yerevan)
# CONFLICT! AMT is not unique
# Other timezones:
# - AMT: Amazon Time (America)
-AMT 14400 # Armenia Time
+AMT Asia/Yerevan # Armenia Time
# (Asia/Yerevan)
-ANAST 46800 D # Anadyr Summer Time (obsolete)
-ANAT 43200 # Anadyr Time
+ANAST Asia/Anadyr # Anadyr Summer Time (obsolete)
+ANAT Asia/Anadyr # Anadyr Time
# (Asia/Anadyr)
-AZST 18000 D # Azerbaijan Summer Time
+AZST Asia/Baku # Azerbaijan Summer Time
# (Asia/Baku)
-AZT 14400 # Azerbaijan Time
+AZT Asia/Baku # Azerbaijan Time
# (Asia/Baku)
BDT 21600 # Bangladesh Time
# (Asia/Dhaka)
@@ -275,9 +275,8 @@ BORT 28800 # Borneo Time (Indonesia) (not in zic)
BTT 21600 # Bhutan Time
# (Asia/Thimphu)
CCT 28800 # China Coastal Time (not in zic)
-GEST 14400 D # Georgia Summer Time (obsolete)
- # (Asia/Tbilisi)
-GET 14400 # Georgia Time (caution: this used to mean 10800)
+GEST Asia/Tbilisi # Georgia Summer Time (obsolete)
+GET Asia/Tbilisi # Georgia Time
# (Asia/Tbilisi)
HKT 28800 # Hong Kong Time (not in zic)
ICT 25200 # Indochina Time
@@ -287,8 +286,8 @@ ICT 25200 # Indochina Time
# (Asia/Vientiane)
IDT 10800 D # Israel Daylight Time
# (Asia/Jerusalem)
-IRKST 32400 D # Irkutsk Summer Time (obsolete)
-IRKT 28800 # Irkutsk Time (caution: this used to mean 32400)
+IRKST Asia/Irkutsk # Irkutsk Summer Time (obsolete)
+IRKT Asia/Irkutsk # Irkutsk Time
# (Asia/Irkutsk)
IRT 12600 # Iran Time (not in zic)
# CONFLICT! IST is not unique
@@ -302,33 +301,32 @@ JST 32400 # Japan Standard Time
# (Asia/Tokyo)
KDT 36000 D # Korean Daylight Time (not in zic)
KGST 21600 D # Kyrgyzstan Summer Time (obsolete)
+KGT Asia/Bishkek # Kyrgyzstan Time
# (Asia/Bishkek)
-KGT 21600 # Kyrgyzstan Time (caution: this used to mean 18000)
- # (Asia/Bishkek)
-KRAST 28800 D # Krasnoyarsk Summer Time (obsolete)
-KRAT 25200 # Krasnoyarsk Time (caution: this used to mean 28800)
+KRAST Asia/Krasnoyarsk # Krasnoyarsk Summer Time (obsolete)
+KRAT Asia/Krasnoyarsk # Krasnoyarsk Time
# (Asia/Krasnoyarsk)
KST 32400 # Korean Standard Time
# (Asia/Pyongyang)
-LKT 21600 # Lanka Time (obsolete)
-MAGST 43200 D # Magadan Summer Time (obsolete)
-MAGT 36000 # Magadan Time (caution: this used to mean 43200)
+LKT Asia/Colombo # Lanka Time (obsolete)
+MAGST Asia/Magadan # Magadan Summer Time (obsolete)
+MAGT Asia/Magadan # Magadan Time
# (Asia/Magadan)
MMT 23400 # Myanmar Time
# (Asia/Rangoon)
MYT 28800 # Malaysia Time
# (Asia/Kuala_Lumpur)
# (Asia/Kuching)
-NOVST 25200 D # Novosibirsk Summer Time (obsolete)
-NOVT 21600 # Novosibirsk Time (caution: this used to mean 25200)
+NOVST Asia/Novosibirsk # Novosibirsk Summer Time (obsolete)
+NOVT Asia/Novosibirsk # Novosibirsk Time
# (Asia/Novosibirsk)
NPT 20700 # Nepal Time
# (Asia/Katmandu)
-OMSST 25200 D # Omsk Summer Time (obsolete)
-OMST 21600 # Omsk Time (caution: this used to mean 25200)
+OMSST Asia/Omsk # Omsk Summer Time (obsolete)
+OMST Asia/Omsk # Omsk Time
# (Asia/Omsk)
-PETST 46800 D # Petropavlovsk-Kamchatski Summer Time (obsolete)
-PETT 43200 # Petropavlovsk-Kamchatski Time
+PETST Asia/Kamchatka # Petropavlovsk-Kamchatski Summer Time (obsolete)
+PETT Asia/Kamchatka # Petropavlovsk-Kamchatski Time
# (Asia/Kamchatka)
PHT 28800 # Philippine Time
# (Asia/Manila)
@@ -336,14 +334,14 @@ PKT 18000 # Pakistan Time
# (Asia/Karachi)
PKST 21600 D # Pakistan Summer Time
# (Asia/Karachi)
-SGT 28800 # Singapore Time
+SGT Asia/Singapore # Singapore Time
# (Asia/Singapore)
TJT 18000 # Tajikistan Time
# (Asia/Dushanbe)
-TMT 18000 # Turkmenistan Time
+TMT Asia/Ashgabat # Turkmenistan Time
# (Asia/Ashgabat)
ULAST 32400 D # Ulan Bator Summer Time (obsolete)
-ULAT 28800 # Ulan Bator Time
+ULAT Asia/Ulaanbaatar # Ulan Bator Time
# (Asia/Ulaanbaatar)
UZST 21600 D # Uzbekistan Summer Time
# (Asia/Samarkand)
@@ -351,16 +349,16 @@ UZST 21600 D # Uzbekistan Summer Time
UZT 18000 # Uzbekistan Time
# (Asia/Samarkand)
# (Asia/Tashkent)
-VLAST 39600 D # Vladivostok Summer Time (obsolete)
-VLAT 36000 # Vladivostok Time (caution: this used to mean 39600)
+VLAST Asia/Vladivostok # Vladivostok Summer Time (obsolete)
+VLAT Asia/Vladivostok # Vladivostok Time
# (Asia/Vladivostok)
XJT 21600 # Xinjiang Time
# (Asia/Urumqi)
-YAKST 36000 D # Yakutsk Summer Time (obsolete)
-YAKT 32400 # Yakutsk Time (caution: this used to mean 36000)
+YAKST Asia/Yakutsk # Yakutsk Summer Time (obsolete)
+YAKT Asia/Yakutsk # Yakutsk Time
# (Asia/Yakutsk)
YEKST 21600 D # Yekaterinburg Summer Time (obsolete)
-YEKT 18000 # Yekaterinburg Time (caution: this used to mean 21600)
+YEKT Asia/Yekaterinburg # Yekaterinburg Time
# (Asia/Yekaterinburg)
#################### ATLANTIC ####################
@@ -406,9 +404,9 @@ AZOST 0 D # Azores Summer Time
# (Atlantic/Azores)
AZOT -3600 # Azores Time
# (Atlantic/Azores)
-FKST -10800 # Falkland Islands Summer Time (now used all year round)
+FKST Atlantic/Stanley # Falkland Islands Summer/Standard Time
# (Atlantic/Stanley)
-FKT -14400 # Falkland Islands Time (obsolete)
+FKT Atlantic/Stanley # Falkland Islands Time (obsolete)
#################### AUSTRALIA ####################
@@ -443,7 +441,7 @@ AWST 28800 # Australian Western Standard Time
# (Australia/Perth)
CADT 37800 D # Central Australia Daylight-Saving Time (not in zic)
CAST 34200 # Central Australia Standard Time (not in zic)
-LHDT 39600 D # Lord Howe Daylight Time
+LHDT Australia/Lord_Howe # Lord Howe Daylight Time
# (Australia/Lord_Howe)
LHST 37800 # Lord Howe Standard Time
# (Australia/Lord_Howe)
@@ -639,9 +637,10 @@ MET 3600 # Middle Europe Time (not in zic)
METDST 7200 D # Middle Europe Summer Time (not in zic)
MEZ 3600 # Mitteleuropaeische Zeit (German) (not in zic)
MSD 14400 D # Moscow Daylight Time (obsolete)
-MSK 10800 # Moscow Time (caution: this used to mean 14400)
+MSK Europe/Moscow # Moscow Time
# (Europe/Moscow)
-VOLT 14400 # Volgograd Time (obsolete)
+ # (Europe/Volgograd)
+VOLT Europe/Volgograd # Volgograd Time (obsolete)
WET 0 # Western Europe Time
# (Africa/Casablanca)
# (Africa/El_Aaiun)
@@ -659,7 +658,7 @@ WETDST 3600 D # Western Europe Summer Time
CXT 25200 # Christmas Island Time (Indian Ocean)
# (Indian/Christmas)
-IOT 21600 # British Indian Ocean Territory (Chagos) (there was a timezone change recently in 1996)
+IOT Indian/Chagos # British Indian Ocean Territory (Chagos)
# (Indian/Chagos)
MUT 14400 # Mauritius Island Time
# (Indian/Mauritius)
@@ -682,11 +681,11 @@ CHAST 45900 # Chatham Standard Time (New Zealand)
# (Pacific/Chatham)
CHUT 36000 # Chuuk Time
# (Pacific/Chuuk)
-CKT -36000 # Cook Islands Time (caution: this used to mean 43200)
+CKT Pacific/Rarotonga # Cook Islands Time
# (Pacific/Rarotonga)
-EASST -18000 D # Easter Island Summer Time (Chile)
+EASST Pacific/Easter # Easter Island Summer Time (Chile)
# (Pacific/Easter)
-EAST -21600 # Easter Island Time (Chile)
+EAST Pacific/Easter # Easter Island Time (Chile)
# (Pacific/Easter)
FJST 46800 D # Fiji Summer Time
# (Pacific/Fiji)
@@ -701,9 +700,9 @@ GILT 43200 # Gilbert Islands Time
HST -36000 # Hawaiian Standard Time
# (Pacific/Honolulu)
# (Pacific/Johnston)
-KOST 39600 # Kosrae Time
+KOST Pacific/Kosrae # Kosrae Time
# (Pacific/Kosrae)
-LINT 50400 # Line Islands Time (Kiribati)
+LINT Pacific/Kiritimati # Line Islands Time (Kiribati)
# (Pacific/Kiritimati)
MART -34200 # Marquesas Time
# (Pacific/Marquesas)
@@ -715,7 +714,7 @@ MPT 36000 # North Mariana Islands Time (not in zic)
# Other timezones:
# - NFT: Norfolk Time (Pacific)
NFT -12600 # Newfoundland Time (not in zic)
-NUT -39600 # Niue Time
+NUT Pacific/Niue # Niue Time
# (Pacific/Niue)
NZDT 46800 D # New Zealand Daylight Time
# (Antarctica/McMurdo)
@@ -725,7 +724,7 @@ NZST 43200 # New Zealand Standard Time
# (Pacific/Auckland)
PGT 36000 # Papua New Guinea Time
# (Pacific/Port_Moresby)
-PHOT 46800 # Phoenix Islands Time (Kiribati)
+PHOT Pacific/Enderbury # Phoenix Islands Time (Kiribati)
# (Pacific/Enderbury)
PONT 39600 # Ponape Time (Micronesia)
# (Pacific/Ponape)
@@ -733,7 +732,7 @@ PWT 32400 # Palau Time
# (Pacific/Palau)
TAHT -36000 # Tahiti Time (zic says "TAHT", other sources "THAT")
# (Pacific/Tahiti)
-TKT 46800 # Tokelau Time (caution: this used to mean -36000)
+TKT Pacific/Fakaofo # Tokelau Time
# (Pacific/Fakaofo)
TOT 46800 # Tonga Time
# (Pacific/Tongatapu)
diff --git a/src/timezone/tznames/Europe.txt b/src/timezone/tznames/Europe.txt
index c6b37bdd5ed..421f8f18ad4 100644
--- a/src/timezone/tznames/Europe.txt
+++ b/src/timezone/tznames/Europe.txt
@@ -186,12 +186,13 @@ MET 3600 # Middle Europe Time (not in zic)
METDST 7200 D # Middle Europe Summer Time (not in zic)
MEZ 3600 # Mitteleuropäische Zeit (German) (not in zic)
MSD 14400 D # Moscow Daylight Time (obsolete)
-MSK 10800 # Moscow Time (caution: this used to mean 14400)
+MSK Europe/Moscow # Moscow Time
# (Europe/Moscow)
-SAMST 18000 D # Samara Summer Time (obsolete)
-SAMT 14400 # Samara Time
+ # (Europe/Volgograd)
+SAMST Europe/Samara # Samara Summer Time (obsolete)
+SAMT Europe/Samara # Samara Time
# (Europe/Samara)
-VOLT 14400 # Volgograd Time (obsolete)
+VOLT Europe/Volgograd # Volgograd Time (obsolete)
WEST 3600 D # Western Europe Summer Time
# (Africa/Casablanca)
# (Atlantic/Canary)
diff --git a/src/timezone/tznames/Indian.txt b/src/timezone/tznames/Indian.txt
index c77c9919a1c..634660075ff 100644
--- a/src/timezone/tznames/Indian.txt
+++ b/src/timezone/tznames/Indian.txt
@@ -23,7 +23,7 @@ EAT 10800 # East Africa Time
# (Indian/Antananarivo)
# (Indian/Comoro)
# (Indian/Mayotte)
-IOT 21600 # British Indian Ocean Territory (Chagos) (there was a timezone change recently in 1996)
+IOT Indian/Chagos # British Indian Ocean Territory (Chagos)
# (Indian/Chagos)
MUT 14400 # Mauritius Island Time
# (Indian/Mauritius)
diff --git a/src/timezone/tznames/Pacific.txt b/src/timezone/tznames/Pacific.txt
index 2f988140014..1d205589bbc 100644
--- a/src/timezone/tznames/Pacific.txt
+++ b/src/timezone/tznames/Pacific.txt
@@ -16,14 +16,14 @@ ChST 36000 # Chamorro Standard Time (lower case "h" is as in zic)
# (Pacific/Saipan)
CHUT 36000 # Chuuk Time
# (Pacific/Chuuk)
-CKT -36000 # Cook Islands Time (caution: this used to mean 43200)
+CKT Pacific/Rarotonga # Cook Islands Time
# (Pacific/Rarotonga)
-EASST -18000 D # Easter Island Summer Time (Chile)
+EASST Pacific/Easter # Easter Island Summer Time (Chile)
# (Pacific/Easter)
# CONFLICT! EAST is not unique
# Other timezones:
# - EAST: East Australian Standard Time (Australia)
-EAST -21600 # Easter Island Time (Chile)
+EAST Pacific/Easter # Easter Island Time (Chile)
# (Pacific/Easter)
FJST 46800 D # Fiji Summer Time (caution: this used to mean -46800)
# (Pacific/Fiji)
@@ -38,9 +38,9 @@ GILT 43200 # Gilbert Islands Time
HST -36000 # Hawaiian Standard Time
# (Pacific/Honolulu)
# (Pacific/Johnston)
-KOST 39600 # Kosrae Time
+KOST Pacific/Kosrae # Kosrae Time
# (Pacific/Kosrae)
-LINT 50400 # Line Islands Time (Kiribati)
+LINT Pacific/Kiritimati # Line Islands Time (Kiribati)
# (Pacific/Kiritimati)
MART -34200 # Marquesas Time
# (Pacific/Marquesas)
@@ -55,9 +55,9 @@ NCT 39600 # New Caledonia Time
# - NFT: Newfoundland Time (America)
NFT 41400 # Norfolk Time
# (Pacific/Norfolk)
-NRT 43200 # Nauru Time
+NRT Pacific/Nauru # Nauru Time
# (Pacific/Nauru)
-NUT -39600 # Niue Time
+NUT Pacific/Niue # Niue Time
# (Pacific/Niue)
NZDT 46800 D # New Zealand Daylight Time
# (Antarctica/McMurdo)
@@ -67,7 +67,7 @@ NZST 43200 # New Zealand Standard Time
# (Pacific/Auckland)
PGT 36000 # Papua New Guinea Time
# (Pacific/Port_Moresby)
-PHOT 46800 # Phoenix Islands Time (Kiribati)
+PHOT Pacific/Enderbury # Phoenix Islands Time (Kiribati)
# (Pacific/Enderbury)
PONT 39600 # Ponape Time (Micronesia)
# (Pacific/Ponape)
@@ -87,7 +87,7 @@ SST -39600 # South Sumatran Time
# (Pacific/Pago_Pago)
TAHT -36000 # Tahiti Time (zic says "TAHT", other sources "THAT")
# (Pacific/Tahiti)
-TKT 46800 # Tokelau Time (caution: this used to mean -36000)
+TKT Pacific/Fakaofo # Tokelau Time
# (Pacific/Fakaofo)
TOT 46800 # Tonga Time
# (Pacific/Tongatapu)
diff --git a/src/timezone/tznames/README b/src/timezone/tznames/README
index 6cb0ae88c93..c80caa37869 100644
--- a/src/timezone/tznames/README
+++ b/src/timezone/tznames/README
@@ -6,26 +6,29 @@ tznames
This directory contains files with timezone sets for PostgreSQL. The problem
is that time zone abbreviations are not unique throughout the world and you
might find out that a time zone abbreviation in the `Default' set collides
-with the one you wanted to use. All other files except for `Default' are
-intended to override values from the `Default' set. So you might already have
-a file here that serves your needs. If not, you can create your own.
+with the one you wanted to use. This can be fixed by selecting a timezone
+set that defines the abbreviation the way you want it. There might already
+be a file here that serves your needs. If not, you can create your own.
In order to use one of these files, you need to set
timezone_abbreviations = 'xyz'
in any of the usual ways for setting a parameter, where xyz is the filename
-that contains the desired time zone names.
+that contains the desired time zone abbreviations.
-If you do not find an appropriate set of time zone names for your geographic
+If you do not find an appropriate set of abbreviations for your geographic
location supplied here, please report this to <pgsql-hackers@postgresql.org>.
-Your set of time zone names can then be included in future releases.
+Your set of time zone abbreviations can then be included in future releases.
For the time being you can always add your own set.
+Typically a custom abbreviation set is made by including the `Default' set
+and then adding or overriding abbreviations as necessary. For examples,
+see the `Australia' and `India' files.
+
The files named Africa.txt, etc, are not intended to be used directly as
time zone abbreviation files. They contain reference definitions of time zone
-names that can be copied into a custom abbreviation file as needed.
-
-Note that these files (*.txt) are already a subset of the zic timezone
-database files: we tried to list only those time zones that (according to
-the zic timezone database) appear to be still in use.
+abbreviations that can be copied into a custom abbreviation file as needed.
+Note that these files (*.txt) are already a subset of the IANA timezone
+database files: we tried to list only those time zone abbreviations that
+(according to the IANA timezone database) appear to be still in use.
diff --git a/src/timezone/zic.c b/src/timezone/zic.c
index 13baf73d3c1..1a7ec68d7c0 100644
--- a/src/timezone/zic.c
+++ b/src/timezone/zic.c
@@ -1771,7 +1771,7 @@ writezone(const char *name, const char *string)
/* Print current timezone abbreviations if requested */
if (print_abbrevs &&
- (ats[i] >= print_cutoff || i == thistimelim - 1))
+ (i == thistimelim - 1 || ats[i + 1] > print_cutoff))
{
unsigned char tm = typemap[types[i]];
char *thisabbrev = &thischars[indmap[abbrinds[tm]]];