summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Bishop <stuart.bishop@canonical.com>2018-10-29 16:58:05 +0700
committerStuart Bishop <stuart.bishop@canonical.com>2018-10-29 16:58:05 +0700
commit33997e9a17fae2ecc9f825eac056e22ea4d5dc27 (patch)
tree2e42bc348246850f4d8dfee71cdec64e43cb0b0a
parentc9df7ae6222875f943245c14782873c0863fd99c (diff)
parent7e33478a034ba25464cfbb9b2ee8306174eae2aa (diff)
downloadpytz-git-33997e9a17fae2ecc9f825eac056e22ea4d5dc27.tar.gz
IANA 2018g
-rw-r--r--tz/NEWS35
-rw-r--r--tz/africa96
-rw-r--r--tz/europe3
-rw-r--r--tz/northamerica17
-rw-r--r--tz/theory.html2
-rw-r--r--tz/tz-how-to.html14
-rw-r--r--tz/tz-link.html23
-rw-r--r--tz/tzfile.5192
-rw-r--r--tz/zdump.819
-rw-r--r--tz/zic.84
-rw-r--r--tz/zic.c79
-rw-r--r--tz/ziguard.awk7
-rw-r--r--tz/zishrink.awk5
13 files changed, 368 insertions, 128 deletions
diff --git a/tz/NEWS b/tz/NEWS
index aeeef10..d4cb723 100644
--- a/tz/NEWS
+++ b/tz/NEWS
@@ -1,5 +1,40 @@
News for the tz database
+Release 2018g - 2018-10-26 22:22:45 -0700
+
+ Briefly:
+ Morocco switches to permanent +01 on 2018-10-27.
+
+ Changes to future timestamps
+
+ Morocco switches from +00/+01 to permanent +01 effective 2018-10-27,
+ so its clocks will not fall back on 2018-10-28 as previously scheduled.
+ (Thanks to Mohamed Essedik Najd and Brian Inglis.)
+
+ Changes to code
+
+ When generating TZif files with leap seconds, zic no longer uses a
+ format that trips up older 32-bit clients, fixing a bug introduced
+ in 2018f. (Reported by Daniel Fischer.) Also, the zic workaround
+ for QTBUG-53071 now also works for TZif files with leap seconds.
+
+ The translator to rearguard format now rewrites the line
+ "Rule Japan 1948 1951 - Sep Sat>=8 25:00 0 S" to
+ "Rule Japan 1948 1951 - Sep Sun>=9 1:00 0 S".
+ This caters to zic before 2007 and to Oracle TZUpdater 2.2.0
+ and earlier. (Reported by Christos Zoulas.)
+
+ Changes to past time zone abbreviations
+
+ Change HDT to HWT/HPT for WWII-era abbreviations in Hawaii.
+ This reverts to 2011h, as the abbreviation change in 2011i was
+ likely inadvertent.
+
+ Changes to documentation
+
+ tzfile.5 has new sections on interoperability issues.
+
+
Release 2018f - 2018-10-18 00:14:18 -0700
Briefly:
diff --git a/tz/africa b/tz/africa
index 555052b..a26b91b 100644
--- a/tz/africa
+++ b/tz/africa
@@ -844,94 +844,61 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis
# <https://lnt.ma/le-maroc-reculera-dune-heure-le-dimanche-14-juin/> agrees
# with the patch.
-# From Paul Eggert (2015-06-08):
-# For now, guess that later spring and fall transitions will use 2015's rules,
-# and guess that Morocco will switch to standard time at 03:00 the last
-# Sunday before Ramadan, and back to DST at 02:00 the first Sunday after
-# Ramadan. To implement this, transition dates for 2016 through 2037 were
-# determined by running the following program under GNU Emacs 24.3, with the
-# results integrated by hand into the table below.
-# (let ((islamic-year 1437))
-# (require 'cal-islam)
-# (while (< islamic-year 1460)
-# (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year)))
-# (b (calendar-islamic-to-absolute (list 10 1 islamic-year)))
-# (sunday 0))
-# (while (/= sunday (mod (setq a (1- a)) 7)))
-# (while (/= sunday (mod b 7))
-# (setq b (1+ b)))
-# (setq a (calendar-gregorian-from-absolute a))
-# (setq b (calendar-gregorian-from-absolute b))
-# (insert
-# (format
-# (concat "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 3:00\t0\t-\n"
-# "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 2:00\t1:00\tS\n")
-# (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a))
-# (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
-# (setq islamic-year (+ 1 islamic-year))))
+# From Mohamed Essedik Najd (2018-10-26):
+# Today, a Moroccan government council approved the perpetual addition
+# of 60 minutes to the regular Moroccan timezone.
+# From Brian Inglis (2018-10-26):
+# http://www.maroc.ma/fr/actualites/le-conseil-de-gouvernement-adopte-un-projet-de-decret-relatif-lheure-legale-stipulant-le
# RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-
-Rule Morocco 1939 only - Sep 12 0:00 1:00 S
+Rule Morocco 1939 only - Sep 12 0:00 1:00 -
Rule Morocco 1939 only - Nov 19 0:00 0 -
-Rule Morocco 1940 only - Feb 25 0:00 1:00 S
+Rule Morocco 1940 only - Feb 25 0:00 1:00 -
Rule Morocco 1945 only - Nov 18 0:00 0 -
-Rule Morocco 1950 only - Jun 11 0:00 1:00 S
+Rule Morocco 1950 only - Jun 11 0:00 1:00 -
Rule Morocco 1950 only - Oct 29 0:00 0 -
-Rule Morocco 1967 only - Jun 3 12:00 1:00 S
+Rule Morocco 1967 only - Jun 3 12:00 1:00 -
Rule Morocco 1967 only - Oct 1 0:00 0 -
-Rule Morocco 1974 only - Jun 24 0:00 1:00 S
+Rule Morocco 1974 only - Jun 24 0:00 1:00 -
Rule Morocco 1974 only - Sep 1 0:00 0 -
-Rule Morocco 1976 1977 - May 1 0:00 1:00 S
+Rule Morocco 1976 1977 - May 1 0:00 1:00 -
Rule Morocco 1976 only - Aug 1 0:00 0 -
Rule Morocco 1977 only - Sep 28 0:00 0 -
-Rule Morocco 1978 only - Jun 1 0:00 1:00 S
+Rule Morocco 1978 only - Jun 1 0:00 1:00 -
Rule Morocco 1978 only - Aug 4 0:00 0 -
-Rule Morocco 2008 only - Jun 1 0:00 1:00 S
+Rule Morocco 2008 only - Jun 1 0:00 1:00 -
Rule Morocco 2008 only - Sep 1 0:00 0 -
-Rule Morocco 2009 only - Jun 1 0:00 1:00 S
+Rule Morocco 2009 only - Jun 1 0:00 1:00 -
Rule Morocco 2009 only - Aug 21 0:00 0 -
-Rule Morocco 2010 only - May 2 0:00 1:00 S
+Rule Morocco 2010 only - May 2 0:00 1:00 -
Rule Morocco 2010 only - Aug 8 0:00 0 -
-Rule Morocco 2011 only - Apr 3 0:00 1:00 S
+Rule Morocco 2011 only - Apr 3 0:00 1:00 -
Rule Morocco 2011 only - Jul 31 0:00 0 -
-Rule Morocco 2012 2013 - Apr lastSun 2:00 1:00 S
+Rule Morocco 2012 2013 - Apr lastSun 2:00 1:00 -
Rule Morocco 2012 only - Jul 20 3:00 0 -
-Rule Morocco 2012 only - Aug 20 2:00 1:00 S
+Rule Morocco 2012 only - Aug 20 2:00 1:00 -
Rule Morocco 2012 only - Sep 30 3:00 0 -
Rule Morocco 2013 only - Jul 7 3:00 0 -
-Rule Morocco 2013 only - Aug 10 2:00 1:00 S
-Rule Morocco 2013 max - Oct lastSun 3:00 0 -
-Rule Morocco 2014 2021 - Mar lastSun 2:00 1:00 S
+Rule Morocco 2013 only - Aug 10 2:00 1:00 -
+Rule Morocco 2013 2018 - Oct lastSun 3:00 0 -
+Rule Morocco 2014 2018 - Mar lastSun 2:00 1:00 -
Rule Morocco 2014 only - Jun 28 3:00 0 -
-Rule Morocco 2014 only - Aug 2 2:00 1:00 S
+Rule Morocco 2014 only - Aug 2 2:00 1:00 -
Rule Morocco 2015 only - Jun 14 3:00 0 -
-Rule Morocco 2015 only - Jul 19 2:00 1:00 S
+Rule Morocco 2015 only - Jul 19 2:00 1:00 -
Rule Morocco 2016 only - Jun 5 3:00 0 -
-Rule Morocco 2016 only - Jul 10 2:00 1:00 S
+Rule Morocco 2016 only - Jul 10 2:00 1:00 -
Rule Morocco 2017 only - May 21 3:00 0 -
-Rule Morocco 2017 only - Jul 2 2:00 1:00 S
+Rule Morocco 2017 only - Jul 2 2:00 1:00 -
Rule Morocco 2018 only - May 13 3:00 0 -
-Rule Morocco 2018 only - Jun 17 2:00 1:00 S
-Rule Morocco 2019 only - May 5 3:00 0 -
-Rule Morocco 2019 only - Jun 9 2:00 1:00 S
-Rule Morocco 2020 only - Apr 19 3:00 0 -
-Rule Morocco 2020 only - May 24 2:00 1:00 S
-Rule Morocco 2021 only - Apr 11 3:00 0 -
-Rule Morocco 2021 only - May 16 2:00 1:00 S
-Rule Morocco 2022 only - May 8 2:00 1:00 S
-Rule Morocco 2023 only - Apr 23 2:00 1:00 S
-Rule Morocco 2024 only - Apr 14 2:00 1:00 S
-Rule Morocco 2025 only - Apr 6 2:00 1:00 S
-Rule Morocco 2026 max - Mar lastSun 2:00 1:00 S
-Rule Morocco 2036 only - Oct 19 3:00 0 -
-Rule Morocco 2037 only - Oct 4 3:00 0 -
+Rule Morocco 2018 only - Jun 17 2:00 1:00 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
- 0:00 Morocco WE%sT 1984 Mar 16
- 1:00 - CET 1986
- 0:00 Morocco WE%sT
+ 0:00 Morocco +00/+01 1984 Mar 16
+ 1:00 - +01 1986
+ 0:00 Morocco +00/+01 2018 Oct 27
+ 1:00 - +01
# Western Sahara
#
@@ -946,7 +913,8 @@ Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
Zone Africa/El_Aaiun -0:52:48 - LMT 1934 Jan # El AaiĂșn
-1:00 - -01 1976 Apr 14
- 0:00 Morocco WE%sT
+ 0:00 Morocco +00/+01 2018 Oct 27
+ 1:00 - +01
# Mozambique
#
diff --git a/tz/europe b/tz/europe
index 5b0a829..587f7b0 100644
--- a/tz/europe
+++ b/tz/europe
@@ -3440,7 +3440,8 @@ Rule Spain 1978 only - Oct 1 2:00s 0 -
#Rule NatSpain 1937 only - May 22 23:00 1:00 S
#Rule NatSpain 1937 1938 - Oct Sat>=1 24:00s 0 -
#Rule NatSpain 1938 only - Mar 26 23:00 1:00 S
-# The following rules are copied from Morocco from 1967 through 1978.
+# The following rules are copied from Morocco from 1967 through 1978,
+# except with "S" letters.
Rule SpainAfrica 1967 only - Jun 3 12:00 1:00 S
Rule SpainAfrica 1967 only - Oct 1 0:00 0 -
Rule SpainAfrica 1974 only - Jun 24 0:00 1:00 S
diff --git a/tz/northamerica b/tz/northamerica
index 88c0f6f..9d5bad2 100644
--- a/tz/northamerica
+++ b/tz/northamerica
@@ -439,6 +439,19 @@ Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53
# western South Dakota, far western Texas (El Paso County, Hudspeth County,
# and Pine Springs and Nickel Creek in Culberson County), Utah, Wyoming
#
+# From Paul Eggert (2018-10-25):
+# On 1921-03-04 federal law placed all of Texas into the central time zone.
+# However, El Paso ignored the law for decades and continued to observe
+# mountain time, on the grounds that that's what they had always done
+# and they weren't about to let the federal government tell them what to do.
+# Eventually the federal government gave in and changed the law on
+# 1970-04-10 to match what El Paso was actually doing. Although
+# that's slightly after our 1970 cutoff, there is no need to create a
+# separate zone for El Paso since they were ignoring the law anyway. See:
+# Long T. El Pasoans were time rebels, fought to stay in Mountain zone.
+# El Paso Times. 2018-10-24 06:40 -06.
+# https://www.elpasotimes.com/story/news/local/el-paso/2018/10/24/el-pasoans-were-time-rebels-fought-stay-mountain-zone/1744509002/
+#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
Rule Denver 1920 1921 - Mar lastSun 2:00 1:00 D
Rule Denver 1920 only - Oct lastSun 2:00 0 S
@@ -708,9 +721,7 @@ Zone America/Adak 12:13:22 - LMT 1867 Oct 19 12:44:35
Zone Pacific/Honolulu -10:31:26 - LMT 1896 Jan 13 12:00
-10:30 - HST 1933 Apr 30 2:00
-10:30 1:00 HDT 1933 May 21 12:00
- -10:30 - HST 1942 Feb 9 2:00
- -10:30 1:00 HDT 1945 Sep 30 2:00
- -10:30 - HST 1947 Jun 8 2:00
+ -10:30 US H%sT 1947 Jun 8 2:00
-10:00 - HST
# Now we turn to US areas that have diverged from the consensus since 1970.
diff --git a/tz/theory.html b/tz/theory.html
index 8dd58db..e9c9716 100644
--- a/tz/theory.html
+++ b/tz/theory.html
@@ -407,7 +407,7 @@ in decreasing order of importance:
EST/EDT/EWT/EPT/EDDT Eastern [North America],
EET/EEST Eastern European,
GST Guam,
- HST/HDT Hawaii,
+ HST/HDT/HWT/HPT Hawaii,
HKT/HKST Hong Kong,
IST India,
IST/GMT Irish,
diff --git a/tz/tz-how-to.html b/tz/tz-how-to.html
index 159ed89..8471b67 100644
--- a/tz/tz-how-to.html
+++ b/tz/tz-how-to.html
@@ -459,8 +459,8 @@ given alphabetic string.</li>
<p>An example of a specific amount of time is:</p>
<pre>
#Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Honolulu ... 1933 Apr 30 2:00
- -10:30 1:00 HDT 1933 May 21 2:00
+Zone Pacific/Honolulu ... 1933 Apr 30 2:00
+ -10:30 1:00 HDT 1933 May 21 12:00
...
</pre>
@@ -559,7 +559,7 @@ the true offset is undefined.
Rule US 1918 1919 - Oct lastSun 2:00 0 S
Rule US 1942 only - Feb 9 2:00 1:00 W # War
Rule US 1945 only - Aug 14 23:00u 1:00 P # Peace
-Rule US 1945 only - Sep 30 2:00 0 S
+Rule US 1945 only - Sep lastSun 2:00 0 S
</pre>
</td></tr></table></td>
</tr>
@@ -570,7 +570,7 @@ Rule US 1945 only - Sep 30 2:00 0 S
<td colspan="6" align="center"><table><tr><td>
<pre>
#Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Honolulu -10:31:26 - LMT 1900 Jan 1 12:00
+Zone Pacific/Honolulu -10:31:26 - LMT 1896 Jan 13 12:00
-10:30 - HST 1933 Apr 30 2:00
-10:30 1:00 HDT 1933 May 21 2:00
-10:30 US H%sT 1947 Jun 8 2:00
@@ -598,7 +598,7 @@ Zone Pacific/Honolulu -10:31:26 - LMT 1900 Jan 1 12:00
<td>&mdash;</td>
<td>LMT</td>
<td>local mean time</td>
- <td>1900-01-01</td>
+ <td>1896-01-13</td>
<td>12:00</td>
</tr>
<tr align="center">
@@ -607,7 +607,7 @@ Zone Pacific/Honolulu -10:31:26 - LMT 1900 Jan 1 12:00
<td>HST</td>
<td>Hawaii standard time</td>
<td>1933-04-30</td>
- <td rowspan="3">02:00</td>
+ <td>02:00</td>
</tr>
<tr align="center">
<td>&minus;9:30</td>
@@ -615,6 +615,7 @@ Zone Pacific/Honolulu -10:31:26 - LMT 1900 Jan 1 12:00
<td>HDT</td>
<td>Hawaii daylight time</td>
<td>1933-05-21</td>
+ <td>12:00</td>
</tr>
<tr align="center">
<td>&minus;10:30&sup1;</td>
@@ -622,6 +623,7 @@ Zone Pacific/Honolulu -10:31:26 - LMT 1900 Jan 1 12:00
<td>HST&sup1;</td>
<td>Hawaii standard time</td>
<td>1942-02-09</td>
+ <td>02:00</td>
</tr>
<tr align="center">
<td rowspan="2">&minus;9:30</td>
diff --git a/tz/tz-link.html b/tz/tz-link.html
index 8593ba6..956af52 100644
--- a/tz/tz-link.html
+++ b/tz/tz-link.html
@@ -524,10 +524,11 @@ clock (intclock)</a> is a clock that displays multiple time zones on
under the <abbr>GPL</abbr>.</li>
<li>Microsoft Windows 8.1
and later has <code><abbr>tz</abbr></code> data and <abbr>CLDR</abbr>
-data (mentioned <a href="#CLDR">below</a>) used by
-<a href="https://en.wikipedia.org/wiki/Windows_Runtime">Windows Runtime</a>
-classes such as <a
-href="https://msdn.microsoft.com/en-us/library/windows/apps/windows.globalization.datetimeformatting.datetimeformatter.aspx"><code>DateTimeFormatter</code></a>.
+data (mentioned <a href="#CLDR">below</a>) used by the
+<a href="https://en.wikipedia.org/wiki/Windows_Runtime">Windows Runtime</a> /
+<a href="https://en.wikipedia.org/wiki/Universal_Windows_Platform">Universal Windows Platform</a> classes
+<a href="https://docs.microsoft.com/uwp/api/Windows.Globalization.DateTimeFormatting.DateTimeFormatter"><code>DateTimeFormatter</code></a> and
+<a href="https://docs.microsoft.com/uwp/api/windows.globalization.calendar"><code>Calendar</code></a>.
<a id="System.TimeZoneInfo"
href="https://blogs.msdn.microsoft.com/bclteam/2007/06/07/exploring-windows-time-zones-with-system-timezoneinfo-josh-free/">Exploring
Windows Time Zones with <code>System.TimeZoneInfo</code></a> describes
@@ -540,6 +541,8 @@ Tzid table</a> or <a
href="https://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml"><abbr>XML</abbr>
file</a> of the <abbr>CLDR</abbr> data maps proprietary zone IDs
to <code><abbr>tz</abbr></code> names.
+These mappings can be performed programmatically via the <a href="https://github.com/mj1856/TimeZoneConverter">TimeZoneConverter</a> .NET library,
+or the ICU Java and C++ libraries mentioned <a href="#ICU">above</a>.
<li><a
href="https://www.oracle.com/java/index.html">Oracle
Java</a> contains a copy of a subset of a recent
@@ -742,6 +745,14 @@ zones &amp; daylight saving time</a>.</dd>
<dd>The Hydrographic and Oceanographic Service of the Chilean Navy publishes a
<a href="http://www.horaoficial.cl/historia_hora.html" hreflang="es">history of
Chile's official time (in Spanish)</a>.</dd>
+<dt>China</dt>
+<dd>The Hong Kong Observatory maintains a
+<a href="https://www.hko.gov.hk/gts/time/Summertime.htm">history of
+ summer time in Hong Kong</a>,
+and Macau's Meteorological and Geophysical Bureau maintains a <a
+href="http://www.smg.gov.mo/smg/geophysics/e_t_Summer%20Time.htm">similar
+history for Macau</a>.
+Unfortunately the latter is incomplete and has errors.</dd>
<dt>Czech Republic</dt>
<dd><a href="https://kalendar.beda.cz/kdy-zacina-a-konci-letni-cas"
hreflang="cs">When daylight saving time starts and ends (in Czech)</a>
@@ -758,10 +769,6 @@ hreflang="he">announcements (in Hebrew)</a>.</dd>
<dd>The National Institute of Metrological Research maintains a
<a href="http://oldsite.inrim.it/res/tf/ora_legale_i.shtml">table of civil time
(in Italian)</a>.</dd>
-<dt>Macau</dt>
-<dd>The Meteorological and Geophysical Bureau maintains a
-<a href="http://www.smg.gov.mo/smg/geophysics/e_t_Summer%20Time.htm">history
-of summer time</a>. Unfortunately it is incomplete and has errors.</dd>
<dt>Malaysia</dt>
<dd>See Singapore <a href="#Singapore">below</a>.</dd>
<dt>Mexico</dt>
diff --git a/tz/tzfile.5 b/tz/tzfile.5
index 79b19bf..bbdccfc 100644
--- a/tz/tzfile.5
+++ b/tz/tzfile.5
@@ -9,6 +9,8 @@ tzfile \- timezone information
.de q
\\$3\*(lq\\$1\*(rq\\$2
..
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
The timezone information files used by
.BR tzset (3)
are typically found under a directory with a name like
@@ -186,8 +188,196 @@ from 0 through 24.
Second, DST is in effect all year if it starts
January 1 at 00:00 and ends December 31 at 24:00 plus the difference
between daylight saving and standard time.
-.PP
+.SS Interoperability considerations
Future changes to the format may append more data.
+.PP
+Version 1 files are considered a legacy format and
+should be avoided, as they do not support transition
+times after the year 2038.
+Readers that only understand Version 1 must ignore
+any data that extends beyond the calculated end of the version
+1 data block.
+.PP
+Writers should generate a version 3 file if
+TZ string extensions are necessary to accurately
+model transition times.
+Otherwise, version 2 files should be generated.
+.PP
+The sequence of time changes defined by the version 1
+header and data block should be a contiguous subsequence
+of the time changes defined by the version 2+ header and data
+block, and by the footer.
+This guideline helps obsolescent version 1 readers
+agree with current readers about timestamps within the
+contiguous subsequence. It also lets writers not
+supporting obsolescent readers use a
+.I tzh_timecnt
+of zero
+in the version 1 data block to save space.
+.PP
+Time zone designations should consist of at least three (3)
+and no more than six (6) ASCII characters from the set of
+alphanumerics,
+.q "-",
+and
+.q "+".
+This is for compatibility with POSIX requirements for
+time zone abbreviations.
+.PP
+When reading a version 2 or 3 file, readers
+should ignore the version 1 header and data block except for
+the purpose of skipping over them.
+.PP
+Readers should calculate the total lengths of the
+headers and data blocks and check that they all fit within
+the actual file size, as part of a validity check for the file.
+.SS Common interoperability issues
+This section documents common problems in reading or writing TZif files.
+Most of these are problems in generating TZif files for use by
+older readers.
+The goals of this section are:
+.IP * 2
+to help TZif writers output files that avoid common
+pitfalls in older or buggy TZif readers,
+.IP *
+to help TZif readers avoid common pitfalls when reading
+files generated by future TZif writers, and
+.IP *
+to help any future specification authors see what sort of
+problems arise when the TZif format is changed.
+.PP
+When new versions of the TZif format have been defined, a
+design goal has been that a reader can successfully use a TZif
+file even if the file is of a later TZif version than what the
+reader was designed for.
+When complete compatibility was not achieved, an attempt was
+made to limit glitches to rarely-used timestamps, and to allow
+simple partial workarounds in writers designed to generate
+new-version data useful even for older-version readers.
+This section attempts to document these compatibility issues and
+workarounds, as well as to document other common bugs in
+readers.
+.PP
+Interoperability problems with TZif include the following:
+.IP * 2
+Some readers examine only version 1 data.
+As a partial workaround, a writer can output as much version 1
+data as possible.
+However, a reader should ignore version 1 data, and should use
+version 2+ data even if the reader's native timestamps have only
+32 bits.
+.IP *
+Some readers designed for version 2 might mishandle
+timestamps after a version 3 file's last transition, because
+they cannot parse extensions to POSIX in the TZ-like string.
+As a partial workaround, a writer can output more transitions
+than necessary, so that only far-future timestamps are
+mishandled by version 2 readers.
+.IP *
+Some readers designed for version 2 do not support
+permanent daylight saving time, e.g., a TZ string
+.q "EST5EDT,0/0,J365/25"
+denoting permanent Eastern Daylight Time (\*-04).
+As a partial workaround, a writer can substitute standard time
+for the next time zone east, e.g.,
+.q "AST4"
+for permanent Atlantic Standard Time (\*-04).
+.IP *
+Some readers ignore the footer, and instead predict future
+timestamps from the time type of the last transition.
+As a partial workaround, a writer can output more transitions
+than necessary.
+.IP *
+Some readers do not use time type 0 for timestamps before
+the first transition, in that they infer a time type using a
+heuristic that does not always select time type 0.
+As a partial workaround, a writer can output a dummy (no-op)
+first transition at an early time.
+.IP *
+Some readers mishandle timestamps before the first
+transition that has a timestamp not less than -2**31.
+Readers that support only 32-bit timestamps are likely to be
+more prone to this problem, for example, when they process
+64-bit transitions only some of which are representable in 32
+bits.
+As a partial workaround, a writer can output a dummy
+transition at timestamp \*-2**31.
+.IP *
+Some readers mishandle a transition if its timestamp has
+the minimum possible signed 64-bit value.
+Timestamps less than \*-2**59 are not recommended.
+.IP *
+Some readers mishandle POSIX-style TZ strings that
+contain
+.q "<"
+or
+.q ">".
+As a partial workaround, a writer can avoid using
+.q "<"
+or
+.q ">"
+for time zone abbreviations containing only alphabetic
+characters.
+.IP *
+Many readers mishandle time zone abbreviations that contain
+non-ASCII characters.
+These characters are not recommended.
+.IP *
+Some readers may mishandle time zone abbreviations that
+contain fewer than 3 or more than 6 characters, or that
+contain ASCII characters other than alphanumerics,
+.q "-",
+and
+.q "+".
+These abbreviations are not recommended.
+.IP *
+Some readers mishandle TZif files that specify
+daylight-saving time UT offsets that are less than the UT
+offsets for the corresponding standard time.
+These readers do not support locations like Ireland, which
+uses the equivalent of the POSIX TZ string
+.q "IST\*-1GMT0,M10.5.0,M3.5.0/1",
+observing standard time
+(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
+As a partial workaround, a writer can output data for the
+equivalent of the POSIX TZ string
+.q "GMT0IST,M3.5.0/1,M10.5.0",
+thus swapping standard and daylight saving time.
+Although this workaround misidentifies which part of the year
+uses daylight saving time, it records UT offsets and time zone
+abbreviations correctly.
+.PP
+Some interoperability problems are reader bugs that
+are listed here mostly as warnings to developers of readers.
+.IP * 2
+Some readers do not support negative timestamps.
+Developers of distributed applications should keep this
+in mind if they need to deal with pre-1970 data.
+.IP *
+Some readers mishandle timestamps before the first
+transition that has a nonnegative timestamp.
+Readers that do not support negative timestamps are likely to
+be more prone to this problem.
+.IP *
+Some readers mishandle time zone abbreviations like
+.q "-08"
+that contain
+.q "+",
+.q "-",
+or digits.
+.IP *
+Some readers mishandle UT offsets that are out of the
+traditional range of \*-12 through +12 hours, and so do not
+support locations like Kiritimati that are outside this
+range.
+.IP *
+Some readers mishandle UT offsets in the range [\*-3599, \*-1]
+seconds from UT, because they integer-divide the offset by
+3600 to get 0 and then display the hour part as
+.q "+00".
+.IP *
+Some readers mishandle UT offsets that are not a multiple
+of one hour, or of 15 minutes, or of 1 minute.
.SH SEE ALSO
.BR time (2),
.BR localtime (3),
diff --git a/tz/zdump.8 b/tz/zdump.8
index f369056..fb6b8df 100644
--- a/tz/zdump.8
+++ b/tz/zdump.8
@@ -150,15 +150,16 @@ tabbed columns line up.)
.if \n(.g .ft CW
.if t .in +.5i
.if n .in +2
-.nr w \w'1896-01-13 'u
-.ta \nwu +\nwu +\nwu +\nwu
+.nr w \w'1896-01-13 'u+\n(.i
+.ta \w'1896-01-13 'u +\w'12:01:26 'u +\w'-103126 'u +\w'HWT 'u
TZ="Pacific/Honolulu"
-- - -10:31:26 LMT
-1896-01-13 12:01:26 -10:30 HST
-1933-04-30 03 -09:30 HDT 1
-1933-05-21 11 -10:30 HST
-1942-02-09 03 -09:30 HDT 1
-1945-09-30 01 -10:30 HST
+- - -103126 LMT
+1896-01-13 12:01:26 -1030 HST
+1933-04-30 03 -0930 HDT 1
+1933-05-21 11 -1030 HST
+1942-02-09 03 -0930 HWT 1
+1945-08-14 13:30 -0930 HPT 1
+1945-09-30 01 -1030 HST
1947-06-08 02:30 -10 HST
.in
.if \n(.g .ft
@@ -183,7 +184,7 @@ Here are excerpts from another example:
.if t .in +.5i
.if n .in +2
TZ="Europe/Astrakhan"
-- - +03:12:12 LMT
+- - +031212 LMT
1924-04-30 23:47:48 +03
1930-06-21 01 +04
1981-04-01 01 +05 1
diff --git a/tz/zic.8 b/tz/zic.8
index c277d9c..ac85e46 100644
--- a/tz/zic.8
+++ b/tz/zic.8
@@ -304,6 +304,10 @@ or
if the given time is universal time;
in the absence of an indicator,
wall clock time is assumed.
+These forms ignore leap seconds; for example,
+if a leap second occurs at 00:59:60 local time,
+.q "1:00"
+stands for 3601 seconds after local midnight instead of the usual 3600 seconds.
The intent is that a rule line describes the instants when a
clock/calendar set to the type of time specified in the
.B AT
diff --git a/tz/zic.c b/tz/zic.c
index 06becc2..cb1bf28 100644
--- a/tz/zic.c
+++ b/tz/zic.c
@@ -64,6 +64,11 @@ typedef int_fast64_t zic_t;
static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t));
#endif
+/* The minimum alignment of a type, for pre-C11 platforms. */
+#if __STDC_VERSION__ < 201112
+# define _Alignof(type) offsetof(struct { char a; type b; }, b)
+#endif
+
/* The type for line numbers. Use PRIdMAX to format them; formerly
there was also "#define PRIdLINENO PRIdMAX" and formats used
PRIdLINENO, but xgettext cannot grok that. */
@@ -189,7 +194,9 @@ enum { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1 };
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
workaround will no longer be needed when Qt 5.6.1 and earlier are
obsolete, say in the year 2021. */
+#ifndef WORK_AROUND_QTBUG_53071
enum { WORK_AROUND_QTBUG_53071 = true };
+#endif
static int charcnt;
static bool errors;
@@ -431,6 +438,16 @@ size_product(size_t nitems, size_t itemsize)
return nitems * itemsize;
}
+static ATTRIBUTE_PURE size_t
+align_to(size_t size, size_t alignment)
+{
+ size_t aligned_size = size + alignment - 1;
+ aligned_size -= aligned_size % alignment;
+ if (aligned_size < size)
+ memory_exhausted(_("alignment overflow"));
+ return aligned_size;
+}
+
#if !HAVE_STRDUP
static char *
strdup(char const *str)
@@ -1714,12 +1731,6 @@ atcomp(const void *avp, const void *bvp)
return (a < b) ? -1 : (a > b);
}
-static bool
-is32(const zic_t x)
-{
- return INT32_MIN <= x && x <= INT32_MAX;
-}
-
static void
swaptypes(int i, int j)
{
@@ -1746,7 +1757,11 @@ writezone(const char *const name, const char *const string, char version,
zic_t one = 1;
zic_t y2038_boundary = one << 31;
ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071;
- zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1));
+
+ /* Allocate the ATS and TYPES arrays via a single malloc,
+ as this is a bit faster. */
+ zic_t *ats = emalloc(align_to(size_product(nats, sizeof *ats + 1),
+ _Alignof(zic_t)));
void *typesptr = ats + nats;
unsigned char *types = typesptr;
@@ -1797,18 +1812,6 @@ writezone(const char *const name, const char *const string, char version,
types[i] = attypes[i].type;
}
- /* Work around QTBUG-53071 for timestamps less than y2038_boundary - 1,
- by inserting a no-op transition at time y2038_boundary - 1.
- This works only for timestamps before the boundary, which
- should be good enough in practice as QTBUG-53071 should be
- long-dead by 2038. */
- if (WORK_AROUND_QTBUG_53071 && timecnt != 0
- && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) {
- ats[timecnt] = y2038_boundary - 1;
- types[timecnt] = types[timecnt - 1];
- timecnt++;
- }
-
/*
** Correct for leap seconds.
*/
@@ -1820,6 +1823,22 @@ writezone(const char *const name, const char *const string, char version,
break;
}
}
+
+ /* Work around QTBUG-53071 for timestamps less than y2038_boundary - 1,
+ by inserting a no-op transition at time y2038_boundary - 1.
+ This works only for timestamps before the boundary, which
+ should be good enough in practice as QTBUG-53071 should be
+ long-dead by 2038. Do this after correcting for leap
+ seconds, as the idea is to insert a transition just before
+ 32-bit time_t rolls around, and this occurs at a slightly
+ different moment if transitions are leap-second corrected. */
+ if (WORK_AROUND_QTBUG_53071 && timecnt != 0
+ && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) {
+ ats[timecnt] = y2038_boundary - 1;
+ types[timecnt] = types[timecnt - 1];
+ timecnt++;
+ }
+
/*
** Figure out 32-bit-limited starts and counts.
*/
@@ -1827,22 +1846,22 @@ writezone(const char *const name, const char *const string, char version,
timei32 = 0;
leapcnt32 = leapcnt;
leapi32 = 0;
- while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
+ while (0 < timecnt32 && INT32_MAX < ats[timecnt32 - 1])
--timecnt32;
- while (timecnt32 > 0 && !is32(ats[timei32])) {
+ while (1 < timecnt32 && ats[timei32] < INT32_MIN
+ && ats[timei32 + 1] <= INT32_MIN) {
+ /* Discard too-low transitions, except keep any last too-low
+ transition if no transition is exactly at INT32_MIN.
+ The kept transition will be output as an INT32_MIN
+ "transition" appropriate for buggy 32-bit clients that do
+ not use time type 0 for timestamps before the first
+ transition; see below. */
--timecnt32;
++timei32;
}
- /*
- ** Output an INT32_MIN "transition" if appropriate; see below.
- */
- if (timei32 > 0 && ats[timei32] > INT32_MIN) {
- --timei32;
- ++timecnt32;
- }
- while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
+ while (0 < leapcnt32 && INT32_MAX < trans[leapcnt32 - 1])
--leapcnt32;
- while (leapcnt32 > 0 && !is32(trans[leapi32])) {
+ while (0 < leapcnt32 && trans[leapi32] < INT32_MIN) {
--leapcnt32;
++leapi32;
}
diff --git a/tz/ziguard.awk b/tz/ziguard.awk
index 42e2910..e3c7298 100644
--- a/tz/ziguard.awk
+++ b/tz/ziguard.awk
@@ -80,6 +80,13 @@ DATAFORM != "main" {
if (comment_out) {
sub(/^/, "#")
}
+
+ # In rearguard format, change the Japan rule line with "Sat>=8 25:00"
+ # to "Sun>=9 1:00", to cater to zic before 2007 and to older Java.
+ if (!vanguard && $1 == "Rule" && $7 == "Sat>=8" && $8 == "25:00") {
+ sub(/Sat>=8/, "Sun>=9")
+ sub(/25:00/, " 1:00")
+ }
}
# If a Link line is followed by a Zone line for the same data, comment
diff --git a/tz/zishrink.awk b/tz/zishrink.awk
index 74e0de9..8876b68 100644
--- a/tz/zishrink.awk
+++ b/tz/zishrink.awk
@@ -172,11 +172,6 @@ function process_input_line(line, field, end, i, n, startdef)
if (line ~ /^R /) return
line = substr(line, 1, RSTART) substr(line, RSTART + 5)
}
- # Replace SpainAfrica rules with Morocco, as they are duplicates.
- if (match(line, / SpainAfrica /)) {
- if (line ~ /^R /) return
- line = substr(line, 1, RSTART) "Morocco" substr(line, RSTART + RLENGTH - 1)
- }
# Abbreviate times.
while (match(line, /[: ]0+[0-9]/))