Import tzcode2009k.

- now understands 64bit time_t and 64bit data in timezone files.
- localtime(), gmtime(), asctime() and ctime() may now fail with
  a NULL result if time_t cannot be represented by struct tm.
This commit is contained in:
mlelstv 2009-12-31 22:49:15 +00:00
parent e68a42515b
commit 86162a51cc
22 changed files with 3141 additions and 1361 deletions

View File

@ -1,4 +1,6 @@
@(#)README 7.11
@(#)README 8.3
This file is in the public domain, so clarified as of
2009-05-17 by Arthur David Olson.
"What time is it?" -- Richard Deacon as The King
"Any time you want it to be." -- Frank Baxter as The Scientist
@ -52,8 +54,10 @@ substituting your desired installation directory for "$HOME/tzdir":
To use the new functions, use a "-ltz" option when compiling or linking.
Historical local time information has been included here not because it
is particularly useful, but rather to:
Historical local time information has been included here to:
* provide a compendium of data about the history of civil time
that is useful even if the data are not 100% accurate;
* give an idea of the variety of local time rules that have
existed in the past and thus an idea of the variety that may be
@ -63,7 +67,9 @@ is particularly useful, but rather to:
system.
The information in the time zone data files is by no means authoritative;
if you know that the rules are different from those in a file, by all means
the files currently do not even attempt to cover all time stamps before
1970, and there are undoubtedly errors even for time stamps since 1970.
If you know that the rules are different from those in a file, by all means
feel free to change file (and please send the changed version to
tz@elsie.nci.nih.gov for use in the future). Europeans take note!

View File

@ -1,6 +1,7 @@
# $NetBSD: Theory,v 1.8 2004/05/27 20:39:49 kleink Exp $
@(#)Theory 7.15
# $NetBSD: Theory,v 1.9 2009/12/31 22:49:15 mlelstv Exp $
@(#)Theory 8.3
This file is in the public domain, so clarified as of
2009-05-17 by Arthur David Olson.
----- Outline -----
@ -10,29 +11,29 @@
Calendrical issues
Time and time zones on Mars
----- Time and date functions -----
These time and date functions are upwards compatible with POSIX.1,
These time and date functions are upwards compatible with POSIX,
an international standard for UNIX-like systems.
As of this writing, the current edition of POSIX.1 is:
As of this writing, the current edition of POSIX is:
Information technology --Portable Operating System Interface (POSIX (R))
-- Part 1: System Application Program Interface (API) [C Language]
ISO/IEC 9945-1:1996
ANSI/IEEE Std 1003.1, 1996 Edition
1996-07-12
Standard for Information technology
-- Portable Operating System Interface (POSIX (R))
-- System Interfaces
IEEE Std 1003.1, 2004 Edition
<http://www.opengroup.org/online-pubs?DOC=7999959899>
<http://www.opengroup.org/pubs/catalog/t041.htm>
POSIX.1 has the following properties and limitations.
POSIX has the following properties and limitations.
* In POSIX.1, time display in a process is controlled by the
environment variable TZ. Unfortunately, the POSIX.1 TZ string takes
* In POSIX, time display in a process is controlled by the
environment variable TZ. Unfortunately, the POSIX TZ string takes
a form that is hard to describe and is error-prone in practice.
Also, POSIX.1 TZ strings can't deal with other (for example, Israeli)
Also, POSIX TZ strings can't deal with other (for example, Israeli)
daylight saving time rules, or situations where more than two
time zone abbreviations are used in an area.
The POSIX.1 TZ string takes the following form:
The POSIX TZ string takes the following form:
stdoffset[dst[offset],date[/time],date[/time]]
@ -41,6 +42,9 @@ POSIX.1 has the following properties and limitations.
std and dst
are 3 or more characters specifying the standard
and daylight saving time (DST) zone names.
Starting with POSIX.1-2001, std and dst may also be
in a quoted form like "<UTC+10>"; this allows
"+" and "-" in the names.
offset
is of the form `[-]hh:[mm[:ss]]' and specifies the
offset west of UTC. The default DST offset is one hour
@ -63,14 +67,25 @@ POSIX.1 has the following properties and limitations.
and `5' stands for the last week in which day d appears
(which may be either the 4th or 5th week).
* In POSIX.1, when a TZ value like "EST5EDT" is parsed,
typically the current US DST rules are used,
Here is an example POSIX TZ string, for US Pacific time using rules
appropriate from 1987 through 2006:
TZ='PST8PDT,M4.1.0/02:00,M10.5.0/02:00'
This POSIX TZ string is hard to remember, and mishandles time stamps
before 1987 and after 2006. With this package you can use this
instead:
TZ='America/Los_Angeles'
* POSIX does not define the exact meaning of TZ values like "EST5EDT".
Typically the current US DST rules are used to interpret such values,
but this means that the US DST rules are compiled into each program
that does time conversion. This means that when US time conversion
rules change (as in the United States in 1987), all programs that
do time conversion must be recompiled to ensure proper results.
* In POSIX.1, there's no tamper-proof way for a process to learn the
* In POSIX, there's no tamper-proof way for a process to learn the
system's best idea of local wall clock. (This is important for
applications that an administrator wants used only at certain times--
without regard to whether the user has fiddled the "TZ" environment
@ -79,9 +94,9 @@ POSIX.1 has the following properties and limitations.
daylight saving time shifts--as might be required to limit phone
calls to off-peak hours.)
* POSIX.1 requires that systems ignore leap seconds.
* POSIX requires that systems ignore leap seconds.
These are the extensions that have been made to the POSIX.1 functions:
These are the extensions that have been made to the POSIX functions:
* The "TZ" environment variable is used in generating the name of a file
from which time zone information is read (or is interpreted a la
@ -109,7 +124,7 @@ These are the extensions that have been made to the POSIX.1 functions:
* To handle places where more than two time zone abbreviations are used,
the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst]
(where "tmp" is the value the function returns) to the time zone
abbreviation to be used. This differs from POSIX.1, where the elements
abbreviation to be used. This differs from POSIX, where the elements
of tzname are only changed as a result of calls to tzset.
* Since the "TZ" environment variable can now be used to control time
@ -132,8 +147,7 @@ These are the extensions that have been made to the POSIX.1 functions:
environment variable; portable applications should not, however, rely
on this behavior since it's not the way SVR2 systems behave.)
* These functions can account for leap seconds, thanks to Bradley White
(bww@k.cs.cmu.edu).
* These functions can account for leap seconds, thanks to Bradley White.
Points of interest to folks with other systems:
@ -174,9 +188,9 @@ Hewlett Packard, offer a wider selection of functions that provide capabilities
beyond those provided here. The absence of such functions from this package
is not meant to discourage the development, standardization, or use of such
functions. Rather, their absence reflects the decision to make this package
contain valid extensions to POSIX.1, to ensure its broad
acceptability. If more powerful time conversion functions can be standardized,
so much the better.
contain valid extensions to POSIX, to ensure its broad acceptability. If
more powerful time conversion functions can be standardized, so much the
better.
----- Names of time zone rule files -----
@ -229,6 +243,8 @@ in decreasing order of importance:
Include at least one location per time zone rule set per country.
One such location is enough. Use ISO 3166 (see the file
iso3166.tab) to help decide whether something is a country.
However, uninhabited ISO 3166 regions like Bouvet Island
do not need locations, since local time is not defined there.
If all the clocks in a country's region have agreed since 1970,
don't bother to include more than one location
even if subregions' clocks disagreed before 1970.
@ -264,7 +280,8 @@ in decreasing order of importance:
If a name is changed, put its old spelling in the `backward' file.
The file `zone.tab' lists the geographical locations used to name
time zone rule files.
time zone rule files. It is intended to be an exhaustive list
of canonical names for geographic regions.
Older versions of this package used a different naming scheme,
and these older names are still supported.
@ -278,7 +295,7 @@ and `Factory' (see the file `factory').
----- Time zone abbreviations -----
When this package is installed, it generates time zone abbreviations
like `EST' to be compatible with human tradition and POSIX.1.
like `EST' to be compatible with human tradition and POSIX.
Here are the general rules used for choosing time zone abbreviations,
in decreasing order of importance:
@ -293,17 +310,16 @@ in decreasing order of importance:
preferred "ChST", so the rule has been relaxed.
This rule guarantees that all abbreviations could have
been specified by a POSIX.1 TZ string. POSIX.1
been specified by a POSIX TZ string. POSIX
requires at least three characters for an
abbreviation. POSIX.1-1996 says that an abbreviation
abbreviation. POSIX through 2000 says that an abbreviation
cannot start with ':', and cannot contain ',', '-',
'+', NUL, or a digit. Draft 7 of POSIX 1003.1-200x
changes this rule to say that an abbreviation can
contain only '-', '+', and alphanumeric characters in
the current locale. To be portable to both sets of
'+', NUL, or a digit. POSIX from 2001 on changes this
rule to say that an abbreviation can contain only '-', '+',
and alphanumeric characters from the portable character set
in the current locale. To be portable to both sets of
rules, an abbreviation must therefore use only ASCII
letters, as these are the only letters that are
alphabetic in all locales.
letters.
Use abbreviations that are in common use among English-speakers,
e.g. `EST' for Eastern Standard Time in North America.
@ -329,8 +345,9 @@ in decreasing order of importance:
and then append `T', `ST', etc. as before;
e.g. `VLAST' for VLAdivostok Summer Time.
Use "zzz" for locations while uninhabited. The mnemonic is that
these locations are, in some sense, asleep.
Use UTC (with time zone abbreviation "zzz") for locations while
uninhabited. The "zzz" mnemonic is that these locations are,
in some sense, asleep.
Application writers should note that these abbreviations are ambiguous
in practice: e.g. `EST' has a different meaning in Australia than
@ -344,10 +361,10 @@ abbreviations like `EST'; this avoids the ambiguity.
Calendrical issues are a bit out of scope for a time zone database,
but they indicate the sort of problems that we would run into if we
extended the time zone database further into the past. An excellent
resource in this area is Nachum Dershowitz and Edward M. Reingold,
<a href="http://emr.cs.uiuc.edu/home/reingold/calendar-book/index.shtml">
Calendrical Calculations
</a>, Cambridge University Press (1997). Other information and
resource in this area is Edward M. Reingold and Nachum Dershowitz,
<a href="http://emr.cs.uiuc.edu/home/reingold/calendar-book/second-edition/">
Calendrical Calculations: The Millennium Edition
</a>, Cambridge University Press (2001). Other information and
sources are given below. They sometimes disagree.
@ -360,7 +377,7 @@ and (in Paris only) 1871-05-06 through 1871-05-23.
Russia
From Chris Carrier <72157.3334@CompuServe.COM> (1996-12-02):
From Chris Carrier (1996-12-02):
On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar''
with 30-day months plus 5 holidays, with a 5-day week.
On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the
@ -375,7 +392,7 @@ by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But:
From: Petteri Sulonen (via Usenet)
Date: 14 Jan 1999 00:00:00 GMT
Message-ID: <Petteri.Sulonen-1401991626030001@lapin-kulta.in.helsinki.fi>
...
If your source is correct, how come documents between 1929 -- 1940 were
still dated using the conventional, Gregorian calendar?
@ -388,7 +405,7 @@ Executive Committee of the Supreme Soviet, if you like.
Sweden (and Finland)
From: msb@sq.com (Mark Brader)
From: Mark Brader
<a href="news:1996Jul6.012937.29190@sq.com">
Subject: Re: Gregorian reform -- a part of locale?
</a>
@ -416,11 +433,11 @@ kalendervasen" by Lars-Olof Lode'n (no date was given).)
Grotefend's data
From: "Michael Palmer" <mpalmer@netcom.com> [with one obvious typo fixed]
From: "Michael Palmer" [with one obvious typo fixed]
Subject: Re: Gregorian Calendar (was Re: Another FHC related question
Newsgroups: soc.genealogy.german
Date: Tue, 9 Feb 1999 02:32:48 -800
Message-ID: <199902091032.CAA09644@netcom10.netcom.com>
...
The following is a(n incomplete) listing, arranged chronologically, of
European states, with the date they converted from the Julian to the
@ -547,7 +564,7 @@ Sources:
Michael Allison and Robert Schmunk,
"Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock"
<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2004-03-15).
<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2004-07-30).
Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times
(2004-01-14), pp A1, A20-A21.

View File

@ -1,16 +1,22 @@
/* $NetBSD: asctime.c,v 1.12 2006/10/15 15:32:42 perry Exp $ */
/* $NetBSD: asctime.c,v 1.13 2009/12/31 22:49:16 mlelstv Exp $ */
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
** 1996-06-05 by Arthur David Olson.
*/
/*
** Avoid the temptation to punt entirely to strftime;
** the output of strftime is supposed to be locale specific
** whereas the output of asctime is supposed to be constant.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char elsieid[] = "@(#)asctime.c 7.9";
static char elsieid[] = "@(#)asctime.c 8.2";
#else
__RCSID("$NetBSD: asctime.c,v 1.12 2006/10/15 15:32:42 perry Exp $");
__RCSID("$NetBSD: asctime.c,v 1.13 2009/12/31 22:49:16 mlelstv Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -25,7 +31,57 @@ __weak_alias(asctime_r,_asctime_r)
#endif
/*
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12.
** Some systems only handle "%.2d"; others only handle "%02d";
** "%02.2d" makes (most) everybody happy.
** At least some versions of gcc warn about the %02.2d;
** we conditionalize below to avoid the warning.
*/
/*
** All years associated with 32-bit time_t values are exactly four digits long;
** some years associated with 64-bit time_t values are not.
** Vintage programs are coded for years that are always four digits long
** and may assume that the newline always lands in the same place.
** For years that are less than four digits, we pad the output with
** leading zeroes to get the newline in the traditional place.
** The -4 ensures that we get four characters of output even if
** we call a strftime variant that produces fewer characters for some years.
** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year,
** but many implementations pad anyway; most likely the standards are buggy.
*/
#ifdef __GNUC__
#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n"
#else /* !defined __GNUC__ */
#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n"
#endif /* !defined __GNUC__ */
/*
** For years that are more than four digits we put extra spaces before the year
** so that code trying to overwrite the newline won't end up overwriting
** a digit within a year and truncating the year (operating on the assumption
** that no output is better than wrong output).
*/
#ifdef __GNUC__
#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n"
#else /* !defined __GNUC__ */
#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n"
#endif /* !defined __GNUC__ */
#define STD_ASCTIME_BUF_SIZE 26
/*
** Big enough for something such as
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
** (two three-character abbreviations, five strings denoting integers,
** seven explicit spaces, two explicit colons, a newline,
** and a trailing ASCII nul).
** The values above are for systems where an int is 32 bits and are provided
** as an example; the define below calculates the maximum for the system at
** hand.
*/
#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
/*
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
*/
/*
@ -51,6 +107,8 @@ char * buf;
};
register const char * wn;
register const char * mn;
char year[INT_STRLEN_MAXIMUM(int) + 2];
char result[MAX_ASCTIME_BUF_SIZE];
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
wn = "???";
@ -59,29 +117,39 @@ char * buf;
mn = "???";
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.
** Use strftime's %Y to generate the year, to avoid overflow problems
** when computing timeptr->tm_year + TM_YEAR_BASE.
** Assume that strftime is unaffected by other out-of-range members
** (e.g., timeptr->tm_mday) when processing "%Y".
*/
(void)snprintf(buf,
sizeof (char[ASCTIME_BUFLEN]),
"%.3s %.3s%3d %02d:%02d:%02d %d\n",
(void) strftime(year, sizeof year, "%Y", timeptr);
(void) snprintf(result,
sizeof(result),
((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
wn, mn,
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
TM_YEAR_BASE + timeptr->tm_year);
return buf;
year);
if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) {
(void) strcpy(buf, result);
return buf;
} else {
#ifdef EOVERFLOW
errno = EOVERFLOW;
#else /* !defined EOVERFLOW */
errno = EINVAL;
#endif /* !defined EOVERFLOW */
return NULL;
}
}
/*
** A la X3J11, with core dump avoidance.
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
*/
char *
asctime(timeptr)
register const struct tm * timeptr;
{
static char result[ASCTIME_BUFLEN];
return asctime_r(timeptr, result);
return asctime_r(timeptr, buf_asctime);
}

View File

@ -1,10 +1,10 @@
# $NetBSD: checktab.awk,v 1.3 1999/11/10 20:32:31 kleink Exp $
# $NetBSD: checktab.awk,v 1.4 2009/12/31 22:49:16 mlelstv Exp $
# Check tz tables for consistency.
# @(#)checktab.awk 1.6
# @(#)checktab.awk 8.1
# Contributed by Paul Eggert <eggert@twinsun.com>.
# Contributed by Paul Eggert.
BEGIN {
FS = "\t"

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ctime.3,v 1.27 2003/04/16 13:34:58 wiz Exp $
.\" $NetBSD: ctime.3,v 1.28 2009/12/31 22:49:16 mlelstv Exp $
.Dd March 31, 2001
.Dt CTIME 3
.Os
@ -42,21 +42,31 @@
.Sh DESCRIPTION
.Fn ctime
converts a long integer, pointed to by
.Fa clock ,
representing the time in seconds since 00:00:00 UTC, 1970-01-01,
and returns a pointer to a 26-character string of the form
.Dl Thu Nov 24 18:22:48 1986\en\e0
All the fields have constant width.
.Pp
The
.Fn ctime_r
function provides the same functionality as
.Fn ctime
differing in that the caller must supply a buffer area
.Fa buf
with a size of at least 26 bytes, in which the result is stored.
.Pp
.Fn localtime
.IR clock ,
representing the time in seconds since
00:00:00 UTC, 1970-01-01,
and returns a pointer to a
string of the form
.br
.ce
.eo
Thu Nov 24 18:22:48 1986\n\0
.br
.ec
Years requiring fewer than four characters are padded with leading zeroes.
For years longer than four characters, the string is of the form
.br
.ce
.eo
Thu Nov 24 18:22:48 81986\n\0
.ec
.br
with five spaces before the year.
These unusual formats are designed to make it less likely that older
software that expects exactly 26 bytes of output will mistakenly output
misleading values for out-of-range years.
.PP
.I Localtime\^
and
.Fn gmtime
return pointers to
@ -69,6 +79,11 @@ After filling in the
.Va tm
structure,
.Fn localtime
(such as Daylight Saving Time in the United States).
After filling in the
.Va tm
structure,
.I localtime
sets the
.Fa tm_isdst Ns 'th
element of
@ -99,20 +114,13 @@ the application may need to do so by calling
.Pp
.Fn asctime
converts a time value contained in a
.Va tm
structure to a 26-character string, as shown in the above example,
``tm'' structure to a string,
as shown in the above example,
and returns a pointer to the string.
.Pp
The
.Fn asctime_r
function provides the same functionality as
.Fn asctime
differing in that the caller must supply a buffer area
.Fa buf
with a size of at least 26 bytes, in which the result is stored.
.Pp
.Fn mktime
converts the broken-down time, expressed as local time,
.PP
.I Mktime\^
converts the broken-down time,
expressed as local time,
in the structure pointed to by
.Fa tm
into a calendar time value with the same encoding as that of the values
@ -138,7 +146,9 @@ A negative value for
causes the
.Fn mktime
function to attempt to divine whether summer time is in effect
for the specified time.)
for the specified time; in this case it does not use a consistent
rule and may give a different answer when later
presented with the same argument.)
On successful completion, the values of the
.Fa tm_wday
and
@ -243,11 +253,28 @@ The
.Fa tm_zone
field of a returned
.Va "struct tm"
points to a static array of characters, which will also be overwritten
at the next call (and by calls to
.Xr tzset 3 ) .
.Pp
points to a static array of characters, which
will also be overwritten at the next call
(and by calls to
.Xr tzset 3 ).
.PP
.I Asctime\^
and
.I ctime\^
behave strangely for years before 1000 or after 9999.
The 1989 and 1999 editions of the C Standard say
that years from \-99 through 999 are converted without
extra spaces, but this conflicts with longstanding
tradition and with this implementation.
Traditional implementations of these two functions are
restricted to years in the range 1900 through 2099.
To avoid this portability mess, new programs should use
.I strftime\^
instead.
.PP
Avoid using out-of-range values with
.Fn mktime
when setting up lunch with promptness sticklers in Riyadh.
.\" @(#)newctime.3 7.14
.\" @(#)newctime.3 8.3
.\" This file is in the public domain, so clarified as of
.\" 2009-05-17 by Arthur David Olson.

View File

@ -1,95 +1,74 @@
/* $NetBSD: difftime.c,v 1.9 2002/01/29 12:58:32 kleink Exp $ */
/* $NetBSD: difftime.c,v 1.10 2009/12/31 22:49:16 mlelstv Exp $ */
/*
** This file is in the public domain, so clarified as of
** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
** 1996-06-05 by Arthur David Olson.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char elsieid[] = "@(#)difftime.c 7.9";
static char elsieid[] = "@(#)difftime.c 8.1";
#else
__RCSID("$NetBSD: difftime.c,v 1.9 2002/01/29 12:58:32 kleink Exp $");
__RCSID("$NetBSD: difftime.c,v 1.10 2009/12/31 22:49:16 mlelstv Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
/*LINTLIBRARY*/
#include "private.h"
/*
** Algorithm courtesy Paul Eggert (eggert@twinsun.com).
*/
#ifdef HAVE_LONG_DOUBLE
#define long_double long double
#endif /* defined HAVE_LONG_DOUBLE */
#ifndef HAVE_LONG_DOUBLE
#define long_double double
#endif /* !defined HAVE_LONG_DOUBLE */
#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
double
difftime(time1, time0)
const time_t time1;
const time_t time0;
{
time_t delta;
time_t hibit;
{
time_t tt;
double d;
long_double ld;
#ifdef __lint__
/* LINTED unused warning bug */&tt;
/* LINTED unused warning bug */&d;
/* LINTED unused warning bug */&ld;
#endif
if (/* LINTED constant */sizeof tt < sizeof d)
return (double) time1 - (double) time0;
if (/* LINTED constant */sizeof tt < sizeof ld)
return (long_double) time1 - (long_double) time0;
/*
** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
** (assuming that the larger type has more precision).
** This is the common real-world case circa 2004.
*/
/* LINTED constant */
if (sizeof (double) > sizeof (time_t))
return (double) time1 - (double) time0;
/* LINTED constant */
if (!TYPE_INTEGRAL(time_t)) {
/*
** time_t is floating.
*/
return time1 - time0;
}
/* LINTED constant */
if (!TYPE_SIGNED(time_t)) {
/*
** time_t is integral and unsigned.
** The difference of two unsigned values can't overflow
** if the minuend is greater than or equal to the subtrahend.
*/
if (time1 >= time0)
return time1 - time0;
else return -((double) (time0 - time1));
}
if (time1 < time0)
return -difftime(time0, time1);
/*
** As much as possible, avoid loss of precision
** by computing the difference before converting to double.
** time_t is integral and signed.
** Handle cases where both time1 and time0 have the same sign
** (meaning that their difference cannot overflow).
*/
delta = time1 - time0;
if (delta >= 0)
return delta;
if ((time1 < 0) == (time0 < 0))
return time1 - time0;
/*
** Repair delta overflow.
** time1 and time0 have opposite signs.
** Punt if unsigned long is too narrow.
*/
hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1);
/* CONSTCOND */
if (sizeof (unsigned long) < sizeof (time_t))
return (double) time1 - (double) time0;
/*
** The following expression rounds twice, which means
** the result may not be the closest to the true answer.
** For example, suppose time_t is 64-bit signed int,
** long_double is IEEE 754 double with default rounding,
** time1 = 9223372036854775807 and time0 = -1536.
** Then the true difference is 9223372036854777343,
** which rounds to 9223372036854777856
** with a total error of 513.
** But delta overflows to -9223372036854774273,
** which rounds to -9223372036854774784, and correcting
** this by subtracting 2 * (long_double) hibit
** (i.e. by adding 2**64 = 18446744073709551616)
** yields 9223372036854776832, which
** rounds to 9223372036854775808
** with a total error of 1535 instead.
** This problem occurs only with very large differences.
** It's too painful to fix this portably.
** We are not alone in this problem;
** some C compilers round twice when converting
** large unsigned types to small floating types,
** so if time_t is unsigned the "return delta" above
** has the same double-rounding problem with those compilers.
** Stay calm...decent optimizers will eliminate the complexity below.
*/
return delta - 2 * (long_double) hibit;
if (time1 >= 0 /* && time0 < 0 */)
return (unsigned long) time1 +
(unsigned long) (-(time0 + 1)) + 1;
return -(double) ((unsigned long) time0 +
(unsigned long) (-(time1 + 1)) + 1);
}

View File

@ -1,17 +1,16 @@
/* $NetBSD: ialloc.c,v 1.5 1997/07/13 20:26:49 christos Exp $ */
/* $NetBSD: ialloc.c,v 1.6 2009/12/31 22:49:16 mlelstv Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2006-07-17 by Arthur David Olson.
*/
#include <sys/cdefs.h>
#ifndef lint
#ifndef NOID
#if 0
static char elsieid[] = "@(#)ialloc.c 8.29";
#else
__RCSID("$NetBSD: ialloc.c,v 1.5 1997/07/13 20:26:49 christos Exp $");
#endif
#endif /* !defined NOID */
#endif /* !defined lint */
/*LINTLIBRARY*/
#if 0
static char elsieid[] = "@(#)ialloc.c 8.30";
#else
__RCSID("$NetBSD: ialloc.c,v 1.6 2009/12/31 22:49:16 mlelstv Exp $");
#endif
#include "private.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: private.h,v 1.24 2003/12/20 00:12:05 kleink Exp $ */
/* $NetBSD: private.h,v 1.25 2009/12/31 22:49:16 mlelstv Exp $ */
#ifndef PRIVATE_H
#define PRIVATE_H
@ -16,7 +16,7 @@
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
** 1996-06-05 by Arthur David Olson.
*/
/*
@ -34,11 +34,13 @@
#ifndef lint
#ifndef NOID
#if 0
static char privatehid[] = "@(#)private.h 7.53";
static char privatehid[] = "@(#)private.h 8.6";
#endif
#endif /* !defined NOID */
#endif /* !defined lint */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
/*
** Defaults for preprocessor symbols.
** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
@ -60,10 +62,6 @@ static char privatehid[] = "@(#)private.h 7.53";
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */
#ifndef HAVE_STRERROR
#define HAVE_STRERROR 1
#endif /* !defined HAVE_STRERROR */
#ifndef HAVE_SYMLINK
#define HAVE_SYMLINK 1
#endif /* !defined HAVE_SYMLINK */
@ -101,17 +99,17 @@ static char privatehid[] = "@(#)private.h 7.53";
#include "stdio.h"
#include "errno.h"
#include "string.h"
#include "limits.h" /* for CHAR_BIT */
#include "limits.h" /* for CHAR_BIT et al. */
#include "time.h"
#include "stdlib.h"
#if HAVE_GETTEXT - 0
#if HAVE_GETTEXT
#include "libintl.h"
#endif /* HAVE_GETTEXT - 0 */
#endif /* HAVE_GETTEXT */
#if HAVE_SYS_WAIT_H - 0
#if HAVE_SYS_WAIT_H
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
#endif /* HAVE_SYS_WAIT_H - 0 */
#endif /* HAVE_SYS_WAIT_H */
#ifndef WIFEXITED
#define WIFEXITED(status) (((status) & 0xff) == 0)
@ -120,104 +118,82 @@ static char privatehid[] = "@(#)private.h 7.53";
#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
#endif /* !defined WEXITSTATUS */
#if HAVE_UNISTD_H - 0
#include "unistd.h" /* for F_OK and R_OK */
#endif /* HAVE_UNISTD_H - 0 */
#if HAVE_UNISTD_H
#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */
#endif /* HAVE_UNISTD_H */
#if !(HAVE_UNISTD_H - 0)
#ifndef F_OK
#define F_OK 0
#endif /* !defined F_OK */
#ifndef R_OK
#define R_OK 4
#endif /* !defined R_OK */
#endif /* !(HAVE_UNISTD_H - 0) */
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
/*
** Define HAVE_STDINT_H's default value here, rather than at the
** start, since __GLIBC__'s value depends on previously-included
** files.
** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
*/
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ || \
2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
#endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
#include "stdint.h"
#endif /* !HAVE_STDINT_H */
#ifndef INT_FAST64_MAX
/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
#if defined LLONG_MAX || defined __LONG_LONG_MAX__
typedef long long int_fast64_t;
#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
#if (LONG_MAX >> 31) < 0xffffffff
Please use a compiler that supports a 64-bit integer type (or wider);
you may need to compile with "-DHAVE_STDINT_H".
#endif /* (LONG_MAX >> 31) < 0xffffffff */
typedef long int_fast64_t;
#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
#endif /* !defined INT_FAST64_MAX */
#ifndef INT32_MAX
#define INT32_MAX 0x7fffffff
#endif /* !defined INT32_MAX */
#ifndef INT32_MIN
#define INT32_MIN (-1 - INT32_MAX)
#endif /* !defined INT32_MIN */
/*
** Workarounds for compilers/systems.
*/
/*
** SunOS 4.1.1 cc lacks prototypes.
*/
#ifndef P
#define P(x) x
#endif /* !defined P */
/*
** SunOS 4.1.1 headers lack EXIT_SUCCESS.
*/
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif /* !defined EXIT_SUCCESS */
/*
** SunOS 4.1.1 headers lack EXIT_FAILURE.
*/
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif /* !defined EXIT_FAILURE */
/*
** SunOS 4.1.1 headers lack FILENAME_MAX.
*/
#ifndef FILENAME_MAX
#ifndef MAXPATHLEN
#ifdef unix
#include "sys/param.h"
#endif /* defined unix */
#endif /* !defined MAXPATHLEN */
#ifdef MAXPATHLEN
#define FILENAME_MAX MAXPATHLEN
#endif /* defined MAXPATHLEN */
#ifndef MAXPATHLEN
#define FILENAME_MAX 1024 /* Pure guesswork */
#endif /* !defined MAXPATHLEN */
#endif /* !defined FILENAME_MAX */
/*
** SunOS 4.1.1 libraries lack remove.
*/
#ifndef __NetBSD__
#ifndef remove
extern int unlink P((const char * filename));
#define remove unlink
#endif /* !defined remove */
#endif
/*
** Some ancient errno.h implementations don't declare errno.
** But some newer errno.h implementations define it as a macro.
** Some time.h implementations don't declare asctime_r.
** Others might define it as a macro.
** Fix the former without affecting the latter.
*/
#ifndef errno
extern int errno;
#endif /* !defined errno */
#ifndef asctime_r
extern char * asctime_r(struct tm const *, char *);
#endif
/*
** Private function declarations.
*/
char * icalloc P((int nelem, int elsize));
char * icatalloc P((char * old, const char * new));
char * icpyalloc P((const char * string));
char * imalloc P((int n));
void * irealloc P((void * pointer, int size));
void icfree P((char * pointer));
void ifree P((char * pointer));
char * scheck P((const char *string, const char *format))
__attribute__((__format_arg__(2)));
char * icalloc(int nelem, int elsize);
char * icatalloc(char * old, const char * new);
char * icpyalloc(const char * string);
char * imalloc(int n);
void * irealloc(void * pointer, int size);
void icfree(char * pointer);
void ifree(char * pointer);
const char * scheck(const char * string, const char * format);
/*
** Finally, some convenience items.
@ -239,6 +215,15 @@ char * scheck P((const char *string, const char *format))
#define TYPE_SIGNED(type) (((type) -1) < 0)
#endif /* !defined TYPE_SIGNED */
/*
** Since the definition of TYPE_INTEGRAL contains floating point numbers,
** it cannot be used in preprocessor directives.
*/
#ifndef TYPE_INTEGRAL
#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
#endif /* !defined TYPE_INTEGRAL */
#ifndef INT_STRLEN_MAXIMUM
/*
** 302 / 1000 is log10(2.0) rounded up.
@ -247,7 +232,8 @@ char * scheck P((const char *string, const char *format))
** 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))
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
1 + TYPE_SIGNED(type))
#endif /* !defined INT_STRLEN_MAXIMUM */
/*
@ -281,11 +267,11 @@ char * scheck P((const char *string, const char *format))
*/
#ifndef _
#if HAVE_GETTEXT - 0
#if HAVE_GETTEXT
#define _(msgid) gettext(msgid)
#else /* !(HAVE_GETTEXT - 0) */
#else /* !HAVE_GETTEXT */
#define _(msgid) msgid
#endif /* !(HAVE_GETTEXT - 0) */
#endif /* !HAVE_GETTEXT */
#endif /* !defined _ */
#ifndef TZ_DOMAIN
@ -295,10 +281,30 @@ char * scheck P((const char *string, const char *format))
#if HAVE_INCOMPATIBLE_CTIME_R
#undef asctime_r
#undef ctime_r
char *asctime_r P((struct tm const *, char *));
char *ctime_r P((time_t const *, char *));
char *asctime_r(struct tm const *, char *);
char *ctime_r(time_t const *, char *);
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
#ifndef YEARSPERREPEAT
#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
#endif /* !defined YEARSPERREPEAT */
/*
** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
*/
#ifndef AVGSECSPERYEAR
#define AVGSECSPERYEAR 31556952L
#endif /* !defined AVGSECSPERYEAR */
#ifndef SECSPERREPEAT
#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
#endif /* !defined SECSPERREPEAT */
#ifndef SECSPERREPEAT_BITS
#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
#endif /* !defined SECSPERREPEAT_BITS */
/*
** UNIX was a registered trademark of The Open Group in 2003.
*/

View File

@ -1,12 +1,18 @@
/* $NetBSD: scheck.c,v 1.6 1997/09/05 02:11:58 jtc Exp $ */
/* $NetBSD: scheck.c,v 1.7 2009/12/31 22:49:16 mlelstv Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2006-07-17 by Arthur David Olson.
*/
#include <sys/cdefs.h>
#ifndef lint
#ifndef NOID
#if 0
static char elsieid[] = "@(#)scheck.c 8.15";
static char elsieid[] = "@(#)scheck.c 8.19";
#else
__RCSID("$NetBSD: scheck.c,v 1.6 1997/09/05 02:11:58 jtc Exp $");
__RCSID("$NetBSD: scheck.c,v 1.7 2009/12/31 22:49:16 mlelstv Exp $");
#endif
#endif /* !defined lint */
#endif /* !defined NOID */
@ -15,7 +21,7 @@ __RCSID("$NetBSD: scheck.c,v 1.6 1997/09/05 02:11:58 jtc Exp $");
#include "private.h"
char *
const char *
scheck(string, format)
const char * const string;
const char * const format;
@ -24,11 +30,10 @@ const char * const format;
register const char * fp;
register char * tp;
register int c;
register char * result;
register const char * result;
char dummy;
static char nada;
result = &nada;
result = "";
if (string == NULL || format == NULL)
return result;
fbuf = imalloc((int) (2 * strlen(format) + 4));

View File

@ -1,11 +1,12 @@
/* $NetBSD: strftime.c,v 1.19 2009/01/11 02:46:30 christos Exp $ */
/* $NetBSD: strftime.c,v 1.20 2009/12/31 22:49:16 mlelstv Exp $ */
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char elsieid[] = "@(#)strftime.c 7.64";
static char elsieid[] = "@(#)strftime.c 8.3";
#else
__RCSID("$NetBSD: strftime.c,v 1.19 2009/01/11 02:46:30 christos Exp $");
__RCSID("$NetBSD: strftime.c,v 1.20 2009/12/31 22:49:16 mlelstv Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -74,18 +75,20 @@ static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89";
#include "sys/localedef.h"
#define Locale _CurrentTimeLocale
#define c_fmt d_t_fmt
static char * _add P((const char *, char *, const char *));
static char * _conv P((int, const char *, char *, const char *));
static char * _fmt P((const char *, const struct tm *, char *, const char *, int *));
static char * _add(const char *, char *, const char *);
static char * _conv(int, const char *, char *, const char *);
static char * _fmt(const char *, const struct tm *, char *, const char *,
int *);
static char * _yconv(int, int, int, int, char *, const char *);
#define NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
extern char * tzname[];
#ifndef YEAR_2000_NAME
#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
#endif /* !defined YEAR_2000_NAME */
#define IN_NONE 0
#define IN_SOME 1
#define IN_THIS 2
@ -174,14 +177,14 @@ label:
** something completely different.
** (ado, 1993-05-24)
*/
pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
"%02d", pt, ptlim);
pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0,
pt, ptlim);
continue;
case 'c':
{
int warn2 = IN_SOME;
pt = _fmt(Locale->d_t_fmt, t, pt, ptlim, &warn2);
pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
if (warn2 == IN_ALL)
warn2 = IN_THIS;
if (warn2 > *warnp)
@ -230,7 +233,7 @@ label:
** t->tm_hour % 12 : 12, 2, ' ');
** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbins'
** strftime version 3.0. That is, "%k" and
** strftime version 3.0. That is, "%k" and
** "%l" have been swapped.
** (ado, 1993-05-24)
*/
@ -250,7 +253,7 @@ label:
** _conv(t->tm_hour, 2, ' ');
** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbin's
** strftime version 3.0. That is, "%k" and
** strftime version 3.0. That is, "%k" and
** "%l" have been swapped.
** (ado, 1993-05-24)
*/
@ -328,7 +331,7 @@ label:
case 'G': /* ISO 8601 year (four digits) */
case 'g': /* ISO 8601 year (two digits) */
/*
** From Arnold Robbins' strftime version 3.0: "the week number of the
** From Arnold Robbins' strftime version 3.0: "the week number of the
** year (the first Monday as the first day of week 1) as a decimal number
** (01-53)."
** (ado, 1993-05-24)
@ -341,17 +344,19 @@ label:
** might also contain days from the previous year and the week before week
** 01 of a year is the last week (52 or 53) of the previous year even if
** it contains days from the new year. A week starts with Monday (day 1)
** and ends with Sunday (day 7). For example, the first week of the year
** and ends with Sunday (day 7). For example, the first week of the year
** 1997 lasts from 1996-12-30 to 1997-01-05..."
** (ado, 1996-01-02)
*/
{
int year;
int base;
int yday;
int wday;
int w;
year = t->tm_year + TM_YEAR_BASE;
year = t->tm_year;
base = TM_YEAR_BASE;
yday = t->tm_yday;
wday = t->tm_wday;
for ( ; ; ) {
@ -359,7 +364,7 @@ label:
int bot;
int top;
len = isleap(year) ?
len = isleap_sum(year, base) ?
DAYSPERLYEAR :
DAYSPERNYEAR;
/*
@ -378,7 +383,7 @@ label:
top += DAYSPERWEEK;
top += len;
if (yday >= top) {
++year;
++base;
w = 1;
break;
}
@ -387,26 +392,26 @@ label:
DAYSPERWEEK);
break;
}
--year;
yday += isleap(year) ?
--base;
yday += isleap_sum(year, base) ?
DAYSPERLYEAR :
DAYSPERNYEAR;
}
#ifdef XPG4_1994_04_09
if ((w == 52
&& t->tm_mon == TM_JANUARY)
|| (w == 1
&& t->tm_mon == TM_DECEMBER))
w = 53;
if ((w == 52 &&
t->tm_mon == TM_JANUARY) ||
(w == 1 &&
t->tm_mon == TM_DECEMBER))
w = 53;
#endif /* defined XPG4_1994_04_09 */
if (*format == 'V')
pt = _conv(w, "%02d",
pt, ptlim);
else if (*format == 'g') {
*warnp = IN_ALL;
pt = _conv(year % 100, "%02d",
pt = _yconv(year, base, 0, 1,
pt, ptlim);
} else pt = _conv(year, "%04d",
} else pt = _yconv(year, base, 1, 1,
pt, ptlim);
}
continue;
@ -444,11 +449,11 @@ label:
continue;
case 'y':
*warnp = IN_ALL;
pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
"%02d", pt, ptlim);
pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1,
pt, ptlim);
continue;
case 'Y':
pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1,
pt, ptlim);
continue;
case 'Z':
@ -479,12 +484,12 @@ label:
/*
** C99 says that the UTC offset must
** be computed by looking only at
** tm_isdst. This requirement is
** tm_isdst. This requirement is
** incorrect, since it means the code
** must rely on magic (in this case
** altzone and timezone), and the
** magic might not have the correct
** offset. Doing things correctly is
** offset. Doing things correctly is
** tricky and requires disobeying C99;
** see GNU C strftime for details.
** For now, punt and conform to the
@ -543,9 +548,10 @@ label:
diff = -diff;
} else sign = "+";
pt = _add(sign, pt, ptlim);
diff /= 60;
pt = _conv((diff/60)*100 + diff%60,
"%04d", pt, ptlim);
diff /= SECSPERMIN;
diff = (diff / MINSPERHOUR) * 100 +
(diff % MINSPERHOUR);
pt = _conv(diff, "%04d", pt, ptlim);
}
continue;
#if 0
@ -557,7 +563,7 @@ label:
case '%':
/*
** X311J/88-090 (4.12.3.5): if conversion char is
** undefined, behavior is undefined. Print out the
** undefined, behavior is undefined. Print out the
** character itself as printf(3) also does.
*/
default:
@ -594,3 +600,165 @@ const char * const ptlim;
++pt;
return pt;
}
/*
** POSIX and the C Standard are unclear or inconsistent about
** what %C and %y do if the year is negative or exceeds 9999.
** Use the convention that %C concatenated with %y yields the
** same output as %Y, and that %Y contains at least 4 bytes,
** with more only if necessary.
*/
static char *
_yconv(a, b, convert_top, convert_yy, pt, ptlim)
const int a;
const int b;
const int convert_top;
const int convert_yy;
char * pt;
const char * const ptlim;
{
register int lead;
register int trail;
#define DIVISOR 100
trail = a % DIVISOR + b % DIVISOR;
lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
trail %= DIVISOR;
if (trail < 0 && lead > 0) {
trail += DIVISOR;
--lead;
} else if (lead < 0 && trail > 0) {
trail -= DIVISOR;
++lead;
}
if (convert_top) {
if (lead == 0 && trail < 0)
pt = _add("-0", pt, ptlim);
else pt = _conv(lead, "%02d", pt, ptlim);
}
if (convert_yy)
pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim);
return pt;
}
#ifdef LOCALE_HOME
static struct lc_time_T *
_loc(void)
{
static const char locale_home[] = LOCALE_HOME;
static const char lc_time[] = "LC_TIME";
static char * locale_buf;
int fd;
int oldsun; /* "...ain't got nothin' to do..." */
char * lbuf;
char * name;
char * p;
const char ** ap;
const char * plim;
char filename[FILENAME_MAX];
struct stat st;
size_t namesize;
size_t bufsize;
/*
** Use localebuf.mon[0] to signal whether locale is already set up.
*/
if (localebuf.mon[0])
return &localebuf;
name = setlocale(LC_TIME, (char *) NULL);
if (name == NULL || *name == '\0')
goto no_locale;
/*
** If the locale name is the same as our cache, use the cache.
*/
lbuf = locale_buf;
if (lbuf != NULL && strcmp(name, lbuf) == 0) {
p = lbuf;
for (ap = (const char **) &localebuf;
ap < (const char **) (&localebuf + 1);
++ap)
*ap = p += strlen(p) + 1;
return &localebuf;
}
/*
** Slurp the locale file into the cache.
*/
namesize = strlen(name) + 1;
if (sizeof filename <
((sizeof locale_home) + namesize + (sizeof lc_time)))
goto no_locale;
oldsun = 0;
(void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time);
fd = open(filename, O_RDONLY);
if (fd < 0) {
/*
** Old Sun systems have a different naming and data convention.
*/
oldsun = 1;
(void) sprintf(filename, "%s/%s/%s", locale_home,
lc_time, name);
fd = open(filename, O_RDONLY);
if (fd < 0)
goto no_locale;
}
if (fstat(fd, &st) != 0)
goto bad_locale;
if (st.st_size <= 0)
goto bad_locale;
bufsize = namesize + st.st_size;
locale_buf = NULL;
lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize);
if (lbuf == NULL)
goto bad_locale;
(void) strcpy(lbuf, name);
p = lbuf + namesize;
plim = p + st.st_size;
if (read(fd, p, (size_t) st.st_size) != st.st_size)
goto bad_lbuf;
if (close(fd) != 0)
goto bad_lbuf;
/*
** Parse the locale file into localebuf.
*/
if (plim[-1] != '\n')
goto bad_lbuf;
for (ap = (const char **) &localebuf;
ap < (const char **) (&localebuf + 1);
++ap) {
if (p == plim)
goto bad_lbuf;
*ap = p;
while (*p != '\n')
++p;
*p++ = '\0';
}
if (oldsun) {
/*
** SunOS 4 used an obsolescent format; see localdtconv(3).
** c_fmt had the ``short format for dates and times together''
** (SunOS 4 date, "%a %b %e %T %Z %Y" in the C locale);
** date_fmt had the ``long format for dates''
** (SunOS 4 strftime %C, "%A, %B %e, %Y" in the C locale).
** Discard the latter in favor of the former.
*/
localebuf.date_fmt = localebuf.c_fmt;
}
/*
** Record the successful parse in the cache.
*/
locale_buf = lbuf;
return &localebuf;
bad_lbuf:
free(lbuf);
bad_locale:
(void) close(fd);
no_locale:
localebuf = C_time_locale;
locale_buf = NULL;
return &localebuf;
}
#endif /* defined LOCALE_HOME */

View File

@ -1,4 +1,4 @@
.\" $NetBSD: time2posix.3,v 1.14 2009/04/11 16:29:09 joerg Exp $
.\" $NetBSD: time2posix.3,v 1.15 2009/12/31 22:49:16 mlelstv Exp $
.Dd April 1, 2001
.Dt TIME2POSIX 3
.Os
@ -119,4 +119,4 @@ degenerate to the identity function.
.Xr time 3
.\" @(#)time2posix.3 7.7
.\" This file is in the public domain, so clarified as of
.\" 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
.\" 1996-06-05 by Arthur David Olson.

View File

@ -1,78 +1,98 @@
<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Sources for Time Zone and Daylight Saving Time Data</title>
<link rel="schema.DC" href="http://purl.org/DC/elements/1.1/" />
<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" />
<link rel="schema.DC" href="http://purl.org/DC/elements/1.1/">
<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="2007-12-26">
<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" />
content="Sources of information about time zones and daylight saving time">
<meta name="DC.Identifier" content="http://www.twinsun.com/tz/tz-link.htm">
<meta name="Keywords"
content="database,daylight saving,DST,time zone,timezone,tz,zoneinfo" />
content="database,daylight saving,DST,time zone,timezone,tz,zoneinfo">
</head>
<body>
<h1>Sources for Time Zone and Daylight Saving Time Data</h1>
<address>
@(#)tz-link.htm 7.42
@(#)tz-link.htm 8.22
</address>
<p>
Please send corrections to this web page to the
<a href="mailto:tz@elsie.nci.nih.gov">time zone mailing list</a>.
This file is in the public domain, so clarified as of
2009-05-17 by Arthur David Olson.
</p>
<p>
Please send corrections to this web page to the
<a href="mailto:tz@elsie.nci.nih.gov">time zone mailing list</a>.</p>
<h2>The <code>tz</code> database</h2>
<p>
The public-domain time zone database contains code and data
The <a href="http://en.wikipedia.org/wiki/Public_domain">public-domain</a>
time zone database contains code and data
that represent the history of local time
for many representative locations around the globe.
It is updated periodically to reflect changes made by political bodies
to UTC offsets and daylight-saving rules.
This database (often called <code>tz</code> or <code>zoneinfo</code>)
to <a href="http://en.wikipedia.org/wiki/Time_zone">time zone</a>
boundaries, <a
href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time"><abbr
title="Coordinated Universal Time">UTC</abbr></a> offsets, and
<a href="http://en.wikipedia.org/wiki/Daylight_saving">daylight-saving</a>
rules.
This database (often called <code>tz</code> or <a
href="http://en.wikipedia.org/wiki/Zoneinfo"><code>zoneinfo</code></a>)
is used by several implementations,
including
<a href="http://www.gnu.org/software/libc/">the GNU C Library</a> used in
<a href="http://www.linux.org/">GNU/Linux</a>,
<a href="http://www.gnu.org/software/libc/">the
<abbr title="GNU's Not Unix">GNU</abbr>
C Library</a> used in
<a href="http://www.linux.org/"><abbr>GNU</abbr>/Linux</a>,
<a href="http://www.freebsd.org/">FreeBSD</a>,
<a href="http://www.netbsd.org/">NetBSD</a>,
<a href="http://www.openbsd.org/">OpenBSD</a>,
<a href="http://www.cygwin.com/">Cygwin</a>,
<a href="http://www.delorie.com/djgpp/">DJGPP</a>,
<a href="http://www.hp.com/products1/unix/operating/">HP-UX</a>,
<a href="http://www.sgi.com/developers/technology/irix/">IRIX</a>,
<a href="http://netbsd.org/">NetBSD</a>,
<a href="http://openbsd.org/">OpenBSD</a>,
<a href="http://cygwin.com/">Cygwin</a>,
<a href="http://www.delorie.com/djgpp/"><abbr
title="DJ's GNU Programming Platform">DJGPP</abbr></a>,
<a href="http://ibm.com/aix">AIX</a>,
<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://www.sco.com/products/unixware/">UnixWare</a>.</p>
<a href="http://oracle.com/database">Oracle Database</a>,
<a href="http://sun.com/software/solaris">Solaris</a>,
<a href="http://h30097.www3.hp.com/">Tru64</a>, and
<a href="http://sco.com/products/unixware">UnixWare</a>.</p>
<p>
Each location in the database represents a national region where all
clocks keeping local time have agreed since 1970.
Locations are identified by continent or ocean and then by the name of
the location, which is typically the largest city within the region.
For example, <code>America/New_York</code>
represents most of the US eastern time zone;
<code>America/Indianapolis</code> represents most of Indiana, which
uses eastern time without daylight saving time (DST);
represents most of the <abbr title="United States">US</abbr> eastern time zone;
<code>America/Phoenix</code> represents most of Arizona, which
uses mountain time without daylight saving time (<abbr
title="daylight saving time">DST</abbr>);
<code>America/Detroit</code> represents most of Michigan, which uses
eastern time but with different DST rules in 1975;
eastern time but with different <abbr>DST</abbr> rules in 1975;
and other entries represent smaller regions like Starke County,
Kentucky, which switched from central to eastern time in 1991.
To use the database, set the <code>TZ</code> environment variable to
Indiana, which switched from central to eastern time in 1991
and switched back in 2006.
To use the database on an extended <a
href="http://en.wikipedia.org/wiki/POSIX"><abbr
title="Portable Operating System Interface">POSIX</abbr></a>
implementation set the <code>TZ</code> environment variable to
the location's full name, e.g., <code>TZ="America/New_York"</code>.</p>
<p>
In the <code>tz</code> database's
<a href="ftp://elsie.nci.nih.gov/pub/">FTP distribution</a>,
<a href="ftp://elsie.nci.nih.gov/pub"><abbr
title="File Transfer Protocol">FTP</abbr> distribution</a>
the code is in the file <code>tzcode<var>C</var>.tar.gz</code>,
where <code><var>C</var></code> is the code's version;
similarly, the data are in <code>tzdata<var>D</var>.tar.gz</code>,
where <code><var>D</var></code> is the data's version.
The following shell commands download
these files to a GNU/Linux or similar host; see the downloaded
The following <a
href="http://en.wikipedia.org/wiki/Unix_shell">shell</a> commands download
these files to a <abbr>GNU</abbr>/Linux or similar host;
see the downloaded
<code>README</code> file for what to do next.</p>
<pre style="margin-left: 2em"><code><a href="http://www.gnu.org/software/wget/">wget</a> 'ftp://elsie.nci.nih.gov/pub/tz*.tar.gz'
<a href="http://www.gnu.org/software/gzip/">gzip</a> -dc tzcode*.tar.gz | <a href="http://www.gnu.org/software/tar/">tar</a> -xf -
@ -87,148 +107,238 @@ location.</p>
The data are by no means authoritative. If you find errors, please
send changes to the <a href="mailto:tz@elsie.nci.nih.gov">time zone
mailing list</a>. You can also <a
href="mailto:tz-request@elsie.nci.nih.gov">subscribe</a> to the
mailing list, retrieve the <a
href="ftp://elsie.nci.nih.gov/pub/tzarchive.gz">archive of old
href="http://news.gmane.org/gmane.comp.time.tz">browse recent
messages</a> sent to the mailing list, <a
href="mailto:tz-request@elsie.nci.nih.gov">subscribe</a> to it,
retrieve the <a
href="ftp://elsie.nci.nih.gov/pub/tzarchive.gz">full archive of old
messages</a> (in gzip compressed format), or retrieve <a
href="ftp://munnari.oz.au/pub/oldtz/">archived older versions of code
href="ftp://munnari.oz.au/pub/oldtz">archived older versions of code
and data</a>.</p>
<p>
The Web has several other sources for time zone and daylight saving time data.
Here are some recent links that may be of interest.
</p>
<h2>Web pages using recent versions of the <code>tz</code> database</h2>
<p>
These are listed roughly in ascending order of complexity and fanciness.
</p>
<ul>
<li><a href="http://twiki.org/cgi-bin/xtra/tzdate">Date and Time Gateway</a>
is a text-based point-and-click interface to tables of current time
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
&amp; 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
<code>tz</code>'s.</li>
<li><a href="http://twiki.org/cgi-bin/xtra/tzdatepick.html">Date and Time Gateway</a>
lets you see the <code>TZ</code> values directly.</li>
<li><a
href="http://convertit.com/Go/ConvertIt/World_Time/Current_Time.ASP">Current
Time in 1000 Places</a> uses descriptions of the values.</li>
<li><a href="http://www.timezoneconverter.com/">Time Zone Converter</a>
uses a pulldown menu.</li>
<li><a href="http://home.tiscali.nl/~t876506/TZworld.html">Complete
timezone information for all countries</a> displays tables of DST rules.
<li><a href="http://timeanddate.com/worldclock/">The World Clock -
Time Zones</a> lets you sort zone names and convert times.</li>
<li><a href="http://daylight-savings-time.info/">Graphical Display of
Time Zones and Daylight Saving Times</a> shows a graph of time
difference versus time for any pair of locations.</li>
<li>The <a href="http://worldtimeengine.com/">World Time Engine</a>
also contains data about time zone boundaries; it supports queries via place
names and shows location maps.</li>
</ul>
<h2>Other time zone database formats</h2>
<ul>
<li>The <a href="ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt">
Internet Calendaring and Scheduling Core Object Specification
(iCalendar)</a> specification published by the <a
href="http://www.ietf.org/html.charters/calsch-charter.html">IETF
Calendaring and Scheduling Working Group (calsch)</a> covers time zone
data; see its VTIMEZONE calendar component.</li>
(iCalendar)</a>, Internet <abbr title="Request For
Comments">RFC</abbr> 2445, published by the (now-concluded) <a
href="http://ietf.org/html.charters/OLD/calsch-charter.html"><abbr
title="Internet Engineering Task Force">IETF</abbr>
Calendaring and Scheduling Working Group (<abbr
title="Calendaring and Scheduling Working Group">calsch</abbr>)</a>
covers time zone
data; see its VTIMEZONE calendar component.
The <a href="http://calconnect.org/">Calendaring and Scheduling
Consortium</a> is promoting further work in this area. <a
href="http://calconnect.org/publications/icalendartimezoneproblemsandrecommendationsv1.0.pdf">iCalendar
TIMEZONE Problems and Recommendations</a> offers guidelines and
recommendations for the use of VTIMEZONE and <code>tz</code>.</li>
<li><a href="http://calconnect.org/dstlinks.shtml">Extended Daylight
Saving Time Links, Advisories and Changes</a> lists vendor material on recent
daylight saving time changes.</li>
<li><a
href="http://calconnect.org/publications/timezoneregistryandservicerecommendationsv1.0.pdf">Timezone
Registry and Service Recommendations</a> discusses a
strategy for defining and deploying a time zone
registration process that would establish unique names for each
version of each <code>tz</code> zone, along with a polygonal
representation of the geographical area corresponding to the
zone.</li>
<li>The <a
href="http://lists.w3.org/Archives/Public/www-rdf-calendar/">www-rdf-calendar</a>
list discusses <a href="http://www.w3.org/RDF/">RDF</a>-based calendar
list discusses <a
href="http://www.w3.org/RDF/"><abbr
title="Resource Description Framework">RDF</abbr></a>-based calendar
and group scheduling systems, and has a <a
href="http://www.w3.org/2002/12/cal/#tzd">workspace on time zone
data</a> converted from <code>tz</code>. An earlier <a
href="http://www.w3.org/2000/01/foo">schema</a> was sketched out by <a
href="http://www.w3.org/People/Berners-Lee/">Tim Berners-Lee</a>.</li>
<li><a
href="http://www.calsch.org/ietf/archives/draft-ietf-calsch-many-xcal-02.txt">XCal</a>
was a draft <a href="http://www.w3.org/XML/">XML</a> document type
definition that corresponded to iCalendar.</li>
href="http://www.w3.org/2000/01/foo">schema</a> was sketched out.</li>
</ul>
<h2>Other <code>tz</code> compilers</h2>
<ul>
<li><a href="http://www.dachaplin.dsl.pipex.com/vzic">Vzic iCalendar
Timezone Converter</a> describes a program Vzic that compiles
<li><a href="http://www.dachaplin.dsl.pipex.com/vzic/">Vzic iCalendar
Timezone Converter</a> describes a <a
href="http://en.wikipedia.org/wiki/C_%28programming_language%29">C</a>
program that compiles
<code>tz</code> source into iCalendar-compatible VTIMEZONE files.
Vzic is freely
available under the <a href="http://www.gnu.org/copyleft/gpl.html">GNU
General Public License (GPL)</a>.</li>
available under the <a
href="http://www.gnu.org/copyleft/gpl.html"><abbr>GNU</abbr>
General Public License (<abbr
title="General Public License">GPL</abbr>)</a>.</li>
<li><a href="http://sourceforge.net/projects/tzical">tziCal - tz
database conversion utility</a> is like Vzic, except for the <a
href="http://msdn.microsoft.com/netframework">.NET framework</a>.</li>
<li><a
href="http://search.cpan.org/dist/DateTime-TimeZone/">DateTime::TimeZone</a>
contains a script <code>parse_olson</code> that compiles
<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 <abbr>GPL</abbr> 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
Unicode (ICU)</a> contains a C/C++ library for internationalization that
has a compiler from <samp>tz</samp> source into an ICU-specific format.
ICU is freely available under a BSD-style license.</li>
<li><a href="http://icu-project.org/">International Components for
Unicode (<abbr>ICU</abbr>)</a> contains C/C++ and <a
href="http://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a>
libraries for internationalization that
has a compiler from <code>tz</code> source
into an <abbr>ICU</abbr>-specific format.
<abbr>ICU</abbr> is freely available under a
<abbr title="Berkeley Software Distribution">BSD</abbr>-style license.</li>
<li><a href="http://joda-time.sourceforge.net/">Joda Time - Java date
and time API</a> contains a class
and time <abbr title="Application Program Interface">API</abbr></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>
is freely available under a <abbr>BSD</abbr>-style license.</li>
<li><a href="http://pytz.sourceforge.net">PyTZ - Python Time
Zone Library</a> compiles <code>tz</code> source into
<a href="http://python.org/">Python</a>.
It is freely available under a <abbr>BSD</abbr>-style license.</li>
<li><a href="http://tzinfo.rubyforge.org/">TZInfo - Ruby Timezone Library</a>
compiles <code>tz</code> source into
<a href="http://ruby-lang.org">Ruby</a>.
It is freely available under the <abbr
title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
<li>The <a href="http://chronos-st.org/">Chronos Date/Time
Library</a> is a <a href="http://smalltalk.org">Smalltalk</a> class
library that compiles <code>tz</code> source into a <a
href="http://date-time-zone.com/">time zone repository</a> whose format
is either proprietary or an <a href="http://www.w3.org/XML/"><abbr
title="Extensible Markup Language">XML</abbr></a>-encoded
representation.</li>
<li>Starting with version 8.5, <a href="http://tcl.tk/">Tcl</a>
contains a developer-oriented parser that compiles <samp>tz</samp>
source into text files, along with a runtime that can read those
files. Tcl is freely available under a <abbr>BSD</abbr>-style
license.</li>
</ul>
<h2>Other <code>tz</code> binary file readers</h2>
<ul>
<li>The <a href="http://www.gnu.org/software/libc/">GNU C Library</a>
<li>The <a
href="http://www.gnu.org/software/libc/"><abbr>GNU</abbr> C
Library</a>
has an independent, thread-safe implementation of
a <code>tz</code> binary file reader.
This library is freely available under the
<a href="http://www.gnu.org/copyleft/lesser.html">
GNU Lesser General Public License (LGPL)</a>,
and is widely used in GNU/Linux systems.</li>
<li><a href="http://www.bmsi.com/java/#TZ">ZoneInfo.java</a>
<abbr>GNU</abbr> Lesser General Public License
(<abbr title="Lesser General Public License">LGPL</abbr>)</a>,
and is widely used in <abbr>GNU</abbr>/Linux systems.</li>
<li><a href="http://bmsi.com/java/#TZ">ZoneInfo.java</a>
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>
It is freely available under the <abbr>LGPL</abbr>.</li>
<li>Tcl, mentioned above, also contains a
<code>tz</code> binary file reader.</li>
</ul>
<h2>Other <code>tz</code>-based time zone conversion software</h2>
<h2>Other <code>tz</code>-based time zone software</h2>
<ul>
<li><a href="http://stemhaus.com/firefox/foxclocks/">FoxClocks</a>
is an extension for <a
href="http://developer.mozilla.org/en/docs/Toolkit_API">Mozilla
Toolkit</a> applications like <a
href="http://mozilla.com/firefox">Firefox</a>, <a
href="http://mozilla.com/thunderbird">Thunderbird</a>, and
<a
href="http://www.mozilla.org/projects/calendar/sunbird/">Sunbird</a>.
It displays multiple clocks in the application window, and has a mapping
interface to <a href="http://earth.google.com/">Google Earth</a>.
It is freely available under the <abbr>GPL</abbr>.</li>
<li><a
href="http://users.skynet.be/Peter.Verthez/projects/intclock/">International
clock (intclock)</a> is a multi-timezone clock for
<abbr>GNU</abbr>/Linux and similar systems. It is freely available
under the <abbr>GPL</abbr>.</li>
<li><a href="http://codeplex.com/publicdomain">PublicDomain</a>
has a copy of a recent <code>tz</code> database, accessed via a <a
href="http://en.wikipedia.org/wiki/C_Sharp">C#</a> library. As its
name suggests, it is in the public domain. Only current time stamps
are well supported; historical data are compiled into the runtime but
are not easily accessible.</li>
<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 <code>tz</code> database in a
Java-specific format.</li>
<li><a href="http://kimmo.suominen.com/sw/timezone/">Time Zone</a> is
a <a href="http://wordpress.org/">WordPress</a> plugin. It is freely
available under a <abbr>BSD</abbr>-style license.</li>
<li><a
href="http://www1.tip.nl/~t876506/AboutTimeZonesHC.html">HyperCard
time zones calculator</a> is a HyperCard stack.</li>
href="http://veladg.com/velaterra.html">VelaTerra</a> is
a Mac OS X program. Its developers
<a href="http://veladg.com/tzoffer.html">offer free
licenses</a> to <code>tz</code> contributors.</li>
<li><a
href="http://www.cimmyt.org/timezone/">World Time Explorer</a> is a
href="http://worldtimeexplorer.com/">World Time Explorer</a> is a
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">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
href="http://astrocom.com/products/software.php?software_id=ibmwboth">computer</a>
and book form (<a
href="http://astrocom.com/products/book.php?book_id=b110x">one volume
for the USA</a>, and <a
href="http://astrocom.com/products/book.php?book_id=b112x">one for
other locations</a>) by <a
href="http://astrocom.com/">Astro Communications Services</a>.</li>
<li><a href="http://worldtime.com/">WORLDTIME: interactive atlas,
time info, public holidays</a>
contains information on local time, sunrise and sunset,
and public holidays in several hundred cities around the world.</li>
<li><a href="http://www.worldtimeserver.com/">World Time Server</a>
<li><a href="http://worldtimeserver.com/">World Time Server</a>
is another time zone database.</li>
<li><a href="http://tycho.usno.navy.mil/tzones.html">World Time Zones</a>
contains data from the Time Service Department of the US Naval Observatory
(USNO), used as the source
contains data from the Time Service Department of the
<abbr>US</abbr> Naval Observatory, used as the source
for the <code>usno*</code> files in the <code>tz</code> distribution.</li>
<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
Schedules Information Manual (SSIM)</a> of the
the <a href="http://www.iata.org/">International Air Transport
Association</a>,
which gives current time zone rules for
all the airports served by commercial aviation.</li>
<li>The <a href="http://iata.org/ps/publications/SSIM.htm">Standard
Schedules Information Manual</a> of the
<a href="http://iata.org/index.htm">International Air Transport
Association</a>
gives current time zone rules for airports served by commercial aviation.</li>
<li>Some Microsoft Windows versions contain time zone information in
an undocumented format, with IDs that can be mapped to <code>TZ</code>
values using the <a
href="http://unicode.org/cldr/data/diff/supplemental/windows_tzid.html">Windows
&rarr; Tzid table</a> maintained by the <abbr
title="Common Locale Data Repository">CLDR</abbr> data mentioned
below.</li>
</ul>
<h2>Maps</h2>
<ul>
<li>The <a href="http://www.odci.gov/">United States Central
Intelligence Agency (CIA)</a> publishes a <a
href="http://www.odci.gov/cia/publications/factbook/reference_maps/pdf/time_zones.pdf">time
<li>The <a href="https://www.cia.gov/">United States Central
Intelligence Agency (<abbr
title="Central Intelligence Agency">CIA</abbr>)</a> publishes a <a
href="https://www.cia.gov/library/publications/the-world-factbook/reference_maps/pdf/time_zones.pdf">time
zone map</a>; the
<a
href="http://www.lib.utexas.edu/maps/world.html">Perry-Casta&ntilde;eda
@ -238,37 +348,60 @@ 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
The maps' pictorial quality is not quite as good as the
<abbr>CIA</abbr>'s
but the maps are more up to date.</li>
</ul>
<h2>Time zone boundaries</h2>
<ul>
<li><a href="http://home-4.tiscali.nl/~t876506/Multizones.html">Time
<li><a href="http://efele.net/maps/tz/">TZ timezone maps</a> contains a <a
href="http://en.wikipedia.org/wiki/Shapefile">shapefile</a> of the
<code>tz</code> regions in the world.</li>
<li><a href="http://statoids.com/statoids.html">Administrative Divisions
of Countries ("Statoids")</a> contains detailed lists of
<code>tz</code>-related zone subdivision data.</li>
<li><a href="http://home.tiscali.nl/~t876506/Multizones.html">Time
zone boundaries for multizone countries</a> summarizes legal
boundaries between time zones within countries.</li>
<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>
<li>The US Geological Survey's National Atlas of the United States
publishes the <a href="http://www.nationalatlas.gov/timeznm.html">Time
<abbr title="Geographic Information Systems">GIS</abbr>
Data</a> includes a Manifold-format map of
world time zone boundaries distributed under the
<abbr>GPL</abbr>.</li>
<li>The <abbr>US</abbr> Geological Survey's National Atlas of
the United States
publishes the <a href="http://nationalatlas.gov/mld/timeznp.html">Time
Zones of the United States</a> in the public domain.</li>
<li>The GeoCommunity lists several commercial sources for <a
href="http://spatialnews.geocomm.com/features/timezones/">International
Time Zones and Time Zone Data</a>.</li>
<li>A ship within the <a
href="http://en.wikipedia.org/wiki/Territorial_waters">territorial
waters</a> of any nation uses that nation's time. In international
waters, time zone boundaries are meridians 15&deg; apart, except that
UTC&minus;12 and UTC+12 are each 7.5&deg; wide and are separated by
the 180&deg; meridian (not by the International Date Line, which is
for land and territorial waters only). A captain can change ship's
clocks any time after entering a new time zone; midnight changes are
common.</li>
</ul>
<h2>Civil time concepts and history</h2>
<ul>
<li><a href="http://physics.nist.gov/time">A Walk through Time</a>
<li><a href="http://physics.nist.gov/GenInt/Time/time.html">A
Walk through Time</a>
surveys the evolution of timekeeping.</li>
<li><a href="http://webexhibits.org/daylightsaving/">About Daylight
Saving Time - History, rationale, laws and dates</a>
is an overall history of DST.</li>
Saving Time - History, rationale, laws &amp; dates</a>
is an overall history of <abbr>DST</abbr>.</li>
<li><a href="http://energy.ca.gov/daylightsaving.html">Saving Time,
Saving Energy</a> discusses a primary justification for <abbr>DST</abbr>.</li>
<li><a href="http://seizethedaylight.com/dst/">Who Knew? A Brief
History of Daylight Saving Time</a> summarizes some of the contentious
history of <abbr>DST</abbr>.</li>
<li><a href="http://toi.iriti.cnr.it/">The
Time of Internet</a>
describes time zones and daylight saving time,
@ -277,20 +410,17 @@ The time zone map is out of date, however.</li>
<li><a href="http://www.phys.uu.nl/~vgent/idl/idl.htm">A History of
the International Date Line</a> tells the story of the most important
time zone boundary.</li>
<li><a href="http://www.statoids.com/tconcept.html">Basic Time
<li><a href="http://statoids.com/tconcept.html">Basic Time
Zone Concepts</a> discusses terminological issues behind time zones.</li>
</ul>
<h2>National histories of legal time</h2>
<dl>
<dt>Australia</dt>
<dd>The Community Relations Division of the New South Wales (NSW)
Attorney General's Department maintains a <a
href="http://www.lawlink.nsw.gov.au/crd.nsf/pages/time2">history of
daylight saving in NSW</a>.</dd>
<dt>Austria</dt>
<dd>The Federal Office of Metrology and Surveying publishes a
table of <a href="http://www.metrologie.at/pdf/sommerzeit.pdf"
hreflang="de">daylight saving time in Austria (in German)</a>.</dd>
<dd>The Parliamentary Library has commissioned <a
href="http://www.aph.gov.au/LIBRARY/Pubs/rn/2006-07/07rn13.pdf">research
note on daylight saving time in Australia</a>.
The Bureau of Meteorology publishes a list of
<a href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">Implementation Dates of Daylight Savings Time within Australia</a>.</dd>
<dt>Belgium</dt>
<dd>The Royal Observatory of Belgium maintains a table of <a
href="http://www.astro.oma.be/GENERAL/INFO/nli001a.html"
@ -303,20 +433,19 @@ Portuguese)</a>.</dd>
<dt>Canada</dt>
<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>
href="http://inms-ienm.nrc-cnrc.gc.ca/time_services/daylight_saving_e.html">Time
Zones &amp; Daylight Saving Time</a>.</dd>
<dt>Chile</dt>
<dd>WebExhibits publishes a <a
href="http://webexhibits.org/daylightsaving/chile.html"
hreflang="es">history of official time (in Spanish)</a> originally
written by the Chilean Hydrographic and Oceanographic Service.</dd>
<dd>The Chilean Hydrographic and Oceanographic Service publishes a <a
href="http://www.horaoficial.cl/horaof.htm" hreflang="es"> history of
official time (in Spanish)</a>.</dd>
<dt>Germany</dt>
<dd>The National Institute for Science and Technology maintains the <a
href="http://www.ptb.de/en/org/4/44/441/dars_e.htm">Realisation of
Legal Time in Germany</a>.</dd>
<dt>Israel</dt>
<dd>The Interior Ministry periodically issues <a
href="ftp://ftp.cs.huji.ac.il/pub/tz/announcements/"
href="ftp://ftp.cs.huji.ac.il/pub/tz/announcements"
hreflang="he">announcements (in Hebrew)</a>.</dd>
<dt>Mexico</dt>
<dd>The Investigation and Analysis Service of the Mexican Library of
@ -331,10 +460,15 @@ hreflang="nl">Legal time in the Netherlands (in Dutch)</a>
covers the history of local time in the Netherlands from ancient times.</dd>
<dt>New Zealand</dt>
<dd>The Department of Internal Affairs maintains a brief history <a
href="http://www.dia.govt.nz/diawebsite.nsf/wpg_URL/Resource-material-Information-We-Provide-About-Daylight-Saving">about
daylight saving</a>. The privately-maintained <a
href="http://www.astrologyhouse.co.nz/timechanges.htm">Time Changes in
New Zealand</a> has more details.</dd>
href="http://dia.govt.nz/diawebsite.nsf/wpg_URL/Resource-material-Information-We-Provide-About-Daylight-Saving">About
Daylight Saving</a>. The privately-maintained <a
href="http://astrologyschool.com/nztime.html">History of New Zealand
time</a> has more details.</dd>
<dt>Norway</dt>
<dd>The Norwegian Meteorological Institute lists
<a href="http://met.no/met/met_lex/q_u/sommertid.html" hreflang="no">Summer
time in Norway (in Norwegian)</a>, citing the
Institute of Theoretical Astrophysics, Oslo.</dd>
<dt>Singapore</dt>
<dd><a
href="http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html">Why
@ -346,56 +480,86 @@ href="http://www.srcf.ucam.org/~jsm28/british-time/">History of
legal time in Britain</a> discusses in detail the country
with perhaps the best-documented history of clock adjustments.
The National Physical Laboratory also maintains an <a
href="http://www.npl.co.uk/time/summer_time_archive.html">archive
of summer time dates</a>.</dd>
href="http://www.npl.co.uk/server.php?show=ConWebDoc.2714">Archive
of Summer time dates</a>.</dd>
</dl>
<h2>Precision timekeeping</h2>
<ul>
<li><a
href="http://literature.agilent.com/litwebbin/purl.cgi?org_id=tmo&amp;pub_id=5965-7984E">The
href="http://literature.agilent.com/litweb/pdf/5965-7984E.pdf">The
Science of Timekeeping</a> is a thorough introduction
to the theory and practice of precision timekeeping.</li>
<li><a href="http://www.ntp.org/">NTP: The Network Time Protocol</a>
<li><a href="http://www.ntp.org/"><abbr
title="Network Time Protocol">NTP</abbr>: The Network
Time Protocol</a>
discusses how to synchronize clocks of
Internet hosts.</li>
<li><a href="http://gauss.gge.unb.ca/GMT.UT.and.the.RGO.txt"
charset="macintosh">A
Few Facts Concerning GMT, UT, and the RGO</a>
answers questions like "What is the difference between GMT and UTC?"</li>
<li><a
href="http://www.gb.nrao.edu/~rfisher/Ephemerides/times.html">Astronomical
Times</a> explains more abstruse astronomical time scales like TT, TCG,
and TDB.</li>
<li>The <a href="http://www.iau.org/">IAU</a>'s <a
href="http://www.iau-sofa.rl.ac.uk/">Standards Of Fundamental
Astronomy</a> (SOFA) initiative publishes Fortran code for converting
among time scales like TAI, TDB, TT and UTC.</li>
<li><a href="http://www.jpl.nasa.gov/basics/bsf2-3.htm">Basics of
href="ftp://ftp.rfc-editor.org/in-notes/rfc4833.txt">Timezone
Options for <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr></a>
(Internet <abbr>RFC</abbr> 4833)
specifies a <a
href="http://www.dhcp.org/">DHCP</a> option for a server to configure
a client's time zone and daylight saving settings automatically.</li>
<li><a href="http://gauss.gge.unb.ca/GMT.UT.and.the.RGO.html">A Few
Facts Concerning <abbr title="Greenwich Mean Time">GMT</abbr>, <abbr
title="Universal Time">UT</abbr>, and
the <abbr title="Royal Greenwich Observatory">RGO</abbr></a>
answers questions like "What is the
difference between <abbr>GMT</abbr> and <abbr>UTC</abbr>?"</li>
<li><a
href="http://www.cv.nrao.edu/~rfisher/Ephemerides/times.html">Astronomical
Times</a> explains more abstruse astronomical time scales like
<abbr title="Terrestrial Dynamic Time">TDT</abbr>,
<abbr title="Geocentric Coordinate Time">TCG</abbr>, and
<abbr title="Barycentric Dynamic Time">TDB</abbr>.
<a href="http://www.ucolick.org/~sla/leapsecs/timescales.html">Time
Scales</a> goes into more detail, particularly for historical variants.</li>
<li>The <a href="http://iau.org/"><abbr
title="International Astronomical Union">IAU</abbr></a>'s <a
href="http://www.iau-sofa.rl.ac.uk/"><abbr
title="Standards Of Fundamental Astronomy">SOFA</abbr></a>
initiative publishes Fortran
code for converting among time scales like
<abbr title="International Atomic Time">TAI</abbr>,
<abbr>TDB</abbr>, <abbr>TDT</abbr> and
<abbr>UTC</abbr>.</li>
<li><a href="http://jpl.nasa.gov/basics/bsf2-3.htm">Basics of
Space Flight - Reference Systems - Time Conventions</a>
briefly explains interplanetary space flight timekeeping.</li>
<li><a
href="http://www.giss.nasa.gov/tools/mars24/help/notes.html">Technical
Notes on Mars Solar Time as Adopted by the Mars24 Sunclock</a> briefly
describes Mars Coordinated Time (MTC) and the diverse local time
describes Mars Coordinated Time (<abbr
title="Mars Coordinated Time">MTC</abbr>) and the
diverse local time
scales used by each landed mission on Mars.</li>
<li><a href="http://leapsecond.com/">LeapSecond.com</a> is
dedicated not only to leap seconds but to precise time and frequency
in general. It covers the state of the art in amateur timekeeping, and
how the art has progressed over the past few decades.</li>
<li><a
href="http://hpiers.obspm.fr/eop-pc/products/bulletins/bulletins.html">Bulletins
maintained by the IERS EOP (PC)</a> contains official publications of
maintained by the
<abbr title="International Earth Rotation Service">IERS</abbr>
<abbr title="Earth Orientation Parameters">EOP</abbr>
(<abbr title="Product Center">PC</abbr>)</a> contains official publications of
the Earth Orientation Parameters Product Center of the
International Earth Rotation Service, the committee that decides
when leap seconds occur.</li>
<li>The <a
href="http://www.mail-archive.com/leapsecs@rom.usno.navy.mil/">Leap
Second Discussion List</a> covers McCarthy and Klepczynski's proposal
to discontinue leap seconds, published in <a
href="http://www.gpsworld.com/">GPS World</a> <strong>10</strong>, 11
(1999-11), 50&ndash;57 and discussed further in R. A. Nelson et al.,
href="http://six.pairlist.net/mailman/listinfo/leapsecs">Leap
Second Discussion List</a> covers <a
href="http://gauss.gge.unb.ca/papers.pdf/gpsworld.november99.pdf">McCarthy
and Klepczynski's proposal to discontinue leap seconds</a>,
discussed further in
<a href="http://www.cl.cam.ac.uk/~mgk25/time/metrologia-leapsecond.pdf">The
leap second: its history and possible future</a>,
<a href="http://www.bipm.fr/metrologia/metrologia.html">Metrologia</a>
<strong>38</strong> (2001), 509&ndash;529.
<a href="http://www.ucolick.org/~sla/leapsecs/onlinebib.html">The
Future of Leap Seconds</a> catalogs information about this
leap second: its history and possible future</a>.
The (now disbanded) <a href="http://members.aas.org/comms/leap.cfm"><abbr
title="American Astronomical Society">AAS</abbr> Leap Second
Committee</a> has solicited input on this proposal.
<a href="http://www.ucolick.org/~sla/leapsecs/">The
Future of Leap Seconds</a> covers this
contentious issue.</li>
</ul>
<h2>Time notation</h2>
@ -403,41 +567,82 @@ contentious issue.</li>
<li>
<a href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">A Summary of
the International Standard Date and Time Notation</a> is a good
summary of ISO
8601:1988 - Data elements and interchange formats - Information interchange
- Representation of dates and times (which has been superseded by
<a href="http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=26780">ISO 8601:2000</a>).</li>
summary of
<a
href="http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=40874"><abbr
title="International Organization for Standardization">ISO</abbr>
8601:2004 -- Data elements and interchange formats -- Information
interchange -- Representation of dates and times</a>.</li>
<li>
Section 3.3 of <a
href="ftp://ftp.rfc-editor.org/in-notes/rfc2822.txt">Internet RFC 2822</a>
<a href="http://www.w3.org/TR/xmlschema-2/#dateTime"><abbr>XML</abbr>
Schema: Datatypes - dateTime</a> specifies a format inspired by
<abbr>ISO</abbr> 8601 that is in common use in XML data.</li>
<li>
<a href="ftp://ftp.rfc-editor.org/in-notes/rfc2822.txt">Internet
Message Format</a> (Internet <abbr>RFC</abbr> 2822) &sect;3.3
specifies the time notation used in email and <a
href="ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt">HTTP</a> headers.</li>
href="ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt"><abbr>HTTP</abbr></a>
headers.</li>
<li>
<a href="ftp://ftp.rfc-editor.org/in-notes/rfc3339.txt">Internet RFC
3339</a> specifies an ISO 8601 profile for use in new Internet
<a href="ftp://ftp.rfc-editor.org/in-notes/rfc3339.txt">Date and Time
on the Internet: Timestamps</a> (Internet <abbr>RFC</abbr> 3339)
specifies an <abbr>ISO</abbr> 8601
profile for use in new Internet
protocols.</li>
<li>
<a href="http://www.exit109.com/~ghealton/y2k/yrexamples.html">The
<a href="http://www.hackcraft.net/web/datetime/">Date &amp; Time
Formats on the Web</a> surveys web- and Internet-oriented date and time
formats.</li>
<li>
<a href="http://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>
Alphabetic time zone abbreviations should not be used as unique
identifiers for UTC offsets as they are ambiguous in practice. For
example, "EST" denotes 5 hours behind UTC in English-speaking North
America, but it denotes 10 or 11 hours ahead of UTC in Australia;
and French-speaking North Americans prefer "HNE" to "EST". For
compatibility with <a href="http://www.pasc.org/#POSIX">POSIX</a> the
<code>tz</code> database contains English abbreviations for all time
stamps but in many cases these are merely inventions of the database
<li>The <a
href="http://unicode.org/cldr/">Unicode Common Locale Data Repository
(<abbr>CLDR</abbr>) Project</a> has localizations for time zone names,
abbreviations, identifiers, and formats. For example, it contains
French translations for "Eastern European Summer Time", "<abbr
title="Eastern European Summer Time">EEST</abbr>", and
"Bucharest". <a
href="http://unicode.org/cldr/data/charts/by_type/names.metazone.html">By-Type
Chart: names.metazone</a> shows these values for many locales.
<abbr>ICU</abbr> contains a mechanism for using this data.</li>
<li>Alphabetic time zone abbreviations should not be used as unique
identifiers for <abbr>UTC</abbr> offsets as they are ambiguous in
practice. For example, "<abbr>EST</abbr>" denotes 5 hours behind
<abbr>UTC</abbr> in English-speaking North America, but it denotes 10
or 11 hours ahead of <abbr>UTC</abbr> in Australia; and
French-speaking North Americans prefer
"<abbr title="Heure Normale de l'Est">HNE</abbr>" to
"<abbr>EST</abbr>". For <abbr>POSIX</abbr> the <code>tz</code>
database contains English abbreviations for all time stamps but in
many cases these are merely inventions of the database
maintainers.</li>
<li>Numeric time zone abbreviations typically count hours east of
<abbr>UTC</abbr>, e.g., <code>+09</code> for Japan and
<code>-10</code> for Hawaii. However, the <abbr>POSIX</abbr>
<code>TZ</code> environment variable uses the opposite convention. For
example, one might use <code>TZ="JST-9"</code> and
<code>TZ="HST10"</code> for Japan and Hawaii, respectively. If the
<code>tz</code> database is available, it is usually better to use
settings like <code>TZ="Asia/Tokyo"</code> and
<code>TZ="Pacific/Honolulu"</code> instead, as this should avoid
confusion, handle old time stamps better, and insulate you better from
any future changes to the rules. One should never set
<abbr>POSIX</abbr> <code>TZ</code> to a value like
<code>"GMT-9"</code>, though, since this would falsely claim that
local time is nine hours ahead of <abbr>UTC</abbr> and the time zone
is called "<abbr>GMT</abbr>".</li>
</ul>
<h2>Related indexes</h2>
<ul>
<li><a href="tz-art.htm">Time and the Arts</a></li>
<li><a href="http://dmoz.org/Reference/Time/">Open Directory -
<li><a href="http://www.dmoz.org/Reference/Time/">Open Directory -
Reference: Time</a></li>
<li><a href="http://directory.google.com/Top/Reference/Time/">Google Directory - Reference &gt; Time</a></li>
<li><a href="http://dir.yahoo.com/Science/Measurements_and_Units/Time/">Yahoo! Science &gt; Measurements and Units &gt; Time</a></li>
<li><a href="http://directory.google.com/Top/Reference/Time/">Google Directory
- Reference &gt; Time</a></li>
<li><a href="http://dir.yahoo.com/Science/Measurements_and_Units/Time">Yahoo!
Directory &gt; Science &gt; Measurements and Units &gt; Time</a></li>
</ul>
</body>
</html>

View File

@ -1,4 +1,4 @@
.\" $NetBSD: tzfile.5,v 1.13 2009/03/09 19:24:27 joerg Exp $
.\" $NetBSD: tzfile.5,v 1.14 2009/12/31 22:49:16 mlelstv Exp $
.\"
.\" @(#)tzfile.5 7.11
.\" This file is in the public domain, so clarified as of
@ -17,7 +17,9 @@ The time zone information files used by
begin with the magic characters
.Dq TZif
to identify them as time zone information files,
followed by sixteen bytes reserved for future use,
followed by a character identifying the version of the file's format
(as of 2005, either an ASCII NUL or a '2')
followed by fifteen bytes containing zeroes reserved for future use,
followed by six four-byte values of type
.Fa long ,
written in a
@ -65,7 +67,10 @@ types described in the file is associated with the same-indexed
transition time.
These values serve as indices into an array of
.Fa ttinfo
structures that appears next in the file;
.I ttinfo
structures (with
.I tzh_typecnt
entries) that appears next in the file;
these structures are defined as follows:
.Bd -literal
struct ttinfo {
@ -136,7 +141,20 @@ if either
.Va tzh_timecnt
is zero or the time argument is less than the first transition time recorded
in the file.
.PP
For version-2-format time zone files,
the above header and data is followed by a second header and data,
identical in format except that
eight bytes are used for each transition time or leap second time.
After the second header and data comes a newline-enclosed,
POSIX-TZ-environment-variable-style string for use in handling instants
after the last transition time stored in the file
(with nothing between the newlines if there is no POSIX representation for
such instants).
.Sh SEE ALSO
.Xr ctime 3 ,
.Xr localtime 3 ,
.Xr time 3
.\" @(#)tzfile.5 8.2
.\" This file is in the public domain, so clarified as of
.\" 1996-06-05 by Arthur David Olson.

View File

@ -1,11 +1,11 @@
/* $NetBSD: tzfile.h,v 1.8 1998/01/22 07:06:59 jtc Exp $ */
/* $NetBSD: tzfile.h,v 1.9 2009/12/31 22:49:16 mlelstv Exp $ */
#ifndef TZFILE_H
#define TZFILE_H
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
** 1996-06-05 by Arthur David Olson.
*/
/*
@ -23,7 +23,7 @@
#ifndef lint
#ifndef NOID
#if 0
static char tzfilehid[] = "@(#)tzfile.h 7.14";
static char tzfilehid[] = "@(#)tzfile.h 8.1";
#endif
#endif /* !defined NOID */
#endif /* !defined lint */
@ -51,8 +51,9 @@ static char tzfilehid[] = "@(#)tzfile.h 7.14";
#define TZ_MAGIC "TZif"
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
char tzh_reserved[16]; /* reserved for future use */
char tzh_magic[4]; /* TZ_MAGIC */
char tzh_version[1]; /* '\0' or '2' as of 2005 */
char tzh_reserved[15]; /* reserved--must be zero */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
@ -86,19 +87,23 @@ struct tzhead {
** assumed to be local time
*/
/*
** If tzh_version is '2' or greater, the above is followed by a second instance
** of tzhead and a second instance of the data in which each coded transition
** time uses 8 rather than 4 chars,
** then a POSIX-TZ-environment-variable-style string for use in handling
** instants after the last transition time stored in the file
** (with nothing between the newlines if there is no POSIX representation for
** such instants).
*/
/*
** In the current implementation, "tzset()" refuses to deal with files that
** exceed any of the limits below.
*/
#ifndef TZ_MAX_TIMES
/*
** The TZ_MAX_TIMES value below is enough to handle a bit more than a
** year's worth of solar time (corrected daily to the nearest second) or
** 138 years of Pacific Presidential Election time
** (where there are three time zone transitions every fourth year).
*/
#define TZ_MAX_TIMES 370
#define TZ_MAX_TIMES 1200
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
@ -108,7 +113,7 @@ struct tzhead {
#ifdef NOSOLAR
/*
** Must be at least 14 for Europe/Riga as of Jan 12 1995,
** as noted by Earl Chew <earl@hpato.aus.hp.com>.
** as noted by Earl Chew.
*/
#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
#endif /* !defined NOSOLAR */
@ -159,33 +164,20 @@ struct tzhead {
#define EPOCH_YEAR 1970
#define EPOCH_WDAY TM_THURSDAY
/*
** Accurate only for the past couple of centuries;
** that will probably do.
*/
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#ifndef USG
/*
** Use of the underscored variants may cause problems if you move your code to
** certain System-V-based systems; for maximum portability, use the
** underscore-free variants. The underscored variants are provided for
** backward compatibility only; they may disappear from future versions of
** this file.
** Since everything in isleap is modulo 400 (or a factor of 400), we know that
** isleap(y) == isleap(y % 400)
** and so
** isleap(a + b) == isleap((a + b) % 400)
** or
** isleap(a + b) == isleap(a % 400 + b % 400)
** This is true even if % means modulo rather than Fortran remainder
** (which is allowed by C89 but not C99).
** We use this to avoid addition overflow problems.
*/
#define SECS_PER_MIN SECSPERMIN
#define MINS_PER_HOUR MINSPERHOUR
#define HOURS_PER_DAY HOURSPERDAY
#define DAYS_PER_WEEK DAYSPERWEEK
#define DAYS_PER_NYEAR DAYSPERNYEAR
#define DAYS_PER_LYEAR DAYSPERLYEAR
#define SECS_PER_HOUR SECSPERHOUR
#define SECS_PER_DAY SECSPERDAY
#define MONS_PER_YEAR MONSPERYEAR
#endif /* !defined USG */
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
#endif /* !defined TZFILE_H */

View File

@ -1,4 +1,4 @@
.\" $NetBSD: tzselect.8,v 1.3 1999/11/10 20:32:31 kleink Exp $
.\" $NetBSD: tzselect.8,v 1.4 2009/12/31 22:49:16 mlelstv Exp $
.\"
.TH TZSELECT 8
.SH NAME
@ -40,4 +40,6 @@ The exit status is zero if a time zone was successfully obtained from the user,
nonzero otherwise.
.SH "SEE ALSO"
newctime(3), tzfile(5), zdump(8), zic(8)
.\" @(#)tzselect.8 1.3
.\" @(#)tzselect.8 8.2
.\" This file is in the public domain, so clarified as of
.\" 2009-05-17 by Arthur David Olson.

View File

@ -1,13 +1,13 @@
#! /bin/ksh
#
# $NetBSD: tzselect.ksh,v 1.5 1999/11/10 20:32:31 kleink Exp $
# $NetBSD: tzselect.ksh,v 1.6 2009/12/31 22:49:16 mlelstv Exp $
#
# '@(#)tzselect.ksh 1.7'
VERSION='@(#)tzselect.ksh 8.2'
# Ask the user about the time zone, and output the resulting TZ value to stdout.
# Interact with the user via stderr and stdin.
# Contributed by Paul Eggert <eggert@twinsun.com>.
# Contributed by Paul Eggert.
# Porting notes:
#
@ -47,6 +47,21 @@
exit 1
}
if [ "$1" = "--help" ]; then
cat <<EOF
Usage: tzselect
Select a time zone interactively.
Report bugs to tz@elsie.nci.nih.gov.
EOF
exit 0
elif [ "$1" = "--version" ]; then
cat <<EOF
tzselect $VERSION
EOF
exit 0
fi
# Make sure the tables are readable.
TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab
TZ_ZONE_TABLE=$TZDIR/zone.tab

View File

@ -1,4 +1,4 @@
.\" $NetBSD: tzset.3,v 1.23 2009/03/10 23:25:32 joerg Exp $
.\" $NetBSD: tzset.3,v 1.24 2009/12/31 22:49:16 mlelstv Exp $
.Dd April 1, 2001
.Dt TZSET 3
.Os
@ -263,4 +263,6 @@ The
tzset()
function conforms to
.St -p1003.1-88 .
.\" @(#)newtzset.3 7.5
.\" @(#)newtzset.3 8.2
.\" This file is in the public domain, so clarified as of
.\" 2009-05-17 by Arthur David Olson.

View File

@ -1,4 +1,4 @@
.\" $NetBSD: zdump.8,v 1.6 2009/03/09 19:24:27 joerg Exp $
.\" $NetBSD: zdump.8,v 1.7 2009/12/31 22:49:16 mlelstv Exp $
.\" @(#)zdump.8 7.4
.Dd October 29, 2003
.Dt ZDUMP 8
@ -10,7 +10,7 @@
.Nm zdump
.Op Fl \-version
.Op Fl v
.Op Fl c Ar cutoffyear
.Op Fl c Ar [loyear,]highyear
.Op Ar zonename ...
.Sh DESCRIPTION
.Nm
@ -37,10 +37,25 @@ Each line ends with
if the given time is Daylight Saving Time or
.Dl isdst=0
otherwise.
.It Fl c Ar cutoffyear
Cut off the verbose output near the start of the given year.
.It Fl c Ar [loyear,]highyear
Cut off the verbose output near the start of the given year(s).
By default,
the program cuts off verbose output near the starts of the years -500 and 2500.
.El
.SH LIMITATIONS
The
.B \-v
option may not be used on systems with floating-point time_t values
that are neither float nor double.
.PP
Time discontinuities are found by sampling the results returned by localtime
at twelve-hour intervals.
This works in all real-world cases;
one can construct artificial time zones for which this fails.
.Sh SEE ALSO
.Xr ctime 3 ,
.Xr tzfile 5 ,
.Xr zic 8
.\" @(#)zdump.8 8.2
.\" This file is in the public domain, so clarified as of
.\" 2009-05-17 by Arthur David Olson.

View File

@ -1,13 +1,17 @@
/* $NetBSD: zdump.c,v 1.16 2006/12/04 17:24:40 kleink Exp $ */
/* $NetBSD: zdump.c,v 1.17 2009/12/31 22:49:16 mlelstv Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2009-05-17 by Arthur David Olson.
*/
#include <sys/cdefs.h>
#ifndef lint
#ifndef NOID
__RCSID("$NetBSD: zdump.c,v 1.16 2006/12/04 17:24:40 kleink Exp $");
__RCSID("$NetBSD: zdump.c,v 1.17 2009/12/31 22:49:16 mlelstv Exp $");
#endif /* !defined NOID */
#endif /* !defined lint */
static char elsieid[] = "@(#)zdump.c 7.31";
static char elsieid[] = "@(#)zdump.c 8.9";
/*
** This code has been made independent of the rest of the time
@ -21,6 +25,19 @@ static char elsieid[] = "@(#)zdump.c 7.31";
#include "time.h" /* for struct tm */
#include "stdlib.h" /* for exit, malloc, atoi */
#include <err.h>
#include "float.h" /* for FLT_MAX and DBL_MAX */
#include "ctype.h" /* for isalpha et al. */
#ifndef isascii
#define isascii(x) 1
#endif /* !defined isascii */
#ifndef ZDUMP_LO_YEAR
#define ZDUMP_LO_YEAR (-500)
#endif /* !defined ZDUMP_LO_YEAR */
#ifndef ZDUMP_HI_YEAR
#define ZDUMP_HI_YEAR 2500
#endif /* !defined ZDUMP_HI_YEAR */
#ifndef MAX_STRING_LENGTH
#define MAX_STRING_LENGTH 1024
@ -71,19 +88,32 @@ static char elsieid[] = "@(#)zdump.c 7.31";
#endif /* !defined DAYSPERNYEAR */
#ifndef isleap
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#endif /* !defined isleap */
#if HAVE_GETTEXT - 0
#ifndef isleap_sum
/*
** See tzfile.h for details on isleap_sum.
*/
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
#endif /* !defined isleap_sum */
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR)
#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY)
#ifndef HAVE_GETTEXT
#define HAVE_GETTEXT 0
#endif
#if HAVE_GETTEXT
#include "locale.h" /* for setlocale */
#include "libintl.h"
#endif /* HAVE_GETTEXT - 0 */
#endif /* HAVE_GETTEXT */
#ifndef GNUC_or_lint
#ifdef lint
#define GNUC_or_lint
#endif /* defined lint */
#ifndef lint
#else /* !defined lint */
#ifdef __GNUC__
#define GNUC_or_lint
#endif /* defined __GNUC__ */
@ -93,8 +123,7 @@ static char elsieid[] = "@(#)zdump.c 7.31";
#ifndef INITIALIZE
#ifdef GNUC_or_lint
#define INITIALIZE(x) ((x) = 0)
#endif /* defined GNUC_or_lint */
#ifndef GNUC_or_lint
#else /* !defined GNUC_or_lint */
#define INITIALIZE(x)
#endif /* !defined GNUC_or_lint */
#endif /* !defined INITIALIZE */
@ -106,34 +135,125 @@ static char elsieid[] = "@(#)zdump.c 7.31";
*/
#ifndef _
#if HAVE_GETTEXT - 0
#if HAVE_GETTEXT
#define _(msgid) gettext(msgid)
#else /* !(HAVE_GETTEXT - 0) */
#define _(msgid) msgid
#endif /* !(HAVE_GETTEXT - 0) */
#else /* !HAVE_GETTEXT */
#define _(msgid) __UNCONST(msgid)
#endif /* !HAVE_GETTEXT */
#endif /* !defined _ */
#ifndef TZ_DOMAIN
#define TZ_DOMAIN "tz"
#endif /* !defined TZ_DOMAIN */
#ifndef P
#define P(x) x
#endif /* !defined P */
extern char ** environ;
extern int getopt P((int argc, char * const argv[],
const char * options));
extern int getopt(int argc, char * const argv[],
const char * options);
extern char * optarg;
extern int optind;
static const char * abbr P((struct tm * tmp));
static long delta P((struct tm * newp, struct tm * oldp));
static time_t hunt P((char * name, time_t lot, time_t hit));
int main P((int, char **));
static time_t absolute_min_time;
static time_t absolute_max_time;
static size_t longest;
static char * progname;
static void show P((char * zone, time_t t, int v));
static int warned;
static const char * abbr(struct tm * tmp);
static void abbrok(const char * abbrp, const char * zone);
static long delta(struct tm * newp, struct tm * oldp);
static void dumptime(const struct tm * tmp);
static time_t hunt(char * name, time_t lot, time_t hit);
int main(int, char **);
static void setabsolutes(void);
static void show(char * zone, time_t t, int v);
static const char * tformat(void);
static time_t yeartot(long y);
#ifndef TYPECHECK
#define my_localtime localtime
#else /* !defined TYPECHECK */
static struct tm *
my_localtime(tp)
time_t * tp;
{
register struct tm * tmp;
tmp = localtime(tp);
if (tp != NULL && tmp != NULL) {
struct tm tm;
register time_t t;
tm = *tmp;
t = mktime(&tm);
if (t - *tp >= 1 || *tp - t >= 1) {
(void) fflush(stdout);
(void) fprintf(stderr, "\n%s: ", progname);
(void) fprintf(stderr, tformat(), *tp);
(void) fprintf(stderr, " ->");
(void) fprintf(stderr, " year=%d", tmp->tm_year);
(void) fprintf(stderr, " mon=%d", tmp->tm_mon);
(void) fprintf(stderr, " mday=%d", tmp->tm_mday);
(void) fprintf(stderr, " hour=%d", tmp->tm_hour);
(void) fprintf(stderr, " min=%d", tmp->tm_min);
(void) fprintf(stderr, " sec=%d", tmp->tm_sec);
(void) fprintf(stderr, " isdst=%d", tmp->tm_isdst);
(void) fprintf(stderr, " -> ");
(void) fprintf(stderr, tformat(), t);
(void) fprintf(stderr, "\n");
}
}
return tmp;
}
#endif /* !defined TYPECHECK */
static void
abbrok(abbrp, zone)
const char * const abbrp;
const char * const zone;
{
register const char * cp;
register char * wp;
if (warned)
return;
cp = abbrp;
wp = NULL;
while (isascii((unsigned char) *cp) && isalpha((unsigned char) *cp))
++cp;
if (cp - abbrp == 0)
wp = _("lacks alphabetic at start");
else if (cp - abbrp < 3)
wp = _("has fewer than 3 alphabetics");
else if (cp - abbrp > 6)
wp = _("has more than 6 alphabetics");
if (wp == NULL && (*cp == '+' || *cp == '-')) {
++cp;
if (isascii((unsigned char) *cp) &&
isdigit((unsigned char) *cp))
if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
++cp;
if (*cp != '\0')
wp = _("differs from POSIX standard");
}
if (wp == NULL)
return;
(void) fflush(stdout);
(void) fprintf(stderr,
_("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"),
progname, zone, abbrp, wp);
warned = TRUE;
}
static void
usage(const char *xprogname, FILE *stream, int status)
{
(void) fprintf(stream,
_("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n\
\n\
Report bugs to tz@elsie.nci.nih.gov.\n"),
xprogname, xprogname);
exit(status);
}
int
main(argc, argv)
@ -143,65 +263,79 @@ char * argv[];
register int i;
register int c;
register int vflag;
register char * cutoff;
register int cutyear;
register long cuttime;
char ** fakeenv;
register char * cutarg;
register long cutloyear = ZDUMP_LO_YEAR;
register long cuthiyear = ZDUMP_HI_YEAR;
register time_t cutlotime;
register time_t cuthitime;
register char ** fakeenv;
time_t now;
time_t t;
time_t newt;
time_t hibit;
struct tm tm;
struct tm newtm;
register struct tm * tmp;
register struct tm * newtmp;
INITIALIZE(cuttime);
#if HAVE_GETTEXT - 0
(void) setlocale(LC_MESSAGES, "");
INITIALIZE(cutlotime);
INITIALIZE(cuthitime);
#if HAVE_GETTEXT
(void) setlocale(LC_ALL, "");
#ifdef TZ_DOMAINDIR
(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined(TEXTDOMAINDIR) */
#endif /* defined TEXTDOMAINDIR */
(void) textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT - 0 */
#endif /* HAVE_GETTEXT */
progname = argv[0];
for (i = 1; i < argc; ++i)
if (strcmp(argv[i], "--version") == 0) {
(void) printf("%s\n", elsieid);
(void) exit(EXIT_SUCCESS);
exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "--help") == 0) {
usage(progname, stdout, EXIT_SUCCESS);
}
vflag = 0;
cutoff = NULL;
cutarg = NULL;
while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
if (c == 'v')
vflag = 1;
else cutoff = optarg;
else cutarg = optarg;
if ((c != EOF && c != -1) ||
(optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
(void) fprintf(stderr,
_("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"),
argv[0], argv[0]);
(void) exit(EXIT_FAILURE);
usage(progname, stderr, EXIT_FAILURE);
}
if (cutoff != NULL) {
int y;
if (vflag) {
if (cutarg != NULL) {
long lo;
long hi;
char dummy;
cutyear = atoi(cutoff);
cuttime = 0;
for (y = EPOCH_YEAR; y < cutyear; ++y)
cuttime += DAYSPERNYEAR + isleap(y);
cuttime *= SECSPERHOUR * HOURSPERDAY;
if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) {
cuthiyear = hi;
} else if (sscanf(cutarg, "%ld,%ld%c",
&lo, &hi, &dummy) == 2) {
cutloyear = lo;
cuthiyear = hi;
} else {
(void) fprintf(stderr, _("%s: wild -c argument %s\n"),
progname, cutarg);
exit(EXIT_FAILURE);
}
}
setabsolutes();
cutlotime = yeartot(cutloyear);
cuthitime = yeartot(cuthiyear);
}
(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;
for (i = 0; environ[i] != NULL; ++i)
for (i = 0; environ[i] != NULL; ++i)
continue;
fakeenv = (char **) malloc((size_t) ((i + 2) *
sizeof *fakeenv));
@ -226,43 +360,43 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"),
show(argv[i], now, FALSE);
continue;
}
/*
** Get lowest value of t.
*/
t = hibit;
if (t > 0) /* time_t is unsigned */
t = 0;
warned = FALSE;
t = absolute_min_time;
show(argv[i], t, TRUE);
t += SECSPERHOUR * HOURSPERDAY;
show(argv[i], t, TRUE);
tm = *localtime(&t);
(void) strlcpy(buf, abbr(&tm), (sizeof buf));
if (t < cutlotime)
t = cutlotime;
tmp = my_localtime(&t);
if (tmp != NULL) {
tm = *tmp;
(void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
}
for ( ; ; ) {
if (cutoff != NULL && t >= cuttime)
if (t >= cuthitime || t >= cuthitime - SECSPERHOUR * 12)
break;
newt = t + SECSPERHOUR * 12;
if (cutoff != NULL && newt >= cuttime)
break;
if (newt <= t)
break;
newtm = *localtime(&newt);
if (delta(&newtm, &tm) != (newt - t) ||
newtmp = localtime(&newt);
if (newtmp != NULL)
newtm = *newtmp;
if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
(delta(&newtm, &tm) != (newt - t) ||
newtm.tm_isdst != tm.tm_isdst ||
strcmp(abbr(&newtm), buf) != 0) {
strcmp(abbr(&newtm), buf) != 0)) {
newt = hunt(argv[i], t, newt);
newtm = *localtime(&newt);
(void) strlcpy(buf, abbr(&newtm),
(sizeof buf));
newtmp = localtime(&newt);
if (newtmp != NULL) {
newtm = *newtmp;
(void) strncpy(buf,
abbr(&newtm),
(sizeof buf) - 1);
}
}
t = newt;
tm = newtm;
tmp = newtmp;
}
/*
** Get highest value of t.
*/
t = ~((time_t) 0);
if (t < 0) /* time_t is signed */
t &= ~hibit;
t = absolute_max_time;
t -= SECSPERHOUR * HOURSPERDAY;
show(argv[i], t, TRUE);
t += SECSPERHOUR * HOURSPERDAY;
@ -272,37 +406,123 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"),
err(EXIT_FAILURE, _("Error writing standard output"));
}
exit(EXIT_SUCCESS);
/* If exit fails to exit... */
return EXIT_FAILURE;
}
/* gcc -Wall pacifier */
for ( ; ; )
continue;
static void
setabsolutes(void)
{
if (0.5 == (time_t) 0.5) {
/*
** time_t is floating.
*/
if (sizeof (time_t) == sizeof (float)) {
absolute_min_time = (time_t) -FLT_MAX;
absolute_max_time = (time_t) FLT_MAX;
} else if (sizeof (time_t) == sizeof (double)) {
absolute_min_time = (time_t) -DBL_MAX;
absolute_max_time = (time_t) DBL_MAX;
} else {
(void) fprintf(stderr,
_("%s: use of -v on system with floating time_t other than float or double\n"),
progname);
exit(EXIT_FAILURE);
}
} else if (0 > (time_t) -1) {
/*
** time_t is signed. Assume overflow wraps around.
*/
time_t t = 0;
time_t t1 = 1;
while (t < t1) {
t = t1;
t1 = 2 * t1 + 1;
}
absolute_max_time = t;
t = -t;
absolute_min_time = t - 1;
if (t < absolute_min_time)
absolute_min_time = t;
} else {
/*
** time_t is unsigned.
*/
absolute_min_time = 0;
absolute_max_time = absolute_min_time - 1;
}
}
static time_t
hunt(name, lot, hit)
char * name;
time_t lot;
time_t hit;
yeartot(y)
const long y;
{
time_t t;
struct tm lotm;
struct tm tm;
static char loab[MAX_STRING_LENGTH];
register long myy;
register long seconds;
register time_t t;
lotm = *localtime(&lot);
(void) strlcpy(loab, abbr(&lotm), (sizeof loab));
while ((hit - lot) >= 2) {
t = lot / 2 + hit / 2;
myy = EPOCH_YEAR;
t = 0;
while (myy != y) {
if (myy < y) {
seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
++myy;
if (t > absolute_max_time - seconds) {
t = absolute_max_time;
break;
}
t += seconds;
} else {
--myy;
seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
if (t < absolute_min_time + seconds) {
t = absolute_min_time;
break;
}
t -= seconds;
}
}
return t;
}
static time_t
hunt(char *name, time_t lot, time_t hit)
{
time_t t;
long diff;
struct tm lotm;
register struct tm * lotmp;
struct tm tm;
register struct tm * tmp;
char loab[MAX_STRING_LENGTH];
lotmp = my_localtime(&lot);
if (lotmp != NULL) {
lotm = *lotmp;
(void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
}
for ( ; ; ) {
diff = (long) (hit - lot);
if (diff < 2)
break;
t = lot;
t += diff / 2;
if (t <= lot)
++t;
else if (t >= hit)
--t;
tm = *localtime(&t);
if (delta(&tm, &lotm) == (t - lot) &&
tmp = my_localtime(&t);
if (tmp != NULL)
tm = *tmp;
if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) :
(delta(&tm, &lotm) == (t - lot) &&
tm.tm_isdst == lotm.tm_isdst &&
strcmp(abbr(&tm), loab) == 0) {
strcmp(abbr(&tm), loab) == 0)) {
lot = t;
lotm = tm;
lotmp = tmp;
} else hit = t;
}
show(name, lot, TRUE);
@ -311,7 +531,7 @@ time_t hit;
}
/*
** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta.
** Thanks to Paul Eggert for logic used in delta.
*/
static long
@ -319,14 +539,14 @@ delta(newp, oldp)
struct tm * newp;
struct tm * oldp;
{
long result;
int tmy;
register long result;
register int tmy;
if (newp->tm_year < oldp->tm_year)
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_sum(tmy, TM_YEAR_BASE);
result += newp->tm_yday - oldp->tm_yday;
result *= HOURSPERDAY;
result += newp->tm_hour - oldp->tm_hour;
@ -338,27 +558,36 @@ struct tm * oldp;
}
static void
show(zone, t, v)
char * zone;
time_t t;
int v;
show(char *zone, time_t t, int v)
{
struct tm * tmp;
register struct tm * tmp;
(void) printf("%-*s ", (int) longest, zone);
if (v)
(void) printf("%.24s UTC = ", asctime(gmtime(&t)));
tmp = localtime(&t);
(void) printf("%.24s", asctime(tmp));
if (*abbr(tmp) != '\0')
(void) printf(" %s", abbr(tmp));
if (v) {
(void) printf(" isdst=%d", tmp->tm_isdst);
tmp = gmtime(&t);
if (tmp == NULL) {
(void) printf(tformat(), t);
} else {
dumptime(tmp);
(void) printf(" UTC");
}
(void) printf(" = ");
}
tmp = my_localtime(&t);
dumptime(tmp);
if (tmp != NULL) {
if (*abbr(tmp) != '\0')
(void) printf(" %s", abbr(tmp));
if (v) {
(void) printf(" isdst=%d", tmp->tm_isdst);
#ifdef TM_GMTOFF
(void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
(void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
#endif /* defined TM_GMTOFF */
}
}
(void) printf("\n");
if (tmp != NULL && *abbr(tmp) != '\0')
abbrok(abbr(tmp), zone);
}
static const char *
@ -373,3 +602,84 @@ struct tm * tmp;
result = tzname[tmp->tm_isdst];
return (result == NULL) ? &nada : result;
}
/*
** The code below can fail on certain theoretical systems;
** it works on all known real-world systems as of 2004-12-30.
*/
static const char *
tformat(void)
{
if (0.5 == (time_t) 0.5) { /* floating */
if (sizeof (time_t) > sizeof (double))
return "%Lg";
return "%g";
}
if (0 > (time_t) -1) { /* signed */
if (sizeof (time_t) > sizeof (long))
return "%lld";
if (sizeof (time_t) > sizeof (int))
return "%ld";
return "%d";
}
if (sizeof (time_t) > sizeof (unsigned long))
return "%llu";
if (sizeof (time_t) > sizeof (unsigned int))
return "%lu";
return "%u";
}
static void
dumptime(timeptr)
register const struct tm * timeptr;
{
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;
register int lead;
register int trail;
if (timeptr == NULL) {
(void) printf("NULL");
return;
}
/*
** The packaged versions of localtime and gmtime never put out-of-range
** values in tm_wday or tm_mon, but since this code might be compiled
** with other (perhaps experimental) versions, paranoia is in order.
*/
if (timeptr->tm_wday < 0 || timeptr->tm_wday >=
(int) (sizeof wday_name / sizeof wday_name[0]))
wn = "???";
else wn = wday_name[timeptr->tm_wday];
if (timeptr->tm_mon < 0 || timeptr->tm_mon >=
(int) (sizeof mon_name / sizeof mon_name[0]))
mn = "???";
else mn = mon_name[timeptr->tm_mon];
(void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d ",
wn, mn,
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec);
#define DIVISOR 10
trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
trail / DIVISOR;
trail %= DIVISOR;
if (trail < 0 && lead > 0) {
trail += DIVISOR;
--lead;
} else if (lead < 0 && trail > 0) {
trail -= DIVISOR;
++lead;
}
if (lead == 0)
(void) printf("%d", trail);
else (void) printf("%d%d", lead, ((trail < 0) ? -trail : trail));
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: zic.8,v 1.15 2009/03/09 19:24:27 joerg Exp $
.\" $NetBSD: zic.8,v 1.16 2009/12/31 22:49:16 mlelstv Exp $
.\" @(#)zic.8 7.22
.Dd December 20, 2003
.Dt ZIC 8
@ -222,7 +222,12 @@ the variable part is null.
.El
.Pp
A zone line has the form
.Dl Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL]
.sp
.nf
.ti +.5i
.ta \w'Zone\0\0'u +\w'Australia/Adelaide\0\0'u +\w'GMTOFF\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u
Zone NAME GMTOFF RULES/SAVE FORMAT [UNTILYEAR [MONTH [DAY [TIME]]]]
.sp
For example:
.Dl Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00
The fields that make up a zone line are:
@ -256,16 +261,17 @@ Alternatively,
a slash
.Pq \&/
separates standard and daylight abbreviations.
.It UNTIL
.TP
.B UNTILYEAR [MONTH [DAY [TIME]]]
The time at which the UTC offset or the rule(s) change for a location.
It is specified as a year, a month, a day, and a time of day.
If this is specified,
the time zone information is generated from the given UTC offset
and rule change until the time specified.
The month, day, and time of day have the same format as the IN, ON, and AT
columns of a rule; trailing columns can be omitted, and default to the
earliest possible value for the missing columns.
.El
fields of a rule; trailing fields can be omitted, and default to the
earliest possible value for the missing fields.
.IP
The next line must be a
.Dq continuation
line; this has the same form as a zone line except that the
@ -273,11 +279,11 @@ string
.Dq Zone
and the name are omitted, as the continuation line will
place information starting at the time specified as the
.Em UNTIL
field in the previous line in the file used by the previous line.
Continuation lines may contain an
.Em UNTIL
field, just as zone lines do, indicating that the next line is a further
.q until
information in the previous line in the file used by the previous line.
Continuation lines may contain
.q until
information, just as zone lines do, indicating that the next line is a further
continuation.
.Pp
A link line has the form
@ -338,13 +344,81 @@ or
.Dq Rolling
if the leap second time given by the other fields should be interpreted as
local wall clock time.
.El
.Sh NOTES
.SH "EXTENDED EXAMPLE"
Here is an extended example of
.I zic
input, intended to illustrate many of its features.
.br
.ne 22
.nf
.in +2m
.ta \w'# Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u
.sp
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Swiss 1940 only - Nov 2 0:00 1:00 S
Rule Swiss 1940 only - Dec 31 0:00 0 -
Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S
Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0
.sp .5
Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
Rule EU 1977 only - Sep lastSun 1:00u 0 -
Rule EU 1978 only - Oct 1 1:00u 0 -
Rule EU 1979 1995 - Sep lastSun 1:00u 0 -
Rule EU 1981 max - Mar lastSun 1:00u 1:00 S
Rule EU 1996 max - Oct lastSun 1:00u 0 -
.sp
.ta \w'# Zone\0\0'u +\w'Europe/Zurich\0\0'u +\w'0:34:08\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u
# Zone NAME GMTOFF RULES FORMAT UNTIL
Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12
0:29:44 - BMT 1894 Jun
1:00 Swiss CE%sT 1981
1:00 EU CE%sT
.sp
Link Europe/Zurich Switzerland
.sp
.in
.fi
In this example, the zone is named Europe/Zurich but it has an alias
as Switzerland. Zurich was 34 minutes and 8 seconds west of GMT until
1848-09-12 at 00:00, when the offset changed to 29 minutes and 44
seconds. After 1894-06-01 at 00:00 Swiss daylight saving rules (defined
with lines beginning with "Rule Swiss") apply, and the GMT offset
became one hour. From 1981 to the present, EU daylight saving rules have
applied, and the UTC offset has remained at one hour.
.PP
In 1940, daylight saving time applied from November 2 at 00:00 to
December 31 at 00:00. In 1941 and 1942, daylight saving time applied
from the first Sunday in May at 02:00 to the first Sunday in October
at 00:00.
The pre-1981 EU daylight-saving rules have no effect
here, but are included for completeness. Since 1981, daylight
saving has begun on the last Sunday in March at 01:00 UTC.
Until 1995 it ended the last Sunday in September at 01:00 UTC,
but this changed to the last Sunday in October starting in 1996.
.PP
For purposes of
display, "LMT" and "BMT" were initially used, respectively. Since
Swiss rules and later EU rules were applied, the display name for the
timezone has been CET for standard time and CEST for daylight saving
time.
.SH NOTES
For areas with more than two types of local time,
you may need to use local standard time in the
.Em AT
field of the earliest transition time's rule to ensure that
the earliest transition time recorded in the compiled file is correct.
.PP
If,
for a particular zone,
a clock advance caused by the start of daylight saving
coincides with and is equal to
a clock retreat caused by a change in UTC offset,
.IR zic
produces a single transition to daylight saving at the new UTC offset
(without any change in wall clock time).
To get separate transitions
use multiple zone continuation lines
specifying transition instants using universal time.
.Sh FILES
.Pa /usr/share/zoneinfo
- standard directory used for created files
@ -352,3 +426,6 @@ the earliest transition time recorded in the compiled file is correct.
.Xr ctime 3 ,
.Xr tzfile 5 ,
.Xr zdump 8
.\" @(#)zic.8 8.5
.\" This file is in the public domain, so clarified as of
.\" 2009-05-17 by Arthur David Olson.

File diff suppressed because it is too large Load Diff