Dust settled on Argentina?
Paul Eggert
eggert at CS.UCLA.EDU
Tue Jul 13 20:55:02 UTC 2004
"Olson, Arthur David (NIH/NCI)" <olsona at dc37a.nci.nih.gov> writes:
> I haven't seen another patch. Should I go ahead and promulgate the
> 2004-06-15 patch, or should I wait?
Sorry, I dropped the ball on that one. Here's a revised version:
it incorporates the discussion to earlier revisions of
all the patches I've posted. I also updated the tz-link.htm web page
to reflect foreign web site changes.
* Patches relevant to current time stamps.
- Major reorganizaton for Argentina.
. New zones America/Argentina/Tucuman, America/Argentina/La_Rioja,
America/Argentina/San_Juan, America/Argentina/ComodRivadavia,
America/Argentina/Rio_Gallegos, America/Argentina/Ushuaia reflecting
this year's changes. (Thanks to Mariano Absatz and Gwillim Law for
their dogged reporting of this info.)
. America/Buenos_Aires renamed to America/Argentina/Buenos_Aires,
and similarly for America/Cordoba, America/Jujuy,
America/Catamarca, America/Mendoza. Backward-compatible links
retained so that old TZ settings still work.
- Georgia switched to Moscow time on June 27. (Thanks to Joseph S. Myers
for this info.)
* Patch relevant to historical time stamps.
- Where new zones were created, I recorded Shanks's opinions of what
happened to Argentina in 1991.
* Patch due to ISO 3166 change.
- The ISO added a country code AX for the Aaland Islands, so I added
a new link Europe/Mariehamn for AX.
* Documentation patches.
- Add URL for PyTZ.
- Update URL for Tru64.
- Remove dangling URL to <http://www.hilink.com.au/times/>.
- Mention that Java has only a subset of the Olson database.
- Move ICU localization reference to "Time Notation" section.
- Update names for Astrodienst, worldtimezone.com, INMS.
* Some proposed source-code patches for 64-bit hosts.
- Use 'long' when computing years, not 'int', to avoid spurious
overflow on 64-bit hosts.
- Use our (more generous) asctime implementation than relying on the
system asctime, so that we can print years before 1900 and after
9999 (even on HP-UX).
- When localtime/gmtime fails, print the raw time_t value as an
integer than the less-informative "NULL".
- Don't attempt to print out all the 64-bit time_t space, as that will
take nearly forever; instead, default to printing a few decades
into the future, and don't bother to print times before about 1833.
This suffices for all the current tz data and is good enough for
POSIX tz values until the year 2106. We can revisit this when we
add true 64-bit support for tz data.
diff -pru tz-2004aa/asia tz/asia
--- tz-2004aa/asia 2004-05-27 09:00:30.000000000 -0700
+++ tz/asia 2004-07-13 13:16:45.000000000 -0700
@@ -335,6 +335,16 @@ Link Asia/Nicosia Europe/Nicosia
# Instead of putting back clocks at the end of October, Georgia
# will stay on daylight savings time this winter to save energy,
# President Eduard Shevardnadze decreed Wednesday.
+#
+# From the BBC via Joseph S. Myers (2004-06-27):
+#
+# Georgia moved closer to Western Europe on Sunday... The former Soviet
+# republic has changed its time zone back to that of Moscow. As a result it
+# is now just four hours ahead of Greenwich Mean Time, rather than five hours
+# ahead. The switch was decreed by the pro-Western president of Georgia,
+# Mikhail Saakashvili, who said the change was partly prompted by the process
+# of integration into Europe.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Tbilisi 2:59:16 - LMT 1880
2:59:16 - TBMT 1924 May 2 # Tbilisi Mean Time
@@ -345,7 +355,8 @@ Zone Asia/Tbilisi 2:59:16 - LMT 1880
3:00 E-EurAsia GE%sT 1994 Sep lastSun
4:00 E-EurAsia GE%sT 1996 Oct lastSun
4:00 1:00 GEST 1997 Mar lastSun
- 4:00 E-EurAsia GE%sT
+ 4:00 E-EurAsia GE%sT 2004 Jun 27
+ 3:00 RussiaAsia GE%sT
# East Timor
diff -pru tz-2004aa/backward tz/backward
--- tz-2004aa/backward 2004-05-27 09:00:30.000000000 -0700
+++ tz/backward 2004-06-14 12:30:06.845824000 -0700
@@ -4,9 +4,14 @@
# and their old names. Many names changed in late 1993.
Link America/Adak America/Atka
+Link America/Argentina/Buenos_Aires America/Buenos_Aires
+Link America/Argentina/Catamarca America/Catamarca
+Link America/Argentina/Cordoba America/Cordoba
Link America/Tijuana America/Ensenada
Link America/Indianapolis America/Fort_Wayne
+Link America/Argentina/Jujuy America/Jujuy
Link America/Indiana/Knox America/Knox_IN
+Link America/Argentina/Mendoza America/Mendoza
Link America/Rio_Branco America/Porto_Acre
Link America/Cordoba America/Rosario
Link America/St_Thomas America/Virgin
diff -pru tz-2004aa/europe tz/europe
--- tz-2004aa/europe 2004-05-27 09:00:30.000000000 -0700
+++ tz/europe 2004-06-12 18:37:32.547326000 -0700
@@ -921,6 +921,10 @@ Zone Europe/Helsinki 1:39:52 - LMT 1878
2:00 Finland EE%sT 1981 Mar 29 2:00
2:00 EU EE%sT
+# Aaland Is
+Link Europe/Helsinki Europe/Mariehamn
+
+
# France
# From Ciro Discepolo (2000-12-20):
diff -pru tz-2004aa/iso3166.tab tz/iso3166.tab
--- tz-2004aa/iso3166.tab 2003-12-15 06:36:37.000000000 -0800
+++ tz/iso3166.tab 2004-06-13 23:50:45.657245000 -0700
@@ -2,11 +2,11 @@
#
# @(#)iso3166.tab 1.14
#
-# From Paul Eggert <eggert at twinsun.com> (2003-02-04):
+# From Paul Eggert <eggert at twinsun.com> (2004-06-14):
#
# This file contains a table with the following columns:
# 1. ISO 3166-1 alpha-2 country code, current as of
-# ISO 3166-1 Newsletter No. V-8 (2003-07-23). See:
+# ISO 3166-1 Newsletter No. V-10 (2004-04-26). See:
# <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html">
# ISO 3166 Maintenance agency (ISO 3166/MA)
# </a>.
@@ -36,6 +36,7 @@ AS Samoa (American)
AT Austria
AU Australia
AW Aruba
+AX Aaland Islands
AZ Azerbaijan
BA Bosnia & Herzegovina
BB Barbados
diff -pru tz-2004aa/southamerica tz/southamerica
--- tz-2004aa/southamerica 2004-05-27 09:00:30.000000000 -0700
+++ tz/southamerica 2004-06-22 21:39:13.762385000 -0700
@@ -155,17 +155,47 @@ Rule Arg 2000 only - Mar Sun>=1 0:00 0 -
# </a> says that standard time in Argentina from 1894-10-31
# to 1920-05-01 was -4:16:48.25. Go with this more-precise value
# over Shanks.
+#
+# From Mariano Absatz (2004-06-05):
+# These media articles from a major newspaper mostly cover the current state:
+# http://www.lanacion.com.ar/04/05/27/de_604825.asp
+# http://www.lanacion.com.ar/04/05/28/de_605203.asp
+#
+# The following eight (8) provinces pulled clocks back to UTC-04:00 at
+# midnight Monday May 31st. (that is, the night between 05/31 and 06/01).
+# Apparently, all nine provinces would go back to UTC-03:00 at the same
+# time in October 17th.
+#
+# Catamarca, Chubut, La Rioja, San Juan, San Luis, Santa Cruz,
+# Tierra del Fuego, Tucuman.
+#
+# From Mariano Absatz (2004-06-14):
+# ... this weekend, the Province of Tucuman decided it'd go back to UTC-03:00
+# yesterday midnight (that is, at 24:00 Saturday 12th), since the people's
+# annoyance with the change is much higher than the power savings obtained....
+#
+# From Gwillim Law (2004-06-14):
+# http://www.lanacion.com.ar/04/06/10/de_609078.asp ...
+# "The time change in Tierra del Fuego was a conflicted decision from
+# the start. The government had decreed that the measure would take
+# effect on June 1, but a normative error forced the new time to begin
+# three days earlier, from a Saturday to a Sunday....
+# Our understanding was that the change was originally scheduled to take place
+# on June 1 at 00:00 in Chubut, Santa Cruz, Tierra del Fuego (and some other
+# provinces). Sunday was May 30, only two days earlier. So the article
+# contains a contradiction. I would give more credence to the Saturday/Sunday
+# date than the "three days earlier" phrase, and conclude that Tierra del
+# Fuego set its clocks back at 2004-05-30 00:00.
# Unless otherwise specified, data are from Shanks through 1992, from
# the IATA otherwise. As noted below, Shanks says that
-# America/Cordoba split into 7 subregions during 1991/1992, but we
+# America/Cordoba split into 6 subregions during 1991/1992, but we
# haven't verified this yet so for now we'll keep it a single region.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
#
-# Buenos Aires (BA), Capital Federal (CF), Santa Cruz (SC),
-# Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF)
-Zone America/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
+# Buenos Aires (BA), Capital Federal (CF),
+Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
-4:16:48 - CMT 1920 May # Cordoba Mean Time
-4:00 - ART 1930 Dec
-4:00 Arg AR%sT 1969 Oct 5
@@ -174,24 +204,19 @@ Zone America/Buenos_Aires -3:53:48 - LMT
-3:00 - ART
#
# Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN), Chaco (CC),
-# Formosa (FM), Salta (SA), Tucuman (TM), Santiago del Estero (SE),
-# Cordoba (CB), La Rioja (LR), San Juan (SJ), San Luis (SL), La Pampa (LP),
-# Neuquen (NQ), Rio Negro (RN), Chubut (CH)
+# Formosa (FM), Salta (SA), Santiago del Estero (SE), Cordoba (CB),
+# San Luis (SL), La Pampa (LP), Neuquen (NQ), Rio Negro (RN)
#
# Shanks also makes the following claims, which we haven't verified:
# - Formosa switched to -3:00 on 1991-01-07.
-# - La Rioja and San Juan switched to -4:00 on 1991-03-01
-# and then to -3:00 on 1991-05-07.
# - Misiones switched to -3:00 on 1990-12-29.
# - Chaco switched to -3:00 on 1991-01-04.
# - San Luis switched to -4:00 on 1990-03-14, then to -3:00 on 1990-10-15,
# then to -4:00 on 1991-03-01, then to -3:00 on 1991-06-01.
# - Santiago del Estero switched to -4:00 on 1991-04-01,
# then to -3:00 on 1991-04-26.
-# If we need to add Zones for these areas, we may need to have a subdirectory
-# for Argentina, as e.g. "America/San_Luis" is too ambiguious.
#
-Zone America/Cordoba -4:16:48 - LMT 1894 Oct 31
+Zone America/Argentina/Cordoba -4:16:48 - LMT 1894 Oct 31
-4:16:48 - CMT 1920 May
-4:00 - ART 1930 Dec
-4:00 Arg AR%sT 1969 Oct 5
@@ -201,8 +226,47 @@ Zone America/Cordoba -4:16:48 - LMT 1894
-4:00 Arg AR%sT 2000 Mar 3
-3:00 - ART
#
+# Tucuman (TM)
+Zone America/Argentina/Tucuman -4:20:52 - LMT 1894 Oct 31
+ -4:16:48 - CMT 1920 May
+ -4:00 - ART 1930 Dec
+ -4:00 Arg AR%sT 1969 Oct 5
+ -3:00 Arg AR%sT 1991 Mar 3
+ -4:00 - WART 1991 Oct 20
+ -3:00 Arg AR%sT 1999 Oct 3
+ -4:00 Arg AR%sT 2000 Mar 3
+ -3:00 - ART 2004 Jun 1
+ -4:00 - WART 2004 Jun 13
+ -3:00 - ART
+#
+# La Rioja (LR)
+Zone America/Argentina/La_Rioja -4:27:24 - LMT 1894 Oct 31
+ -4:16:48 - CMT 1920 May
+ -4:00 - ART 1930 Dec
+ -4:00 Arg AR%sT 1969 Oct 5
+ -3:00 Arg AR%sT 1991 Mar 1
+ -4:00 - WART 1991 May 7
+ -3:00 Arg AR%sT 1999 Oct 3
+ -4:00 Arg AR%sT 2000 Mar 3
+ -3:00 - ART 2004 Jun 1
+ -4:00 - WART 2004 Jun 20
+ -3:00 - ART
+#
+# San Juan (SJ)
+Zone America/Argentina/San_Juan -4:34:04 - LMT 1894 Oct 31
+ -4:16:48 - CMT 1920 May
+ -4:00 - ART 1930 Dec
+ -4:00 Arg AR%sT 1969 Oct 5
+ -3:00 Arg AR%sT 1991 Mar 1
+ -4:00 - WART 1991 May 7
+ -3:00 Arg AR%sT 1999 Oct 3
+ -4:00 Arg AR%sT 2000 Mar 3
+ -3:00 - ART 2004 Jun 1
+ -4:00 - WART 2004 Oct 17
+ -3:00 - ART
+#
# Jujuy (JY)
-Zone America/Jujuy -4:21:12 - LMT 1894 Oct 31
+Zone America/Argentina/Jujuy -4:21:12 - LMT 1894 Oct 31
-4:16:48 - CMT 1920 May
-4:00 - ART 1930 Dec
-4:00 Arg AR%sT 1969 Oct 5
@@ -216,7 +280,7 @@ Zone America/Jujuy -4:21:12 - LMT 1894 O
-3:00 - ART
#
# Catamarca (CT)
-Zone America/Catamarca -4:23:08 - LMT 1894 Oct 31
+Zone America/Argentina/Catamarca -4:23:08 - LMT 1894 Oct 31
-4:16:48 - CMT 1920 May
-4:00 - ART 1930 Dec
-4:00 Arg AR%sT 1969 Oct 5
@@ -224,10 +288,12 @@ Zone America/Catamarca -4:23:08 - LMT 18
-4:00 - WART 1991 Oct 20
-3:00 Arg AR%sT 1999 Oct 3
-4:00 Arg AR%sT 2000 Mar 3
+ -3:00 - ART 2004 Jun 1
+ -4:00 - WART 2004 Jun 20
-3:00 - ART
#
# Mendoza (MZ)
-Zone America/Mendoza -4:35:16 - LMT 1894 Oct 31
+Zone America/Argentina/Mendoza -4:35:16 - LMT 1894 Oct 31
-4:16:48 - CMT 1920 May
-4:00 - ART 1930 Dec
-4:00 Arg AR%sT 1969 Oct 5
@@ -242,6 +308,42 @@ Zone America/Mendoza -4:35:16 - LMT 1894
-3:00 - ART 2004 May 23
-4:00 - WART 2004 Oct 17
-3:00 - ART
+#
+# Chubut (CH)
+# The name "Comodoro Rivadavia" exceeds the 14-byte POSIX limit.
+Zone America/Argentina/ComodRivadavia -4:30:00 - LMT 1894 Oct 31
+ -4:16:48 - CMT 1920 May
+ -4:00 - ART 1930 Dec
+ -4:00 Arg AR%sT 1969 Oct 5
+ -3:00 Arg AR%sT 1991 Mar 3
+ -4:00 - WART 1991 Oct 20
+ -3:00 Arg AR%sT 1999 Oct 3
+ -4:00 Arg AR%sT 2000 Mar 3
+ -3:00 - ART 2004 Jun 1
+ -4:00 - WART 2004 Jun 20
+ -3:00 - ART
+#
+# Santa Cruz (SC)
+Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
+ -4:16:48 - CMT 1920 May # Cordoba Mean Time
+ -4:00 - ART 1930 Dec
+ -4:00 Arg AR%sT 1969 Oct 5
+ -3:00 Arg AR%sT 1999 Oct 3
+ -4:00 Arg AR%sT 2000 Mar 3
+ -3:00 - ART 2004 Jun 1
+ -4:00 - WART 2004 Jun 20
+ -3:00 - ART
+#
+# Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF)
+Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31
+ -4:16:48 - CMT 1920 May # Cordoba Mean Time
+ -4:00 - ART 1930 Dec
+ -4:00 Arg AR%sT 1969 Oct 5
+ -3:00 Arg AR%sT 1999 Oct 3
+ -4:00 Arg AR%sT 2000 Mar 3
+ -3:00 - ART 2004 May 30
+ -4:00 - WART 2004 Jun 20
+ -3:00 - ART
# Aruba
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
diff -pru tz-2004aa/tz-link.htm tz/tz-link.htm
--- tz-2004aa/tz-link.htm 2004-05-27 09:00:30.000000000 -0700
+++ tz/tz-link.htm 2004-07-13 13:21:17.651768000 -0700
@@ -9,7 +9,7 @@
<meta http-equiv="Content-type" content='text/html; charset="US-ASCII"' />
<meta name="DC.Creator" content="Eggert, Paul" />
<meta name="DC.Contributor" content="Olson, Arthur David" />
-<meta name="DC.Date" content="2004-05-24" />
+<meta name="DC.Date" content="2004-07-13" />
<meta name="DC.Description"
content="Sources of information about time zones and daylight saving time" />
<meta name="DC.Identifier" content="http://www.twinsun.com/tz/tz-link.htm" />
@@ -47,7 +47,7 @@ including
<a href="http://www.apple.com/macosx/">Mac OS X</a>,
<a href="http://h71000.www7.hp.com/">OpenVMS</a>,
<a href="http://wwws.sun.com/software/solaris/">Solaris</a>,
-<a href="http://www.tru64unix.compaq.com/">Tru64</a>, and
+<a href="http://h30097.www3.hp.com/">Tru64</a>, and
<a href="http://www.sco.com/products/unixware/">UnixWare</a>.</p>
<p>
Each location in the database represents a national region where all
@@ -104,14 +104,9 @@ is a text-based point-and-click interfac
throughout the world.</li>
<li>Fancier web interfaces, roughly in ascending order of complexity, include:
<ul>
-<li><a href="http://www.hilink.com.au/times/">Local Times Around the
-World</a></li>
<li><a href="http://www.convertit.com/Go/ConvertIt/World_Time/Current_Time.ASP">Current Time in 1000 Places</a></li>
<li><a href="http://timezoneconverter.com/">Time Zone Converter</a></li>
</ul></li>
-<li><a href="http://www.holidayfestival.com/">The Worldwide Holiday
-& Festival Site</a> lists DST-related clock changes along with
-holidays.</li>
<li><a href="http://www.timeanddate.com/worldclock/">The World Clock -
Time Zones</a>
is a web interface to a time zone database derived from
@@ -152,9 +147,8 @@ contains a script <code>parse_olson</cod
<code>tz</code> source into <a href="http://www.perl.org/">Perl</a>
modules. It is part of the Perl <a
href="http://datetime.perl.org/">DateTime Project</a>, which is freely
-available under both the GPL and the Perl <a
-href="http://www.perl.com/language/misc/Artistic.html">Artistic
-License</a>. DateTime::TimeZone also contains a script
+available under both the GPL and the Perl Artistic
+License. DateTime::TimeZone also contains a script
<code>tests_from_zdump</code> that generates test cases for each clock
transition in the <code>tz</code> database.</li>
<li><a href="http://oss.software.ibm.com/icu/">International Components for
@@ -166,6 +160,10 @@ and time API</a> contains a class
<code>org.joda.time.tz.ZoneInfoCompiler</code> that compiles
<code>tz</code> source into a Joda-specific binary format. Joda Time
is freely available under a BSD-style license.</li>
+<li><a href="http://sourceforge.net/projects/pytz/">PyTZ - Python Time
+Zone Library</a> compiles <code>tz</code> source into
+<a href="http://www.python.org/">Python</a>.
+It is freely available under a BSD-style license.</li>
</ul>
<h2>Other <code>tz</code> binary file readers</h2>
<ul>
@@ -180,15 +178,14 @@ and is widely used in GNU/Linux systems.
is a <code>tz</code> binary file reader written in Java.
It is freely available under the GNU LGPL.</li>
<li><a href="http://s.keim.free.fr/tz/doc.html">Python time zones</a>
-is a <code>tz</code> binary file reader written in <a
-href="http://www.python.org/">Python</a>. It is freely available
-under a BSD-style license.</li>
+is a <code>tz</code> binary file reader written in Python.
+It is freely available under a BSD-style license.</li>
</ul>
<h2>Other <code>tz</code>-based time zone conversion software</h2>
<ul>
<li><a href="http://java.sun.com/">Sun Java</a> releases since 1.4
-contain a copy of a recent <samp>tz</samp> database in a Java-specific
-format.</li>
+contain a copy of a subset of a recent <samp>tz</samp> database in a
+Java-specific format.</li>
<li><a
href="http://www1.tip.nl/~t876506/AboutTimeZonesHC.html">HyperCard
time zones calculator</a> is a HyperCard stack.</li>
@@ -198,8 +195,8 @@ Microsoft Windows program.</li>
</ul>
<h2>Other time zone databases</h2>
<ul>
-<li><a href="http://www.astro.com/cgi-bin/atlw3/aq.cgi?lang=e">Atlas Query
-- Astrodienst</a> is Astrodienst's Web version of Shanks's
+<li><a href="http://www.astro.com/cgi/aq.cgi?lang=e">Atlas Query</a>
+is Astrodienst's Web version of Shanks's
excellent time zone history atlases published in both <a
href="http://astrocom.com/software/pcatlas.php">computer</a> and <a
href="http://astrocom.com/books/xrefa.php#SHANKS">book</a> form by <a
@@ -217,7 +214,7 @@ for the <code>usno*</code> files in the
<li><a href="http://www.airportcitycodes.com/aaa/">Airlines, Airplanes
and Airports</a> lists current standard times for thousands of
airports around the world. This seems to be derived from
-the <a href="http://www.iata.org/sked/publications/">Standard
+the <a href="http://www.iata.org/ps/publications/9179.htm">Standard
Schedules Information Manual (SSIM)</a> of the
the <a href="http://www.iata.org/">International Air Transport
Association</a>,
@@ -238,8 +235,8 @@ recent editions.
The pictorial quality is good,
but the maps do not indicate summer time,
and parts of the data are a few years out of date.</li>
-<li><a href="http://worldtimezone.com/">World timezones map with
-current time</a>
+<li><a href="http://worldtimezone.com/">Current time around the world
+and standard time zones map of the world</a>
has several fancy time zone maps; it covers Russia particularly well.
The maps' pictorial quality is not quite as good as the CIA's
but the maps are more up to date.</li>
@@ -252,9 +249,7 @@ boundaries between time zones within cou
<li>Manifold.net's <a
href="http://www.manifold.net/download/freemaps.html">Free Maps and
GIS Data</a> includes a Manifold-format map of world time zone
-boundaries distributed under the GPL. The GeoCommunity's <a
-href="http://software.geocomm.com/data/intl_timezones.html">International
-Time Zones</a> publishes the same data in other formats.</li>
+boundaries distributed under the GPL.</li>
<li>The US Geological Survey's National Atlas of the United States
publishes the <a href="http://www.nationalatlas.gov/timeznm.html">Time
Zones of the United States</a> in the public domain.</li>
@@ -304,7 +299,7 @@ Portuguese)</a>.</dd>
<dd>The Institute for National Measurement Standards publishes current
and some older information about <a
href="http://inms-ienm.nrc-cnrc.gc.ca/time_services/daylight_savings_e.html">Time
-Zones and Daylight Saving Time</a>.</dd>
+Zones & Daylight Saving Time</a>.</dd>
<dt>Chile</dt>
<dd>WebExhibits publishes a <a
href="http://webexhibits.org/daylightsaving/chile.html"
@@ -420,6 +415,12 @@ protocols.</li>
<a href="http://www.exit109.com/~ghealton/y2k/yrexamples.html">The
Best of Dates, the Worst of Dates</a> covers many problems encountered
by software developers when handling dates and time stamps.</li>
+<li><a
+href="http://oss.software.ibm.com/cvs/icu/~checkout~/icuhtml/design/formatting/time_zone_localization.html">Time
+Zone Localization</a> is a proposed mechanism for localizing time zone
+labels and abbreviations; for example, one might use it to specify
+Russian translations for "Eastern European Summer Time", "EEST", and
+<code>Europe/Bucharest</code>.</li>
<li>
Alphabetic time zone abbreviations should not be used as unique
identifiers for UTC offsets as they are ambiguous in practice. For
diff -pru tz-2004aa/zone.tab tz/zone.tab
--- tz-2004aa/zone.tab 2003-10-06 06:32:21.000000000 -0700
+++ tz/zone.tab 2004-06-22 21:35:35.301478000 -0700
@@ -41,11 +41,17 @@ AQ -6617+11031 Antarctica/Casey Casey St
AQ -7824+10654 Antarctica/Vostok Vostok Station, S Magnetic Pole
AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Base, Terre Adelie
AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I
-AR -3436-05827 America/Buenos_Aires E Argentina (BA, DF, SC, TF)
-AR -3124-06411 America/Cordoba most locations (CB,CC,CH,CN,ER,FM,LP,LR,MN,NQ,RN,SA,SE,SF,SJ,SL,TM)
-AR -2411-06518 America/Jujuy Jujuy (JY)
-AR -2828-06547 America/Catamarca Catamarca (CT)
-AR -3253-06849 America/Mendoza Mendoza (MZ)
+AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF)
+AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, LP, MN, NQ, RN, SA, SE, SF, SL)
+AR -2411-06518 America/Argentina/Jujuy Jujuy (JY)
+AR -3124-06411 America/Argentina/Tucuman Tucuman (TM)
+AR -2828-06547 America/Argentina/Catamarca Catamarca (CT)
+AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR)
+AR -3132-06831 America/Argentina/San_Juan San Juan (SJ)
+AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ)
+AR -4552-06730 America/Argentina/ComodRivadavia Chubut (CH)
+AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC)
+AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF)
AS -1416-17042 Pacific/Pago_Pago
AT +4813+01620 Europe/Vienna
AU -3133+15905 Australia/Lord_Howe Lord Howe Island
@@ -59,6 +65,7 @@ AU -3455+13835 Australia/Adelaide South
AU -1228+13050 Australia/Darwin Northern Territory
AU -3157+11551 Australia/Perth Western Australia
AW +1230-06858 America/Aruba
+AX +6006+01957 Europe/Mariehamn
AZ +4023+04951 Asia/Baku
BA +4352+01825 Europe/Sarajevo
BB +1306-05937 America/Barbados
diff -pru tz-2004aa/asctime.c tz/asctime.c
--- tz-2004aa/asctime.c 1998-05-28 06:56:06.000000000 -0700
+++ tz/asctime.c 2004-06-14 21:23:43.000000000 -0700
@@ -41,14 +41,14 @@ char * buf;
else mn = mon_name[timeptr->tm_mon];
/*
** The X3J11-suggested format is
- ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n"
- ** Since the .2 in 02.2d is ignored, we drop it.
+ ** "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n"
+ ** Use "%02d", as it is a bit more portable than "%.2d".
*/
- (void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
+ (void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %ld\n",
wn, mn,
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
- TM_YEAR_BASE + timeptr->tm_year);
+ timeptr->tm_year + (long) TM_YEAR_BASE);
return buf;
}
diff -pru tz-2004aa/date.c tz/date.c
--- tz-2004aa/date.c 2001-10-09 10:31:31.000000000 -0700
+++ tz/date.c 2004-06-14 22:44:08.703969000 -0700
@@ -630,8 +630,12 @@ const time_t t;
time_t outt;
tm = *localtime(&t);
- cent = (tm.tm_year + TM_YEAR_BASE) / 100;
- year_in_cent = (tm.tm_year + TM_YEAR_BASE) - cent * 100;
+ cent = tm.tm_year / 100 + TM_YEAR_BASE / 100;
+ year_in_cent = tm.tm_year % 100;
+ if (year_int_cent < 0) {
+ cent--;
+ year_in_cent += 100;
+ }
month = tm.tm_mon + 1;
day = tm.tm_mday;
hour = tm.tm_hour;
diff -pru tz-2004aa/localtime.c tz/localtime.c
--- tz-2004aa/localtime.c 2003-12-15 06:36:35.000000000 -0800
+++ tz/localtime.c 2004-06-14 23:11:00.519250000 -0700
@@ -134,8 +134,11 @@ static void gmtsub P((const time_t * ti
static void localsub P((const time_t * timep, long offset,
struct tm * tmp));
static int increment_overflow P((int * number, int delta));
+static int long_increment_overflow P((long * number, int delta));
static int normalize_overflow P((int * tensptr, int * unitsptr,
int base));
+static int long_normalize_overflow P((long * tensptr,
+ int * unitsptr, int base));
static void settzname P((void));
static time_t time1 P((struct tm * tmp,
void(*funcp) P((const time_t *,
@@ -1149,7 +1152,7 @@ register struct tm * const tmp;
register const struct lsinfo * lp;
register long days;
register long rem;
- register int y;
+ register long y;
register int yleap;
register const int * ip;
register long corr;
@@ -1218,7 +1221,7 @@ register struct tm * const tmp;
y = EPOCH_YEAR;
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
- register int newy;
+ register long newy;
newy = y + days / DAYSPERNYEAR;
if (days < 0)
@@ -1294,6 +1297,18 @@ int delta;
}
static int
+long_increment_overflow(number, delta)
+long * number;
+int delta;
+{
+ long number0;
+
+ number0 = *number;
+ *number += delta;
+ return (*number < number0) != (delta < 0);
+}
+
+static int
normalize_overflow(tensptr, unitsptr, base)
int * const tensptr;
int * const unitsptr;
@@ -1309,6 +1324,21 @@ const int base;
}
static int
+long_normalize_overflow(tensptr, unitsptr, base)
+long * const tensptr;
+int * const unitsptr;
+const int base;
+{
+ register int tensdelta;
+
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) :
+ (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return long_increment_overflow(tensptr, tensdelta);
+}
+
+static int
tmcomp(atmp, btmp)
register const struct tm * const atmp;
register const struct tm * const btmp;
@@ -1336,6 +1366,8 @@ const int do_norm_secs;
register int dir;
register int bits;
register int i, j ;
+ register long li;
+ long y;
register int saved_seconds;
time_t newt;
time_t t;
@@ -1352,42 +1384,46 @@ const int do_norm_secs;
return WRONG;
if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
return WRONG;
- if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR))
+ y = yourtm.tm_year;
+ if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
return WRONG;
/*
- ** Turn yourtm.tm_year into an actual year number for now.
+ ** Turn y into an actual year number for now.
** It is converted back to an offset from TM_YEAR_BASE later.
*/
- if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE))
+ if (long_increment_overflow(&y, TM_YEAR_BASE))
return WRONG;
while (yourtm.tm_mday <= 0) {
- if (increment_overflow(&yourtm.tm_year, -1))
+ if (long_increment_overflow(&y, -1))
return WRONG;
- i = yourtm.tm_year + (1 < yourtm.tm_mon);
- yourtm.tm_mday += year_lengths[isleap(i)];
+ li = y + (1 < yourtm.tm_mon);
+ yourtm.tm_mday += year_lengths[isleap(li)];
}
while (yourtm.tm_mday > DAYSPERLYEAR) {
- i = yourtm.tm_year + (1 < yourtm.tm_mon);
- yourtm.tm_mday -= year_lengths[isleap(i)];
- if (increment_overflow(&yourtm.tm_year, 1))
+ li = y + (1 < yourtm.tm_mon);
+ yourtm.tm_mday -= year_lengths[isleap(li)];
+ if (long_increment_overflow(&y, 1))
return WRONG;
}
for ( ; ; ) {
- i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];
+ i = mon_lengths[isleap(y)][yourtm.tm_mon];
if (yourtm.tm_mday <= i)
break;
yourtm.tm_mday -= i;
if (++yourtm.tm_mon >= MONSPERYEAR) {
yourtm.tm_mon = 0;
- if (increment_overflow(&yourtm.tm_year, 1))
+ if (long_increment_overflow(&y, 1))
return WRONG;
}
}
- if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))
+ if (long_increment_overflow(&y, -TM_YEAR_BASE))
+ return WRONG;
+ yourtm.tm_year = y;
+ if (yourtm.tm_year != y)
return WRONG;
if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
saved_seconds = 0;
- else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
+ else if (y < EPOCH_YEAR - TM_YEAR_BASE) {
/*
** We can't set tm_sec to 0, because that might push the
** time below the minimum representable time.
diff -pru tz-2004aa/strftime.c tz/strftime.c
--- tz-2004aa/strftime.c 2001-10-04 14:01:17.000000000 -0700
+++ tz/strftime.c 2004-06-14 22:37:47.213984000 -0700
@@ -108,6 +108,7 @@ static const struct lc_time_T C_time_loc
static char * _add P((const char *, char *, const char *));
static char * _conv P((int, const char *, char *, const char *));
+static char * _lconv P((long, const char *, char *, const char *));
static char * _fmt P((const char *, const struct tm *, char *, const char *, int *));
size_t strftime P((char *, size_t, const char *, const struct tm *));
@@ -210,8 +211,12 @@ label:
** something completely different.
** (ado, 1993-05-24)
*/
- pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
- "%02d", pt, ptlim);
+ {
+ int c = (TM_YEAR_BASE / 100
+ + t->tm_year / 100
+ - (t->tm_year % 100 < 0));
+ pt = _conv(c, "%02d", pt, ptlim);
+ }
continue;
case 'c':
{
@@ -379,12 +384,13 @@ label:
** (ado, 1996-01-02)
*/
{
- int year;
+ long year;
int yday;
int wday;
int w;
- year = t->tm_year + TM_YEAR_BASE;
+ year = t->tm_year;
+ year += TM_YEAR_BASE;
yday = t->tm_yday;
wday = t->tm_wday;
for ( ; ; ) {
@@ -436,10 +442,13 @@ label:
pt = _conv(w, "%02d",
pt, ptlim);
else if (*format == 'g') {
+ int g = year % 100;
+ if (g < 0)
+ g += 100;
*warnp = IN_ALL;
- pt = _conv(year % 100, "%02d",
+ pt = _conv(g, "%02d",
pt, ptlim);
- } else pt = _conv(year, "%04d",
+ } else pt = _lconv(year, "%04ld",
pt, ptlim);
}
continue;
@@ -476,13 +485,17 @@ label:
}
continue;
case 'y':
+ {
+ int y = t->tm_year % 100;
+ if (y < 0)
+ y += 100;
*warnp = IN_ALL;
- pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
- "%02d", pt, ptlim);
+ pt = _conv(y, "%02d", pt, ptlim);
+ }
continue;
case 'Y':
- pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
- pt, ptlim);
+ pt = _lconv(t->tm_year + (long) TM_YEAR_BASE,
+ "%04ld", pt, ptlim);
continue;
case 'Z':
#ifdef TM_ZONE
@@ -586,6 +599,19 @@ const char * const ptlim;
}
static char *
+_lconv(n, format, pt, ptlim)
+const long n;
+const char * const format;
+char * const pt;
+const char * const ptlim;
+{
+ char buf[INT_STRLEN_MAXIMUM(long) + 1];
+
+ (void) sprintf(buf, format, n);
+ return _add(buf, pt, ptlim);
+}
+
+static char *
_add(str, pt, ptlim)
const char * str;
char * pt;
diff -pru tz-2004aa/zdump.8 tz/zdump.8
--- tz-2004aa/zdump.8 2003-09-16 04:12:41.000000000 -0700
+++ tz/zdump.8 2004-06-17 13:33:33.238073000 -0700
@@ -40,6 +40,12 @@ otherwise.
.TP
.BI "\-c " cutoffyear
Cut off the verbose output near the start of the given year.
+By default, verbose output is cut off a few decades after the
+current date and time.
.SH "SEE ALSO"
newctime(3), tzfile(5), zic(8)
+.SH "BUGS"
+Time discontinuities are detected via a heuristic that suffices for
+all historically valid discontinuities, but one can construct
+artificial time zones for which the heuristic fails.
.\" @(#)zdump.8 7.4
diff -pru tz-2004aa/zdump.c tz/zdump.c
--- tz-2004aa/zdump.c 2003-09-16 04:12:41.000000000 -0700
+++ tz/zdump.c 2004-06-17 14:12:10.425374000 -0700
@@ -6,6 +6,7 @@ static char elsieid[] = "@(#)zdump.c 7.3
** You can use this code to help in verifying other implementations.
*/
+#include "limits.h" /* for CHAR_BIT */
#include "stdio.h" /* for stdout, stderr, perror */
#include "string.h" /* for strcpy */
#include "sys/types.h" /* for time_t */
@@ -24,6 +25,25 @@ static char elsieid[] = "@(#)zdump.c 7.3
#define FALSE 0
#endif /* !defined FALSE */
+#ifndef TYPE_BIT
+#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
+#endif /* !defined TYPE_BIT */
+
+#ifndef TYPE_SIGNED
+#define TYPE_SIGNED(type) (((type) -1) < 0)
+#endif /* !defined TYPE_SIGNED */
+
+#ifndef INT_STRLEN_MAXIMUM
+/*
+** 302 / 1000 is log10(2.0) rounded up.
+** Subtract one for the sign bit if the type is signed;
+** add one for integer division truncation;
+** add one more for a minus sign if the type is signed.
+*/
+#define INT_STRLEN_MAXIMUM(type) \
+ ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type))
+#endif /* !defined INT_STRLEN_MAXIMUM */
+
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif /* !defined EXIT_SUCCESS */
@@ -56,10 +76,18 @@ static char elsieid[] = "@(#)zdump.c 7.3
#define TM_YEAR_BASE 1900
#endif /* !defined TM_YEAR_BASE */
+#ifndef DAYSPERWEEK
+#define DAYSPERWEEK 7
+#endif /* !defined DAYSPERWEEK */
+
#ifndef DAYSPERNYEAR
#define DAYSPERNYEAR 365
#endif /* !defined DAYSPERNYEAR */
+#ifndef MONSPERYEAR
+#define MONSPERYEAR 12
+#endif /* !defined MONSPERYEAR */
+
#ifndef isleap
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
#endif /* !defined isleap */
@@ -128,6 +156,9 @@ static long delta P((struct tm * newp, s
static time_t hunt P((char * name, time_t lot, time_t hit));
static size_t longest;
static char * progname;
+static char * my_asctime_r P((const struct tm *, char *));
+static char * my_asctime P((const struct tm *));
+static void showtime P((time_t, const struct tm *));
static void show P((char * zone, time_t t, int v));
int
@@ -139,17 +170,19 @@ char * argv[];
register int c;
register int vflag;
register char * cutoff;
- register int cutyear;
- register long cuttime;
+ register long cutyear;
+ long y;
+ register time_t lasttime;
char ** fakeenv;
time_t now;
time_t t;
time_t newt;
time_t hibit;
+ time_t time_t_min;
+ time_t time_t_max;
struct tm tm;
- struct tm newtm;
+ struct tm * newtm;
- INITIALIZE(cuttime);
#if HAVE_GETTEXT - 0
(void) setlocale(LC_MESSAGES, "");
#ifdef TZ_DOMAINDIR
@@ -176,22 +209,44 @@ _("%s: usage is %s [ --version ] [ -v ]
argv[0], argv[0]);
(void) exit(EXIT_FAILURE);
}
+ for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
+ continue;
+ time_t_max = ~((time_t) 0);
+ if (TYPE_SIGNED(time_t))
+ time_t_max &= ~hibit;
+ time_t_min = TYPE_SIGNED(time_t) ? hibit : 0;
+ (void) time(&now);
if (cutoff != NULL) {
- int y;
-
- cutyear = atoi(cutoff);
- cuttime = 0;
- for (y = EPOCH_YEAR; y < cutyear; ++y)
- cuttime += DAYSPERNYEAR + isleap(y);
- cuttime *= SECSPERHOUR * HOURSPERDAY;
+ cutyear = atol(cutoff);
+ } else {
+ /*
+ ** By default, the cutoff is the maximum time value,
+ ** or a few decades from now, whichever comes first.
+ ** This prevents us from generating too much output if
+ ** time_t is wider than 32 bits.
+ */
+ newtm = gmtime (&now);
+ if (newtm == NULL)
+ cutyear = now < 0 ? LONG_MIN : LONG_MAX;
+ else {
+ cutyear = newtm->tm_year + (long) TM_YEAR_BASE;
+ cutyear = 2050 + 100 * ((cutyear - 1930) / 100);
+ }
+ }
+ lasttime = 0;
+ for (y = EPOCH_YEAR; y < cutyear; ++y) {
+ newt = lasttime - !lasttime;
+ newt += (DAYSPERNYEAR + isleap(y)) * SECSPERHOUR * HOURSPERDAY;
+ if (newt < lasttime) {
+ lasttime = time_t_max;
+ break;
+ }
+ lasttime = newt;
}
- (void) time(&now);
longest = 0;
for (i = optind; i < argc; ++i)
if (strlen(argv[i]) > longest)
longest = strlen(argv[i]);
- for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
- continue;
{
register int from;
register int to;
@@ -224,40 +279,47 @@ _("%s: usage is %s [ --version ] [ -v ]
/*
** Get lowest value of t.
*/
- t = hibit;
- if (t > 0) /* time_t is unsigned */
- t = 0;
+ t = time_t_min;
show(argv[i], t, TRUE);
t += SECSPERHOUR * HOURSPERDAY;
show(argv[i], t, TRUE);
+ /*
+ ** But don't go below - 2**32 in the following loop,
+ ** as that predates standard time, would cause us to
+ ** generate too much output, and could dump core if
+ ** localtime returns NULL. The earliest known use of
+ ** standard time is 1837 (Iceland) and - 2**32 is a
+ ** bit before that.
+ */
+ if ((t + 1) / 2 < -2147483647) {
+ t = -1 - 2147483647;
+ t *= 2;
+ }
tm = *localtime(&t);
(void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
for ( ; ; ) {
- if (cutoff != NULL && t >= cuttime)
+ if (lasttime < t)
break;
newt = t + SECSPERHOUR * 12;
- if (cutoff != NULL && newt >= cuttime)
+ if (lasttime < newt)
break;
if (newt <= t)
break;
- newtm = *localtime(&newt);
- if (delta(&newtm, &tm) != (newt - t) ||
- newtm.tm_isdst != tm.tm_isdst ||
- strcmp(abbr(&newtm), buf) != 0) {
+ newtm = localtime(&newt);
+ if (newtm == NULL)
+ break;
+ if (delta(newtm, &tm) != (newt - t) ||
+ newtm->tm_isdst != tm.tm_isdst ||
+ strcmp(abbr(newtm), buf) != 0) {
newt = hunt(argv[i], t, newt);
- newtm = *localtime(&newt);
- (void) strncpy(buf, abbr(&newtm),
+ newtm = localtime(&newt);
+ (void) strncpy(buf, abbr(newtm),
(sizeof buf) - 1);
}
t = newt;
- tm = newtm;
+ tm = *newtm;
}
- /*
- ** Get highest value of t.
- */
- t = ~((time_t) 0);
- if (t < 0) /* time_t is signed */
- t &= ~hibit;
+ t = time_t_max;
t -= SECSPERHOUR * HOURSPERDAY;
show(argv[i], t, TRUE);
t += SECSPERHOUR * HOURSPERDAY;
@@ -323,7 +385,7 @@ struct tm * oldp;
return -delta(oldp, newp);
result = 0;
for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
- result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE);
+ result += DAYSPERNYEAR + isleap(tmy + (long) TM_YEAR_BASE);
result += newp->tm_yday - oldp->tm_yday;
result *= HOURSPERDAY;
result += newp->tm_hour - oldp->tm_hour;
@@ -334,6 +396,80 @@ struct tm * oldp;
return result;
}
+/*
+** my_asctime_r and my_asctime are stolen from asctime.c. Unlike
+** Standard C asctime, my_asctime has well-defined behavior even if
+** the year is less than -999 or greater than 9999.
+*/
+
+static char *
+my_asctime_r(timeptr, buf)
+register const struct tm * timeptr;
+char * buf;
+{
+ static const char wday_name[][3] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char mon_name[][3] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ register const char * wn;
+ register const char * mn;
+
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
+ wn = "???";
+ else wn = wday_name[timeptr->tm_wday];
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
+ mn = "???";
+ else mn = mon_name[timeptr->tm_mon];
+ /*
+ ** The X3J11-suggested format is
+ ** "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n"
+ ** Use "%02d", as it is a bit more portable than "%.2d".
+ */
+ (void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %ld\n",
+ wn, mn,
+ timeptr->tm_mday, timeptr->tm_hour,
+ timeptr->tm_min, timeptr->tm_sec,
+ timeptr->tm_year + (long) TM_YEAR_BASE);
+ return buf;
+}
+
+static char *
+my_asctime(timeptr)
+register const struct tm * timeptr;
+{
+ /*
+ ** Big enough for something such as
+ ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
+ ** (two three-character abbreviations, five strings denoting integers,
+ ** three explicit spaces, two explicit colons, a newline,
+ ** and a trailing ASCII nul).
+ */
+ static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) +
+ 3 + 2 + 1 + 1];
+
+ return my_asctime_r(timeptr, result);
+}
+
+static void
+showtime(t, timeptr)
+time_t t;
+const struct tm * timeptr;
+{
+ if (timeptr != NULL) {
+ const char *p;
+ for (p = my_asctime (timeptr); *p != '\n'; p++)
+ putchar (*p);
+ } else {
+ if (TYPE_SIGNED(time_t))
+ printf ("%ld\n", (long) t);
+ else
+ printf ("%lu\n", (unsigned long) t);
+ }
+}
+
static void
show(zone, t, v)
char * zone;
@@ -343,13 +479,15 @@ int v;
struct tm * tmp;
(void) printf("%-*s ", (int) longest, zone);
- if (v)
- (void) printf("%.24s UTC = ", asctime(gmtime(&t)));
+ if (v) {
+ showtime(t, gmtime(&t));
+ (void) printf(" UTC = ");
+ }
tmp = localtime(&t);
- (void) printf("%.24s", asctime(tmp));
+ showtime(t, tmp);
if (*abbr(tmp) != '\0')
(void) printf(" %s", abbr(tmp));
- if (v) {
+ if (v && tmp != NULL) {
(void) printf(" isdst=%d", tmp->tm_isdst);
#ifdef TM_GMTOFF
(void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
@@ -365,7 +503,7 @@ struct tm * tmp;
register char * result;
static char nada;
- if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
+ if (!tmp || (tmp->tm_isdst != 0 && tmp->tm_isdst != 1))
return &nada;
result = tzname[tmp->tm_isdst];
return (result == NULL) ? &nada : result;
More information about the tz
mailing list