mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-04 15:40:44 +00:00
Bring our tzcode up to date.
* Replay 2010[acflm] which had been merged but not recorded. * Merge 2010n. * Reorganize (unsplit) the code to match the upstream layout. * Merge 2022[cdefg]. MFC after: 1 week Sponsored by: Klara, Inc.
This commit is contained in:
commit
bc42155199
97
contrib/tzcode/CONTRIBUTING
Normal file
97
contrib/tzcode/CONTRIBUTING
Normal file
|
@ -0,0 +1,97 @@
|
|||
# Contributing to the tz code and data
|
||||
|
||||
Please do not create issues or pull requests on GitHub, as the
|
||||
proper procedure for proposing and distributing patches is via
|
||||
email as described below.
|
||||
|
||||
The time zone database is by no means authoritative: governments
|
||||
change timekeeping rules erratically and sometimes with little
|
||||
warning, the data entries do not cover all of civil time before
|
||||
1970, and undoubtedly errors remain in the code and data. Feel
|
||||
free to fill gaps or fix mistakes, and please email improvements
|
||||
to <tz@iana.org> for use in the future. In your email, please give
|
||||
reliable sources that reviewers can check.
|
||||
|
||||
## Contributing technical changes
|
||||
|
||||
To email small changes, please run a POSIX shell command like
|
||||
'diff -u old/europe new/europe >myfix.patch', and attach
|
||||
'myfix.patch' to the email.
|
||||
|
||||
For more-elaborate or possibly-controversial changes,
|
||||
such as renaming, adding or removing zones, please read
|
||||
"Theory and pragmatics of the tz code and data"
|
||||
<https://www.iana.org/time-zones/repository/theory.html>.
|
||||
It is also good to browse the mailing list archives
|
||||
<https://mm.icann.org/pipermail/tz/> for examples of patches that tend
|
||||
to work well. Additions to data should contain commentary citing
|
||||
reliable sources as justification. Citations should use "https:" URLs
|
||||
if available.
|
||||
|
||||
For changes that fix sensitive security-related bugs, please see the
|
||||
distribution's 'SECURITY' file.
|
||||
|
||||
Please submit changes against either the latest release
|
||||
<https://www.iana.org/time-zones> or the main branch of the development
|
||||
repository. The latter is preferred.
|
||||
|
||||
## Sample Git workflow for developing contributions
|
||||
|
||||
If you use Git the following workflow may be helpful:
|
||||
|
||||
* Copy the development repository.
|
||||
|
||||
git clone https://github.com/eggert/tz.git
|
||||
cd tz
|
||||
|
||||
* Get current with the main branch.
|
||||
|
||||
git checkout main
|
||||
git pull
|
||||
|
||||
* Switch to a new branch for the changes. Choose a different
|
||||
branch name for each change set.
|
||||
|
||||
git checkout -b mybranch
|
||||
|
||||
* Sleuth by using 'git blame'. For example, when fixing data for
|
||||
Africa/Sao_Tome, if the command 'git blame africa' outputs a line
|
||||
'2951fa3b (Paul Eggert 2018-01-08 09:03:13 -0800 1068) Zone
|
||||
Africa/Sao_Tome 0:26:56 - LMT 1884', commit 2951fa3b should
|
||||
provide some justification for the 'Zone Africa/Sao_Tome' line.
|
||||
|
||||
* Edit source files. Include commentary that justifies the
|
||||
changes by citing reliable sources.
|
||||
|
||||
* Debug the changes, e.g.:
|
||||
|
||||
make check
|
||||
make install
|
||||
./zdump -v America/Los_Angeles
|
||||
|
||||
* For each separable change, commit it in the new branch, e.g.:
|
||||
|
||||
git add northamerica
|
||||
git commit
|
||||
|
||||
See recent 'git log' output for the commit-message style.
|
||||
|
||||
* Create patch files 0001-..., 0002-..., ...
|
||||
|
||||
git format-patch main
|
||||
|
||||
* After reviewing the patch files, send the patches to <tz@iana.org>
|
||||
for others to review.
|
||||
|
||||
git send-email main
|
||||
|
||||
For an archived example of such an email, see
|
||||
"[PROPOSED] Fix off-by-1 error for Jamaica and T&C before 1913"
|
||||
<https://mm.icann.org/pipermail/tz/2018-February/026122.html>.
|
||||
|
||||
* Start anew by getting current with the main branch again
|
||||
(the second step above).
|
||||
|
||||
-----
|
||||
|
||||
This file is in the public domain.
|
5
contrib/tzcode/LICENSE
Normal file
5
contrib/tzcode/LICENSE
Normal file
|
@ -0,0 +1,5 @@
|
|||
Unless specified below, all files in the tz code and data (including
|
||||
this LICENSE file) are in the public domain.
|
||||
|
||||
If the files date.c, newstrftime.3, and strftime.c are present, they
|
||||
contain material derived from BSD and use the BSD 3-clause license.
|
1250
contrib/tzcode/Makefile
Normal file
1250
contrib/tzcode/Makefile
Normal file
File diff suppressed because it is too large
Load diff
5902
contrib/tzcode/NEWS
Normal file
5902
contrib/tzcode/NEWS
Normal file
File diff suppressed because it is too large
Load diff
52
contrib/tzcode/README
Normal file
52
contrib/tzcode/README
Normal file
|
@ -0,0 +1,52 @@
|
|||
README for the tz distribution
|
||||
|
||||
"Where do I set the hands of the clock?" -- Les Tremayne as The King
|
||||
"Oh that--you can set them any place you want." -- Frank Baxter as The Scientist
|
||||
(from the Bell System film "About Time")
|
||||
|
||||
The Time Zone Database (called tz, tzdb or zoneinfo) 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 time zone boundaries, UTC offsets,
|
||||
and daylight-saving rules.
|
||||
|
||||
See <https://www.iana.org/time-zones/repository/tz-link.html> or the
|
||||
file tz-link.html for how to acquire the code and data. Once acquired,
|
||||
read the comments in the file 'Makefile' and make any changes needed
|
||||
to make things right for your system, especially if you are using some
|
||||
platform other than GNU/Linux. Then run the following commands,
|
||||
substituting your desired installation directory for "$HOME/tzdir":
|
||||
|
||||
make TOPDIR=$HOME/tzdir install
|
||||
$HOME/tzdir/usr/bin/zdump -v America/Los_Angeles
|
||||
|
||||
See the file tz-how-to.html for examples of how to read the data files.
|
||||
|
||||
This database of historical local time information has several goals:
|
||||
|
||||
* Provide a compendium of data about the history of civil time that
|
||||
is useful even if not 100% accurate.
|
||||
|
||||
* Give an idea of the variety of local time rules that have existed
|
||||
in the past and thus may be expected in the future.
|
||||
|
||||
* Test the generality of the local time rule description system.
|
||||
|
||||
The information in the time zone data files is by no means authoritative;
|
||||
fixes and enhancements are welcome. Please see the file CONTRIBUTING
|
||||
for details.
|
||||
|
||||
Thanks to these Time Zone Caballeros who've made major contributions to the
|
||||
time conversion package: Keith Bostic; Bob Devine; Paul Eggert; Robert Elz;
|
||||
Guy Harris; Mark Horton; John Mackin; and Bradley White. Thanks also to
|
||||
Michael Bloom, Art Neilson, Stephen Prince, John Sovereign, and Frank Wales
|
||||
for testing work, and to Gwillim Law for checking local mean time data.
|
||||
Thanks in particular to Arthur David Olson, the project's founder and first
|
||||
maintainer, to whom the time zone community owes the greatest debt of all.
|
||||
None of them are responsible for remaining errors.
|
||||
|
||||
-----
|
||||
|
||||
This file is in the public domain, so clarified as of 2009-05-17 by
|
||||
Arthur David Olson. The other files in this distribution are either
|
||||
public domain or BSD licensed; see the file LICENSE for details.
|
15
contrib/tzcode/SECURITY
Normal file
15
contrib/tzcode/SECURITY
Normal file
|
@ -0,0 +1,15 @@
|
|||
Please report any sensitive security-related bugs via email to the
|
||||
tzdb designated coordinators, currently Paul Eggert
|
||||
<eggert@cs.ucla.edu> and Tim Parenti <tim@timtimeonline.com>.
|
||||
Put "tzdb security" at the start of your email's subject line.
|
||||
We prefer communications to be in English.
|
||||
|
||||
You should receive a response within a week. If not, please follow up
|
||||
via email to make sure we received your original message.
|
||||
|
||||
If we confirm the bug, we plan to notify affected third-party services
|
||||
or software that we know about, prepare an advisory, commit fixes to
|
||||
the main development branch as quickly as is practical, and finally
|
||||
publish the advisory on tz@iana.org. As with all tzdb contributions,
|
||||
we give credit to security contributors unless they wish to remain
|
||||
anonymous.
|
|
@ -1,3 +1,5 @@
|
|||
/* asctime and asctime_r a la POSIX and ISO C, except pad years before 1000. */
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
|
@ -9,27 +11,13 @@
|
|||
** whereas the output of asctime is supposed to be constant.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] __unused = "@(#)asctime.c 8.5";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include "private.h"
|
||||
#include "un-namespace.h"
|
||||
#include "tzfile.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
** 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.
|
||||
|
@ -39,61 +27,45 @@ __FBSDID("$FreeBSD$");
|
|||
** 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,
|
||||
** The ISO C and POSIX 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__ */
|
||||
static char const ASCTIME_FMT[] = "%s %s%3d %.2d:%.2d:%.2d %-4s\n";
|
||||
/*
|
||||
** 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__ */
|
||||
static char const ASCTIME_FMT_B[] = "%s %s%3d %.2d:%.2d:%.2d %s\n";
|
||||
|
||||
#define STD_ASCTIME_BUF_SIZE 26
|
||||
enum { 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).
|
||||
** and a trailing NUL byte).
|
||||
** 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
|
||||
** as an example; the size expression below is a bound 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.
|
||||
*/
|
||||
static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
|
||||
|
||||
char *
|
||||
asctime_r(timeptr, buf)
|
||||
const struct tm * timeptr;
|
||||
char * buf;
|
||||
asctime_r(register const struct tm *timeptr, char *buf)
|
||||
{
|
||||
static const char wday_name[][3] = {
|
||||
static const char wday_name[][4] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
};
|
||||
static const char mon_name[][3] = {
|
||||
static const char mon_name[][4] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
const char * wn;
|
||||
const char * mn;
|
||||
char year[INT_STRLEN_MAXIMUM(int) + 2];
|
||||
char result[MAX_ASCTIME_BUF_SIZE];
|
||||
char result[sizeof buf_asctime];
|
||||
|
||||
if (timeptr == NULL) {
|
||||
errno = EINVAL;
|
||||
|
@ -111,11 +83,11 @@ char * buf;
|
|||
** Assume that strftime is unaffected by other out-of-range members
|
||||
** (e.g., timeptr->tm_mday) when processing "%Y".
|
||||
*/
|
||||
(void) strftime(year, sizeof year, "%Y", timeptr);
|
||||
strftime(year, sizeof year, "%Y", timeptr);
|
||||
/*
|
||||
** We avoid using snprintf since it's not available on all systems.
|
||||
*/
|
||||
(void) sprintf(result,
|
||||
sprintf(result,
|
||||
((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
|
||||
wn, mn,
|
||||
timeptr->tm_mday, timeptr->tm_hour,
|
||||
|
@ -124,22 +96,13 @@ char * buf;
|
|||
if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
|
||||
return strcpy(buf, result);
|
||||
else {
|
||||
#ifdef EOVERFLOW
|
||||
errno = EOVERFLOW;
|
||||
#else /* !defined EOVERFLOW */
|
||||
errno = EINVAL;
|
||||
#endif /* !defined EOVERFLOW */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
|
||||
*/
|
||||
|
||||
char *
|
||||
asctime(timeptr)
|
||||
const struct tm * timeptr;
|
||||
asctime(register const struct tm *timeptr)
|
||||
{
|
||||
return asctime_r(timeptr, buf_asctime);
|
||||
}
|
173
contrib/tzcode/calendars
Normal file
173
contrib/tzcode/calendars
Normal file
|
@ -0,0 +1,173 @@
|
|||
----- Calendrical issues -----
|
||||
|
||||
As mentioned in Theory.html, although calendrical issues are out of
|
||||
scope for tzdb, they indicate the sort of problems that we would run
|
||||
into if we extended tzdb further into the past. The following
|
||||
information and sources go beyond Theory.html's brief discussion.
|
||||
They sometimes disagree.
|
||||
|
||||
|
||||
France
|
||||
|
||||
Gregorian calendar adopted 1582-12-20.
|
||||
French Revolutionary calendar used 1793-11-24 through 1805-12-31,
|
||||
and (in Paris only) 1871-05-06 through 1871-05-23.
|
||||
|
||||
|
||||
Russia
|
||||
|
||||
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
|
||||
Gregorian calendar while retaining the 6-day week; on 1940-06-27 it
|
||||
reverted to the 7-day week. With the 6-day week the usual days
|
||||
off were the 6th, 12th, 18th, 24th and 30th of the month.
|
||||
(Source: Evitiar Zerubavel, _The Seven Day Circle_)
|
||||
|
||||
|
||||
Mark Brader reported a similar story in "The Book of Calendars", edited
|
||||
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
|
||||
...
|
||||
|
||||
If your source is correct, how come documents between 1929 and 1940 were
|
||||
still dated using the conventional, Gregorian calendar?
|
||||
|
||||
I can post a scan of a document dated December 1, 1934, signed by
|
||||
Yenukidze, the secretary, on behalf of Kalinin, the President of the
|
||||
Executive Committee of the Supreme Soviet, if you like.
|
||||
|
||||
|
||||
|
||||
Sweden (and Finland)
|
||||
|
||||
From: Mark Brader
|
||||
Subject: Re: Gregorian reform - a part of locale?
|
||||
<news:1996Jul6.012937.29190@sq.com>
|
||||
Date: 1996-07-06
|
||||
|
||||
In 1700, Denmark made the transition from Julian to Gregorian. Sweden
|
||||
decided to *start* a transition in 1700 as well, but rather than have one of
|
||||
those unsightly calendar gaps :-), they simply decreed that the next leap
|
||||
year after 1696 would be in 1744 - putting the whole country on a calendar
|
||||
different from both Julian and Gregorian for a period of 40 years.
|
||||
|
||||
However, in 1704 something went wrong and the plan was not carried through;
|
||||
they did, after all, have a leap year that year. And one in 1708. In 1712
|
||||
they gave it up and went back to Julian, putting 30 days in February that
|
||||
year!...
|
||||
|
||||
Then in 1753, Sweden made the transition to Gregorian in the usual manner,
|
||||
getting there only 13 years behind the original schedule.
|
||||
|
||||
(A previous posting of this story was challenged, and Swedish readers
|
||||
produced the following references to support it: "Tideräkning och historia"
|
||||
by Natanael Beckman (1924) and "Tid, en bok om tideräkning och
|
||||
kalenderväsen" by Lars-Olof Lodén (1968).
|
||||
|
||||
|
||||
Grotefend's data
|
||||
|
||||
From: "Michael Palmer" [with two obvious typos fixed]
|
||||
Subject: Re: Gregorian Calendar (was Re: Another FHC related question
|
||||
Newsgroups: soc.genealogy.german
|
||||
Date: Tue, 9 Feb 1999 02:32:48 -800
|
||||
...
|
||||
|
||||
The following is a(n incomplete) listing, arranged chronologically, of
|
||||
European states, with the date they converted from the Julian to the
|
||||
Gregorian calendar:
|
||||
|
||||
04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman
|
||||
Catholics and Danzig only)
|
||||
09/20 Dec 1582 - France, Lorraine
|
||||
|
||||
21 Dec 1582/
|
||||
01 Jan 1583 - Holland, Brabant, Flanders, Hennegau
|
||||
10/21 Feb 1583 - bishopric of Liege (Lüttich)
|
||||
13/24 Feb 1583 - bishopric of Augsburg
|
||||
04/15 Oct 1583 - electorate of Trier
|
||||
05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg,
|
||||
Salzburg, Brixen
|
||||
13/24 Oct 1583 - Austrian Oberelsaß and Breisgau
|
||||
20/31 Oct 1583 - bishopric of Basel
|
||||
02/13 Nov 1583 - duchy of Jülich-Berg
|
||||
02/13 Nov 1583 - electorate and city of Köln
|
||||
04/15 Nov 1583 - bishopric of Würzburg
|
||||
11/22 Nov 1583 - electorate of Mainz
|
||||
16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden
|
||||
17/28 Nov 1583 - bishopric of Münster and duchy of Cleve
|
||||
14/25 Dec 1583 - Steiermark
|
||||
|
||||
06/17 Jan 1584 - Austria and Bohemia
|
||||
11/22 Jan 1584 - Lucerne, Uri, Schwyz, Zug, Freiburg, Solothurn
|
||||
12/23 Jan 1584 - Silesia and the Lausitz
|
||||
22 Jan/
|
||||
02 Feb 1584 - Hungary (legally on 21 Oct 1587)
|
||||
Jun 1584 - Unterwalden
|
||||
01/12 Jul 1584 - duchy of Westfalen
|
||||
|
||||
16/27 Jun 1585 - bishopric of Paderborn
|
||||
|
||||
14/25 Dec 1590 - Transylvania
|
||||
|
||||
22 Aug/
|
||||
02 Sep 1612 - duchy of Prussia
|
||||
|
||||
13/24 Dec 1614 - Pfalz-Neuburg
|
||||
|
||||
1617 - duchy of Kurland (reverted to the Julian calendar in
|
||||
1796)
|
||||
|
||||
1624 - bishopric of Osnabrück
|
||||
|
||||
1630 - bishopric of Minden
|
||||
|
||||
15/26 Mar 1631 - bishopric of Hildesheim
|
||||
|
||||
1655 - Kanton Wallis
|
||||
|
||||
05/16 Feb 1682 - city of Strassburg
|
||||
|
||||
18 Feb/
|
||||
01 Mar 1700 - Protestant Germany (including Swedish possessions in
|
||||
Germany), Denmark, Norway
|
||||
30 Jun/
|
||||
12 Jul 1700 - Gelderland, Zutphen
|
||||
10 Nov/
|
||||
12 Dec 1700 - Utrecht, Overijssel
|
||||
|
||||
31 Dec 1700/
|
||||
12 Jan 1701 - Friesland, Groningen, Zürich, Bern, Basel, Geneva,
|
||||
Thurgau, and Schaffhausen
|
||||
|
||||
1724 - Glarus, Appenzell, and the city of St. Gallen
|
||||
|
||||
01 Jan 1750 - Pisa and Florence
|
||||
|
||||
02/14 Sep 1752 - Great Britain
|
||||
|
||||
17 Feb/
|
||||
01 Mar 1753 - Sweden
|
||||
|
||||
1760-1812 - Graubünden
|
||||
|
||||
The Russian empire (including Finland and the Baltic states) did not
|
||||
convert to the Gregorian calendar until the Soviet revolution of 1917.
|
||||
|
||||
Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen
|
||||
Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend
|
||||
(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28.
|
||||
|
||||
-----
|
||||
|
||||
This file is in the public domain, so clarified as of 2009-05-17 by
|
||||
Arthur David Olson.
|
||||
|
||||
-----
|
||||
Local Variables:
|
||||
coding: utf-8
|
||||
End:
|
167
contrib/tzcode/date.1
Normal file
167
contrib/tzcode/date.1
Normal file
|
@ -0,0 +1,167 @@
|
|||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.TH date 1
|
||||
.SH NAME
|
||||
date \- show and set date and time
|
||||
.SH SYNOPSIS
|
||||
.if n .nh
|
||||
.if n .na
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.B date
|
||||
[
|
||||
.B \*-u
|
||||
] [
|
||||
.B \*-c
|
||||
] [
|
||||
.B \*-r
|
||||
.I seconds
|
||||
] [
|
||||
.BI + format
|
||||
] [
|
||||
\fR[\fIyyyy\fR]\fImmddhhmm\fR[\fIyy\fR][\fB.\fIss\fR]
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.ie '\(lq'' .ds lq \&"\"
|
||||
.el .ds lq \(lq\"
|
||||
.ie '\(rq'' .ds rq \&"\"
|
||||
.el .ds rq \(rq\"
|
||||
.de q
|
||||
\\$3\*(lq\\$1\*(rq\\$2
|
||||
..
|
||||
The
|
||||
.B date
|
||||
command
|
||||
without arguments writes the date and time to the standard output in
|
||||
the form
|
||||
.ce 1
|
||||
Wed Mar 8 14:54:40 EST 1989
|
||||
.br
|
||||
with
|
||||
.B EST
|
||||
replaced by the local time zone's abbreviation
|
||||
(or by the abbreviation for the time zone specified in the
|
||||
.B TZ
|
||||
environment variable if set).
|
||||
The exact output format depends on the locale.
|
||||
.PP
|
||||
If a command-line argument starts with a plus sign (\c
|
||||
.q "\fB+\fP" ),
|
||||
the rest of the argument is used as a
|
||||
.I format
|
||||
that controls what appears in the output.
|
||||
In the format, when a percent sign (\c
|
||||
.q "\fB%\fP"
|
||||
appears,
|
||||
it and the character after it are not output,
|
||||
but rather identify part of the date or time
|
||||
to be output in a particular way
|
||||
(or identify a special character to output):
|
||||
.nf
|
||||
.sp
|
||||
.if t .in +.5i
|
||||
.if n .in +2
|
||||
.ta \w'%M\0\0'u +\w'Wed Mar 8 14:54:40 EST 1989\0\0'u
|
||||
Sample output Explanation
|
||||
%a Wed Abbreviated weekday name*
|
||||
%A Wednesday Full weekday name*
|
||||
%b Mar Abbreviated month name*
|
||||
%B March Full month name*
|
||||
%c Wed Mar 08 14:54:40 1989 Date and time*
|
||||
%C 19 Century
|
||||
%d 08 Day of month (always two digits)
|
||||
%D 03/08/89 Month/day/year (eight characters)
|
||||
%e 8 Day of month (leading zero blanked)
|
||||
%h Mar Abbreviated month name*
|
||||
%H 14 24-hour-clock hour (two digits)
|
||||
%I 02 12-hour-clock hour (two digits)
|
||||
%j 067 Julian day number (three digits)
|
||||
%k 2 12-hour-clock hour (leading zero blanked)
|
||||
%l 14 24-hour-clock hour (leading zero blanked)
|
||||
%m 03 Month number (two digits)
|
||||
%M 54 Minute (two digits)
|
||||
%n \\n newline character
|
||||
%p PM AM/PM designation
|
||||
%r 02:54:40 PM Hour:minute:second AM/PM designation
|
||||
%R 14:54 Hour:minute
|
||||
%S 40 Second (two digits)
|
||||
%t \\t tab character
|
||||
%T 14:54:40 Hour:minute:second
|
||||
%U 10 Sunday-based week number (two digits)
|
||||
%w 3 Day number (one digit, Sunday is 0)
|
||||
%W 10 Monday-based week number (two digits)
|
||||
%x 03/08/89 Date*
|
||||
%X 14:54:40 Time*
|
||||
%y 89 Last two digits of year
|
||||
%Y 1989 Year in full
|
||||
%z -0500 Numeric time zone
|
||||
%Z EST Time zone abbreviation
|
||||
%+ Wed Mar 8 14:54:40 EST 1989 Default output format*
|
||||
.if t .in -.5i
|
||||
.if n .in -2
|
||||
* The exact output depends on the locale.
|
||||
.sp
|
||||
.fi
|
||||
If a character other than one of those shown above appears after
|
||||
a percent sign in the format,
|
||||
that following character is output.
|
||||
All other characters in the format are copied unchanged to the output;
|
||||
a newline character is always added at the end of the output.
|
||||
.PP
|
||||
In Sunday-based week numbering,
|
||||
the first Sunday of the year begins week 1;
|
||||
days preceding it are part of
|
||||
.q "week 0" .
|
||||
In Monday-based week numbering,
|
||||
the first Monday of the year begins week 1.
|
||||
.PP
|
||||
To set the date, use a command line argument with one of the following forms:
|
||||
.nf
|
||||
.if t .in +.5i
|
||||
.if n .in +2
|
||||
.ta \w'198903081454\0'u
|
||||
1454 24-hour-clock hours (first two digits) and minutes
|
||||
081454 Month day (first two digits), hours, and minutes
|
||||
03081454 Month (two digits, January is 01), month day, hours, minutes
|
||||
8903081454 Year, month, month day, hours, minutes
|
||||
0308145489 Month, month day, hours, minutes, year
|
||||
(on System V-compatible systems)
|
||||
030814541989 Month, month day, hours, minutes, four-digit year
|
||||
198903081454 Four-digit year, month, month day, hours, minutes
|
||||
.if t .in -.5i
|
||||
.if n .in -2
|
||||
.fi
|
||||
If the century, year, month, or month day is not given,
|
||||
the current value is used.
|
||||
Any of the above forms may be followed by a period and two digits that give
|
||||
the seconds part of the new time; if no seconds are given, zero is assumed.
|
||||
.PP
|
||||
These options are available:
|
||||
.TP
|
||||
.BR \*-u " or " \*-c
|
||||
Use Universal Time when setting and showing the date and time.
|
||||
.TP
|
||||
.BI "\*-r " seconds
|
||||
Output the date that corresponds to
|
||||
.I seconds
|
||||
past the epoch of 1970-01-01 00:00:00 UTC, where
|
||||
.I seconds
|
||||
should be an integer, either decimal, octal (leading 0), or
|
||||
hexadecimal (leading 0x), preceded by an optional sign.
|
||||
.SH FILES
|
||||
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
|
||||
/etc/localtime local timezone file
|
||||
.br
|
||||
/usr/lib/locale/\f2L\fP/LC_TIME description of time locale \f2L\fP
|
||||
.br
|
||||
/usr/share/zoneinfo timezone information directory
|
||||
.br
|
||||
/usr/share/zoneinfo/posixrules used with POSIX-style TZ's
|
||||
.br
|
||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||
.sp
|
||||
If
|
||||
.B /usr/share/zoneinfo/GMT
|
||||
is absent,
|
||||
UTC leap seconds are loaded from
|
||||
.BR /usr/share/zoneinfo/posixrules .
|
216
contrib/tzcode/date.c
Normal file
216
contrib/tzcode/date.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
/* Display or set the current time and date. */
|
||||
|
||||
/* Copyright 1985, 1987, 1988 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE. */
|
||||
|
||||
#include "private.h"
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if !HAVE_POSIX_DECLS
|
||||
extern char * optarg;
|
||||
extern int optind;
|
||||
#endif
|
||||
|
||||
static int retval = EXIT_SUCCESS;
|
||||
|
||||
static void display(const char *, time_t);
|
||||
static void dogmt(void);
|
||||
static void errensure(void);
|
||||
static void timeout(FILE *, const char *, const struct tm *);
|
||||
static ATTRIBUTE_NORETURN void usage(void);
|
||||
|
||||
int
|
||||
main(const int argc, char *argv[])
|
||||
{
|
||||
register const char * format = "+%+";
|
||||
register int ch;
|
||||
register bool rflag = false;
|
||||
time_t t;
|
||||
intmax_t secs;
|
||||
char * endarg;
|
||||
|
||||
#ifdef LC_ALL
|
||||
setlocale(LC_ALL, "");
|
||||
#endif /* defined(LC_ALL) */
|
||||
#if HAVE_GETTEXT
|
||||
# ifdef TZ_DOMAINDIR
|
||||
bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
|
||||
# endif /* defined(TEXTDOMAINDIR) */
|
||||
textdomain(TZ_DOMAIN);
|
||||
#endif /* HAVE_GETTEXT */
|
||||
t = time(NULL);
|
||||
while ((ch = getopt(argc, argv, "ucr:")) != EOF && ch != -1) {
|
||||
switch (ch) {
|
||||
default:
|
||||
usage();
|
||||
case 'u': /* do it in UT */
|
||||
case 'c':
|
||||
dogmt();
|
||||
break;
|
||||
case 'r': /* seconds since 1970 */
|
||||
if (rflag) {
|
||||
fprintf(stderr,
|
||||
_("date: error: multiple -r's used"));
|
||||
usage();
|
||||
}
|
||||
rflag = true;
|
||||
errno = 0;
|
||||
secs = strtoimax(optarg, &endarg, 0);
|
||||
if (*endarg || optarg == endarg)
|
||||
errno = EINVAL;
|
||||
else if (! (TIME_T_MIN <= secs && secs <= TIME_T_MAX))
|
||||
errno = ERANGE;
|
||||
if (errno) {
|
||||
perror(optarg);
|
||||
errensure();
|
||||
exit(retval);
|
||||
}
|
||||
t = secs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
if (argc - optind != 1) {
|
||||
fprintf(stderr,
|
||||
_("date: error: multiple operands in command line\n"));
|
||||
usage();
|
||||
}
|
||||
format = argv[optind];
|
||||
if (*format != '+') {
|
||||
fprintf(stderr, _("date: unknown operand: %s\n"), format);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
display(format, t);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
dogmt(void)
|
||||
{
|
||||
static char ** fakeenv;
|
||||
|
||||
if (fakeenv == NULL) {
|
||||
static char tzeutc0[] = "TZ=UTC0";
|
||||
ptrdiff_t from, to, n;
|
||||
|
||||
for (n = 0; environ[n] != NULL; ++n)
|
||||
continue;
|
||||
#if defined ckd_add && defined ckd_mul
|
||||
if (!ckd_add(&n, n, 2) && !ckd_mul(&n, n, sizeof *fakeenv)
|
||||
&& n <= SIZE_MAX)
|
||||
fakeenv = malloc(n);
|
||||
#else
|
||||
if (n <= min(PTRDIFF_MAX, SIZE_MAX) / sizeof *fakeenv - 2)
|
||||
fakeenv = malloc((n + 2) * sizeof *fakeenv);
|
||||
#endif
|
||||
if (fakeenv == NULL) {
|
||||
fprintf(stderr, _("date: Memory exhausted\n"));
|
||||
errensure();
|
||||
exit(retval);
|
||||
}
|
||||
to = 0;
|
||||
fakeenv[to++] = tzeutc0;
|
||||
for (from = 1; environ[from] != NULL; ++from)
|
||||
if (strncmp(environ[from], "TZ=", 3) != 0)
|
||||
fakeenv[to++] = environ[from];
|
||||
fakeenv[to] = NULL;
|
||||
environ = fakeenv;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
errensure(void)
|
||||
{
|
||||
if (retval == EXIT_SUCCESS)
|
||||
retval = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
_("date: usage: date [-u] [-c] [-r seconds]"
|
||||
" [+format]\n"));
|
||||
errensure();
|
||||
exit(retval);
|
||||
}
|
||||
|
||||
static void
|
||||
display(char const *format, time_t now)
|
||||
{
|
||||
struct tm *tmp;
|
||||
|
||||
tmp = localtime(&now);
|
||||
if (!tmp) {
|
||||
fprintf(stderr,
|
||||
_("date: error: time out of range\n"));
|
||||
errensure();
|
||||
return;
|
||||
}
|
||||
timeout(stdout, format, tmp);
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
if (ferror(stdout) || ferror(stderr)) {
|
||||
fprintf(stderr,
|
||||
_("date: error: couldn't write results\n"));
|
||||
errensure();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
timeout(FILE *fp, char const *format, struct tm const *tmp)
|
||||
{
|
||||
char *cp = NULL;
|
||||
ptrdiff_t result;
|
||||
ptrdiff_t size = 1024 / 2;
|
||||
|
||||
for ( ; ; ) {
|
||||
#ifdef ckd_mul
|
||||
bool bigger = !ckd_mul(&size, size, 2) && size <= SIZE_MAX;
|
||||
#else
|
||||
bool bigger = (size <= min(PTRDIFF_MAX, SIZE_MAX) / 2
|
||||
&& (size *= 2, true));
|
||||
#endif
|
||||
char *newcp = bigger ? realloc(cp, size) : NULL;
|
||||
if (!newcp) {
|
||||
fprintf(stderr,
|
||||
_("date: error: can't get memory\n"));
|
||||
errensure();
|
||||
exit(retval);
|
||||
}
|
||||
cp = newcp;
|
||||
result = strftime(cp, size, format, tmp);
|
||||
if (result != 0)
|
||||
break;
|
||||
}
|
||||
fwrite(cp + 1, 1, result - 1, fp);
|
||||
free(cp);
|
||||
}
|
62
contrib/tzcode/difftime.c
Normal file
62
contrib/tzcode/difftime.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* Return the difference between two timestamps. */
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include "private.h" /* for time_t and TYPE_SIGNED */
|
||||
#include "un-namespace.h"
|
||||
|
||||
/* Return -X as a double. Using this avoids casting to 'double'. */
|
||||
static double
|
||||
dminus(double x)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
|
||||
double
|
||||
difftime(time_t time1, time_t time0)
|
||||
{
|
||||
/*
|
||||
** If double is large enough, simply convert and subtract
|
||||
** (assuming that the larger type has more precision).
|
||||
*/
|
||||
if (sizeof(time_t) < sizeof(double)) {
|
||||
double t1 = time1, t0 = time0;
|
||||
return t1 - t0;
|
||||
}
|
||||
|
||||
/*
|
||||
** The difference of two unsigned values can't overflow
|
||||
** if the minuend is greater than or equal to the subtrahend.
|
||||
*/
|
||||
if (!TYPE_SIGNED(time_t))
|
||||
return time0 <= time1 ? time1 - time0 : dminus(time0 - time1);
|
||||
|
||||
/* Use uintmax_t if wide enough. */
|
||||
if (sizeof(time_t) <= sizeof(uintmax_t)) {
|
||||
uintmax_t t1 = time1, t0 = time0;
|
||||
return time0 <= time1 ? t1 - t0 : dminus(t0 - t1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Handle cases where both time1 and time0 have the same sign
|
||||
** (meaning that their difference cannot overflow).
|
||||
*/
|
||||
if ((time1 < 0) == (time0 < 0))
|
||||
return time1 - time0;
|
||||
|
||||
/*
|
||||
** The values have opposite signs and uintmax_t is too narrow.
|
||||
** This suffers from double rounding; attempt to lessen that
|
||||
** by using long double temporaries.
|
||||
*/
|
||||
{
|
||||
long double t1 = time1, t0 = time0;
|
||||
return t1 - t0;
|
||||
}
|
||||
}
|
2669
contrib/tzcode/localtime.c
Normal file
2669
contrib/tzcode/localtime.c
Normal file
File diff suppressed because it is too large
Load diff
344
contrib/tzcode/newctime.3
Normal file
344
contrib/tzcode/newctime.3
Normal file
|
@ -0,0 +1,344 @@
|
|||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.TH NEWCTIME 3
|
||||
.SH NAME
|
||||
asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.B #include <time.h>
|
||||
.PP
|
||||
.BR "extern char *tzname[];" " /\(** (optional) \(**/"
|
||||
.PP
|
||||
.B char *ctime(time_t const *clock);
|
||||
.PP
|
||||
.B char *ctime_r(time_t const *clock, char *buf);
|
||||
.PP
|
||||
.B double difftime(time_t time1, time_t time0);
|
||||
.PP
|
||||
.B char *asctime(struct tm const *tm);
|
||||
.PP
|
||||
.B "char *asctime_r(struct tm const *restrict tm,"
|
||||
.B " char *restrict result);"
|
||||
.PP
|
||||
.B struct tm *localtime(time_t const *clock);
|
||||
.PP
|
||||
.B "struct tm *localtime_r(time_t const *restrict clock,"
|
||||
.B " struct tm *restrict result);"
|
||||
.PP
|
||||
.B "struct tm *localtime_rz(timezone_t restrict zone,"
|
||||
.B " time_t const *restrict clock,"
|
||||
.B " struct tm *restrict result);"
|
||||
.PP
|
||||
.B struct tm *gmtime(time_t const *clock);
|
||||
.PP
|
||||
.B "struct tm *gmtime_r(time_t const *restrict clock,"
|
||||
.B " struct tm *restrict result);"
|
||||
.PP
|
||||
.B time_t mktime(struct tm *tm);
|
||||
.PP
|
||||
.B "time_t mktime_z(timezone_t restrict zone,"
|
||||
.B " struct tm *restrict tm);"
|
||||
.PP
|
||||
.B cc ... \*-ltz
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.ie '\(en'' .ds en \-
|
||||
.el .ds en \(en
|
||||
.ie '\(lq'' .ds lq \&"\"
|
||||
.el .ds lq \(lq\"
|
||||
.ie '\(rq'' .ds rq \&"\"
|
||||
.el .ds rq \(rq\"
|
||||
.de q
|
||||
\\$3\*(lq\\$1\*(rq\\$2
|
||||
..
|
||||
The
|
||||
.B ctime
|
||||
function
|
||||
converts a long integer, pointed to by
|
||||
.IR clock ,
|
||||
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
|
||||
The
|
||||
.BI * clock
|
||||
timestamp represents the time in seconds since 1970-01-01 00:00:00
|
||||
Coordinated Universal Time (UTC).
|
||||
The POSIX standard says that timestamps must be nonnegative
|
||||
and must ignore leap seconds.
|
||||
Many implementations extend POSIX by allowing negative timestamps,
|
||||
and can therefore represent timestamps that predate the
|
||||
introduction of UTC and are some other flavor of Universal Time (UT).
|
||||
Some implementations support leap seconds, in contradiction to POSIX.
|
||||
.PP
|
||||
The
|
||||
.B localtime
|
||||
and
|
||||
.B gmtime
|
||||
functions
|
||||
return pointers to
|
||||
.q "tm"
|
||||
structures, described below.
|
||||
The
|
||||
.B localtime
|
||||
function
|
||||
corrects for the time zone and any time zone adjustments
|
||||
(such as Daylight Saving Time in the United States).
|
||||
After filling in the
|
||||
.q "tm"
|
||||
structure,
|
||||
.B localtime
|
||||
sets the
|
||||
.BR tm_isdst 'th
|
||||
element of
|
||||
.B tzname
|
||||
to a pointer to a string that's the time zone abbreviation to be used with
|
||||
.BR localtime 's
|
||||
return value.
|
||||
.PP
|
||||
The
|
||||
.B gmtime
|
||||
function
|
||||
converts to Coordinated Universal Time.
|
||||
.PP
|
||||
The
|
||||
.B asctime
|
||||
function
|
||||
converts a time value contained in a
|
||||
.q "tm"
|
||||
structure to a string,
|
||||
as shown in the above example,
|
||||
and returns a pointer to the string.
|
||||
.PP
|
||||
The
|
||||
.B mktime
|
||||
function
|
||||
converts the broken-down time,
|
||||
expressed as local time,
|
||||
in the structure pointed to by
|
||||
.I tm
|
||||
into a calendar time value with the same encoding as that of the values
|
||||
returned by the
|
||||
.B time
|
||||
function.
|
||||
The original values of the
|
||||
.B tm_wday
|
||||
and
|
||||
.B tm_yday
|
||||
components of the structure are ignored,
|
||||
and the original values of the other components are not restricted
|
||||
to their normal ranges.
|
||||
(A positive or zero value for
|
||||
.B tm_isdst
|
||||
causes
|
||||
.B mktime
|
||||
to presume initially that daylight saving time
|
||||
respectively,
|
||||
is or is not in effect for the specified time.
|
||||
A negative value for
|
||||
.B tm_isdst
|
||||
causes the
|
||||
.B mktime
|
||||
function to attempt to divine whether daylight saving time is in effect
|
||||
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
|
||||
.B tm_wday
|
||||
and
|
||||
.B tm_yday
|
||||
components of the structure are set appropriately,
|
||||
and the other components are set to represent the specified calendar time,
|
||||
but with their values forced to their normal ranges; the final value of
|
||||
.B tm_mday
|
||||
is not set until
|
||||
.B tm_mon
|
||||
and
|
||||
.B tm_year
|
||||
are determined.
|
||||
The
|
||||
.B mktime
|
||||
function
|
||||
returns the specified calendar time;
|
||||
If the calendar time cannot be represented,
|
||||
it returns \-1.
|
||||
.PP
|
||||
The
|
||||
.B difftime
|
||||
function
|
||||
returns the difference between two calendar times,
|
||||
.RI ( time1
|
||||
\-
|
||||
.IR time0 ),
|
||||
expressed in seconds.
|
||||
.PP
|
||||
The
|
||||
.BR ctime_r ,
|
||||
.BR localtime_r ,
|
||||
.BR gmtime_r ,
|
||||
and
|
||||
.B asctime_r
|
||||
functions
|
||||
are like their unsuffixed counterparts, except that they accept an
|
||||
additional argument specifying where to store the result if successful.
|
||||
.PP
|
||||
The
|
||||
.B localtime_rz
|
||||
and
|
||||
.B mktime_z
|
||||
functions
|
||||
are like their unsuffixed counterparts, except that they accept an
|
||||
extra initial
|
||||
.B zone
|
||||
argument specifying the timezone to be used for conversion.
|
||||
If
|
||||
.B zone
|
||||
is null, UT is used; otherwise,
|
||||
.B zone
|
||||
should be have been allocated by
|
||||
.B tzalloc
|
||||
and should not be freed until after all uses (e.g., by calls to
|
||||
.BR strftime )
|
||||
of the filled-in
|
||||
.B tm_zone
|
||||
fields.
|
||||
.PP
|
||||
Declarations of all the functions and externals, and the
|
||||
.q "tm"
|
||||
structure,
|
||||
are in the
|
||||
.B <time.h>
|
||||
header file.
|
||||
The structure (of type)
|
||||
.B struct tm
|
||||
includes the following fields:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
.ta 2n +\w'long tm_gmtoff;nn'u
|
||||
int tm_sec; /\(** seconds (0\*(en60) \(**/
|
||||
int tm_min; /\(** minutes (0\*(en59) \(**/
|
||||
int tm_hour; /\(** hours (0\*(en23) \(**/
|
||||
int tm_mday; /\(** day of month (1\*(en31) \(**/
|
||||
int tm_mon; /\(** month of year (0\*(en11) \(**/
|
||||
int tm_year; /\(** year \- 1900 \(**/
|
||||
int tm_wday; /\(** day of week (Sunday = 0) \(**/
|
||||
int tm_yday; /\(** day of year (0\*(en365) \(**/
|
||||
int tm_isdst; /\(** is daylight saving time in effect? \(**/
|
||||
char \(**tm_zone; /\(** time zone abbreviation (optional) \(**/
|
||||
long tm_gmtoff; /\(** offset from UT in seconds (optional) \(**/
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
The
|
||||
.B tm_isdst
|
||||
field
|
||||
is non-zero if daylight saving time is in effect.
|
||||
.PP
|
||||
The
|
||||
.B tm_gmtoff
|
||||
field
|
||||
is the offset (in seconds) of the time represented
|
||||
from UT, with positive values indicating east
|
||||
of the Prime Meridian.
|
||||
The field's name is derived from Greenwich Mean Time, a precursor of UT.
|
||||
.PP
|
||||
In
|
||||
.B "struct tm"
|
||||
the
|
||||
.B tm_zone
|
||||
and
|
||||
.B tm_gmtoff
|
||||
fields exist, and are filled in, only if arrangements to do
|
||||
so were made when the library containing these functions was
|
||||
created.
|
||||
Similarly, the
|
||||
.B tzname
|
||||
variable is optional; also, there is no guarantee that
|
||||
.B tzname
|
||||
will
|
||||
continue to exist in this form in future releases of this code.
|
||||
.SH FILES
|
||||
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
|
||||
/usr/share/zoneinfo timezone information directory
|
||||
.br
|
||||
/usr/share/zoneinfo/localtime local timezone file
|
||||
.br
|
||||
/usr/share/zoneinfo/posixrules used with POSIX-style TZ's
|
||||
.br
|
||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||
.sp
|
||||
If
|
||||
.B /usr/share/zoneinfo/GMT
|
||||
is absent,
|
||||
UTC leap seconds are loaded from
|
||||
.BR /usr/share/zoneinfo/posixrules .
|
||||
.SH SEE ALSO
|
||||
getenv(3),
|
||||
newstrftime(3),
|
||||
newtzset(3),
|
||||
time(2),
|
||||
tzfile(5)
|
||||
.SH NOTES
|
||||
The return values of
|
||||
.BR asctime ,
|
||||
.BR ctime ,
|
||||
.BR gmtime ,
|
||||
and
|
||||
.B localtime
|
||||
point to static data
|
||||
overwritten by each call.
|
||||
The
|
||||
.B tzname
|
||||
variable (once set) and the
|
||||
.B tm_zone
|
||||
field of a returned
|
||||
.B "struct tm"
|
||||
both point to an array of characters that
|
||||
can be freed or overwritten by later calls to the functions
|
||||
.BR localtime ,
|
||||
.BR tzfree ,
|
||||
and
|
||||
.BR tzset ,
|
||||
if these functions affect the timezone information that specifies the
|
||||
abbreviation in question.
|
||||
The remaining functions and data are thread-safe.
|
||||
.PP
|
||||
The
|
||||
.BR asctime ,
|
||||
.BR asctime_r ,
|
||||
.BR ctime ,
|
||||
and
|
||||
.B ctime_r
|
||||
functions
|
||||
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.
|
||||
The 2011 edition says that the behavior
|
||||
is undefined if the year is before 1000 or after 9999.
|
||||
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
|
||||
.B strftime
|
||||
instead.
|
290
contrib/tzcode/newstrftime.3
Normal file
290
contrib/tzcode/newstrftime.3
Normal file
|
@ -0,0 +1,290 @@
|
|||
.\" strftime man page
|
||||
.\"
|
||||
.\" Based on the UCB file whose corrected copyright information appears below.
|
||||
.\" Copyright 1989, 1991 The Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" the American National Standards Committee X3, on Information
|
||||
.\" Processing Systems.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
|
||||
.\" $Id: strftime.3,v 1.4 1993/12/15 20:33:00 jtc Exp $
|
||||
.\"
|
||||
.TH NEWSTRFTIME 3
|
||||
.SH NAME
|
||||
strftime \- format date and time
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.B #include <time.h>
|
||||
.PP
|
||||
.B "size_t strftime(char *restrict buf, size_t maxsize,"
|
||||
.B " char const *restrict format, struct tm const *restrict timeptr);"
|
||||
.PP
|
||||
.B cc ... \-ltz
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.ie '\(lq'' .ds lq \&"\"
|
||||
.el .ds lq \(lq\"
|
||||
.ie '\(rq'' .ds rq \&"\"
|
||||
.el .ds rq \(rq\"
|
||||
.de c
|
||||
.ie \n(.g \f(CR\\$1\fP\\$2
|
||||
.el \\$1\\$2
|
||||
..
|
||||
.de q
|
||||
\\$3\*(lq\\$1\*(rq\\$2
|
||||
..
|
||||
The
|
||||
.B strftime
|
||||
function formats the information from
|
||||
.I timeptr
|
||||
into the array pointed to by
|
||||
.I buf
|
||||
according to the string pointed to by
|
||||
.IR format .
|
||||
.PP
|
||||
The
|
||||
.I format
|
||||
string consists of zero or more conversion specifications and
|
||||
ordinary characters.
|
||||
All ordinary characters are copied directly into the array.
|
||||
A conversion specification consists of a percent sign
|
||||
.Ql %
|
||||
and one other character.
|
||||
.PP
|
||||
No more than
|
||||
.I maxsize
|
||||
bytes are placed into the array.
|
||||
.PP
|
||||
Each conversion specification is replaced by the characters as
|
||||
follows which are then copied into the array.
|
||||
.TP
|
||||
%A
|
||||
is replaced by the locale's full weekday name.
|
||||
.TP
|
||||
%a
|
||||
is replaced by the locale's abbreviated weekday name.
|
||||
.TP
|
||||
%B
|
||||
is replaced by the locale's full month name.
|
||||
.TP
|
||||
%b or %h
|
||||
is replaced by the locale's abbreviated month name.
|
||||
.TP
|
||||
%C
|
||||
is replaced by the century (a year divided by 100 and truncated to an integer)
|
||||
as a decimal number [00,99].
|
||||
.TP
|
||||
%c
|
||||
is replaced by the locale's appropriate date and time representation.
|
||||
.TP
|
||||
%D
|
||||
is equivalent to
|
||||
.c %m/%d/%y .
|
||||
.TP
|
||||
%d
|
||||
is replaced by the day of the month as a decimal number [01,31].
|
||||
.TP
|
||||
%e
|
||||
is replaced by the day of month as a decimal number [1,31];
|
||||
single digits are preceded by a blank.
|
||||
.TP
|
||||
%F
|
||||
is equivalent to
|
||||
.c %Y-%m-%d
|
||||
(the ISO 8601 date format).
|
||||
.TP
|
||||
%G
|
||||
is replaced by the ISO 8601 year with century as a decimal number.
|
||||
See also the
|
||||
.c %V
|
||||
conversion specification.
|
||||
.TP
|
||||
%g
|
||||
is replaced by the ISO 8601 year without century as a decimal number [00,99].
|
||||
This is the year that includes the greater part of the week.
|
||||
(Monday as the first day of a week).
|
||||
See also the
|
||||
.c %V
|
||||
conversion specification.
|
||||
.TP
|
||||
%H
|
||||
is replaced by the hour (24-hour clock) as a decimal number [00,23].
|
||||
.TP
|
||||
%I
|
||||
is replaced by the hour (12-hour clock) as a decimal number [01,12].
|
||||
.TP
|
||||
%j
|
||||
is replaced by the day of the year as a decimal number [001,366].
|
||||
.TP
|
||||
%k
|
||||
is replaced by the hour (24-hour clock) as a decimal number [0,23];
|
||||
single digits are preceded by a blank.
|
||||
.TP
|
||||
%l
|
||||
is replaced by the hour (12-hour clock) as a decimal number [1,12];
|
||||
single digits are preceded by a blank.
|
||||
.TP
|
||||
%M
|
||||
is replaced by the minute as a decimal number [00,59].
|
||||
.TP
|
||||
%m
|
||||
is replaced by the month as a decimal number [01,12].
|
||||
.TP
|
||||
%n
|
||||
is replaced by a newline.
|
||||
.TP
|
||||
%p
|
||||
is replaced by the locale's equivalent of either
|
||||
.q AM
|
||||
or
|
||||
.q PM .
|
||||
.TP
|
||||
%R
|
||||
is replaced by the time in the format
|
||||
.c %H:%M .
|
||||
.TP
|
||||
%r
|
||||
is replaced by the locale's representation of 12-hour clock time
|
||||
using AM/PM notation.
|
||||
.TP
|
||||
%S
|
||||
is replaced by the second as a decimal number [00,60].
|
||||
The range of
|
||||
seconds is [00,60] instead of [00,59] to allow for the periodic occurrence
|
||||
of leap seconds.
|
||||
.TP
|
||||
%s
|
||||
is replaced by the number of seconds since the Epoch (see
|
||||
.BR ctime (3)).
|
||||
.TP
|
||||
%T
|
||||
is replaced by the time in the format
|
||||
.c %H:%M:%S .
|
||||
.TP
|
||||
%t
|
||||
is replaced by a tab.
|
||||
.TP
|
||||
%U
|
||||
is replaced by the week number of the year (Sunday as the first day of
|
||||
the week) as a decimal number [00,53].
|
||||
.TP
|
||||
%u
|
||||
is replaced by the weekday (Monday as the first day of the week)
|
||||
as a decimal number [1,7].
|
||||
.TP
|
||||
%V
|
||||
is replaced by the week number of the year (Monday as the first day of
|
||||
the week) as a decimal number [01,53]. If the week containing January
|
||||
1 has four or more days in the new year, then it is week 1; otherwise
|
||||
it is week 53 of the previous year, and the next week is week 1.
|
||||
The year is given by the
|
||||
.c %G
|
||||
conversion specification.
|
||||
.TP
|
||||
%W
|
||||
is replaced by the week number of the year (Monday as the first day of
|
||||
the week) as a decimal number [00,53].
|
||||
.TP
|
||||
%w
|
||||
is replaced by the weekday (Sunday as the first day of the week)
|
||||
as a decimal number [0,6].
|
||||
.TP
|
||||
%X
|
||||
is replaced by the locale's appropriate time representation.
|
||||
.TP
|
||||
%x
|
||||
is replaced by the locale's appropriate date representation.
|
||||
.TP
|
||||
%Y
|
||||
is replaced by the year with century as a decimal number.
|
||||
.TP
|
||||
%y
|
||||
is replaced by the year without century as a decimal number [00,99].
|
||||
.TP
|
||||
%Z
|
||||
is replaced by the time zone abbreviation,
|
||||
or by the empty string if this is not determinable.
|
||||
.TP
|
||||
%z
|
||||
is replaced by the offset from the Prime Meridian
|
||||
in the format +HHMM or \*-HHMM (ISO 8601) as appropriate,
|
||||
with positive values representing locations east of Greenwich,
|
||||
or by the empty string if this is not determinable.
|
||||
The numeric time zone abbreviation \*-0000 is used when the time is
|
||||
Universal Time
|
||||
but local time is indeterminate; by convention this is used for
|
||||
locations while uninhabited, and corresponds to a zero offset when the
|
||||
time zone abbreviation begins with
|
||||
.q "\*-" .
|
||||
.TP
|
||||
%%
|
||||
is replaced by a single %.
|
||||
.TP
|
||||
%+
|
||||
is replaced by the locale's date and time in
|
||||
.BR date (1)
|
||||
format.
|
||||
.SH "RETURN VALUE"
|
||||
If the conversion is successful,
|
||||
.B strftime
|
||||
returns the number of bytes placed into the array, not counting the
|
||||
terminating NUL;
|
||||
.B errno
|
||||
is unchanged if the returned value is zero.
|
||||
Otherwise,
|
||||
.B errno
|
||||
is set to indicate the error, zero is returned,
|
||||
and the array contents are unspecified.
|
||||
.SH ERRORS
|
||||
This function fails if:
|
||||
.TP
|
||||
[ERANGE]
|
||||
The total number of resulting bytes, including the terminating
|
||||
NUL character, is more than
|
||||
.IR maxsize .
|
||||
.PP
|
||||
This function may fail if:
|
||||
.TP
|
||||
[EOVERFLOW]
|
||||
The format includes an
|
||||
.c %s
|
||||
conversion and the number of seconds since the Epoch cannot be represented
|
||||
in a
|
||||
.c time_t .
|
||||
.SH SEE ALSO
|
||||
date(1),
|
||||
getenv(3),
|
||||
newctime(3),
|
||||
newtzset(3),
|
||||
time(2),
|
||||
tzfile(5)
|
||||
.SH BUGS
|
||||
There is no conversion specification for the phase of the moon.
|
350
contrib/tzcode/newtzset.3
Normal file
350
contrib/tzcode/newtzset.3
Normal file
|
@ -0,0 +1,350 @@
|
|||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.TH NEWTZSET 3
|
||||
.SH NAME
|
||||
tzset \- initialize time conversion information
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.B #include <time.h>
|
||||
.PP
|
||||
.B timezone_t tzalloc(char const *TZ);
|
||||
.PP
|
||||
.B void tzfree(timezone_t tz);
|
||||
.PP
|
||||
.B void tzset(void);
|
||||
.PP
|
||||
.B cc ... \*-ltz
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.ie '\(en'' .ds en \-
|
||||
.el .ds en \(en
|
||||
.ie '\(lq'' .ds lq \&"\"
|
||||
.el .ds lq \(lq\"
|
||||
.ie '\(rq'' .ds rq \&"\"
|
||||
.el .ds rq \(rq\"
|
||||
.de q
|
||||
\\$3\*(lq\\$1\*(rq\\$2
|
||||
..
|
||||
The
|
||||
.B tzalloc
|
||||
function
|
||||
allocates and returns a timezone object described by
|
||||
.BR TZ .
|
||||
If
|
||||
.B TZ
|
||||
is not a valid timezone description, or if the object cannot be allocated,
|
||||
.B tzalloc
|
||||
returns a null pointer and sets
|
||||
.BR errno .
|
||||
.PP
|
||||
The
|
||||
.B tzfree
|
||||
function
|
||||
frees a timezone object
|
||||
.BR tz ,
|
||||
which should have been successfully allocated by
|
||||
.BR tzalloc .
|
||||
This invalidates any
|
||||
.B tm_zone
|
||||
pointers that
|
||||
.B tz
|
||||
was used to set.
|
||||
.PP
|
||||
The
|
||||
.B tzset
|
||||
function
|
||||
acts like
|
||||
.BR tzalloc(getenv("TZ")) ,
|
||||
except it saves any resulting timezone object into internal
|
||||
storage that is accessed by
|
||||
.BR localtime ,
|
||||
.BR localtime_r ,
|
||||
and
|
||||
.BR mktime .
|
||||
The anonymous shared timezone object is freed by the next call to
|
||||
.BR tzset .
|
||||
If the implied call to
|
||||
.B tzalloc
|
||||
fails,
|
||||
.B tzset
|
||||
falls back on Universal Time (UT).
|
||||
.PP
|
||||
If
|
||||
.B TZ
|
||||
is null, the best available approximation to local (wall
|
||||
clock) time, as specified by the
|
||||
.BR tzfile (5)-format
|
||||
file
|
||||
.B localtime
|
||||
in the system time conversion information directory, is used.
|
||||
If
|
||||
.B TZ
|
||||
is the empty string,
|
||||
UT is used, with the abbreviation "UTC"
|
||||
and without leap second correction; please see
|
||||
.BR newctime (3)
|
||||
for more about UT, UTC, and leap seconds. If
|
||||
.B TZ
|
||||
is nonnull and nonempty:
|
||||
.IP
|
||||
if the value begins with a colon, it is used as a pathname of a file
|
||||
from which to read the time conversion information;
|
||||
.IP
|
||||
if the value does not begin with a colon, it is first used as the
|
||||
pathname of a file from which to read the time conversion information,
|
||||
and, if that file cannot be read, is used directly as a specification of
|
||||
the time conversion information.
|
||||
.PP
|
||||
When
|
||||
.B TZ
|
||||
is used as a pathname, if it begins with a slash,
|
||||
it is used as an absolute pathname; otherwise,
|
||||
it is used as a pathname relative to a system time conversion information
|
||||
directory.
|
||||
The file must be in the format specified in
|
||||
.BR tzfile (5).
|
||||
.PP
|
||||
When
|
||||
.B TZ
|
||||
is used directly as a specification of the time conversion information,
|
||||
it must have the following syntax (spaces inserted for clarity):
|
||||
.IP
|
||||
\fIstd\|offset\fR[\fIdst\fR[\fIoffset\fR][\fB,\fIrule\fR]]
|
||||
.PP
|
||||
Where:
|
||||
.RS
|
||||
.TP 15
|
||||
.IR std " and " dst
|
||||
Three or more bytes that are the designation for the standard
|
||||
.RI ( std )
|
||||
or the alternative
|
||||
.RI ( dst ,
|
||||
such as daylight saving time)
|
||||
time zone. Only
|
||||
.I std
|
||||
is required; if
|
||||
.I dst
|
||||
is missing, then daylight saving time does not apply in this locale.
|
||||
Upper- and lowercase letters are explicitly allowed. Any characters
|
||||
except a leading colon
|
||||
.RB ( : ),
|
||||
digits, comma
|
||||
.RB ( , ),
|
||||
ASCII minus
|
||||
.RB ( \*- ),
|
||||
ASCII plus
|
||||
.RB ( + ),
|
||||
and NUL bytes are allowed.
|
||||
Alternatively, a designation can be surrounded by angle brackets
|
||||
.B <
|
||||
and
|
||||
.BR > ;
|
||||
in this case, the designation can contain any characters other than
|
||||
.B >
|
||||
and NUL.
|
||||
.TP
|
||||
.I offset
|
||||
Indicates the value one must add to the local time to arrive at
|
||||
Coordinated Universal Time. The
|
||||
.I offset
|
||||
has the form:
|
||||
.RS
|
||||
.IP
|
||||
\fIhh\fR[\fB:\fImm\fR[\fB:\fIss\fR]]
|
||||
.RE
|
||||
.IP
|
||||
The minutes
|
||||
.RI ( mm )
|
||||
and seconds
|
||||
.RI ( ss )
|
||||
are optional. The hour
|
||||
.RI ( hh )
|
||||
is required and may be a single digit. The
|
||||
.I offset
|
||||
following
|
||||
.I std
|
||||
is required. If no
|
||||
.I offset
|
||||
follows
|
||||
.IR dst ,
|
||||
daylight saving time is assumed to be one hour ahead of standard time. One or
|
||||
more digits may be used; the value is always interpreted as a decimal
|
||||
number. The hour must be between zero and 24, and the minutes (and
|
||||
seconds) \*(en if present \*(en between zero and 59. If preceded by a
|
||||
.q "\*-" ,
|
||||
the time zone shall be east of the Prime Meridian; otherwise it shall be
|
||||
west (which may be indicated by an optional preceding
|
||||
.q "+" .
|
||||
.TP
|
||||
.I rule
|
||||
Indicates when to change to and back from daylight saving time. The
|
||||
.I rule
|
||||
has the form:
|
||||
.RS
|
||||
.IP
|
||||
\fIdate\fB/\fItime\fB,\fIdate\fB/\fItime\fR
|
||||
.RE
|
||||
.IP
|
||||
where the first
|
||||
.I date
|
||||
describes when the change from standard to daylight saving time occurs and the
|
||||
second
|
||||
.I date
|
||||
describes when the change back happens. Each
|
||||
.I time
|
||||
field describes when, in current local time, the change to the other
|
||||
time is made.
|
||||
As an extension to POSIX, daylight saving is assumed to be in effect
|
||||
all year if it begins January 1 at 00:00 and ends December 31 at
|
||||
24:00 plus the difference between daylight saving and standard time,
|
||||
leaving no room for standard time in the calendar.
|
||||
.IP
|
||||
The format of
|
||||
.I date
|
||||
is one of the following:
|
||||
.RS
|
||||
.TP 10
|
||||
.BI J n
|
||||
The Julian day
|
||||
.I n
|
||||
.RI "(1\ \(<=" "\ n\ " "\(<=\ 365).
|
||||
Leap days are not counted; that is, in all years \*(en including leap
|
||||
years \*(en February 28 is day 59 and March 1 is day 60. It is
|
||||
impossible to explicitly refer to the occasional February 29.
|
||||
.TP
|
||||
.I n
|
||||
The zero-based Julian day
|
||||
.RI "(0\ \(<=" "\ n\ " "\(<=\ 365).
|
||||
Leap days are counted, and it is possible to refer to February 29.
|
||||
.TP
|
||||
.BI M m . n . d
|
||||
The
|
||||
.IR d' th
|
||||
day
|
||||
.RI "(0\ \(<=" "\ d\ " "\(<=\ 6)
|
||||
of week
|
||||
.I n
|
||||
of month
|
||||
.I m
|
||||
of the year
|
||||
.RI "(1\ \(<=" "\ n\ " "\(<=\ 5,
|
||||
.RI "1\ \(<=" "\ m\ " "\(<=\ 12,
|
||||
where week 5 means
|
||||
.q "the last \fId\fP day in month \fIm\fP"
|
||||
which may occur in either the fourth or the fifth week). Week 1 is the
|
||||
first week in which the
|
||||
.IR d' th
|
||||
day occurs. Day zero is Sunday.
|
||||
.RE
|
||||
.IP "" 15
|
||||
The
|
||||
.I time
|
||||
has the same format as
|
||||
.I offset
|
||||
except that POSIX does not allow a leading sign (\c
|
||||
.q "\*-"
|
||||
or
|
||||
.q "+" ).
|
||||
As an extension to POSIX, the hours part of
|
||||
.I time
|
||||
can range from \-167 through 167; this allows for unusual rules such
|
||||
as
|
||||
.q "the Saturday before the first Sunday of March" .
|
||||
The default, if
|
||||
.I time
|
||||
is not given, is
|
||||
.BR 02:00:00 .
|
||||
.RE
|
||||
.LP
|
||||
Here are some examples of
|
||||
.B TZ
|
||||
values that directly specify the timezone; they use some of the
|
||||
extensions to POSIX.
|
||||
.TP
|
||||
.B EST5
|
||||
stands for US Eastern Standard
|
||||
Time (EST), 5 hours behind UT, without daylight saving.
|
||||
.TP
|
||||
.B <+12>\*-12<+13>,M11.1.0,M1.2.1/147
|
||||
stands for Fiji time, 12 hours ahead
|
||||
of UT, springing forward on November's first Sunday at 02:00, and
|
||||
falling back on January's second Monday at 147:00 (i.e., 03:00 on the
|
||||
first Sunday on or after January 14). The abbreviations for standard
|
||||
and daylight saving time are
|
||||
.q "+12"
|
||||
and
|
||||
.q "+13".
|
||||
.TP
|
||||
.B IST\*-2IDT,M3.4.4/26,M10.5.0
|
||||
stands for Israel Standard Time (IST) and Israel Daylight Time (IDT),
|
||||
2 hours ahead of UT, springing forward on March's fourth
|
||||
Thursday at 26:00 (i.e., 02:00 on the first Friday on or after March
|
||||
23), and falling back on October's last Sunday at 02:00.
|
||||
.TP
|
||||
.B <\*-04>4<\*-03>,J1/0,J365/25
|
||||
stands for permanent daylight saving time, 3 hours behind UT with
|
||||
abbreviation
|
||||
.q "\*-03".
|
||||
There is a dummy fall-back transition on December 31 at 25:00 daylight
|
||||
saving time (i.e., 24:00 standard time, equivalent to January 1 at
|
||||
00:00 standard time), and a simultaneous spring-forward transition on
|
||||
January 1 at 00:00 standard time, so daylight saving time is in effect
|
||||
all year and the initial
|
||||
.B <\*-04>
|
||||
is a placeholder.
|
||||
.TP
|
||||
.B <\*-03>3<\*-02>,M3.5.0/\*-2,M10.5.0/\*-1
|
||||
stands for time in western Greenland, 3 hours behind UT, where clocks
|
||||
follow the EU rules of
|
||||
springing forward on March's last Sunday at 01:00 UT (\-02:00 local
|
||||
time, i.e., 22:00 the previous day) and falling back on October's last
|
||||
Sunday at 01:00 UT (\-01:00 local time, i.e., 23:00 the previous day).
|
||||
The abbreviations for standard and daylight saving time are
|
||||
.q "\*-03"
|
||||
and
|
||||
.q "\*-02".
|
||||
.PP
|
||||
If no
|
||||
.I rule
|
||||
is present in
|
||||
.BR TZ ,
|
||||
the rules specified
|
||||
by the
|
||||
.BR tzfile (5)-format
|
||||
file
|
||||
.B posixrules
|
||||
in the system time conversion information directory are used, with the
|
||||
standard and daylight saving time offsets from UT replaced by those specified by
|
||||
the
|
||||
.I offset
|
||||
values in
|
||||
.BR TZ .
|
||||
.PP
|
||||
For compatibility with System V Release 3.1, a semicolon
|
||||
.RB ( ; )
|
||||
may be used to separate the
|
||||
.I rule
|
||||
from the rest of the specification.
|
||||
.SH FILES
|
||||
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
|
||||
/usr/share/zoneinfo timezone information directory
|
||||
.br
|
||||
/usr/share/zoneinfo/localtime local timezone file
|
||||
.br
|
||||
/usr/share/zoneinfo/posixrules used with POSIX-style TZ
|
||||
.br
|
||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||
.sp
|
||||
If
|
||||
.B /usr/share/zoneinfo/GMT
|
||||
is absent,
|
||||
UTC leap seconds are loaded from
|
||||
.BR /usr/share/zoneinfo/posixrules .
|
||||
.SH SEE ALSO
|
||||
getenv(3),
|
||||
newctime(3),
|
||||
newstrftime(3),
|
||||
time(2),
|
||||
tzfile(5)
|
957
contrib/tzcode/private.h
Normal file
957
contrib/tzcode/private.h
Normal file
|
@ -0,0 +1,957 @@
|
|||
/* Private header for tzdb code. */
|
||||
|
||||
#ifndef PRIVATE_H
|
||||
|
||||
#define PRIVATE_H
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
**
|
||||
** $FreeBSD$
|
||||
*/
|
||||
|
||||
/* Stuff moved from Makefile.inc to reduce clutter */
|
||||
#ifndef TM_GMTOFF
|
||||
#define TM_GMTOFF tm_gmtoff
|
||||
#define TM_ZONE tm_zone
|
||||
#define PCTS 1
|
||||
#define HAVE_LONG_DOUBLE 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define LOCALE_HOME _PATH_LOCALE
|
||||
#define TZDIR "/usr/share/zoneinfo"
|
||||
#endif /* ndef TM_GMTOFF */
|
||||
|
||||
/*
|
||||
** This header is for use ONLY with the time conversion code.
|
||||
** There is no guarantee that it will remain unchanged,
|
||||
** or that it will remain at all.
|
||||
** Do NOT copy it to any system include directory.
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
#ifndef __STDC_VERSION__
|
||||
# define __STDC_VERSION__ 0
|
||||
#endif
|
||||
|
||||
/* Define true, false and bool if they don't work out of the box. */
|
||||
#if __STDC_VERSION__ < 199901
|
||||
# define true 1
|
||||
# define false 0
|
||||
# define bool int
|
||||
#elif __STDC_VERSION__ < 202311
|
||||
# include <stdbool.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
** zdump has been made independent of the rest of the time
|
||||
** conversion package to increase confidence in the verification it provides.
|
||||
** You can use zdump to help in verifying other implementations.
|
||||
** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
|
||||
*/
|
||||
#ifndef USE_LTZ
|
||||
# define USE_LTZ 1
|
||||
#endif
|
||||
|
||||
/* This string was in the Factory zone through version 2016f. */
|
||||
#define GRANDPARENTED "Local time zone must be set--use tzsetup"
|
||||
|
||||
/*
|
||||
** Defaults for preprocessor symbols.
|
||||
** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_DECL_ASCTIME_R
|
||||
# define HAVE_DECL_ASCTIME_R 1
|
||||
#endif
|
||||
|
||||
#if !defined HAVE_GENERIC && defined __has_extension
|
||||
# if __has_extension(c_generic_selections)
|
||||
# define HAVE_GENERIC 1
|
||||
# else
|
||||
# define HAVE_GENERIC 0
|
||||
# endif
|
||||
#endif
|
||||
/* _Generic is buggy in pre-4.9 GCC. */
|
||||
#if !defined HAVE_GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
|
||||
# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
|
||||
#endif
|
||||
#ifndef HAVE_GENERIC
|
||||
# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
|
||||
#endif
|
||||
|
||||
#if !defined HAVE_GETTEXT && defined __has_include
|
||||
# if __has_include(<libintl.h>)
|
||||
# define HAVE_GETTEXT true
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_GETTEXT
|
||||
# define HAVE_GETTEXT false
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INCOMPATIBLE_CTIME_R
|
||||
# define HAVE_INCOMPATIBLE_CTIME_R 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LINK
|
||||
# define HAVE_LINK 1
|
||||
#endif /* !defined HAVE_LINK */
|
||||
|
||||
#ifndef HAVE_MALLOC_ERRNO
|
||||
# define HAVE_MALLOC_ERRNO 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_POSIX_DECLS
|
||||
# define HAVE_POSIX_DECLS 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SETENV
|
||||
# define HAVE_SETENV 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
# define HAVE_STRDUP 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRTOLL
|
||||
# define HAVE_STRTOLL 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SYMLINK
|
||||
# define HAVE_SYMLINK 1
|
||||
#endif /* !defined HAVE_SYMLINK */
|
||||
|
||||
#if !defined HAVE_SYS_STAT_H && defined __has_include
|
||||
# if !__has_include(<sys/stat.h>)
|
||||
# define HAVE_SYS_STAT_H false
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_SYS_STAT_H
|
||||
# define HAVE_SYS_STAT_H true
|
||||
#endif
|
||||
|
||||
#if !defined HAVE_UNISTD_H && defined __has_include
|
||||
# if !__has_include(<unistd.h>)
|
||||
# define HAVE_UNISTD_H false
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_UNISTD_H
|
||||
# define HAVE_UNISTD_H true
|
||||
#endif
|
||||
|
||||
#ifndef NETBSD_INSPIRED
|
||||
# define NETBSD_INSPIRED 1
|
||||
#endif
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
# define asctime_r _incompatible_asctime_r
|
||||
# define ctime_r _incompatible_ctime_r
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
|
||||
#define _GNU_SOURCE 1
|
||||
/* Fix asctime_r on Solaris 11. */
|
||||
#define _POSIX_PTHREAD_SEMANTICS 1
|
||||
/* Enable strtoimax on pre-C99 Solaris 11. */
|
||||
#define __EXTENSIONS__ 1
|
||||
|
||||
/* On GNUish systems where time_t might be 32 or 64 bits, use 64.
|
||||
On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
|
||||
setting _TIME_BITS to 64 does not work. The code does not
|
||||
otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
|
||||
use off_t or functions like 'stat' that depend on off_t. */
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
# define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
#if !defined _TIME_BITS && _FILE_OFFSET_BITS == 64
|
||||
# define _TIME_BITS 64
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Nested includes
|
||||
*/
|
||||
|
||||
/* Avoid clashes with NetBSD by renaming NetBSD's declarations.
|
||||
If defining the 'timezone' variable, avoid a clash with FreeBSD's
|
||||
'timezone' function by renaming its declaration. */
|
||||
#define localtime_rz sys_localtime_rz
|
||||
#define mktime_z sys_mktime_z
|
||||
#define posix2time_z sys_posix2time_z
|
||||
#define time2posix_z sys_time2posix_z
|
||||
#if defined USG_COMPAT && USG_COMPAT == 2
|
||||
# define timezone sys_timezone
|
||||
#endif
|
||||
#define timezone_t sys_timezone_t
|
||||
#define tzalloc sys_tzalloc
|
||||
#define tzfree sys_tzfree
|
||||
#include <time.h>
|
||||
#undef localtime_rz
|
||||
#undef mktime_z
|
||||
#undef posix2time_z
|
||||
#undef time2posix_z
|
||||
#if defined USG_COMPAT && USG_COMPAT == 2
|
||||
# undef timezone
|
||||
#endif
|
||||
#undef timezone_t
|
||||
#undef tzalloc
|
||||
#undef tzfree
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h> /* for CHAR_BIT et al. */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef EINVAL
|
||||
# define EINVAL ERANGE
|
||||
#endif
|
||||
|
||||
#ifndef ELOOP
|
||||
# define ELOOP EINVAL
|
||||
#endif
|
||||
#ifndef ENAMETOOLONG
|
||||
# define ENAMETOOLONG EINVAL
|
||||
#endif
|
||||
#ifndef ENOMEM
|
||||
# define ENOMEM EINVAL
|
||||
#endif
|
||||
#ifndef ENOTSUP
|
||||
# define ENOTSUP EINVAL
|
||||
#endif
|
||||
#ifndef EOVERFLOW
|
||||
# define EOVERFLOW EINVAL
|
||||
#endif
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
# include <libintl.h>
|
||||
#endif /* HAVE_GETTEXT */
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h> /* for R_OK, and other POSIX goodness */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#ifndef HAVE_STRFTIME_L
|
||||
# if _POSIX_VERSION < 200809
|
||||
# define HAVE_STRFTIME_L 0
|
||||
# else
|
||||
# define HAVE_STRFTIME_L 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef USG_COMPAT
|
||||
# ifndef _XOPEN_VERSION
|
||||
# define USG_COMPAT 0
|
||||
# else
|
||||
# define USG_COMPAT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_TZNAME
|
||||
# if _POSIX_VERSION < 198808 && !USG_COMPAT
|
||||
# define HAVE_TZNAME 0
|
||||
# else
|
||||
# define HAVE_TZNAME 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ALTZONE
|
||||
# if defined __sun || defined _M_XENIX
|
||||
# define ALTZONE 1
|
||||
# else
|
||||
# define ALTZONE 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef R_OK
|
||||
# define R_OK 4
|
||||
#endif /* !defined R_OK */
|
||||
|
||||
/*
|
||||
** Define HAVE_STDINT_H's default value here, rather than at the
|
||||
** start, since __GLIBC__ and INTMAX_MAX's values depend on
|
||||
** previously-included files. glibc 2.1 and Solaris 10 and later have
|
||||
** stdint.h, even with pre-C99 compilers.
|
||||
*/
|
||||
#if !defined HAVE_STDINT_H && defined __has_include
|
||||
# define HAVE_STDINT_H true /* C23 __has_include implies C99 stdint.h. */
|
||||
#endif
|
||||
#ifndef HAVE_STDINT_H
|
||||
# define HAVE_STDINT_H \
|
||||
(199901 <= __STDC_VERSION__ \
|
||||
|| 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
|
||||
|| __CYGWIN__ || INTMAX_MAX)
|
||||
#endif /* !defined HAVE_STDINT_H */
|
||||
|
||||
#if HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif /* !HAVE_STDINT_H */
|
||||
|
||||
#ifndef HAVE_INTTYPES_H
|
||||
# define HAVE_INTTYPES_H HAVE_STDINT_H
|
||||
#endif
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
|
||||
#if defined __LONG_LONG_MAX__ && !defined __STRICT_ANSI__
|
||||
# ifndef LLONG_MAX
|
||||
# define LLONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifndef LLONG_MIN
|
||||
# define LLONG_MIN (-1 - LLONG_MAX)
|
||||
# endif
|
||||
# ifndef ULLONG_MAX
|
||||
# define ULLONG_MAX (LLONG_MAX * 2ull + 1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INT_FAST64_MAX
|
||||
# if 1 <= LONG_MAX >> 31 >> 31
|
||||
typedef long int_fast64_t;
|
||||
# define INT_FAST64_MIN LONG_MIN
|
||||
# define INT_FAST64_MAX LONG_MAX
|
||||
# else
|
||||
/* If this fails, compile with -DHAVE_STDINT_H or with a better compiler. */
|
||||
typedef long long int_fast64_t;
|
||||
# define INT_FAST64_MIN LLONG_MIN
|
||||
# define INT_FAST64_MAX LLONG_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PRIdFAST64
|
||||
# if INT_FAST64_MAX == LONG_MAX
|
||||
# define PRIdFAST64 "ld"
|
||||
# else
|
||||
# define PRIdFAST64 "lld"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SCNdFAST64
|
||||
# define SCNdFAST64 PRIdFAST64
|
||||
#endif
|
||||
|
||||
#ifndef INT_FAST32_MAX
|
||||
# if INT_MAX >> 31 == 0
|
||||
typedef long int_fast32_t;
|
||||
# define INT_FAST32_MAX LONG_MAX
|
||||
# define INT_FAST32_MIN LONG_MIN
|
||||
# else
|
||||
typedef int int_fast32_t;
|
||||
# define INT_FAST32_MAX INT_MAX
|
||||
# define INT_FAST32_MIN INT_MIN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INTMAX_MAX
|
||||
# ifdef LLONG_MAX
|
||||
typedef long long intmax_t;
|
||||
# if HAVE_STRTOLL
|
||||
# define strtoimax strtoll
|
||||
# endif
|
||||
# define INTMAX_MAX LLONG_MAX
|
||||
# define INTMAX_MIN LLONG_MIN
|
||||
# else
|
||||
typedef long intmax_t;
|
||||
# define INTMAX_MAX LONG_MAX
|
||||
# define INTMAX_MIN LONG_MIN
|
||||
# endif
|
||||
# ifndef strtoimax
|
||||
# define strtoimax strtol
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PRIdMAX
|
||||
# if INTMAX_MAX == LLONG_MAX
|
||||
# define PRIdMAX "lld"
|
||||
# else
|
||||
# define PRIdMAX "ld"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PTRDIFF_MAX
|
||||
# define PTRDIFF_MAX MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
|
||||
#endif
|
||||
|
||||
#ifndef UINT_FAST32_MAX
|
||||
typedef unsigned long uint_fast32_t;
|
||||
#endif
|
||||
|
||||
#ifndef UINT_FAST64_MAX
|
||||
# if 3 <= ULONG_MAX >> 31 >> 31
|
||||
typedef unsigned long uint_fast64_t;
|
||||
# define UINT_FAST64_MAX ULONG_MAX
|
||||
# else
|
||||
/* If this fails, compile with -DHAVE_STDINT_H or with a better compiler. */
|
||||
typedef unsigned long long uint_fast64_t;
|
||||
# define UINT_FAST64_MAX ULLONG_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UINTMAX_MAX
|
||||
# ifdef ULLONG_MAX
|
||||
typedef unsigned long long uintmax_t;
|
||||
# else
|
||||
typedef unsigned long uintmax_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PRIuMAX
|
||||
# ifdef ULLONG_MAX
|
||||
# define PRIuMAX "llu"
|
||||
# else
|
||||
# define PRIuMAX "lu"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t) -1)
|
||||
#endif
|
||||
|
||||
/* Support ckd_add, ckd_sub, ckd_mul on C23 or recent-enough GCC-like
|
||||
hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG. */
|
||||
#if !defined HAVE_STDCKDINT_H && defined __has_include
|
||||
# if __has_include(<stdckdint.h>)
|
||||
# define HAVE_STDCKDINT_H true
|
||||
# endif
|
||||
#endif
|
||||
#ifdef HAVE_STDCKDINT_H
|
||||
# if HAVE_STDCKDINT_H
|
||||
# include <stdckdint.h>
|
||||
# endif
|
||||
#elif defined __EDG__
|
||||
/* Do nothing, to work around EDG bug <https://bugs.gnu.org/53256>. */
|
||||
#elif defined __has_builtin
|
||||
# if __has_builtin(__builtin_add_overflow)
|
||||
# define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
|
||||
# endif
|
||||
# if __has_builtin(__builtin_sub_overflow)
|
||||
# define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
|
||||
# endif
|
||||
# if __has_builtin(__builtin_mul_overflow)
|
||||
# define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
|
||||
# endif
|
||||
#elif 7 <= __GNUC__
|
||||
# define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
|
||||
# define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
|
||||
# define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
|
||||
#endif
|
||||
|
||||
#if 3 <= __GNUC__
|
||||
# define ATTRIBUTE_MALLOC __attribute__((malloc))
|
||||
# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
|
||||
#else
|
||||
# define ATTRIBUTE_MALLOC /* empty */
|
||||
# define ATTRIBUTE_FORMAT(spec) /* empty */
|
||||
#endif
|
||||
|
||||
#if (defined __has_c_attribute \
|
||||
&& (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
|
||||
# define HAVE_HAS_C_ATTRIBUTE true
|
||||
#else
|
||||
# define HAVE_HAS_C_ATTRIBUTE false
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(fallthrough)
|
||||
# define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
|
||||
# endif
|
||||
#endif
|
||||
#ifndef ATTRIBUTE_FALLTHROUGH
|
||||
# if 7 <= __GNUC__
|
||||
# define ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
|
||||
# else
|
||||
# define ATTRIBUTE_FALLTHROUGH ((void) 0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(maybe_unused)
|
||||
# define ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
|
||||
# endif
|
||||
#endif
|
||||
#ifndef ATTRIBUTE_MAYBE_UNUSED
|
||||
# if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
|
||||
# define ATTRIBUTE_MAYBE_UNUSED __attribute__((unused))
|
||||
# else
|
||||
# define ATTRIBUTE_MAYBE_UNUSED /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(noreturn)
|
||||
# define ATTRIBUTE_NORETURN [[noreturn]]
|
||||
# endif
|
||||
#endif
|
||||
#ifndef ATTRIBUTE_NORETURN
|
||||
# if 201112 <= __STDC_VERSION__
|
||||
# define ATTRIBUTE_NORETURN _Noreturn
|
||||
# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
|
||||
# define ATTRIBUTE_NORETURN __attribute__((noreturn))
|
||||
# else
|
||||
# define ATTRIBUTE_NORETURN /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(reproducible)
|
||||
# define ATTRIBUTE_REPRODUCIBLE [[reproducible]]
|
||||
# endif
|
||||
#endif
|
||||
#ifndef ATTRIBUTE_REPRODUCIBLE
|
||||
# if 3 <= __GNUC__
|
||||
# define ATTRIBUTE_REPRODUCIBLE __attribute__((pure))
|
||||
# else
|
||||
# define ATTRIBUTE_REPRODUCIBLE /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(unsequenced)
|
||||
# define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
|
||||
# endif
|
||||
#endif
|
||||
#ifndef ATTRIBUTE_UNSEQUENCED
|
||||
# if 3 <= __GNUC__
|
||||
# define ATTRIBUTE_UNSEQUENCED __attribute__((const))
|
||||
# else
|
||||
# define ATTRIBUTE_UNSEQUENCED /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ < 199901 && !defined restrict
|
||||
# define restrict /* empty */
|
||||
#endif
|
||||
|
||||
#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)
|
||||
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
|
||||
#else
|
||||
# define ATTRIBUTE_PURE /* empty */
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Workarounds for compilers/systems.
|
||||
*/
|
||||
|
||||
#ifndef EPOCH_LOCAL
|
||||
# define EPOCH_LOCAL 0
|
||||
#endif
|
||||
#ifndef EPOCH_OFFSET
|
||||
# define EPOCH_OFFSET 0
|
||||
#endif
|
||||
#ifndef RESERVE_STD_EXT_IDS
|
||||
# define RESERVE_STD_EXT_IDS 0
|
||||
#endif
|
||||
|
||||
/* If standard C identifiers with external linkage (e.g., localtime)
|
||||
are reserved and are not already being renamed anyway, rename them
|
||||
as if compiling with '-Dtime_tz=time_t'. */
|
||||
#if !defined time_tz && RESERVE_STD_EXT_IDS && USE_LTZ
|
||||
# define time_tz time_t
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Compile with -Dtime_tz=T to build the tz package with a private
|
||||
** time_t type equivalent to T rather than the system-supplied time_t.
|
||||
** This debugging feature can test unusual design decisions
|
||||
** (e.g., time_t wider than 'long', or unsigned time_t) even on
|
||||
** typical platforms.
|
||||
*/
|
||||
#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
|
||||
# define TZ_TIME_T 1
|
||||
#else
|
||||
# define TZ_TIME_T 0
|
||||
#endif
|
||||
|
||||
#if defined LOCALTIME_IMPLEMENTATION && TZ_TIME_T
|
||||
static time_t sys_time(time_t *x) { return time(x); }
|
||||
#endif
|
||||
|
||||
#if TZ_TIME_T
|
||||
|
||||
typedef time_tz tz_time_t;
|
||||
|
||||
# undef asctime
|
||||
# define asctime tz_asctime
|
||||
# undef asctime_r
|
||||
# define asctime_r tz_asctime_r
|
||||
# undef ctime
|
||||
# define ctime tz_ctime
|
||||
# undef ctime_r
|
||||
# define ctime_r tz_ctime_r
|
||||
# undef difftime
|
||||
# define difftime tz_difftime
|
||||
# undef gmtime
|
||||
# define gmtime tz_gmtime
|
||||
# undef gmtime_r
|
||||
# define gmtime_r tz_gmtime_r
|
||||
# undef localtime
|
||||
# define localtime tz_localtime
|
||||
# undef localtime_r
|
||||
# define localtime_r tz_localtime_r
|
||||
# undef localtime_rz
|
||||
# define localtime_rz tz_localtime_rz
|
||||
# undef mktime
|
||||
# define mktime tz_mktime
|
||||
# undef mktime_z
|
||||
# define mktime_z tz_mktime_z
|
||||
# undef offtime
|
||||
# define offtime tz_offtime
|
||||
# undef posix2time
|
||||
# define posix2time tz_posix2time
|
||||
# undef posix2time_z
|
||||
# define posix2time_z tz_posix2time_z
|
||||
# undef strftime
|
||||
# define strftime tz_strftime
|
||||
# undef time
|
||||
# define time tz_time
|
||||
# undef time2posix
|
||||
# define time2posix tz_time2posix
|
||||
# undef time2posix_z
|
||||
# define time2posix_z tz_time2posix_z
|
||||
# undef time_t
|
||||
# define time_t tz_time_t
|
||||
# undef timegm
|
||||
# define timegm tz_timegm
|
||||
# undef timelocal
|
||||
# define timelocal tz_timelocal
|
||||
# undef timeoff
|
||||
# define timeoff tz_timeoff
|
||||
# undef tzalloc
|
||||
# define tzalloc tz_tzalloc
|
||||
# undef tzfree
|
||||
# define tzfree tz_tzfree
|
||||
# undef tzset
|
||||
# define tzset tz_tzset
|
||||
# if HAVE_STRFTIME_L
|
||||
# undef strftime_l
|
||||
# define strftime_l tz_strftime_l
|
||||
# endif
|
||||
# if HAVE_TZNAME
|
||||
# undef tzname
|
||||
# define tzname tz_tzname
|
||||
# endif
|
||||
# if USG_COMPAT
|
||||
# undef daylight
|
||||
# define daylight tz_daylight
|
||||
# undef timezone
|
||||
# define timezone tz_timezone
|
||||
# endif
|
||||
# if ALTZONE
|
||||
# undef altzone
|
||||
# define altzone tz_altzone
|
||||
# endif
|
||||
|
||||
char *asctime(struct tm const *);
|
||||
char *asctime_r(struct tm const *restrict, char *restrict);
|
||||
char *ctime(time_t const *);
|
||||
char *ctime_r(time_t const *, char *);
|
||||
double difftime(time_t, time_t) ATTRIBUTE_UNSEQUENCED;
|
||||
size_t strftime(char *restrict, size_t, char const *restrict,
|
||||
struct tm const *restrict);
|
||||
# if HAVE_STRFTIME_L
|
||||
size_t strftime_l(char *restrict, size_t, char const *restrict,
|
||||
struct tm const *restrict, locale_t);
|
||||
# endif
|
||||
struct tm *gmtime(time_t const *);
|
||||
struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
|
||||
struct tm *localtime(time_t const *);
|
||||
struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
|
||||
time_t mktime(struct tm *);
|
||||
time_t time(time_t *);
|
||||
time_t timegm(struct tm *);
|
||||
void tzset(void);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_TIMEGM
|
||||
# if (202311 <= __STDC_VERSION__ \
|
||||
|| defined __GLIBC__ || defined __tm_zone /* musl */ \
|
||||
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|
||||
|| (defined __APPLE__ && defined __MACH__))
|
||||
# define HAVE_DECL_TIMEGM true
|
||||
# else
|
||||
# define HAVE_DECL_TIMEGM false
|
||||
# endif
|
||||
#endif
|
||||
#if !HAVE_DECL_TIMEGM && !defined timegm
|
||||
time_t timegm(struct tm *);
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_ASCTIME_R && !defined asctime_r
|
||||
extern char *asctime_r(struct tm const *restrict, char *restrict);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_ENVIRON
|
||||
# if defined environ || defined __USE_GNU
|
||||
# define HAVE_DECL_ENVIRON 1
|
||||
# else
|
||||
# define HAVE_DECL_ENVIRON 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_ENVIRON
|
||||
extern char **environ;
|
||||
#endif
|
||||
|
||||
#if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS)
|
||||
extern char *tzname[];
|
||||
#endif
|
||||
#if 2 <= USG_COMPAT + (TZ_TIME_T || !HAVE_POSIX_DECLS)
|
||||
extern long timezone;
|
||||
extern int daylight;
|
||||
#endif
|
||||
#if 2 <= ALTZONE + (TZ_TIME_T || !HAVE_POSIX_DECLS)
|
||||
extern long altzone;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The STD_INSPIRED functions are similar, but most also need
|
||||
** declarations if time_tz is defined.
|
||||
*/
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
# if TZ_TIME_T || !defined offtime
|
||||
struct tm *offtime(time_t const *, long);
|
||||
# endif
|
||||
# if TZ_TIME_T || !defined timelocal
|
||||
time_t timelocal(struct tm *);
|
||||
# endif
|
||||
# if TZ_TIME_T || !defined timeoff
|
||||
time_t timeoff(struct tm *, long);
|
||||
# endif
|
||||
# if TZ_TIME_T || !defined time2posix
|
||||
time_t time2posix(time_t);
|
||||
# endif
|
||||
# if TZ_TIME_T || !defined posix2time
|
||||
time_t posix2time(time_t);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Infer TM_ZONE on systems where this information is known, but suppress
|
||||
guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
|
||||
#if (defined __GLIBC__ \
|
||||
|| defined __tm_zone /* musl */ \
|
||||
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|
||||
|| (defined __APPLE__ && defined __MACH__))
|
||||
# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
|
||||
# define TM_GMTOFF tm_gmtoff
|
||||
# endif
|
||||
# if !defined TM_ZONE && !defined NO_TM_ZONE
|
||||
# define TM_ZONE tm_zone
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Define functions that are ABI compatible with NetBSD but have
|
||||
** better prototypes. NetBSD 6.1.4 defines a pointer type timezone_t
|
||||
** and labors under the misconception that 'const timezone_t' is a
|
||||
** pointer to a constant. This use of 'const' is ineffective, so it
|
||||
** is not done here. What we call 'struct state' NetBSD calls
|
||||
** 'struct __state', but this is a private name so it doesn't matter.
|
||||
*/
|
||||
#if NETBSD_INSPIRED
|
||||
typedef struct state *timezone_t;
|
||||
struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
|
||||
struct tm *restrict);
|
||||
time_t mktime_z(timezone_t restrict, struct tm *restrict);
|
||||
timezone_t tzalloc(char const *);
|
||||
void tzfree(timezone_t);
|
||||
# ifdef STD_INSPIRED
|
||||
# if TZ_TIME_T || !defined posix2time_z
|
||||
time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
||||
# endif
|
||||
# if TZ_TIME_T || !defined time2posix_z
|
||||
time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Finally, some convenience items.
|
||||
*/
|
||||
|
||||
#define TYPE_BIT(type) (sizeof(type) * CHAR_BIT)
|
||||
#define TYPE_SIGNED(type) (((type) -1) < 0)
|
||||
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
|
||||
|
||||
/* Minimum and maximum of two values. Use lower case to avoid
|
||||
naming clashes with standard include files. */
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
/* Max and min values of the integer type T, of which only the bottom
|
||||
B bits are used, and where the highest-order used bit is considered
|
||||
to be a sign bit if T is signed. */
|
||||
#define MAXVAL(t, b) \
|
||||
((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
|
||||
- 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
|
||||
#define MINVAL(t, b) \
|
||||
((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
|
||||
|
||||
/* The extreme time values, assuming no padding. */
|
||||
#define TIME_T_MIN_NO_PADDING MINVAL(time_t, TYPE_BIT(time_t))
|
||||
#define TIME_T_MAX_NO_PADDING MAXVAL(time_t, TYPE_BIT(time_t))
|
||||
|
||||
/* The extreme time values. These are macros, not constants, so that
|
||||
any portability problems occur only when compiling .c files that use
|
||||
the macros, which is safer for applications that need only zdump and zic.
|
||||
This implementation assumes no padding if time_t is signed and
|
||||
either the compiler lacks support for _Generic or time_t is not one
|
||||
of the standard signed integer types. */
|
||||
#if HAVE_GENERIC
|
||||
# define TIME_T_MIN \
|
||||
_Generic((time_t) 0, \
|
||||
signed char: SCHAR_MIN, short: SHRT_MIN, \
|
||||
int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \
|
||||
default: TIME_T_MIN_NO_PADDING)
|
||||
# define TIME_T_MAX \
|
||||
(TYPE_SIGNED(time_t) \
|
||||
? _Generic((time_t) 0, \
|
||||
signed char: SCHAR_MAX, short: SHRT_MAX, \
|
||||
int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
|
||||
default: TIME_T_MAX_NO_PADDING) \
|
||||
: (time_t) -1)
|
||||
#else
|
||||
# define TIME_T_MIN TIME_T_MIN_NO_PADDING
|
||||
# define TIME_T_MAX TIME_T_MAX_NO_PADDING
|
||||
#endif
|
||||
|
||||
/*
|
||||
** 302 / 1000 is log10(2.0) rounded up.
|
||||
** Subtract one for the sign bit if the type is signed;
|
||||
** add one for integer division truncation;
|
||||
** add one more for a minus sign if the type is signed.
|
||||
*/
|
||||
#define INT_STRLEN_MAXIMUM(type) \
|
||||
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
|
||||
1 + TYPE_SIGNED(type))
|
||||
|
||||
/*
|
||||
** INITIALIZE(x)
|
||||
*/
|
||||
|
||||
#ifdef GCC_LINT
|
||||
# define INITIALIZE(x) ((x) = 0)
|
||||
#else
|
||||
# define INITIALIZE(x)
|
||||
#endif
|
||||
|
||||
/* Whether memory access must strictly follow the C standard.
|
||||
If 0, it's OK to read uninitialized storage so long as the value is
|
||||
not relied upon. Defining it to 0 lets mktime access parts of
|
||||
struct tm that might be uninitialized, as a heuristic when the
|
||||
standard doesn't say what to return and when tm_gmtoff can help
|
||||
mktime likely infer a better value. */
|
||||
#ifndef UNINIT_TRAP
|
||||
# define UNINIT_TRAP 0
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# undef unreachable
|
||||
# define unreachable() abort()
|
||||
#elif !defined unreachable
|
||||
# ifdef __has_builtin
|
||||
# if __has_builtin(__builtin_unreachable)
|
||||
# define unreachable() __builtin_unreachable()
|
||||
# endif
|
||||
# elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
|
||||
# define unreachable() __builtin_unreachable()
|
||||
# endif
|
||||
# ifndef unreachable
|
||||
# define unreachable() ((void) 0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** For the benefit of GNU folk...
|
||||
** '_(MSGID)' uses the current locale's message library string for MSGID.
|
||||
** The default is to use gettext if available, and use MSGID otherwise.
|
||||
*/
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
#define _(msgid) gettext(msgid)
|
||||
#else /* !HAVE_GETTEXT */
|
||||
#define _(msgid) msgid
|
||||
#endif /* !HAVE_GETTEXT */
|
||||
|
||||
#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
|
||||
# define TZ_DOMAIN "tz"
|
||||
#endif
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#undef asctime_r
|
||||
#undef ctime_r
|
||||
char *asctime_r(struct tm const *, char *);
|
||||
char *ctime_r(time_t const *, char *);
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
/* Handy macros that are independent of tzfile implementation. */
|
||||
|
||||
enum {
|
||||
SECSPERMIN = 60,
|
||||
MINSPERHOUR = 60,
|
||||
SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
|
||||
HOURSPERDAY = 24,
|
||||
DAYSPERWEEK = 7,
|
||||
DAYSPERNYEAR = 365,
|
||||
DAYSPERLYEAR = DAYSPERNYEAR + 1,
|
||||
MONSPERYEAR = 12,
|
||||
YEARSPERREPEAT = 400 /* years before a Gregorian repeat */
|
||||
};
|
||||
|
||||
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
|
||||
|
||||
#define DAYSPERREPEAT ((int_fast32_t) 400 * 365 + 100 - 4 + 1)
|
||||
#define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
|
||||
#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)
|
||||
|
||||
enum {
|
||||
TM_SUNDAY,
|
||||
TM_MONDAY,
|
||||
TM_TUESDAY,
|
||||
TM_WEDNESDAY,
|
||||
TM_THURSDAY,
|
||||
TM_FRIDAY,
|
||||
TM_SATURDAY
|
||||
};
|
||||
|
||||
enum {
|
||||
TM_JANUARY,
|
||||
TM_FEBRUARY,
|
||||
TM_MARCH,
|
||||
TM_APRIL,
|
||||
TM_MAY,
|
||||
TM_JUNE,
|
||||
TM_JULY,
|
||||
TM_AUGUST,
|
||||
TM_SEPTEMBER,
|
||||
TM_OCTOBER,
|
||||
TM_NOVEMBER,
|
||||
TM_DECEMBER
|
||||
};
|
||||
|
||||
enum {
|
||||
TM_YEAR_BASE = 1900,
|
||||
TM_WDAY_BASE = TM_MONDAY,
|
||||
EPOCH_YEAR = 1970,
|
||||
EPOCH_WDAY = TM_THURSDAY
|
||||
};
|
||||
|
||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||
|
||||
/*
|
||||
** 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 by C99 or later).
|
||||
** We use this to avoid addition overflow problems.
|
||||
*/
|
||||
|
||||
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
|
||||
|
||||
#endif /* !defined PRIVATE_H */
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] __unused = "@(#)difftime.c 8.1";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
|
||||
#include "un-namespace.h"
|
||||
|
||||
double
|
||||
difftime(const time_t time1, const time_t 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.
|
||||
*/
|
||||
if (sizeof (double) > sizeof (time_t))
|
||||
return (double) time1 - (double) time0;
|
||||
if (!TYPE_INTEGRAL(time_t)) {
|
||||
/*
|
||||
** time_t is floating.
|
||||
*/
|
||||
return time1 - time0;
|
||||
}
|
||||
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));
|
||||
}
|
||||
/*
|
||||
** time_t is integral and signed.
|
||||
** Handle cases where both time1 and time0 have the same sign
|
||||
** (meaning that their difference cannot overflow).
|
||||
*/
|
||||
if ((time1 < 0) == (time0 < 0))
|
||||
return time1 - time0;
|
||||
/*
|
||||
** time1 and time0 have opposite signs.
|
||||
** Punt if unsigned long is too narrow.
|
||||
*/
|
||||
if (sizeof (unsigned long) < sizeof (time_t))
|
||||
return (double) time1 - (double) time0;
|
||||
/*
|
||||
** Stay calm...decent optimizers will eliminate the complexity below.
|
||||
*/
|
||||
if (time1 >= 0 /* && time0 < 0 */)
|
||||
return (unsigned long) time1 +
|
||||
(unsigned long) (-(time0 + 1)) + 1;
|
||||
return -(double) ((unsigned long) time0 +
|
||||
(unsigned long) (-(time1 + 1)) + 1);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,318 +0,0 @@
|
|||
#ifndef PRIVATE_H
|
||||
|
||||
#define PRIVATE_H
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
**
|
||||
** $FreeBSD$
|
||||
*/
|
||||
|
||||
/* Stuff moved from Makefile.inc to reduce clutter */
|
||||
#ifndef TM_GMTOFF
|
||||
#define TM_GMTOFF tm_gmtoff
|
||||
#define TM_ZONE tm_zone
|
||||
#define STD_INSPIRED 1
|
||||
#define PCTS 1
|
||||
#define HAVE_LONG_DOUBLE 1
|
||||
#define HAVE_STRERROR 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define LOCALE_HOME _PATH_LOCALE
|
||||
#define TZDIR "/usr/share/zoneinfo"
|
||||
#endif /* ndef TM_GMTOFF */
|
||||
|
||||
/*
|
||||
** This header is for use ONLY with the time conversion code.
|
||||
** There is no guarantee that it will remain unchanged,
|
||||
** or that it will remain at all.
|
||||
** Do NOT copy it to any system include directory.
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
/*
|
||||
** ID
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
/*
|
||||
static char privatehid[] = "@(#)private.h 8.6";
|
||||
*/
|
||||
#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'.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_ADJTIME
|
||||
#define HAVE_ADJTIME 1
|
||||
#endif /* !defined HAVE_ADJTIME */
|
||||
|
||||
#ifndef HAVE_GETTEXT
|
||||
#define HAVE_GETTEXT 0
|
||||
#endif /* !defined HAVE_GETTEXT */
|
||||
|
||||
#ifndef HAVE_INCOMPATIBLE_CTIME_R
|
||||
#define HAVE_INCOMPATIBLE_CTIME_R 0
|
||||
#endif /* !defined INCOMPATIBLE_CTIME_R */
|
||||
|
||||
#ifndef HAVE_SETTIMEOFDAY
|
||||
#define HAVE_SETTIMEOFDAY 3
|
||||
#endif /* !defined HAVE_SETTIMEOFDAY */
|
||||
|
||||
#ifndef HAVE_SYMLINK
|
||||
#define HAVE_SYMLINK 1
|
||||
#endif /* !defined HAVE_SYMLINK */
|
||||
|
||||
#ifndef HAVE_SYS_STAT_H
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#endif /* !defined HAVE_SYS_STAT_H */
|
||||
|
||||
#ifndef HAVE_SYS_WAIT_H
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
#endif /* !defined HAVE_SYS_WAIT_H */
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif /* !defined HAVE_UNISTD_H */
|
||||
|
||||
#ifndef HAVE_UTMPX_H
|
||||
#define HAVE_UTMPX_H 0
|
||||
#endif /* !defined HAVE_UTMPX_H */
|
||||
|
||||
#ifndef LOCALE_HOME
|
||||
#define LOCALE_HOME "/usr/lib/locale"
|
||||
#endif /* !defined LOCALE_HOME */
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#define asctime_r _incompatible_asctime_r
|
||||
#define ctime_r _incompatible_ctime_r
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
/*
|
||||
** Nested includes
|
||||
*/
|
||||
|
||||
#include "sys/types.h" /* for time_t */
|
||||
#include "stdio.h"
|
||||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "limits.h" /* for CHAR_BIT et al. */
|
||||
#include "time.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
#include "libintl.h"
|
||||
#endif /* HAVE_GETTEXT */
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
|
||||
#endif /* HAVE_SYS_WAIT_H */
|
||||
|
||||
#ifndef WIFEXITED
|
||||
#define WIFEXITED(status) (((status) & 0xff) == 0)
|
||||
#endif /* !defined WIFEXITED */
|
||||
#ifndef WEXITSTATUS
|
||||
#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
|
||||
#endif /* !defined WEXITSTATUS */
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if !(HAVE_UNISTD_H)
|
||||
#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) */
|
||||
|
||||
/* 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 */
|
||||
|
||||
#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)
|
||||
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
|
||||
#else
|
||||
# define ATTRIBUTE_PURE /* empty */
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Workarounds for compilers/systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Some time.h implementations don't declare asctime_r.
|
||||
** Others might define it as a macro.
|
||||
** Fix the former without affecting the latter.
|
||||
*/
|
||||
|
||||
#ifndef asctime_r
|
||||
extern char * asctime_r(struct tm const *, char *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Private function declarations.
|
||||
*/
|
||||
|
||||
char * icatalloc(char * old, const char * new);
|
||||
char * icpyalloc(const char * string);
|
||||
const char * scheck(const char * string, const char * format);
|
||||
|
||||
/*
|
||||
** Finally, some convenience items.
|
||||
*/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* !defined TRUE */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* !defined FALSE */
|
||||
|
||||
#ifndef TYPE_BIT
|
||||
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
|
||||
#endif /* !defined TYPE_BIT */
|
||||
|
||||
#ifndef TYPE_SIGNED
|
||||
#define TYPE_SIGNED(type) (((type) -1) < 0)
|
||||
#endif /* !defined TYPE_SIGNED */
|
||||
|
||||
/*
|
||||
** 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.
|
||||
** Subtract one for the sign bit if the type is signed;
|
||||
** add one for integer division truncation;
|
||||
** add one more for a minus sign if the type is signed.
|
||||
*/
|
||||
#define INT_STRLEN_MAXIMUM(type) \
|
||||
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
|
||||
1 + TYPE_SIGNED(type))
|
||||
#endif /* !defined INT_STRLEN_MAXIMUM */
|
||||
|
||||
/*
|
||||
** INITIALIZE(x)
|
||||
*/
|
||||
|
||||
#ifndef GNUC_or_lint
|
||||
#ifdef lint
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined lint */
|
||||
#ifndef lint
|
||||
#ifdef __GNUC__
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined __GNUC__ */
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
|
||||
#ifndef INITIALIZE
|
||||
#ifdef GNUC_or_lint
|
||||
#define INITIALIZE(x) ((x) = 0)
|
||||
#endif /* defined GNUC_or_lint */
|
||||
#ifndef GNUC_or_lint
|
||||
#define INITIALIZE(x)
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
#endif /* !defined INITIALIZE */
|
||||
|
||||
/*
|
||||
** For the benefit of GNU folk...
|
||||
** `_(MSGID)' uses the current locale's message library string for MSGID.
|
||||
** The default is to use gettext if available, and use MSGID otherwise.
|
||||
*/
|
||||
|
||||
#ifndef _
|
||||
#if HAVE_GETTEXT
|
||||
#define _(msgid) gettext(msgid)
|
||||
#else /* !HAVE_GETTEXT */
|
||||
#define _(msgid) msgid
|
||||
#endif /* !HAVE_GETTEXT */
|
||||
#endif /* !defined _ */
|
||||
|
||||
#ifndef TZ_DOMAIN
|
||||
#define TZ_DOMAIN "tz"
|
||||
#endif /* !defined TZ_DOMAIN */
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#undef asctime_r
|
||||
#undef ctime_r
|
||||
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.
|
||||
*/
|
||||
|
||||
#endif /* !defined PRIVATE_H */
|
|
@ -1,152 +0,0 @@
|
|||
.\" $FreeBSD$
|
||||
.Dd September 13, 1994
|
||||
.Dt TZFILE 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm tzfile
|
||||
.Nd timezone information
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include \&"/usr/src/contrib/tzcode/stdtime/tzfile.h\&"
|
||||
.Sh DESCRIPTION
|
||||
The time zone information files used by
|
||||
.Xr tzset 3
|
||||
begin with the magic characters
|
||||
.Dq Li TZif
|
||||
to identify them as
|
||||
time zone information files,
|
||||
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 four four-byte values
|
||||
written in a ``standard'' byte order
|
||||
(the high-order byte of the value is written first).
|
||||
These values are,
|
||||
in order:
|
||||
.Pp
|
||||
.Bl -tag -compact -width tzh_ttisstdcnt
|
||||
.It Va tzh_ttisgmtcnt
|
||||
The number of UTC/local indicators stored in the file.
|
||||
.It Va tzh_ttisstdcnt
|
||||
The number of standard/wall indicators stored in the file.
|
||||
.It Va tzh_leapcnt
|
||||
The number of leap seconds for which data is stored in the file.
|
||||
.It Va tzh_timecnt
|
||||
The number of ``transition times'' for which data is stored
|
||||
in the file.
|
||||
.It Va tzh_typecnt
|
||||
The number of ``local time types'' for which data is stored
|
||||
in the file (must not be zero).
|
||||
.It Va tzh_charcnt
|
||||
The number of characters of ``time zone abbreviation strings''
|
||||
stored in the file.
|
||||
.El
|
||||
.Pp
|
||||
The above header is followed by
|
||||
.Va tzh_timecnt
|
||||
four-byte values of type
|
||||
.Fa long ,
|
||||
sorted in ascending order.
|
||||
These values are written in ``standard'' byte order.
|
||||
Each is used as a transition time (as returned by
|
||||
.Xr time 3 )
|
||||
at which the rules for computing local time change.
|
||||
Next come
|
||||
.Va tzh_timecnt
|
||||
one-byte values of type
|
||||
.Fa "unsigned char" ;
|
||||
each one tells which of the different types of ``local time'' 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 (with
|
||||
.Fa tzh_typecnt
|
||||
entries) that appears next in the file;
|
||||
these structures are defined as follows:
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
struct ttinfo {
|
||||
long tt_gmtoff;
|
||||
int tt_isdst;
|
||||
unsigned int tt_abbrind;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
Each structure is written as a four-byte value for
|
||||
.Va tt_gmtoff
|
||||
of type
|
||||
.Fa long ,
|
||||
in a standard byte order, followed by a one-byte value for
|
||||
.Va tt_isdst
|
||||
and a one-byte value for
|
||||
.Va tt_abbrind .
|
||||
In each structure,
|
||||
.Va tt_gmtoff
|
||||
gives the number of seconds to be added to UTC,
|
||||
.Li tt_isdst
|
||||
tells whether
|
||||
.Li tm_isdst
|
||||
should be set by
|
||||
.Xr localtime 3
|
||||
and
|
||||
.Va tt_abbrind
|
||||
serves as an index into the array of time zone abbreviation characters
|
||||
that follow the
|
||||
.Li ttinfo
|
||||
structure(s) in the file.
|
||||
.Pp
|
||||
Then there are
|
||||
.Va tzh_leapcnt
|
||||
pairs of four-byte values, written in standard byte order;
|
||||
the first value of each pair gives the time
|
||||
(as returned by
|
||||
.Xr time 3 )
|
||||
at which a leap second occurs;
|
||||
the second gives the
|
||||
.Em total
|
||||
number of leap seconds to be applied after the given time.
|
||||
The pairs of values are sorted in ascending order by time.
|
||||
.Pp
|
||||
Then there are
|
||||
.Va tzh_ttisstdcnt
|
||||
standard/wall indicators, each stored as a one-byte value;
|
||||
they tell whether the transition times associated with local time types
|
||||
were specified as standard time or wall clock time,
|
||||
and are used when a time zone file is used in handling POSIX-style
|
||||
time zone environment variables.
|
||||
.Pp
|
||||
Finally there are
|
||||
.Va tzh_ttisgmtcnt
|
||||
UTC/local indicators, each stored as a one-byte value;
|
||||
they tell whether the transition times associated with local time types
|
||||
were specified as UTC or local time,
|
||||
and are used when a time zone file is used in handling POSIX-style
|
||||
time zone environment variables.
|
||||
.Pp
|
||||
.Nm localtime
|
||||
uses the first standard-time
|
||||
.Li ttinfo
|
||||
structure in the file
|
||||
(or simply the first
|
||||
.Li ttinfo
|
||||
structure in the absence of a standard-time structure)
|
||||
if either
|
||||
.Li 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 time2posix 3 ,
|
||||
.Xr zic 8
|
||||
.\" @(#)tzfile.5 8.3
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 1996-06-05 by Arthur David Olson.
|
|
@ -1,184 +0,0 @@
|
|||
#ifndef TZFILE_H
|
||||
#define TZFILE_H
|
||||
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
**
|
||||
** $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is for use ONLY with the time conversion code.
|
||||
** There is no guarantee that it will remain unchanged,
|
||||
** or that it will remain at all.
|
||||
** Do NOT copy it to any system include directory.
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
/*
|
||||
** ID
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
/*
|
||||
static char tzfilehid[] = "@(#)tzfile.h 8.1";
|
||||
*/
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*
|
||||
** Information about time zone files.
|
||||
*/
|
||||
|
||||
#ifndef TZDIR
|
||||
#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
|
||||
#endif /* !defined TZDIR */
|
||||
|
||||
#ifndef TZDEFAULT
|
||||
#define TZDEFAULT "/etc/localtime"
|
||||
#endif /* !defined TZDEFAULT */
|
||||
|
||||
#ifndef TZDEFRULES
|
||||
#define TZDEFRULES "posixrules"
|
||||
#endif /* !defined TZDEFRULES */
|
||||
|
||||
/*
|
||||
** Each file begins with. . .
|
||||
*/
|
||||
|
||||
#define TZ_MAGIC "TZif"
|
||||
|
||||
struct tzhead {
|
||||
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 */
|
||||
char tzh_timecnt[4]; /* coded number of transition times */
|
||||
char tzh_typecnt[4]; /* coded number of local time types */
|
||||
char tzh_charcnt[4]; /* coded number of abbr. chars */
|
||||
};
|
||||
|
||||
/*
|
||||
** . . .followed by. . .
|
||||
**
|
||||
** tzh_timecnt (char [4])s coded transition times a la time(2)
|
||||
** tzh_timecnt (unsigned char)s types of local time starting at above
|
||||
** tzh_typecnt repetitions of
|
||||
** one (char [4]) coded UTC offset in seconds
|
||||
** one (unsigned char) used to set tm_isdst
|
||||
** one (unsigned char) that's an abbreviation list index
|
||||
** tzh_charcnt (char)s '\0'-terminated zone abbreviations
|
||||
** tzh_leapcnt repetitions of
|
||||
** one (char [4]) coded leap second transition times
|
||||
** one (char [4]) total correction after above
|
||||
** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
|
||||
** time is standard time, if FALSE,
|
||||
** transition time is wall clock time
|
||||
** if absent, transition times are
|
||||
** assumed to be wall clock time
|
||||
** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
|
||||
** time is UTC, if FALSE,
|
||||
** transition time is local time
|
||||
** if absent, transition times are
|
||||
** 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
|
||||
#define TZ_MAX_TIMES 1200
|
||||
#endif /* !defined TZ_MAX_TIMES */
|
||||
|
||||
#ifndef TZ_MAX_TYPES
|
||||
#ifndef NOSOLAR
|
||||
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
|
||||
#endif /* !defined NOSOLAR */
|
||||
#ifdef NOSOLAR
|
||||
/*
|
||||
** Must be at least 14 for Europe/Riga as of Jan 12 1995,
|
||||
** as noted by Earl Chew.
|
||||
*/
|
||||
#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
|
||||
#endif /* !defined NOSOLAR */
|
||||
#endif /* !defined TZ_MAX_TYPES */
|
||||
|
||||
#ifndef TZ_MAX_CHARS
|
||||
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
||||
/* (limited by what unsigned chars can hold) */
|
||||
#endif /* !defined TZ_MAX_CHARS */
|
||||
|
||||
#ifndef TZ_MAX_LEAPS
|
||||
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
|
||||
#endif /* !defined TZ_MAX_LEAPS */
|
||||
|
||||
#define SECSPERMIN 60
|
||||
#define MINSPERHOUR 60
|
||||
#define HOURSPERDAY 24
|
||||
#define DAYSPERWEEK 7
|
||||
#define DAYSPERNYEAR 365
|
||||
#define DAYSPERLYEAR 366
|
||||
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
|
||||
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
|
||||
#define MONSPERYEAR 12
|
||||
|
||||
#define TM_SUNDAY 0
|
||||
#define TM_MONDAY 1
|
||||
#define TM_TUESDAY 2
|
||||
#define TM_WEDNESDAY 3
|
||||
#define TM_THURSDAY 4
|
||||
#define TM_FRIDAY 5
|
||||
#define TM_SATURDAY 6
|
||||
|
||||
#define TM_JANUARY 0
|
||||
#define TM_FEBRUARY 1
|
||||
#define TM_MARCH 2
|
||||
#define TM_APRIL 3
|
||||
#define TM_MAY 4
|
||||
#define TM_JUNE 5
|
||||
#define TM_JULY 6
|
||||
#define TM_AUGUST 7
|
||||
#define TM_SEPTEMBER 8
|
||||
#define TM_OCTOBER 9
|
||||
#define TM_NOVEMBER 10
|
||||
#define TM_DECEMBER 11
|
||||
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define EPOCH_WDAY TM_THURSDAY
|
||||
|
||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||
|
||||
/*
|
||||
** 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 isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
|
||||
|
||||
#endif /* !defined TZFILE_H */
|
657
contrib/tzcode/strftime.c
Normal file
657
contrib/tzcode/strftime.c
Normal file
|
@ -0,0 +1,657 @@
|
|||
/* Convert a broken-down timestamp to a string. */
|
||||
|
||||
/* Copyright 1989 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE. */
|
||||
|
||||
/*
|
||||
** Based on the UCB version with the copyright notice appearing above.
|
||||
**
|
||||
** This is ANSIish only when "multibyte character == plain character".
|
||||
*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef DEPRECATE_TWO_DIGIT_YEARS
|
||||
# define DEPRECATE_TWO_DIGIT_YEARS false
|
||||
#endif
|
||||
|
||||
struct lc_time_T {
|
||||
const char * mon[MONSPERYEAR];
|
||||
const char * month[MONSPERYEAR];
|
||||
const char * wday[DAYSPERWEEK];
|
||||
const char * weekday[DAYSPERWEEK];
|
||||
const char * X_fmt;
|
||||
const char * x_fmt;
|
||||
const char * c_fmt;
|
||||
const char * am;
|
||||
const char * pm;
|
||||
const char * date_fmt;
|
||||
};
|
||||
|
||||
static const struct lc_time_T C_time_locale = {
|
||||
{
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
}, {
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
}, {
|
||||
"Sun", "Mon", "Tue", "Wed",
|
||||
"Thu", "Fri", "Sat"
|
||||
}, {
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday"
|
||||
},
|
||||
|
||||
/* X_fmt */
|
||||
"%H:%M:%S",
|
||||
|
||||
/*
|
||||
** x_fmt
|
||||
** C99 and later require this format.
|
||||
** Using just numbers (as here) makes Quakers happier;
|
||||
** it's also compatible with SVR4.
|
||||
*/
|
||||
"%m/%d/%y",
|
||||
|
||||
/*
|
||||
** c_fmt
|
||||
** C99 and later require this format.
|
||||
** Previously this code used "%D %X", but we now conform to C99.
|
||||
** Note that
|
||||
** "%a %b %d %H:%M:%S %Y"
|
||||
** is used by Solaris 2.3.
|
||||
*/
|
||||
"%a %b %e %T %Y",
|
||||
|
||||
/* am */
|
||||
"AM",
|
||||
|
||||
/* pm */
|
||||
"PM",
|
||||
|
||||
/* date_fmt */
|
||||
"%a %b %e %H:%M:%S %Z %Y"
|
||||
};
|
||||
|
||||
enum warn { IN_NONE, IN_SOME, IN_THIS, IN_ALL };
|
||||
|
||||
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 *,
|
||||
enum warn *);
|
||||
static char * _yconv(int, int, bool, bool, char *, char const *);
|
||||
|
||||
#ifndef YEAR_2000_NAME
|
||||
# define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
|
||||
#endif /* !defined YEAR_2000_NAME */
|
||||
|
||||
#if HAVE_STRFTIME_L
|
||||
size_t
|
||||
strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
|
||||
ATTRIBUTE_MAYBE_UNUSED locale_t locale)
|
||||
{
|
||||
/* Just call strftime, as only the C locale is supported. */
|
||||
return strftime(s, maxsize, format, t);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t
|
||||
strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
|
||||
{
|
||||
char * p;
|
||||
int saved_errno = errno;
|
||||
enum warn warn = IN_NONE;
|
||||
|
||||
tzset();
|
||||
p = _fmt(format, t, s, s + maxsize, &warn);
|
||||
if (!p) {
|
||||
errno = EOVERFLOW;
|
||||
return 0;
|
||||
}
|
||||
if (DEPRECATE_TWO_DIGIT_YEARS
|
||||
&& warn != IN_NONE && getenv(YEAR_2000_NAME)) {
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "strftime format \"%s\" ", format);
|
||||
fprintf(stderr, "yields only two digits of years in ");
|
||||
if (warn == IN_SOME)
|
||||
fprintf(stderr, "some locales");
|
||||
else if (warn == IN_THIS)
|
||||
fprintf(stderr, "the current locale");
|
||||
else fprintf(stderr, "all locales");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
if (p == s + maxsize) {
|
||||
errno = ERANGE;
|
||||
return 0;
|
||||
}
|
||||
*p = '\0';
|
||||
errno = saved_errno;
|
||||
return p - s;
|
||||
}
|
||||
|
||||
static char *
|
||||
_fmt(const char *format, const struct tm *t, char *pt,
|
||||
const char *ptlim, enum warn *warnp)
|
||||
{
|
||||
struct lc_time_T const *Locale = &C_time_locale;
|
||||
|
||||
for ( ; *format; ++format) {
|
||||
if (*format == '%') {
|
||||
label:
|
||||
switch (*++format) {
|
||||
case '\0':
|
||||
--format;
|
||||
break;
|
||||
case 'A':
|
||||
pt = _add((t->tm_wday < 0 ||
|
||||
t->tm_wday >= DAYSPERWEEK) ?
|
||||
"?" : Locale->weekday[t->tm_wday],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'a':
|
||||
pt = _add((t->tm_wday < 0 ||
|
||||
t->tm_wday >= DAYSPERWEEK) ?
|
||||
"?" : Locale->wday[t->tm_wday],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'B':
|
||||
pt = _add((t->tm_mon < 0 ||
|
||||
t->tm_mon >= MONSPERYEAR) ?
|
||||
"?" : Locale->month[t->tm_mon],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'b':
|
||||
case 'h':
|
||||
pt = _add((t->tm_mon < 0 ||
|
||||
t->tm_mon >= MONSPERYEAR) ?
|
||||
"?" : Locale->mon[t->tm_mon],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'C':
|
||||
/*
|
||||
** %C used to do a...
|
||||
** _fmt("%a %b %e %X %Y", t);
|
||||
** ...whereas now POSIX 1003.2 calls for
|
||||
** something completely different.
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE,
|
||||
true, false, pt, ptlim);
|
||||
continue;
|
||||
case 'c':
|
||||
{
|
||||
enum warn warn2 = IN_SOME;
|
||||
|
||||
pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
|
||||
if (warn2 == IN_ALL)
|
||||
warn2 = IN_THIS;
|
||||
if (warn2 > *warnp)
|
||||
*warnp = warn2;
|
||||
}
|
||||
continue;
|
||||
case 'D':
|
||||
pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'd':
|
||||
pt = _conv(t->tm_mday, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'E':
|
||||
case 'O':
|
||||
/*
|
||||
** Locale modifiers of C99 and later.
|
||||
** The sequences
|
||||
** %Ec %EC %Ex %EX %Ey %EY
|
||||
** %Od %oe %OH %OI %Om %OM
|
||||
** %OS %Ou %OU %OV %Ow %OW %Oy
|
||||
** are supposed to provide alternative
|
||||
** representations.
|
||||
*/
|
||||
goto label;
|
||||
case 'e':
|
||||
pt = _conv(t->tm_mday, "%2d", pt, ptlim);
|
||||
continue;
|
||||
case 'F':
|
||||
pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'H':
|
||||
pt = _conv(t->tm_hour, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'I':
|
||||
pt = _conv((t->tm_hour % 12) ?
|
||||
(t->tm_hour % 12) : 12,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'j':
|
||||
pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
|
||||
continue;
|
||||
case 'k':
|
||||
/*
|
||||
** This used to be...
|
||||
** _conv(t->tm_hour % 12 ?
|
||||
** 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
|
||||
** "%l" have been swapped.
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv(t->tm_hour, "%2d", pt, ptlim);
|
||||
continue;
|
||||
#ifdef KITCHEN_SINK
|
||||
case 'K':
|
||||
/*
|
||||
** After all this time, still unclaimed!
|
||||
*/
|
||||
pt = _add("kitchen sink", pt, ptlim);
|
||||
continue;
|
||||
#endif /* defined KITCHEN_SINK */
|
||||
case 'l':
|
||||
/*
|
||||
** This used to be...
|
||||
** _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
|
||||
** "%l" have been swapped.
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_hour % 12) ?
|
||||
(t->tm_hour % 12) : 12,
|
||||
"%2d", pt, ptlim);
|
||||
continue;
|
||||
case 'M':
|
||||
pt = _conv(t->tm_min, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'm':
|
||||
pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'n':
|
||||
pt = _add("\n", pt, ptlim);
|
||||
continue;
|
||||
case 'p':
|
||||
pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
|
||||
Locale->pm :
|
||||
Locale->am,
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'R':
|
||||
pt = _fmt("%H:%M", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'r':
|
||||
pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'S':
|
||||
pt = _conv(t->tm_sec, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 's':
|
||||
{
|
||||
struct tm tm;
|
||||
char buf[INT_STRLEN_MAXIMUM(
|
||||
time_t) + 1];
|
||||
time_t mkt;
|
||||
|
||||
tm.tm_sec = t->tm_sec;
|
||||
tm.tm_min = t->tm_min;
|
||||
tm.tm_hour = t->tm_hour;
|
||||
tm.tm_mday = t->tm_mday;
|
||||
tm.tm_mon = t->tm_mon;
|
||||
tm.tm_year = t->tm_year;
|
||||
tm.tm_isdst = t->tm_isdst;
|
||||
#if defined TM_GMTOFF && ! UNINIT_TRAP
|
||||
tm.TM_GMTOFF = t->TM_GMTOFF;
|
||||
#endif
|
||||
mkt = mktime(&tm);
|
||||
/* If mktime fails, %s expands to the
|
||||
value of (time_t) -1 as a failure
|
||||
marker; this is better in practice
|
||||
than strftime failing. */
|
||||
if (TYPE_SIGNED(time_t)) {
|
||||
intmax_t n = mkt;
|
||||
sprintf(buf, "%"PRIdMAX, n);
|
||||
} else {
|
||||
uintmax_t n = mkt;
|
||||
sprintf(buf, "%"PRIuMAX, n);
|
||||
}
|
||||
pt = _add(buf, pt, ptlim);
|
||||
}
|
||||
continue;
|
||||
case 'T':
|
||||
pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 't':
|
||||
pt = _add("\t", pt, ptlim);
|
||||
continue;
|
||||
case 'U':
|
||||
pt = _conv((t->tm_yday + DAYSPERWEEK -
|
||||
t->tm_wday) / DAYSPERWEEK,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'u':
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "ISO 8601: Weekday as a decimal number
|
||||
** [1 (Monday) - 7]"
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_wday == 0) ?
|
||||
DAYSPERWEEK : t->tm_wday,
|
||||
"%d", pt, ptlim);
|
||||
continue;
|
||||
case 'V': /* ISO 8601 week number */
|
||||
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
|
||||
** year (the first Monday as the first day of week 1) as a decimal number
|
||||
** (01-53)."
|
||||
** (ado, 1993-05-24)
|
||||
**
|
||||
** From <https://www.cl.cam.ac.uk/~mgk25/iso-time.html> by Markus Kuhn:
|
||||
** "Week 01 of a year is per definition the first week which has the
|
||||
** Thursday in this year, which is equivalent to the week which contains
|
||||
** the fourth day of January. In other words, the first week of a new year
|
||||
** is the week which has the majority of its days in the new year. Week 01
|
||||
** 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
|
||||
** 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;
|
||||
base = TM_YEAR_BASE;
|
||||
yday = t->tm_yday;
|
||||
wday = t->tm_wday;
|
||||
for ( ; ; ) {
|
||||
int len;
|
||||
int bot;
|
||||
int top;
|
||||
|
||||
len = isleap_sum(year, base) ?
|
||||
DAYSPERLYEAR :
|
||||
DAYSPERNYEAR;
|
||||
/*
|
||||
** What yday (-3 ... 3) does
|
||||
** the ISO year begin on?
|
||||
*/
|
||||
bot = ((yday + 11 - wday) %
|
||||
DAYSPERWEEK) - 3;
|
||||
/*
|
||||
** What yday does the NEXT
|
||||
** ISO year begin on?
|
||||
*/
|
||||
top = bot -
|
||||
(len % DAYSPERWEEK);
|
||||
if (top < -3)
|
||||
top += DAYSPERWEEK;
|
||||
top += len;
|
||||
if (yday >= top) {
|
||||
++base;
|
||||
w = 1;
|
||||
break;
|
||||
}
|
||||
if (yday >= bot) {
|
||||
w = 1 + ((yday - bot) /
|
||||
DAYSPERWEEK);
|
||||
break;
|
||||
}
|
||||
--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;
|
||||
#endif /* defined XPG4_1994_04_09 */
|
||||
if (*format == 'V')
|
||||
pt = _conv(w, "%02d",
|
||||
pt, ptlim);
|
||||
else if (*format == 'g') {
|
||||
*warnp = IN_ALL;
|
||||
pt = _yconv(year, base,
|
||||
false, true,
|
||||
pt, ptlim);
|
||||
} else pt = _yconv(year, base,
|
||||
true, true,
|
||||
pt, ptlim);
|
||||
}
|
||||
continue;
|
||||
case 'v':
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "date as dd-bbb-YYYY"
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'W':
|
||||
pt = _conv((t->tm_yday + DAYSPERWEEK -
|
||||
(t->tm_wday ?
|
||||
(t->tm_wday - 1) :
|
||||
(DAYSPERWEEK - 1))) / DAYSPERWEEK,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'w':
|
||||
pt = _conv(t->tm_wday, "%d", pt, ptlim);
|
||||
continue;
|
||||
case 'X':
|
||||
pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'x':
|
||||
{
|
||||
enum warn warn2 = IN_SOME;
|
||||
|
||||
pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
|
||||
if (warn2 == IN_ALL)
|
||||
warn2 = IN_THIS;
|
||||
if (warn2 > *warnp)
|
||||
*warnp = warn2;
|
||||
}
|
||||
continue;
|
||||
case 'y':
|
||||
*warnp = IN_ALL;
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE,
|
||||
false, true,
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'Y':
|
||||
pt = _yconv(t->tm_year, TM_YEAR_BASE,
|
||||
true, true,
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'Z':
|
||||
#ifdef TM_ZONE
|
||||
pt = _add(t->TM_ZONE, pt, ptlim);
|
||||
#elif HAVE_TZNAME
|
||||
if (t->tm_isdst >= 0)
|
||||
pt = _add(tzname[t->tm_isdst != 0],
|
||||
pt, ptlim);
|
||||
#endif
|
||||
/*
|
||||
** C99 and later say that %Z must be
|
||||
** replaced by the empty string if the
|
||||
** time zone abbreviation is not
|
||||
** determinable.
|
||||
*/
|
||||
continue;
|
||||
case 'z':
|
||||
#if defined TM_GMTOFF || USG_COMPAT || ALTZONE
|
||||
{
|
||||
long diff;
|
||||
char const * sign;
|
||||
bool negative;
|
||||
|
||||
# ifdef TM_GMTOFF
|
||||
diff = t->TM_GMTOFF;
|
||||
# else
|
||||
/*
|
||||
** C99 and later say that the UT offset must
|
||||
** be computed by looking only at
|
||||
** 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
|
||||
** tricky and requires disobeying the standard;
|
||||
** see GNU C strftime for details.
|
||||
** For now, punt and conform to the
|
||||
** standard, even though it's incorrect.
|
||||
**
|
||||
** C99 and later say that %z must be replaced by
|
||||
** the empty string if the time zone is not
|
||||
** determinable, so output nothing if the
|
||||
** appropriate variables are not available.
|
||||
*/
|
||||
if (t->tm_isdst < 0)
|
||||
continue;
|
||||
if (t->tm_isdst == 0)
|
||||
# if USG_COMPAT
|
||||
diff = -timezone;
|
||||
# else
|
||||
continue;
|
||||
# endif
|
||||
else
|
||||
# if ALTZONE
|
||||
diff = -altzone;
|
||||
# else
|
||||
continue;
|
||||
# endif
|
||||
# endif
|
||||
negative = diff < 0;
|
||||
if (diff == 0) {
|
||||
# ifdef TM_ZONE
|
||||
negative = t->TM_ZONE[0] == '-';
|
||||
# else
|
||||
negative = t->tm_isdst < 0;
|
||||
# if HAVE_TZNAME
|
||||
if (tzname[t->tm_isdst != 0][0] == '-')
|
||||
negative = true;
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
if (negative) {
|
||||
sign = "-";
|
||||
diff = -diff;
|
||||
} else sign = "+";
|
||||
pt = _add(sign, pt, ptlim);
|
||||
diff /= SECSPERMIN;
|
||||
diff = (diff / MINSPERHOUR) * 100 +
|
||||
(diff % MINSPERHOUR);
|
||||
pt = _conv(diff, "%04d", pt, ptlim);
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
case '+':
|
||||
pt = _fmt(Locale->date_fmt, t, pt, ptlim,
|
||||
warnp);
|
||||
continue;
|
||||
case '%':
|
||||
/*
|
||||
** X311J/88-090 (4.12.3.5): if conversion char is
|
||||
** undefined, behavior is undefined. Print out the
|
||||
** character itself as printf(3) also does.
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pt == ptlim)
|
||||
break;
|
||||
*pt++ = *format;
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
||||
static char *
|
||||
_conv(int n, const char *format, char *pt, const char *ptlim)
|
||||
{
|
||||
char buf[INT_STRLEN_MAXIMUM(int) + 1];
|
||||
|
||||
sprintf(buf, format, n);
|
||||
return _add(buf, pt, ptlim);
|
||||
}
|
||||
|
||||
static char *
|
||||
_add(const char *str, char *pt, const char *ptlim)
|
||||
{
|
||||
while (pt < ptlim && (*pt = *str++) != '\0')
|
||||
++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(int a, int b, bool convert_top, bool convert_yy,
|
||||
char *pt, const char *ptlim)
|
||||
{
|
||||
register int lead;
|
||||
register int trail;
|
||||
|
||||
int 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;
|
||||
}
|
1479
contrib/tzcode/theory.html
Normal file
1479
contrib/tzcode/theory.html
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,9 @@
|
|||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 1996-06-05 by Arthur David Olson.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 11, 2005
|
||||
.Dd December 15, 2022
|
||||
.Dt TIME2POSIX 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -17,9 +20,10 @@
|
|||
.Fn posix2time "time_t t"
|
||||
.Sh DESCRIPTION
|
||||
.St -p1003.1-88
|
||||
legislates that a time_t value of
|
||||
536457599 shall correspond to "Wed Dec 31 23:59:59 GMT 1986."
|
||||
This effectively implies that POSIX time_t's cannot include leap
|
||||
requires the time_t value 536457599 to stand for 1986-12-31 23:59:59 UTC.
|
||||
This effectively implies that POSIX
|
||||
.Vt time_t
|
||||
values cannot include leap
|
||||
seconds and,
|
||||
therefore,
|
||||
that the system time must be adjusted as each leap occurs.
|
||||
|
@ -28,15 +32,22 @@ If the time package is configured with leap-second support
|
|||
enabled,
|
||||
however,
|
||||
no such adjustment is needed and
|
||||
time_t values continue to increase over leap events
|
||||
(as a true `seconds since...' value).
|
||||
.Vt time_t
|
||||
values continue to increase over leap events
|
||||
(as a true
|
||||
.Dq "seconds since..."
|
||||
value).
|
||||
This means that these values will differ from those required by POSIX
|
||||
by the net number of leap seconds inserted since the Epoch.
|
||||
.Pp
|
||||
Typically this is not a problem as the type time_t is intended
|
||||
Typically this is not a problem as the type
|
||||
.Vt time_t
|
||||
is intended
|
||||
to be
|
||||
(mostly)
|
||||
opaque\(emtime_t values should only be obtained-from and
|
||||
opaque \(em
|
||||
.Vt time_t
|
||||
values should only be obtained-from and
|
||||
passed-to functions such as
|
||||
.Xr time 3 ,
|
||||
.Xr localtime 3 ,
|
||||
|
@ -46,11 +57,15 @@ and
|
|||
However,
|
||||
.St -p1003.1-88
|
||||
gives an arithmetic
|
||||
expression for directly computing a time_t value from a given date/time,
|
||||
expression for directly computing a
|
||||
.Vt time_t
|
||||
value from a given date/time,
|
||||
and the same relationship is assumed by some
|
||||
(usually older)
|
||||
applications.
|
||||
Any programs creating/dissecting time_t's
|
||||
Any programs creating/dissecting
|
||||
.Vt time_t
|
||||
values
|
||||
using such a relationship will typically not handle intervals
|
||||
over leap seconds correctly.
|
||||
.Pp
|
||||
|
@ -58,8 +73,12 @@ The
|
|||
.Fn time2posix
|
||||
and
|
||||
.Fn posix2time
|
||||
functions are provided to address this time_t mismatch by converting
|
||||
between local time_t values and their POSIX equivalents.
|
||||
functions are provided to address this
|
||||
.Vt time_t
|
||||
mismatch by converting
|
||||
between local
|
||||
.Vt time_t
|
||||
values and their POSIX equivalents.
|
||||
This is done by accounting for the number of time-base changes that
|
||||
would have taken place on a POSIX system as leap seconds were inserted
|
||||
or deleted.
|
||||
|
@ -69,21 +88,27 @@ or when communicating with POSIX-compliant systems.
|
|||
.Pp
|
||||
The
|
||||
.Fn time2posix
|
||||
function is single-valued.
|
||||
function
|
||||
is single-valued.
|
||||
That is,
|
||||
every local time_t
|
||||
corresponds to a single POSIX time_t.
|
||||
every local
|
||||
.Vt time_t
|
||||
corresponds to a single POSIX
|
||||
.Vt time_t .
|
||||
The
|
||||
.Fn posix2time
|
||||
function is less well-behaved:
|
||||
function
|
||||
is less well-behaved:
|
||||
for a positive leap second hit the result is not unique,
|
||||
and for a negative leap second hit the corresponding
|
||||
POSIX time_t does not exist so an adjacent value is returned.
|
||||
POSIX
|
||||
.Vt time_t
|
||||
does not exist so an adjacent value is returned.
|
||||
Both of these are good indicators of the inferiority of the
|
||||
POSIX representation.
|
||||
.Pp
|
||||
The following table summarizes the relationship between time_t
|
||||
and its conversion to,
|
||||
The following table summarizes the relationship between a time
|
||||
T and its conversion to,
|
||||
and back from,
|
||||
the POSIX representation over the leap second inserted at the end of June,
|
||||
1993.
|
||||
|
@ -106,8 +131,12 @@ A leap second deletion would look like...
|
|||
.D1 No "[Note: posix2time(B+1) => A+0 or A+1]"
|
||||
.Pp
|
||||
If leap-second support is not enabled,
|
||||
local time_t's and
|
||||
POSIX time_t's are equivalent,
|
||||
local
|
||||
.Vt time_t
|
||||
and
|
||||
POSIX
|
||||
.Vt time_t
|
||||
values are equivalent,
|
||||
and both
|
||||
.Fn time2posix
|
||||
and
|
||||
|
@ -118,6 +147,3 @@ degenerate to the identity function.
|
|||
.Xr localtime 3 ,
|
||||
.Xr mktime 3 ,
|
||||
.Xr time 3
|
||||
.\" @(#)time2posix.3 8.2
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 1996-06-05 by Arthur David Olson.
|
636
contrib/tzcode/tz-art.html
Normal file
636
contrib/tzcode/tz-art.html
Normal file
|
@ -0,0 +1,636 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Time and the Arts</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Time and the Arts</h1>
|
||||
<h2>Documentaries</h2>
|
||||
<ul>
|
||||
<li>
|
||||
"<a href="https://www.youtube.com/watch?v=84aWtseb2-4">Daylight
|
||||
Saving Time Explained</a>" (2011; 6:39) lightly covers daylight saving
|
||||
time's theory, history, pros and cons. Among other things, it explains
|
||||
Arizona's daylight-saving enclaves quite well.</li>
|
||||
<li>
|
||||
"<a href="https://www.youtube.com/watch?v=-5wpm-gesOY">The Problem
|
||||
with Time & Timezones – Computerphile</a>" (2013; 10:12) delves
|
||||
into problems that programmers have with timekeeping.</li>
|
||||
<li>
|
||||
"<a href="https://www.rferl.org/a/28375932.html">All The Time In The World:
|
||||
Explaining The Mysteries Of Time Zones</a>" (2017; 2:15)
|
||||
briefly says why France has more time zones than Russia.
|
||||
<li>
|
||||
"<a href="https://www.youtube.com/watch?v=yRz-Dl60Lfc">Why Denmark is
|
||||
.17 Seconds Behind The World</a>" (2019; 6:29) explains why Denmark and
|
||||
the United Kingdom don't exactly follow their own law about civil time.
|
||||
<li>
|
||||
"About Time" (1962; 59 minutes) is part of the
|
||||
Bell Science extravaganza, with Frank Baxter, Richard Deacon, and Les Tremayne.
|
||||
Its advisor was Richard Feynman, and it was voiced by Mel Blanc.
|
||||
(<a href="https://www.imdb.com/title/tt0154110/">IMDb entry</a>.)</li>
|
||||
</ul>
|
||||
<h2>Movies</h2>
|
||||
<ul>
|
||||
<li>
|
||||
In the 1946 movie <em>A Matter of Life and Death</em>
|
||||
(U.S. title <em>Stairway to Heaven</em>)
|
||||
there is a reference to British Double Summer Time.
|
||||
The time does not play a large part in the plot;
|
||||
it's just a passing reference to the time when one of the
|
||||
characters was supposed to have died (but didn't).
|
||||
(<a href="https://www.imdb.com/title/tt0038733/">IMDb entry.</a>)
|
||||
(Dave Cantor)
|
||||
<li>
|
||||
The 1953 railway comedy movie <em>The Titfield Thunderbolt</em> includes a
|
||||
play on words on British Double Summer Time. Valentine's wife wants
|
||||
him to leave the pub and asks him, "Do you know what time it is?"
|
||||
And he, happy where he is, replies: "Yes, my love. Summer double time."
|
||||
(<a href="https://www.imdb.com/title/tt0046436/">IMDb entry.</a>)
|
||||
(Mark Brader, 2009-10-02)
|
||||
</li>
|
||||
<li>
|
||||
The premise of the 1999 caper movie <em>Entrapment</em> involves computers
|
||||
in an international banking network being shut down briefly at
|
||||
midnight in each time zone to avoid any problems at the transition
|
||||
from the year 1999 to 2000 in that zone. (Hmmmm.) If this shutdown
|
||||
is extended by 10 seconds, it will create a one-time opportunity for
|
||||
a gigantic computerized theft. To achieve this, at one location the
|
||||
crooks interfere with the microwave system supplying time signals to
|
||||
the computer, advancing the time by 0.1 second each minute over the
|
||||
last hour of 1999. (So this movie teaches us that 0.1 × 60 = 10.)
|
||||
(<a href="https://www.imdb.com/title/tt0137494/">IMDb entry.</a>)
|
||||
(Mark Brader, 2009-10-02)
|
||||
</li>
|
||||
<li>
|
||||
One mustn't forget the
|
||||
<a href="https://www.youtube.com/watch?v=k4EUTMPuvHo">trailer</a>
|
||||
(2014; 2:23) for the movie <em>Daylight Saving</em>.
|
||||
</li>
|
||||
</ul>
|
||||
<h2>TV episodes</h2>
|
||||
<ul>
|
||||
<li>
|
||||
An episode of <em>The Adventures of Superman</em> entitled "The Mysterious
|
||||
Cube," first aired 1958-02-24, had Superman convincing the controllers
|
||||
of the Arlington Time Signal to broadcast ahead of actual time;
|
||||
doing so got a crook trying to be declared dead to
|
||||
emerge a bit too early from the titular enclosure.
|
||||
(<a href="https://www.imdb.com/title/tt0506628/">IMDb entry</a>.)
|
||||
</li>
|
||||
<li>
|
||||
"<a href="https://en.wikipedia.org/wiki/The_Chimes_of_Big_Ben">The Chimes
|
||||
of Big Ben</a>", <em>The Prisoner</em>, episode 2, ITC, 1967-10-06.
|
||||
Our protagonist tumbles to
|
||||
the fraudulent nature of a Poland-to-England escape upon hearing "Big
|
||||
Ben" chiming on Polish local time.
|
||||
(<a href="https://www.imdb.com/title/tt0679185/">IMDb entry.</a>)
|
||||
</li>
|
||||
<li>
|
||||
"The Susie", <em>Seinfeld</em>, season 8, episode 15, NBC, 1997-02-13.
|
||||
Kramer decides that daylight saving time
|
||||
isn't coming fast enough, so he sets his watch ahead an hour.
|
||||
</li>
|
||||
<li>
|
||||
"20 Hours in America", <em>The West Wing</em>, season 4, episodes 1–2,
|
||||
2002-09-25, contained a <a
|
||||
href="https://www.youtube.com/watch?v=-J1NHzQ1sgc">scene</a> that
|
||||
saw White House staffers stranded in Indiana; they thought they had time to
|
||||
catch Air Force One but were done in by intra-Indiana local time changes.
|
||||
</li>
|
||||
<li>
|
||||
"In what time zone would you find New York City?" was a $200 question on
|
||||
the 1999-11-13 United States airing of <em>Who Wants to Be a Millionaire?</em>,
|
||||
and "In 1883, what industry led the movement to divide the U.S. into four time
|
||||
zones?" was a $32,000 question on the 2001-05-23 United States airing of
|
||||
the same show. At this rate, the million-dollar time-zone
|
||||
question should have been asked 2002-06-04.
|
||||
</li>
|
||||
<li>
|
||||
A private jet's mid-flight change of time zones distorts Alison Dubois'
|
||||
premonition in the "We Had a Dream" episode of <em>Medium</em>
|
||||
(originally aired 2007-02-28).
|
||||
</li>
|
||||
<li>
|
||||
A criminal's failure to account for the start of daylight saving is pivotal
|
||||
in "<a href="https://monk.fandom.com/wiki/Mr._Monk_and_the_Rapper">Mr. Monk
|
||||
and the Rapper</a>" (first aired 2007-07-20).
|
||||
</li>
|
||||
<li>
|
||||
In the <em>30 Rock</em> episode "Anna Howard Shaw Day"
|
||||
(first broadcast 2010-02-11),
|
||||
Jack Donaghy's date realizes that a Geneva-to-New-York business phone call
|
||||
received in the evening must be fake given the difference in local times.
|
||||
</li>
|
||||
<li>
|
||||
In the "Run by the Monkeys" episode of <em>Da Vinci's Inquest</em>
|
||||
(first broadcast 2002-11-17),
|
||||
a witness in a five-year-old fire case realizes they may not have set
|
||||
their clock back when daylight saving ended on the day of the fire,
|
||||
introducing the possibility of an hour when arson might have occurred.
|
||||
</li>
|
||||
<li>
|
||||
In "The Todd Couple" episode of <em>Outsourced</em> (first aired 2011-02-10),
|
||||
Manmeet sets up Valentine's Day teledates for 6:00 and 9:00pm;
|
||||
since one is with a New Yorker and the other with a San Franciscan,
|
||||
hilarity ensues.
|
||||
(Never mind that this should be 7:30am in Mumbai, yet for some reason the show
|
||||
proceeds as though it's also mid-evening there.)
|
||||
</li>
|
||||
<li>
|
||||
In the "14 Days to Go"/"T Minus..." episode of
|
||||
<em>You, Me and the Apocalypse</em>
|
||||
(first aired 2015-11-11 in the UK, 2016-03-10 in the US),
|
||||
the success of a mission to deal with a comet
|
||||
hinges on whether or not Russia observes daylight saving time.
|
||||
(In the US,
|
||||
the episode first aired in the week before the switch to <abbr>DST</abbr>.)
|
||||
</li>
|
||||
<li>
|
||||
"The Lost Hour", <em>Eerie, Indiana</em>, episode 10, NBC, 1991-12-01.
|
||||
Despite Indiana's then-lack of <abbr>DST</abbr>,
|
||||
Marshall changes his clock with unusual consequences.
|
||||
See "<a
|
||||
href="https://www.avclub.com/eerie-indiana-was-a-few-dimensions-ahead-of-its-time-1819833380"><em>Eerie,
|
||||
Indiana</em> was a few dimensions ahead of its time</a>".
|
||||
</li>
|
||||
<li>
|
||||
"Time Tunnel", <em>The Adventures of Pete & Pete</em>, season 2, episode 5,
|
||||
Nickelodeon, 1994-10-23.
|
||||
The two Petes travel back in time an hour
|
||||
on the day that <abbr>DST</abbr> ends.
|
||||
</li>
|
||||
<li>
|
||||
"King-Size Homer", <em>The Simpsons</em>, episode 135, Fox, 1995-11-05.
|
||||
Homer, working from home, remarks "8:58, first
|
||||
time I've ever been early for work. Except for all those daylight
|
||||
savings days. Lousy farmers."
|
||||
</li>
|
||||
<li>
|
||||
<em>Last Week Tonight with John Oliver</em>, season 2, episode 5, 2015-03-08,
|
||||
asked, "<a href="https://www.youtube.com/watch?v=br0NW9ufUUw">Daylight Saving
|
||||
Time – How Is This Still A Thing?</a>"
|
||||
</li>
|
||||
<li>
|
||||
"Tracks", <em>The Good Wife</em>, season 7, episode 12,
|
||||
CBS, 2016-01-17.
|
||||
The applicability of a contract hinges on the
|
||||
time zone associated with a video timestamp.
|
||||
</li>
|
||||
<li>
|
||||
"Justice", <em>Veep</em>, season 6, episode 4, HBO, 2017-05-07.
|
||||
Jonah's inability to understand <abbr>DST</abbr> ends up impressing a wealthy
|
||||
backer who sets him up for a 2020 presidential run.
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Books, plays, and magazines</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Jules Verne, <em>Around the World in Eighty Days</em>
|
||||
(<em>Le tour du monde en quatre-vingts jours</em>), 1873.
|
||||
Wall-clock time plays a central role in the plot.
|
||||
European readers of the 1870s clearly held the U.S. press in
|
||||
deep contempt; the protagonists cross the U.S. without once
|
||||
reading a paper.
|
||||
Available versions include
|
||||
<a href="https://www.gutenberg.org/ebooks/103">an English
|
||||
translation</a>, and
|
||||
<a href="https://fourmilab.ch/etexts/www/tdm80j">the original French</a>
|
||||
"with illustrations from the original 1873 French-language edition".
|
||||
</li>
|
||||
<li>
|
||||
Nick Enright, <em>Daylight Saving</em>, 1989.
|
||||
A fast-paced comedy about love and loneliness as the clocks turn back.
|
||||
</li>
|
||||
<li>
|
||||
Umberto Eco,
|
||||
<a href="https://en.wikipedia.org/wiki/The_Island_of_the_Day_Before"><em>The
|
||||
Island of the Day Before</em></a>
|
||||
(<em>L'isola del giorno prima</em>), 1994.
|
||||
"...the story of a 17th century Italian nobleman trapped near an island
|
||||
on the International Date Line. Time and time zones play an integral
|
||||
part in the novel." (Paul Eggert, 2006-04-22)
|
||||
</li>
|
||||
<li>
|
||||
John Dunning, <a
|
||||
href="https://www.simonandschuster.com/books/Two-OClock-Eastern-Wartime/John-Dunning/9781439171530"><em>Two
|
||||
O'Clock, Eastern Wartime</em></a>, 2001.
|
||||
Mystery, history, daylight saving time, and old-time radio.
|
||||
</li>
|
||||
<li>
|
||||
Surrealist artist Guy Billout's work "Date Line" appeared on page 103
|
||||
of the 1999-11 <em>Atlantic Monthly</em>.
|
||||
</li>
|
||||
<li>
|
||||
"Gloom, Gloom, Go Away" by Walter Kirn appeared on page 106 of <em>Time</em>
|
||||
magazine's 2002-11-11 issue; among other things, it proposed
|
||||
year-round <abbr>DST</abbr> as a way of lessening wintertime despair.
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Music</h2>
|
||||
<p>
|
||||
Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:</p>
|
||||
<table>
|
||||
<tr><td>Artist</td><td>Karrin Allyson</td></tr>
|
||||
<tr><td>CD</td><td>I Didn't Know About You</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1993</td></tr>
|
||||
<tr><td>Label</td><td>Concord Jazz, Inc.</td></tr>
|
||||
<tr><td>ID</td><td>CCD-4543</td></tr>
|
||||
<tr><td>Track Time</td><td>3:44</td></tr>
|
||||
<tr><td>Personnel</td><td>Karrin Allyson, vocal;
|
||||
Russ Long, piano;
|
||||
Gerald Spaits, bass;
|
||||
Todd Strait, drums</td></tr>
|
||||
<tr><td>Notes</td><td>CD notes "additional lyric by Karrin Allyson;
|
||||
arranged by Russ Long and Karrin Allyson"</td></tr>
|
||||
<tr><td>ADO Rating</td><td>1 star</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/i-didnt-know-about-you-mw0000618657">AMG Rating</a></td><td>4 stars</td></tr>
|
||||
<tr><td>Penguin Rating</td><td>3.5 stars</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Kevin Mahogany</td></tr>
|
||||
<tr><td>CD</td><td>Double Rainbow</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1993</td></tr>
|
||||
<tr><td>Label</td><td>Enja Records</td></tr>
|
||||
<tr><td>ID</td><td>ENJ-7097 2</td></tr>
|
||||
<tr><td>Track Time</td><td>6:27</td></tr>
|
||||
<tr><td>Personnel</td><td>Kevin Mahogany, vocal;
|
||||
Kenny Barron, piano;
|
||||
Ray Drummond, bass;
|
||||
Ralph Moore, tenor saxophone;
|
||||
Lewis Nash, drums</td></tr>
|
||||
<tr><td>ADO Rating</td><td>1.5 stars</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/double-rainbow-mw0000620371">AMG Rating</a></td><td>3 stars</td></tr>
|
||||
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Joe Williams</td></tr>
|
||||
<tr><td>CD</td><td>Here's to Life</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1994</td></tr>
|
||||
<tr><td>Label</td><td>Telarc International Corporation</td></tr>
|
||||
<tr><td>ID</td><td>CD-83357</td></tr>
|
||||
<tr><td>Track Time</td><td>3:58</td></tr>
|
||||
<tr><td>Personnel</td><td>Joe Williams, vocal
|
||||
The Robert Farnon [39 piece] Orchestra</td></tr>
|
||||
<tr><td>Notes</td><td>This CD is also available as part of a 3-CD package from
|
||||
Telarc, "Triple Play" (CD-83461)</td></tr>
|
||||
<tr><td>ADO Rating</td><td>black dot</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/heres-to-life-mw0000623648">AMG Rating</a></td><td>2 stars</td></tr>
|
||||
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Charles Fambrough</td></tr>
|
||||
<tr><td>CD</td><td>Keeper of the Spirit</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1995</td></tr>
|
||||
<tr><td>Label</td><td>AudioQuest Music</td></tr>
|
||||
<tr><td>ID</td><td>AQ-CD1033</td></tr>
|
||||
<tr><td>Track Time</td><td>7:07</td></tr>
|
||||
<tr><td>Personnel</td><td>Charles Fambrough, bass;
|
||||
Joel Levine, tenor recorder;
|
||||
Edward Simon, piano;
|
||||
Lenny White, drums;
|
||||
Marion Simon, percussion</td></tr>
|
||||
<tr><td>ADO Rating</td><td>2 stars</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/keeper-of-the-spirit-mw0000176559">AMG Rating</a></td><td>unrated</td></tr>
|
||||
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
|
||||
</table>
|
||||
<hr>
|
||||
<p>Also of note:</p>
|
||||
<table>
|
||||
<tr><td>Artist</td><td>Holly Cole Trio</td></tr>
|
||||
<tr><td>CD</td><td>Blame It On My Youth</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1992</td></tr>
|
||||
<tr><td>Label</td><td>Manhattan</td></tr>
|
||||
<tr><td>ID</td><td>CDP 7 97349 2</td></tr>
|
||||
<tr><td>Total Time</td><td>37:45</td></tr>
|
||||
<tr><td>Personnel</td><td>Holly Cole, voice;
|
||||
Aaron Davis, piano;
|
||||
David Piltch, string bass</td></tr>
|
||||
<tr><td>Notes</td><td>Lyrical reference to "Eastern Standard Time" in
|
||||
Tom Waits' "Purple Avenue"</td></tr>
|
||||
<tr><td>ADO Rating</td><td>2.5 stars</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/blame-it-on-my-youth-mw0000274303">AMG Rating</a></td><td>3 stars</td></tr>
|
||||
<tr><td>Penguin Rating</td><td>unrated</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Milt Hinton</td></tr>
|
||||
<tr><td>CD</td><td>Old Man Time</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1990</td></tr>
|
||||
<tr><td>Label</td><td>Chiaroscuro</td></tr>
|
||||
<tr><td>ID</td><td>CR(D) 310</td></tr>
|
||||
<tr><td>Total Time</td><td>149:38 (two CDs)</td></tr>
|
||||
<tr><td>Personnel</td><td>Milt Hinton, bass;
|
||||
Doc Cheatham, Dizzy Gillespie, Clark Terry, trumpet;
|
||||
Al Grey, trombone;
|
||||
Eddie Barefield, Joe Camel (Flip Phillips), Buddy Tate,
|
||||
clarinet and saxophone;
|
||||
John Bunch, Red Richards, Norman Simmons, Derek Smith,
|
||||
Ralph Sutton, piano;
|
||||
Danny Barker, Al Casey, guitar;
|
||||
Gus Johnson, Gerryck King, Bob Rosengarden, Jackie Williams,
|
||||
drums;
|
||||
Lionel Hampton, vibraphone;
|
||||
Cab Calloway, Joe Williams, vocal;
|
||||
Buck Clayton, arrangements</td></tr>
|
||||
<tr><td>Notes</td><td>tunes include Old Man Time, Time After Time,
|
||||
Sometimes I'm Happy,
|
||||
A Hot Time in the Old Town Tonight,
|
||||
Four or Five Times, Now's the Time,
|
||||
Time on My Hands, This Time It's Us,
|
||||
and Good Time Charlie.
|
||||
<a href="http://www.chiaroscurojazz.com/album.php?C=310">Album info</a>
|
||||
is available.</td></tr>
|
||||
<tr><td>ADO Rating</td><td>3 stars</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/old-man-time-mw0000269353">AMG Rating</a></td><td>4.5 stars</td></tr>
|
||||
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Alan Broadbent</td></tr>
|
||||
<tr><td>CD</td><td>Pacific Standard Time</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1995</td></tr>
|
||||
<tr><td>Label</td><td>Concord Jazz, Inc.</td></tr>
|
||||
<tr><td>ID</td><td>CCD-4664</td></tr>
|
||||
<tr><td>Total Time</td><td>62:42</td></tr>
|
||||
<tr><td>Personnel</td><td>Alan Broadbent, piano;
|
||||
Putter Smith, Bass;
|
||||
Frank Gibson, Jr., drums</td></tr>
|
||||
<tr><td>Notes</td><td>The CD cover features an analemma for equation-of-time fans</td></tr>
|
||||
<tr><td>ADO Rating</td><td>1 star</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/pacific-standard-time-mw0000645433">AMG Rating</a></td><td>4 stars</td></tr>
|
||||
<tr><td>Penguin Rating</td><td>3.5 stars</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Anthony Braxton/Richard Teitelbaum</td></tr>
|
||||
<tr><td>CD</td><td>Silence/Time Zones</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1996</td></tr>
|
||||
<tr><td>Label</td><td>Black Lion</td></tr>
|
||||
<tr><td>ID</td><td>BLCD 760221</td></tr>
|
||||
<tr><td>Total Time</td><td>72:58</td></tr>
|
||||
<tr><td>Personnel</td><td>Anthony Braxton, sopranino and alto saxophones,
|
||||
contrebasse clarinet, miscellaneous instruments;
|
||||
Leo Smith, trumpet and miscellaneous instruments;
|
||||
Leroy Jenkins, violin and miscellaneous instruments;
|
||||
Richard Teitelbaum, modular moog and micromoog synthesizer</td></tr>
|
||||
<tr><td>ADO Rating</td><td>black dot</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/silence-time-zones-mw0000595735">AMG Rating</a></td><td>4 stars</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Charles Gayle</td></tr>
|
||||
<tr><td>CD</td><td>Time Zones</td></tr>
|
||||
<tr><td>Copyright Date</td><td>2006</td></tr>
|
||||
<tr><td>Label</td><td>Tompkins Square</td></tr>
|
||||
<tr><td>ID</td><td>TSQ2839</td></tr>
|
||||
<tr><td>Total Time</td><td>49:06</td></tr>
|
||||
<tr><td>Personnel</td><td>Charles Gayle, piano</td></tr>
|
||||
<tr><td>ADO Rating</td><td>1 star</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/time-zones-mw0000349642">AMG Rating</a></td><td>4.5 stars</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>The Get Up Kids</td></tr>
|
||||
<tr><td>CD</td><td>Eudora</td></tr>
|
||||
<tr><td>Copyright Date</td><td>2001</td></tr>
|
||||
<tr><td>Label</td><td>Vagrant</td></tr>
|
||||
<tr><td>ID</td><td>357</td></tr>
|
||||
<tr><td>Total Time</td><td>65:12</td></tr>
|
||||
<tr><td>Notes</td><td>Includes the song "Central Standard Time." Thanks to Colin Bowern for this information.</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/eudora-mw0000592063">AMG Rating</a></td><td>2.5 stars</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
|
||||
<tr><td>Artist</td><td>Coldplay</td></tr>
|
||||
<tr><td>Song</td><td>Clocks</td></tr>
|
||||
<tr><td>Copyright Date</td><td>2003</td></tr>
|
||||
<tr><td>Label</td><td>Capitol Records</td></tr>
|
||||
<tr><td>ID</td><td>52608</td></tr>
|
||||
<tr><td>Total Time</td><td>4:13</td></tr>
|
||||
<tr><td>Notes</td><td>Won the 2004 Record of the Year honor at the
|
||||
Grammy Awards. Co-written and performed by Chris Martin,
|
||||
great-great-grandson of <abbr>DST</abbr> inventor William Willett.
|
||||
The song's first line is "Lights go out and I can't be saved".</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
|
||||
<tr><td>Artist</td><td>Jaime Guevara</td></tr>
|
||||
<tr><td>Song</td><td><a
|
||||
href="https://www.youtube.com/watch?v=ZfN4Fe_A50U">Qué
|
||||
hora es</a></td></tr>
|
||||
<tr><td>Date</td><td>1993</td></tr>
|
||||
<tr><td>Total Time</td><td>3:04</td></tr>
|
||||
<tr><td>Notes</td><td>The song protested "Sixto Hour" in Ecuador
|
||||
(1992–3). Its lyrics include "Amanecía en mitad de la noche, los
|
||||
guaguas iban a clase sin sol" ("It was dawning in the middle of the
|
||||
night, the buses went to class without sun").
|
||||
<tr><td> </td><td></td></tr>
|
||||
|
||||
<tr><td>Artist</td><td>Irving Kahal and Harry Richman</td></tr>
|
||||
<tr><td>Song</td><td>There Ought to be a Moonlight Saving Time</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1931</td>
|
||||
<tr><td>Notes</td><td>This musical standard was a No. 1 hit for Guy Lombardo
|
||||
in 1931, and was also performed by Maurice Chevalier, Blossom Dearie
|
||||
and many others. The phrase "Moonlight saving time" also appears in
|
||||
the 1995 country song "Not Enough Hours in the Night" written by Aaron
|
||||
Barker, Kim Williams and Rob Harbin and performed by Doug
|
||||
Supernaw.</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
|
||||
<tr><td>Artist</td><td>The Microscopic Septet</td></tr>
|
||||
<tr><td>CD</td><td>Lobster Leaps In</td></tr>
|
||||
<tr><td>Copyright Date</td><td>2008</td></tr>
|
||||
<tr><td>Label</td><td>Cuneiform</td></tr>
|
||||
<tr><td>ID</td><td>272</td></tr>
|
||||
<tr><td>Total Time</td><td>73:05</td></tr>
|
||||
<tr><td>Notes</td><td>Includes the song "Twilight Time Zone."</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/lobster-leaps-in-mw0000794929">AMG Rating</a></td><td>3.5 stars</td></tr>
|
||||
<tr><td>ADO Rating</td><td>2 stars</td></tr>
|
||||
|
||||
<tr><td> </td><td></td></tr>
|
||||
|
||||
<tr><td>Artist</td><td>Bob Dylan</td></tr>
|
||||
<tr><td>CD</td><td>The Times They Are a-Changin'</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1964</td></tr>
|
||||
<tr><td>Label</td><td>Columbia</td></tr>
|
||||
<tr><td>ID</td><td>CK-8905</td></tr>
|
||||
<tr><td>Total Time</td><td>45:36</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/the-times-they-a-changin-mw0000202344">AMG Rating</a></td><td>4.5 stars</td></tr>
|
||||
<tr><td>ADO Rating</td><td>1.5 stars</td></tr>
|
||||
<tr><td>Notes<td>The title song is also available on "Bob Dylan's Greatest Hits" and "The Essential Bob Dylan."</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
|
||||
<tr><td>Artist</td><td>Luciana Souza</td></tr>
|
||||
<tr><td>CD</td><td>Tide</td></tr>
|
||||
<tr><td>Copyright Date</td><td>2009</td></tr>
|
||||
<tr><td>Label</td><td>Universal Jazz France</td></tr>
|
||||
<tr><td>ID</td><td>B0012688-02</td></tr>
|
||||
<tr><td>Total Time</td><td>42:31</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/tide-mw0000815692">AMG Rating</a></td><td>3.5 stars</td></tr>
|
||||
<tr><td>ADO Rating</td><td>2.5 stars</td></tr>
|
||||
<tr><td>Notes<td>Includes the song "Fire and Wood" with the lyric
|
||||
"The clocks were turned back you remember/Think it's still November."
|
||||
</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Ken Nordine</td></tr>
|
||||
<tr><td>CD</td><td>You're Getting Better: The Word Jazz Dot Masters</td></tr>
|
||||
<tr><td>Copyright Date</td><td>2005</td></tr>
|
||||
<tr><td>Label</td><td>Geffen</td></tr>
|
||||
<tr><td>ID</td><td>B0005171-02</td></tr>
|
||||
<tr><td>Total Time</td><td>156:22</td></tr>
|
||||
<tr><td>ADO Rating</td><td>1 star</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/youre-getting-better-the-word-jazz-dot-masters-mw0000736197">AMG Rating</a></td><td>4.5 stars</td></tr>
|
||||
<tr><td>Notes</td><td>Includes the piece "What Time Is It"
|
||||
("He knew what time it was everywhere...that counted").</td></tr>
|
||||
<tr><td> </td><td></td></tr>
|
||||
<tr><td>Artist</td><td>Chicago</td></tr>
|
||||
<tr><td>CD</td><td>Chicago Transit Authority</td></tr>
|
||||
<tr><td>Copyright Date</td><td>1969</td></tr>
|
||||
<tr><td>Label</td><td>Columbia</td></tr>
|
||||
<tr><td>ID</td><td>64409</td></tr>
|
||||
<tr><td>Total Time</td><td>1:16:20</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/chicago-transit-authority-mw0000189364">AMG Rating</a></td><td>4 stars</td></tr>
|
||||
<tr><td>Notes</td><td>Includes the song "Does Anybody Really Know What Time It Is?"</td></tr>
|
||||
</table>
|
||||
<h2>Comics</h2>
|
||||
<ul>
|
||||
<li>
|
||||
The webcomic <em>xkcd</em> has the strip
|
||||
"<a href="https://xkcd.com/673/">The Sun</a>" (2009-12-09) and the panels
|
||||
"<a href="https://xkcd.com/1017/">Backward in Time</a>" (2012-02-14),
|
||||
"<a href="https://xkcd.com/1061/">EST</a>" (2012-05-28),
|
||||
"<a href="https://xkcd.com/1179/">ISO 8601</a>" (2013-02-27),
|
||||
"<a href="https://xkcd.com/1335/">Now</a>" (2014-02-26),
|
||||
"<a href="https://xkcd.com/1655/">Doomsday Clock</a>" (2016-03-14),
|
||||
"<a href="https://xkcd.com/1799/">Bad Map Projection: Time Zones</a>"
|
||||
(2017-02-15),
|
||||
"<a href="https://xkcd.com/1883/">Supervillain Plan</a>" (2017-08-30),
|
||||
"<a href="https://xkcd.com/2050/">6/6 Time</a>" (2018-09-24),
|
||||
and "<a href="https://xkcd.com/2266/">Leap Smearing</a>" (2020-02-10).
|
||||
The related book <em>What If?</em> has an entry
|
||||
"<a href="https://what-if.xkcd.com/26/">Leap Seconds</a>" (2012-12-31).
|
||||
</li>
|
||||
<li>
|
||||
Pig kills time in <a
|
||||
href="https://www.gocomics.com/pearlsbeforeswine/2016/11/06"><em>Pearls
|
||||
Before Swine</em> (2016-11-06)</a>.
|
||||
</li>
|
||||
<li>
|
||||
Stonehenge is abandoned in <a
|
||||
href="https://www.gocomics.com/nonsequitur/2017/03/12"><em>Non Sequitur</em>
|
||||
(2017-03-12)</a>.
|
||||
<li>
|
||||
The boss freaks out in <a
|
||||
href="https://dilbert.com/strip/1998-03-14"><em>Dilbert</em> (1998-03-14)</a>.
|
||||
</li>
|
||||
<li>
|
||||
Peppermint Patty: "What if the world comes to an end tonight, Marcie?"
|
||||
<br>
|
||||
Marcie: "I promise there'll be a tomorrow, sir ... in fact,
|
||||
it's already tomorrow in Australia!"
|
||||
<br>
|
||||
(Charles M. Schulz, <a href="https://www.gocomics.com/peanuts/1980/06/13"><em>Peanuts</em>, 1980-06-13</a>)
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Jokes</h2>
|
||||
<ul>
|
||||
<li>
|
||||
The idea behind daylight saving time was first proposed as a joke by
|
||||
Benjamin Franklin. To enforce it, he suggested, "Every
|
||||
morning, as soon as the sun rises, let all the bells in every church
|
||||
be set ringing; and if that is not sufficient, let cannon be fired in
|
||||
every street, to wake the sluggards effectually, and make them open
|
||||
their eyes to see their true interest. All the difficulty will be in
|
||||
the first two or three days: after which the reformation will be as
|
||||
natural and easy as the present irregularity; for, <em>ce n'est que le
|
||||
premier pas qui coûte</em>."
|
||||
<a href="http://www.webexhibits.org/daylightsaving/franklin3.html">Franklin's
|
||||
joke</a> was first published on 1784-04-26 by the
|
||||
<em>Journal de Paris</em> as <a
|
||||
href="https://en.wikipedia.org/wiki/File:Franklin-Benjamin-Journal-de-Paris-1784.jpg">an
|
||||
anonymous letter translated into French</a>.
|
||||
</li>
|
||||
<li>
|
||||
"We've been using the five-cent nickel in this country since 1492.
|
||||
Now that's pretty near 100 years, daylight saving."
|
||||
(Groucho Marx as Captain Spaulding in <em>Animal Crackers</em>, 1930,
|
||||
as noted by Will Fitzgerald)
|
||||
</li>
|
||||
<li>
|
||||
BRADY. ...[Bishop Usher] determined that the Lord began the Creation
|
||||
on the 23rd of October in the Year 4,004 B.C. at – uh, 9 A.M.!
|
||||
<br>
|
||||
DRUMMOND. That Eastern Standard Time? (<em>Laughter.</em>) Or Rocky Mountain
|
||||
Time? (<em>More laughter.</em>) It wasn't daylight-saving time, was it? Because
|
||||
the Lord didn't make the sun until the fourth day!
|
||||
<br>
|
||||
(From the play <em>Inherit the Wind</em> by Jerome Lawrence and Robert E. Lee,
|
||||
filmed in 1960 with Spencer Tracy as Drummond and Fredric March as
|
||||
Brady, and several other times. Thanks to Mark Brader.)
|
||||
</li>
|
||||
<li>
|
||||
"Good news."
|
||||
"What did they do? Extend Daylight Saving Time year round?"
|
||||
(Professional tanner George Hamilton, in dialog from a
|
||||
May, 1999 episode of the syndicated television series <em>Baywatch</em>)
|
||||
</li>
|
||||
<li>
|
||||
"A fundamental belief held by Americans is that if you are on land, you
|
||||
cannot be killed by a fish...So most Americans remain on land, believing
|
||||
they're safe. Unfortunately, this belief – like so many myths, such as that
|
||||
there's a reason for 'Daylight Saving Time' – is false."
|
||||
(Dave Barry column, 2000-07-02)
|
||||
</li>
|
||||
<li>
|
||||
"I once had sex for an hour and five minutes, but that was on the day
|
||||
when you turn the clocks ahead."
|
||||
(Garry Shandling, 52nd Annual Emmys, 2000-09-10)
|
||||
</li>
|
||||
<li>
|
||||
"Would it impress you if I told you I invented Daylight Savings Time?"
|
||||
("Sahjhan" to "Lilah" in dialog from the "Loyalty" episode of <em>Angel</em>,
|
||||
originally aired 2002-02-25)
|
||||
</li>
|
||||
<li>
|
||||
"I thought you said Tulsa was a three-hour flight."
|
||||
"Well, you're forgetting about the time difference."
|
||||
("Joey" and "Chandler" in dialog from the episode of <em>Friends</em>
|
||||
entitled "The One With Rachel's Phone Number," originally aired 2002-12-05)
|
||||
</li>
|
||||
<li>
|
||||
"Is that a pertinent fact,
|
||||
or are you just trying to dazzle me with your command of time zones?"
|
||||
(Kelsey Grammer as "Frasier Crane" to "Roz" from the episode of <em>Frasier</em>
|
||||
entitled "The Kid," originally aired 1997-11-04)
|
||||
</li>
|
||||
<li>
|
||||
"I put myself and my staff through this crazy, huge ordeal, all because
|
||||
I refused to go on at midnight, okay? And so I work, you know, and
|
||||
then I get this job at eleven, supposed to be a big deal. Then
|
||||
yesterday daylight [saving] time ended. Right now it's basically
|
||||
midnight." (Conan O'Brien on the 2010-11-08 premiere of <em>Conan</em>.)
|
||||
</li>
|
||||
<li>
|
||||
"The best method, I told folks, was to hang a large clock high on a
|
||||
barn wall where all the cows could see it. If you have Holsteins, you
|
||||
will need to use an analog clock." (Jerry Nelson, <a
|
||||
href="http://www.agriculture.com/family/farm-humor/how-to-adjust-dairy-cows-to-daylight-savings-time">How
|
||||
to adjust dairy cows to daylight saving time</a>", <em>Successful Farming</em>,
|
||||
2017-10-09.)
|
||||
</li>
|
||||
<li>
|
||||
"And now, driving to California, I find that I must enter a password
|
||||
in order to change the time zone on my laptop clock. Evidently,
|
||||
someone is out to mess up my schedule and my clock must be secured."
|
||||
(Garrison Keillor,
|
||||
"<a href="http://www.garrisonkeillor.com/weve-never-been-here-before/">We've
|
||||
never been here before</a>", 2017-08-22)
|
||||
</li>
|
||||
<li>
|
||||
"Well, in my time zone that's all the time I have,
|
||||
but maybe in your time zone I haven't finished yet. So stay tuned!"
|
||||
(Goldie Hawn, <em>Rowan & Martin's Laugh-In</em> No. 65, 1970-03-09)
|
||||
</li>
|
||||
</ul>
|
||||
<h2>See also</h2>
|
||||
<ul>
|
||||
<li><a href="tz-link.html">Time Zone and Daylight Saving
|
||||
Time Data</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<address>
|
||||
This web page is in the public domain, so clarified as of
|
||||
2009-05-17 by Arthur David Olson.
|
||||
<br>
|
||||
Please send corrections to this web page to the
|
||||
<a href="mailto:tz@iana.org">time zone mailing list</a>.
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
719
contrib/tzcode/tz-how-to.html
Normal file
719
contrib/tzcode/tz-how-to.html
Normal file
|
@ -0,0 +1,719 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>How to Read the tz Database</title>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
pre {margin-left: 2em; white-space: pre-wrap;}
|
||||
pre.td {margin-left: 0;}
|
||||
td {text-align: center;}
|
||||
table {border: 1px outset;}
|
||||
th, td {border: 1px inset;}
|
||||
table.rule {border: none; margin: auto;}
|
||||
td.footnote {text-align: left;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>How to Read the <a href="https://en.wikipedia.org/wiki/Tz_database">tz
|
||||
Database</a> Source Files</h2>
|
||||
<h3>by Bill Seymour</h3>
|
||||
<p>This guide uses the <code>America/Chicago</code> and
|
||||
<code>Pacific/Honolulu</code> zones as examples of how to infer
|
||||
times of day from the <a href="tz-link.html">tz database</a>
|
||||
source files. It might be helpful, but not absolutely necessary,
|
||||
for the reader to have already downloaded the
|
||||
latest release of the database and become familiar with the basic layout
|
||||
of the data files. The format is explained in the “man
|
||||
page” for the zic compiler, <code>zic.8.txt</code>, in
|
||||
the <code>code</code> subdirectory.
|
||||
Although this guide covers many of the common cases, it is not a
|
||||
complete summary of what zic accepts; the man page is the
|
||||
authoritative reference.</p>
|
||||
|
||||
<p>We’ll begin by talking about the rules for changing between standard
|
||||
and daylight saving time since we’ll need that information when we talk
|
||||
about the zones.</p>
|
||||
|
||||
<p>First, let’s consider the special daylight saving time rules
|
||||
for Chicago (from the <code>northamerica</code> file in
|
||||
the <code>data</code> subdirectory):</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="6">From the Source File</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<table class="rule">
|
||||
<tr><td style="border:none;text-align:left">
|
||||
<pre class="td">
|
||||
#Rule NAME FROM TO - IN ON AT SAVE LETTER
|
||||
Rule Chicago 1920 only - Jun 13 2:00 1:00 D
|
||||
Rule Chicago 1920 1921 - Oct lastSun 2:00 0 S
|
||||
Rule Chicago 1921 only - Mar lastSun 2:00 1:00 D
|
||||
Rule Chicago 1922 1966 - Apr lastSun 2:00 1:00 D
|
||||
Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S
|
||||
Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S
|
||||
</pre>
|
||||
</td></tr></table></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="6">Reformatted a Bit</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th colspan="2">On</th>
|
||||
<th>At</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">1920 only</td>
|
||||
<td colspan="2">June 13<small><sup>th</sup></small></td>
|
||||
<td rowspan="6">02:00 local</td>
|
||||
<td>go to daylight saving time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1920</td>
|
||||
<td>1921</td>
|
||||
<td rowspan="5">last Sunday</td>
|
||||
<td>in October</td>
|
||||
<td>return to standard time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">1921 only</td>
|
||||
<td>in March</td>
|
||||
<td rowspan="2">go to daylight saving time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">1922</td>
|
||||
<td>1966</td>
|
||||
<td>in April</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1954</td>
|
||||
<td>in September</td>
|
||||
<td rowspan="2">return to standard time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1955</td>
|
||||
<td>1966</td>
|
||||
<td>in October</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>The <code>FROM</code> and <code>TO</code> columns, respectively, specify the
|
||||
first and last calendar years defining a contiguous range over which a specific
|
||||
Rule line is to apply. The keyword <code>only</code> can be used in the
|
||||
<code>TO</code> field to repeat the value of the <code>FROM</code> field in the
|
||||
event that a rule should only apply to a single year. Often, the keyword
|
||||
<code>max</code> is used to extend a rule’s application into the
|
||||
indefinite future; it is a platform-agnostic stand-in for the largest
|
||||
representable year.
|
||||
|
||||
<p>The next column, <code>-</code>, is reserved; for compatibility with earlier
|
||||
releases, it always contains a hyphen, which acts as a kind of null value.
|
||||
Prior to the 2020b release, it was called the <code>TYPE</code> field, though
|
||||
it had not been used in the main data since the 2000e release.
|
||||
An obsolescent supplementary file used the
|
||||
field as a proof-of-concept to allow <code>zic</code> to apply a given Rule
|
||||
line only to certain “types” of years within the specified range as
|
||||
dictated by the output of a separate script, such as: only years which would
|
||||
have a US presidential election, or only years which wouldn’t.
|
||||
|
||||
<p>The <code>SAVE</code> column contains the local (wall clock) offset from
|
||||
local standard time.
|
||||
This is usually either zero for standard time or one hour for daylight
|
||||
saving time; but there’s no reason, in principle, why it can’t
|
||||
take on other values.
|
||||
|
||||
<p>The <code>LETTER</code> (sometimes called <code>LETTER/S</code>)
|
||||
column can contain a variable
|
||||
part of the usual abbreviation of the time zone’s name, or it can just
|
||||
be a hyphen if there’s no variable part. For example, the abbreviation
|
||||
used in the central time zone will be either “CST” or
|
||||
“CDT”. The variable part is ‘S’ or ‘D’;
|
||||
and, sure enough, that’s just what we find in
|
||||
the <code>LETTER</code> column
|
||||
in the <code>Chicago</code> rules. More about this when we talk about
|
||||
“Zone” lines.
|
||||
|
||||
<p>One important thing to notice is that “Rule” lines
|
||||
want at once to be both <i>transitions</i> and <i>steady states</i>:
|
||||
<ul>
|
||||
<li>On the one hand, they represent transitions between standard and
|
||||
daylight saving time; and any number of Rule lines can be in effect
|
||||
during a given period (which will always be a non-empty set of
|
||||
contiguous calendar years).</li>
|
||||
<li>On the other hand, the <code>SAVE</code> and <code>LETTER</code>
|
||||
columns contain state that exists between transitions. More about this
|
||||
when we talk about the US rules.</li>
|
||||
</ul>
|
||||
|
||||
<p>In the example above, the transition to daylight saving time
|
||||
happened on the 13<small><sup>th</sup></small> of June in 1920, and on
|
||||
the last Sunday in March in 1921; but the return to standard time
|
||||
happened on the last Sunday in October in both of those
|
||||
years. Similarly, the rule for changing to daylight saving time was
|
||||
the same from 1922 to 1966; but the rule for returning to standard
|
||||
time changed in 1955. Got it?</p>
|
||||
|
||||
<p>OK, now for the somewhat more interesting “US” rules:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="6">From the Source File</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<table class="rule">
|
||||
<tr><td style="border:none;text-align:left">
|
||||
<pre class="td">
|
||||
#Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
Rule US 1918 1919 - Mar lastSun 2:00 1:00 D
|
||||
Rule US 1918 1919 - Oct lastSun 2:00 0 S
|
||||
Rule US 1942 only - Feb 9 2:00 1:00 W # War
|
||||
Rule US 1945 only - Aug 14 23:00u 1:00 P # Peace
|
||||
Rule US 1945 only - Sep 30 2:00 0 S
|
||||
Rule US 1967 2006 - Oct lastSun 2:00 0 S
|
||||
Rule US 1967 1973 - Apr lastSun 2:00 1:00 D
|
||||
Rule US 1974 only - Jan 6 2:00 1:00 D
|
||||
Rule US 1975 only - Feb 23 2:00 1:00 D
|
||||
Rule US 1976 1986 - Apr lastSun 2:00 1:00 D
|
||||
Rule US 1987 2006 - Apr Sun>=1 2:00 1:00 D
|
||||
Rule US 2007 max - Mar Sun>=8 2:00 1:00 D
|
||||
Rule US 2007 max - Nov Sun>=1 2:00 0 S
|
||||
</pre>
|
||||
</td></tr></table></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="6">Reformatted a Bit</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th colspan="2">On</th>
|
||||
<th>At</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">1918</td>
|
||||
<td rowspan="2">1919</td>
|
||||
<td rowspan="2">last Sunday</td>
|
||||
<td>in March</td>
|
||||
<td rowspan="3">02:00 local</td>
|
||||
<td>go to daylight saving time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>in October</td>
|
||||
<td>return to standard time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">1942 only</td>
|
||||
<td colspan="2">February 9<small><sup>th</sup></small></td>
|
||||
<td>go to “war time”</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" rowspan="2">1945 only</td>
|
||||
<td colspan="2">August 14<small><sup>th</sup></small></td>
|
||||
<td>23:00 <a href="https://en.wikipedia.org/wiki/Universal_Time">UT</a></td>
|
||||
<td>
|
||||
rename “war time” to “peace<br>time;”
|
||||
clocks don’t change
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">September 30<small><sup>th</sup></small></td>
|
||||
<td rowspan="9">02:00 local</td>
|
||||
<td rowspan="2">return to standard time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">1967</td>
|
||||
<td>2006</td>
|
||||
<td rowspan="2">last Sunday</td>
|
||||
<td>in October</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1973</td>
|
||||
<td>in April</td>
|
||||
<td rowspan="6">go to daylight saving time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">1974 only</td>
|
||||
<td colspan="2">January 6<small><sup>th</sup></small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">1975 only</td>
|
||||
<td colspan="2">February 23<small><sup>rd</sup></small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1976</td>
|
||||
<td>1986</td>
|
||||
<td>last Sunday</td>
|
||||
<td rowspan="2">in April</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1987</td>
|
||||
<td>2006</td>
|
||||
<td>first Sunday</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">2007</td>
|
||||
<td rowspan="2">present</td>
|
||||
<td colspan="2">second Sunday in March</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">first Sunday in November</td>
|
||||
<td>return to standard time</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>There are two interesting things to note here.</p>
|
||||
|
||||
<p>First, the time that something happens (in the <code>AT</code>
|
||||
column) is not necessarily the local (wall clock) time. The time can be
|
||||
suffixed with ‘s’ (for “standard”) to mean
|
||||
local standard time, different from local (wall clock) time when observing
|
||||
daylight saving time; or it can be suffixed with ‘g’,
|
||||
‘u’, or ‘z’, all three of which mean the
|
||||
standard time at the
|
||||
<a href="https://en.wikipedia.org/wiki/Prime_Meridian">prime meridian</a>.
|
||||
‘g’ stands for “<a
|
||||
href="https://en.wikipedia.org/wiki/Greenwich_Mean_Time">GMT</a>”;
|
||||
‘u’ stands for “<a
|
||||
href="https://en.wikipedia.org/wiki/Universal_Time">UT</a>” or “<a
|
||||
href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a>”
|
||||
(whichever was official at the time); ‘z’ stands for the
|
||||
<a href="https://en.wikipedia.org/wiki/Nautical_time">nautical time zone</a>
|
||||
Z (a.k.a. “Zulu” which, in turn, stands for ‘Z’).
|
||||
The time can also be suffixed with ‘w’ meaning local (wall
|
||||
clock) time; but it usually isn’t because that’s the
|
||||
default.</p>
|
||||
|
||||
<p>Second, the day in the <code>ON</code> column, in addition to
|
||||
“<code>lastSun</code>” or a particular day of the month,
|
||||
can have the form, “<code>Sun>=</code><i>x</i>” or
|
||||
“<code>Sun<=</code><i>x</i>,” where <i>x</i> is a day
|
||||
of the month. For example, “<code>Sun>=8</code>” means
|
||||
“the first Sunday on or after the eighth of the month,” in
|
||||
other words, the second Sunday of the month. Furthermore, although
|
||||
there are no examples above, the weekday needn’t be
|
||||
“<code>Sun</code>” in either form, but can be the usual
|
||||
three-character English abbreviation for any day of the week.</p>
|
||||
|
||||
<p>And the US rules give us more examples of a couple of things
|
||||
already mentioned:</p>
|
||||
|
||||
<ul>
|
||||
<li>The rules for changing to and from daylight saving time are
|
||||
actually <i>different sets</i> of rules; and the two sets can change
|
||||
independently. Consider, for example, that the rule for the return to
|
||||
standard time stayed the same from 1967 to 2006; but the rule for the
|
||||
transition to daylight saving time changed several times in the same
|
||||
period. There can also be periods, 1946 to 1966 for example, when no
|
||||
rule from this group is in effect, and so either no transition
|
||||
happened in those years, or some other rule is in effect (perhaps a
|
||||
state or other more local rule).</li>
|
||||
|
||||
<li>The <code>SAVE</code> and <code>LETTER</code> columns
|
||||
contain <i>steady state</i>, not transitions. Consider, for example,
|
||||
the transition from “war time” to “peace time”
|
||||
that happened on August 14, 1945. The “1:00” in
|
||||
the <code>SAVE</code> column is <i>not</i> an instruction to advance
|
||||
the clock an hour. It means that clocks should <i>be</i> one hour
|
||||
ahead of standard time, which they already are because of the previous
|
||||
rule, so there should be no change.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p>OK, now let’s look at a Zone record:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="5">From the Source File</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<table class="rule">
|
||||
<tr><td style="border:none;text-align:left">
|
||||
<pre class="td">
|
||||
#Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
|
||||
-6:00 US C%sT 1920
|
||||
-6:00 Chicago C%sT 1936 Mar 1 2:00
|
||||
-5:00 - EST 1936 Nov 15 2:00
|
||||
-6:00 Chicago C%sT 1942
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 Chicago C%sT 1967
|
||||
-6:00 US C%sT
|
||||
</pre>
|
||||
</td></tr></table></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="5">Columns Renamed</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th rowspan="2">Standard Offset<br>
|
||||
from <a href="https://en.wikipedia.org/wiki/Prime_Meridian">Prime
|
||||
Meridian</a></th>
|
||||
<th rowspan="2">Daylight<br>Saving Time</th>
|
||||
<th rowspan="2">Abbreviation(s)</th>
|
||||
<th colspan="2">Ending at Local Time</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Time</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−5:50:36</td>
|
||||
<td>not observed</td>
|
||||
<td>LMT</td>
|
||||
<td>1883-11-18</td>
|
||||
<td>12:09:24</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">−6:00:00</td>
|
||||
<td>US rules</td>
|
||||
<td rowspan="2">CST or CDT</td>
|
||||
<td>1920-01-01</td>
|
||||
<td>00:00:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Chicago rules</td>
|
||||
<td>1936-03-01</td>
|
||||
<td rowspan="2">02:00:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−5:00:00</td>
|
||||
<td>not observed</td>
|
||||
<td>EST</td>
|
||||
<td>1936-11-15</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="4">−6:00:00</td>
|
||||
<td>Chicago rules</td>
|
||||
<td>CST or CDT</td>
|
||||
<td>1942-01-01</td>
|
||||
<td rowspan="3">00:00:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>US rules</td>
|
||||
<td>CST, CWT or CPT</td>
|
||||
<td>1946-01-01</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Chicago rules</td>
|
||||
<td rowspan="2">CST or CDT</td>
|
||||
<td>1967-01-01</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>US rules</td>
|
||||
<td colspan="2">—</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>There are a couple of interesting differences between Zones and Rules.</p>
|
||||
|
||||
<p>First, and somewhat trivially, whereas Rules are considered to
|
||||
contain one or more records, a Zone is considered to be a single
|
||||
record with zero or more <i>continuation lines</i>. Thus, the keyword,
|
||||
“<code>Zone</code>,” and the zone name are not
|
||||
repeated. The last line is the one without anything in
|
||||
the <code>[UNTIL]</code> column.</p>
|
||||
|
||||
<p>Second, and more fundamentally, each line of a Zone represents a
|
||||
steady state, not a transition between states. The state exists from
|
||||
the date and time in the previous line’s <code>[UNTIL]</code>
|
||||
column up to the date and time in the current
|
||||
line’s <code>[UNTIL]</code> column. In other words, the date and
|
||||
time in the <code>[UNTIL]</code> column is the instant that separates
|
||||
this state from the next. Where that would be ambiguous because
|
||||
we’re setting our clocks back, the <code>[UNTIL]</code> column
|
||||
specifies the first occurrence of the instant. The state specified by
|
||||
the last line, the one without anything in the <code>[UNTIL]</code>
|
||||
column, continues to the present.</p>
|
||||
|
||||
<p>The first line typically specifies the mean solar time observed
|
||||
before the introduction of standard time. Since there’s no line before
|
||||
that, it has no beginning. <code>8-) </code> For some places near the <a
|
||||
href="https://en.wikipedia.org/wiki/International_Date_Line">International
|
||||
Date Line</a>, the first <i>two</i> lines will show solar times
|
||||
differing by 24 hours; this corresponds to a movement of the Date
|
||||
Line. For example:</p>
|
||||
|
||||
<pre>
|
||||
#Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone America/Juneau 15:02:19 - LMT 1867 Oct 18
|
||||
-8:57:41 - LMT ...
|
||||
</pre>
|
||||
|
||||
<p>When Alaska was purchased from Russia in 1867, the Date Line moved
|
||||
from the Alaska/Canada border to the Bering Strait; and the time in
|
||||
Alaska was then 24 hours earlier than it had
|
||||
been. <code><aside></code>(6 October in the Julian calendar,
|
||||
which Russia was still using then for religious reasons, was followed
|
||||
by <i>a second instance of the same day with a different name</i>, 18
|
||||
October in the Gregorian calendar. Isn’t civil time
|
||||
wonderful? <code>8-)</code>)<code></aside></code></p>
|
||||
|
||||
<p>The abbreviation, “LMT” stands for “local mean
|
||||
time”, which is an invention of
|
||||
the <a href="https://en.wikipedia.org/wiki/Tz_database">tz
|
||||
database</a> and was probably never actually used during the
|
||||
period. Furthermore, the value is almost certainly wrong except in the
|
||||
archetypal place after which the zone is named. (The tz database
|
||||
usually doesn’t provide a separate Zone record for places where
|
||||
nothing significant happened after 1970.)</p>
|
||||
|
||||
<p>The <code>RULES</code> column tells us whether daylight saving time is being observed:
|
||||
<ul>
|
||||
<li>A hyphen, a kind of null value, means that we have not set our
|
||||
clocks ahead of standard time.</li>
|
||||
|
||||
<li>An amount of time (usually but not necessarily “1:00”
|
||||
meaning one hour) means that we have set our clocks ahead by that
|
||||
amount.</li>
|
||||
|
||||
<li>Some alphabetic string means that we <i>might have</i> set our
|
||||
clocks ahead; and we need to check the rule the name of which is the
|
||||
given alphabetic string.</li>
|
||||
</ul>
|
||||
|
||||
<p>An example of a specific amount of time is:</p>
|
||||
<pre>
|
||||
#Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Pacific/Honolulu ... 1933 Apr 30 2:00
|
||||
-10:30 1:00 HDT 1933 May 21 12:00
|
||||
...
|
||||
</pre>
|
||||
|
||||
<p>Hawaii tried daylight saving time for three weeks in 1933 and
|
||||
decided they didn’t like it. <code>8-) </code>Note that
|
||||
the <code>STDOFF</code> column always contains the standard time
|
||||
offset, so the local (wall clock) time during this period was GMT −
|
||||
10:30 + 1:00 = GMT − 9:30.</p>
|
||||
|
||||
<p>The <code>FORMAT</code> column specifies the usual abbreviation of
|
||||
the time zone name. It should have one of four forms:</p>
|
||||
<ul>
|
||||
|
||||
<li>a time zone abbreviation that is a string of three or more
|
||||
characters that are either ASCII alphanumerics,
|
||||
“<code>+</code>”, or “<code>-</code>”</li>
|
||||
|
||||
<li>the string “%z”, in which case the
|
||||
“<code>%z</code>” will be replaced by a numeric time zone
|
||||
abbreviation</li>
|
||||
|
||||
<li>a pair of time zone abbreviations separated by a slash
|
||||
(‘<code>/</code>’), in which case the first string is the
|
||||
abbreviation for the standard time name and the second string is the
|
||||
abbreviation for the daylight saving time name</li>
|
||||
|
||||
<li>a string containing “<code>%s</code>”, in which case
|
||||
the “<code>%s</code>” will be replaced by the text in the
|
||||
appropriate Rule’s <code>LETTER</code> column, and the resulting
|
||||
string should be a time zone abbreviation</li>
|
||||
</ul>
|
||||
|
||||
<p>The last two make sense only if there’s a named rule in effect.</p>
|
||||
|
||||
<p>An example of a slash is:</p>
|
||||
<pre>
|
||||
#Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Europe/London ... 1996
|
||||
0:00 EU GMT/BST
|
||||
</pre>
|
||||
|
||||
<p>The current time in the UK is called either Greenwich mean time or
|
||||
British summer time.</p>
|
||||
|
||||
<p>One wrinkle, not fully explained in <code>zic.8.txt</code>, is what
|
||||
happens when switching to a named rule. To what values should
|
||||
the <code>SAVE</code> and <code>LETTER</code> data be initialized?</p>
|
||||
|
||||
<ul>
|
||||
<li>If at least one transition has happened, use
|
||||
the <code>SAVE</code> and <code>LETTER</code> data from the most
|
||||
recent.</li>
|
||||
|
||||
<li>If switching to a named rule before any transition has happened,
|
||||
assume standard time (<code>SAVE</code> zero), and use
|
||||
the <code>LETTER</code> data from the earliest transition with
|
||||
a <code>SAVE</code> of zero.
|
||||
|
||||
</ul>
|
||||
|
||||
<p>And three last things about the <code>FORMAT</code> column:</p>
|
||||
<ul>
|
||||
|
||||
<li>The <a href="https://en.wikipedia.org/wiki/Tz_database">tz
|
||||
database</a> gives abbreviations for time zones in <i>popular
|
||||
usage</i>, which is not necessarily “correct” by law. For
|
||||
example, the last line in
|
||||
<code>Zone</code> <code>Pacific/Honolulu</code> (shown below) gives
|
||||
“HST” for “Hawaii standard time” even though the
|
||||
<a href="https://www.law.cornell.edu/uscode/text/15/263">legal</a>
|
||||
name for that time zone is “Hawaii-Aleutian standard time.”
|
||||
This author has read that there are also some places in Australia where
|
||||
popular time zone names differ from the legal ones.
|
||||
|
||||
<li>No attempt is made to <a
|
||||
href="https://en.wikipedia.org/wiki/Internationalization_and_localization">localize</a>
|
||||
the abbreviations. They are intended to be the values returned through the
|
||||
<code>"%Z"</code> format specifier to
|
||||
<a href="https://en.wikipedia.org/wiki/C_(programming_language)">C</a>’s
|
||||
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html"><code>strftime</code></a>
|
||||
function in the
|
||||
<a href="https://kirste.userpage.fu-berlin.de/chemnet/use/info/libc/libc_19.html#SEC324">“C” locale</a>.
|
||||
|
||||
<li>If there is no generally-accepted abbreviation for a time zone,
|
||||
a numeric offset is used instead, e.g., <code>+07</code> for 7 hours
|
||||
ahead of Greenwich. By convention, <code>-00</code> is used in a
|
||||
zone while uninhabited, where the offset is zero but in some sense
|
||||
the true offset is undefined.
|
||||
</ul>
|
||||
|
||||
<p>As a final example, here’s the complete history for Hawaii:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="6">Relevant Excerpts from the US Rules</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<table class="rule">
|
||||
<tr><td style="border:none;text-align:left">
|
||||
<pre class="td">
|
||||
#Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
Rule US 1918 1919 - Oct lastSun 2:00 0 S
|
||||
Rule US 1942 only - Feb 9 2:00 1:00 W # War
|
||||
Rule US 1945 only - Aug 14 23:00u 1:00 P # Peace
|
||||
Rule US 1945 only - Sep lastSun 2:00 0 S
|
||||
</pre>
|
||||
</td></tr></table></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="6">The Zone Record</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<table class="rule">
|
||||
<tr><td style="border:none;text-align:left">
|
||||
<pre class="td">
|
||||
#Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Pacific/Honolulu -10:31:26 - LMT 1896 Jan 13 12:00
|
||||
-10:30 - HST 1933 Apr 30 2:00
|
||||
-10:30 1:00 HDT 1933 May 21 2:00
|
||||
-10:30 US H%sT 1947 Jun 8 2:00
|
||||
-10:00 - HST
|
||||
</pre>
|
||||
</td></tr></table></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="6">What We Infer</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th rowspan="2">Wall-Clock<br>Offset from<br>Prime Meridian</th>
|
||||
<th rowspan="2">Adjust<br>Clocks</th>
|
||||
<th colspan="2">Time Zone</th>
|
||||
<th colspan="2">Ending at Local Time</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Abbrv.</th>
|
||||
<th>Name</th>
|
||||
<th>Date</th>
|
||||
<th>Time</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−10:31:26</td>
|
||||
<td>—</td>
|
||||
<td>LMT</td>
|
||||
<td>local mean time</td>
|
||||
<td>1896-01-13</td>
|
||||
<td>12:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−10:30</td>
|
||||
<td>+0:01:26</td>
|
||||
<td>HST</td>
|
||||
<td>Hawaii standard time</td>
|
||||
<td>1933-04-30</td>
|
||||
<td>02:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−9:30</td>
|
||||
<td>+1:00</td>
|
||||
<td>HDT</td>
|
||||
<td>Hawaii daylight time</td>
|
||||
<td>1933-05-21</td>
|
||||
<td>12:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−10:30¹</td>
|
||||
<td>−1:00¹</td>
|
||||
<td>HST¹</td>
|
||||
<td>Hawaii standard time</td>
|
||||
<td>1942-02-09</td>
|
||||
<td>02:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">−9:30</td>
|
||||
<td>+1:00</td>
|
||||
<td>HWT</td>
|
||||
<td>Hawaii war time</td>
|
||||
<td>1945-08-14</td>
|
||||
<td>13:30²</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0</td>
|
||||
<td>HPT</td>
|
||||
<td>Hawaii peace time</td>
|
||||
<td>1945-09-30</td>
|
||||
<td rowspan="2">02:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−10:30</td>
|
||||
<td>−1:00</td>
|
||||
<td rowspan="2">HST</td>
|
||||
<td rowspan="2">Hawaii standard time</td>
|
||||
<td>1947-06-08</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−10:00³</td>
|
||||
<td>+0:30³</td>
|
||||
<td colspan="2">—</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" class="footnote">
|
||||
¹Switching to US rules…most recent transition (in 1919) was to standard time
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" class="footnote">
|
||||
²23:00 <a href="https://en.wikipedia.org/wiki/Universal_Time">UT</a>
|
||||
+ (−9:30) = 13:30 local
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" class="footnote">
|
||||
³Since <a href="https://en.wikipedia.org/wiki/ISO_8601">1947–06–08T12:30Z</a>,
|
||||
the civil time in Hawaii has been
|
||||
<a href="https://en.wikipedia.org/wiki/Universal_Time">UT</a>/<a href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a>
|
||||
− 10:00 year-round.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>There will be a short quiz later. <code>8-)</code></p>
|
||||
|
||||
<hr>
|
||||
<address>
|
||||
This web page is in the public domain, so clarified as of
|
||||
2015-10-20 by Bill Seymour.
|
||||
<br>
|
||||
All suggestions and corrections will be welcome; all flames will be amusing.
|
||||
Mail to was at pobox dot com.
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
1175
contrib/tzcode/tz-link.html
Normal file
1175
contrib/tzcode/tz-link.html
Normal file
File diff suppressed because it is too large
Load diff
492
contrib/tzcode/tzfile.5
Normal file
492
contrib/tzcode/tzfile.5
Normal file
|
@ -0,0 +1,492 @@
|
|||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 1996-06-05 by Arthur David Olson.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 15, 2022
|
||||
.Dt TZFILE 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm tzfile
|
||||
.Nd timezone information
|
||||
.Sh DESCRIPTION
|
||||
The timezone information files used by
|
||||
.Xr tzset 3
|
||||
are found under
|
||||
.Pa /usr/share/zoneinfo .
|
||||
These files use the format described in Internet RFC 8536.
|
||||
Each file is a sequence of 8-bit bytes.
|
||||
In a file, a binary integer is represented by a sequence of one or
|
||||
more bytes in network order (bigendian, or high-order byte first),
|
||||
with all bits significant,
|
||||
a signed binary integer is represented using two's complement,
|
||||
and a boolean is represented by a one-byte binary integer that is
|
||||
either 0 (false) or 1 (true).
|
||||
The format begins with a 44-byte header containing the following fields:
|
||||
.Pp
|
||||
.Bl -bullet
|
||||
.It
|
||||
The magic four-byte ASCII sequence
|
||||
.Dq "TZif"
|
||||
identifies the file as a timezone information file.
|
||||
.It
|
||||
A byte identifying the version of the file's format
|
||||
(as of 2021, either an ASCII NUL,
|
||||
.Dq "2" ,
|
||||
.Dq "3" ,
|
||||
or
|
||||
.Dq "4" ) .
|
||||
.It
|
||||
Fifteen bytes containing zeros reserved for future use.
|
||||
.It
|
||||
Six four-byte integer values, in the following order:
|
||||
.Pp
|
||||
.Bl -tag -compat -width tzh_ttisstdcnt
|
||||
.It Va tzh_ttisutcnt
|
||||
The number of UT/local indicators stored in the file.
|
||||
(UT is Universal Time.)
|
||||
.It Va tzh_ttisstdcnt
|
||||
The number of standard/wall indicators stored in the file.
|
||||
.It Va tzh_leapcnt
|
||||
The number of leap seconds for which data entries are stored in the file.
|
||||
.It Va tzh_timecnt
|
||||
The number of transition times for which data entries are stored
|
||||
in the file.
|
||||
.It Va tzh_typecnt
|
||||
The number of local time types for which data entries are stored
|
||||
in the file (must not be zero).
|
||||
.It Va tzh_charcnt
|
||||
The number of bytes of time zone abbreviation strings
|
||||
stored in the file.
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
The above header is followed by the following fields, whose lengths
|
||||
depend on the contents of the header:
|
||||
.Bl -tag -compat -width tzh_timecnt
|
||||
.It Va tzh_timecnt
|
||||
four-byte signed integer values sorted in ascending order.
|
||||
These values are written in network byte order.
|
||||
Each is used as a transition time (as returned by
|
||||
.Xt time 2 )
|
||||
at which the rules for computing local time change.
|
||||
.It Va tzh_timecnt
|
||||
one-byte unsigned integer values;
|
||||
each one but the last tells which of the different types of local time types
|
||||
described in the file is associated with the time period
|
||||
starting with the same-indexed transition time
|
||||
and continuing up to but not including the next transition time.
|
||||
(The last time type is present only for consistency checking with the
|
||||
POSIX-style TZ string described below.)
|
||||
These values serve as indices into the next field.
|
||||
.It Va tzh_typecnt
|
||||
.Vt ttinfo
|
||||
entries, each defined as follows:
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
struct ttinfo {
|
||||
int32_t tt_utoff;
|
||||
unsigned char tt_isdst;
|
||||
unsigned char tt_desigidx;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
Each structure is written as a four-byte signed integer value for
|
||||
.Va tt_utoff ,
|
||||
in network byte order, followed by a one-byte boolean for
|
||||
.Va tt_isdst
|
||||
and a one-byte value for
|
||||
.Va tt_desigidx .
|
||||
In each structure,
|
||||
.Va tt_utoff
|
||||
gives the number of seconds to be added to UT,
|
||||
.Va tt_isdst
|
||||
tells whether
|
||||
.Va tm_isdst
|
||||
should be set by
|
||||
.Xr localtime 3
|
||||
and
|
||||
.Va tt_desigidx
|
||||
serves as an index into the array of time zone abbreviation bytes
|
||||
that follow the
|
||||
.Vt ttinfo
|
||||
entries in the file; if the designated string is "\*-00", the
|
||||
.Vt ttinfo
|
||||
entry is a placeholder indicating that local time is unspecified.
|
||||
The
|
||||
.Va tt_utoff
|
||||
value is never equal to \-2**31, to let 32-bit clients negate it without
|
||||
overflow.
|
||||
Also, in realistic applications
|
||||
.Va tt_utoff
|
||||
is in the range [\-89999, 93599] (i.e., more than \-25 hours and less
|
||||
than 26 hours); this allows easy support by implementations that
|
||||
already support the POSIX-required range [\-24:59:59, 25:59:59].
|
||||
.It Va tzh_charcnt
|
||||
bytes that represent time zone designations,
|
||||
which are null-terminated byte strings, each indexed by the
|
||||
.Va tt_desigidx
|
||||
values mentioned above.
|
||||
The byte strings can overlap if one is a suffix of the other.
|
||||
The encoding of these strings is not specified.
|
||||
.It Va tzh_leapcnt
|
||||
pairs of four-byte values, written in network byte order;
|
||||
the first value of each pair gives the nonnegative time
|
||||
(as returned by
|
||||
.Xr time 3 )
|
||||
at which a leap second occurs or at which the leap second table expires;
|
||||
the second is a signed integer specifying the correction, which is the
|
||||
.Em total
|
||||
number of leap seconds to be applied during the time period
|
||||
starting at the given time.
|
||||
The pairs of values are sorted in strictly ascending order by time.
|
||||
Each pair denotes one leap second, either positive or negative,
|
||||
except that if the last pair has the same correction as the previous one,
|
||||
the last pair denotes the leap second table's expiration time.
|
||||
Each leap second is at the end of a UTC calendar month.
|
||||
The first leap second has a nonnegative occurrence time,
|
||||
and is a positive leap second if and only if its correction is positive;
|
||||
the correction for each leap second after the first differs
|
||||
from the previous leap second by either 1 for a positive leap second,
|
||||
or \-1 for a negative leap second.
|
||||
If the leap second table is empty, the leap-second correction is zero
|
||||
for all timestamps;
|
||||
otherwise, for timestamps before the first occurrence time,
|
||||
the leap-second correction is zero if the first pair's correction is 1 or \-1,
|
||||
and is unspecified otherwise (which can happen only in files
|
||||
truncated at the start).
|
||||
.It Va tzh_ttisstdcnt
|
||||
standard/wall indicators, each stored as a one-byte boolean;
|
||||
they tell whether the transition times associated with local time types
|
||||
were specified as standard time or local (wall clock) time.
|
||||
.It Va tzh_ttisutcnt
|
||||
UT/local indicators, each stored as a one-byte boolean;
|
||||
they tell whether the transition times associated with local time types
|
||||
were specified as UT or local time.
|
||||
If a UT/local indicator is set, the corresponding standard/wall indicator
|
||||
must also be set.
|
||||
.El
|
||||
.Pp
|
||||
The standard/wall and UT/local indicators were designed for
|
||||
transforming a TZif file's transition times into transitions appropriate
|
||||
for another time zone specified via a POSIX-style TZ string that lacks rules.
|
||||
For example, when TZ="EET\*-2EEST" and there is no TZif file "EET\*-2EEST",
|
||||
the idea was to adapt the transition times from a TZif file with the
|
||||
well-known name "posixrules" that is present only for this purpose and
|
||||
is a copy of the file "Europe/Brussels", a file with a different UT offset.
|
||||
POSIX does not specify this obsolete transformational behavior,
|
||||
the default rules are installation-dependent, and no implementation
|
||||
is known to support this feature for timestamps past 2037,
|
||||
so users desiring (say) Greek time should instead specify
|
||||
TZ="Europe/Athens" for better historical coverage, falling back on
|
||||
TZ="EET\*-2EEST,M3.5.0/3,M10.5.0/4" if POSIX conformance is required
|
||||
and older timestamps need not be handled accurately.
|
||||
.Pp
|
||||
The
|
||||
.Xr localtime 3
|
||||
function
|
||||
normally uses the first
|
||||
.Vt ttinfo
|
||||
structure in the file
|
||||
if either
|
||||
.Va tzh_timecnt
|
||||
is zero or the time argument is less than the first transition time recorded
|
||||
in the file.
|
||||
.Ss Version 2 format
|
||||
For version-2-format timezone files,
|
||||
the above header and data are followed by a second header and data,
|
||||
identical in format except that
|
||||
eight bytes are used for each transition time or leap second time.
|
||||
(Leap second counts remain four bytes.)
|
||||
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
|
||||
or for all instants if the file has no transitions.
|
||||
The POSIX-style TZ string is empty (i.e., nothing between the newlines)
|
||||
if there is no POSIX-style representation for such instants.
|
||||
If nonempty, the POSIX-style TZ string must agree with the local time
|
||||
type after the last transition time if present in the eight-byte data;
|
||||
for example, given the string
|
||||
.Dq "WET0WEST,M3.5.0,M10.5.0/3"
|
||||
then if a last transition time is in July, the transition's local time
|
||||
type must specify a daylight-saving time abbreviated
|
||||
.Dq "WEST"
|
||||
that is one hour east of UT.
|
||||
Also, if there is at least one transition, time type 0 is associated
|
||||
with the time period from the indefinite past up to but not including
|
||||
the earliest transition time.
|
||||
.Ss Version 3 format
|
||||
For version-3-format timezone files, the POSIX-TZ-style string may
|
||||
use two minor extensions to the POSIX TZ format, as described in
|
||||
.Xr newtzset 3 .
|
||||
First, the hours part of its transition times may be signed and range from
|
||||
\-167 through 167 instead of the POSIX-required unsigned values
|
||||
from 0 through 24.
|
||||
Second, DST is in effect all year if it starts
|
||||
January 1 at 00:00 and ends December 31 at 24:00 plus the difference
|
||||
between daylight saving and standard time.
|
||||
.Ss Version 4 format
|
||||
For version-4-format TZif files,
|
||||
the first leap second record can have a correction that is neither
|
||||
+1 nor \-1, to represent truncation of the TZif file at the start.
|
||||
Also, if two or more leap second transitions are present and the last
|
||||
entry's correction equals the previous one, the last entry
|
||||
denotes the expiration of the leap second table instead of a leap second;
|
||||
timestamps after this expiration are unreliable in that future
|
||||
releases will likely add leap second entries after the expiration, and
|
||||
the added leap seconds will change how post-expiration timestamps are treated.
|
||||
.Ss Interoperability considerations
|
||||
Future changes to the format may append more data.
|
||||
.Pp
|
||||
Version 1 files are considered a legacy format and
|
||||
should not be generated, as they do not support transition
|
||||
times after the year 2038.
|
||||
Readers that understand only Version 1 must ignore
|
||||
any data that extends beyond the calculated end of the version
|
||||
1 data block.
|
||||
.Pp
|
||||
Other than version 1, writers should generate
|
||||
the lowest version number needed by a file's data.
|
||||
For example, a writer should generate a version 4 file
|
||||
only if its leap second table either expires or is truncated at the start.
|
||||
Likewise, a writer not generating a version 4 file
|
||||
should generate a version 3 file only if
|
||||
TZ string extensions are necessary to accurately
|
||||
model transition times.
|
||||
.Pp
|
||||
The sequence of time changes defined by the version 1
|
||||
header and data block should be a contiguous sub-sequence
|
||||
of the time changes defined by the version 2+ header and data
|
||||
block, and by the footer.
|
||||
This guideline helps obsolescent version 1 readers
|
||||
agree with current readers about timestamps within the
|
||||
contiguous sub-sequence.
|
||||
It also lets writers not
|
||||
supporting obsolescent readers use a
|
||||
.Va tzh_timecnt
|
||||
of zero
|
||||
in the version 1 data block to save space.
|
||||
.Pp
|
||||
When a TZif file contains a leap second table expiration
|
||||
time, TZif readers should either refuse to process
|
||||
post-expiration timestamps, or process them as if the expiration
|
||||
time did not exist (possibly with an error indication).
|
||||
.Pp
|
||||
Time zone designations should consist of at least three (3)
|
||||
and no more than six (6) ASCII characters from the set of
|
||||
alphanumerics,
|
||||
.Dq "\*-" ,
|
||||
and
|
||||
.Dq "+" .
|
||||
This is for compatibility with POSIX requirements for
|
||||
time zone abbreviations.
|
||||
.Pp
|
||||
When reading a version 2 or higher file, readers
|
||||
should ignore the version 1 header and data block except for
|
||||
the purpose of skipping over them.
|
||||
.Pp
|
||||
Readers should calculate the total lengths of the
|
||||
headers and data blocks and check that they all fit within
|
||||
the actual file size, as part of a validity check for the file.
|
||||
.Pp
|
||||
When a positive leap second occurs, readers should append an extra
|
||||
second to the local minute containing the second just before the leap
|
||||
second.
|
||||
If this occurs when the UTC offset is not a multiple of 60
|
||||
seconds, the leap second occurs earlier than the last second of the
|
||||
local minute and the minute's remaining local seconds are numbered
|
||||
through 60 instead of the usual 59; the UTC offset is unaffected.
|
||||
.Ss Common interoperability issues
|
||||
This section documents common problems in reading or writing TZif files.
|
||||
Most of these are problems in generating TZif files for use by
|
||||
older readers.
|
||||
The goals of this section are:
|
||||
.Bl -bullet
|
||||
.It
|
||||
to help TZif writers output files that avoid common
|
||||
pitfalls in older or buggy TZif readers,
|
||||
.It
|
||||
to help TZif readers avoid common pitfalls when reading
|
||||
files generated by future TZif writers, and
|
||||
.It
|
||||
to help any future specification authors see what sort of
|
||||
problems arise when the TZif format is changed.
|
||||
.El
|
||||
.Pp
|
||||
When new versions of the TZif format have been defined, a
|
||||
design goal has been that a reader can successfully use a TZif
|
||||
file even if the file is of a later TZif version than what the
|
||||
reader was designed for.
|
||||
When complete compatibility was not achieved, an attempt was
|
||||
made to limit glitches to rarely used timestamps and allow
|
||||
simple partial workarounds in writers designed to generate
|
||||
new-version data useful even for older-version readers.
|
||||
This section attempts to document these compatibility issues and
|
||||
workarounds, as well as to document other common bugs in
|
||||
readers.
|
||||
.Pp
|
||||
Interoperability problems with TZif include the following:
|
||||
.Bl -bullet
|
||||
.It
|
||||
Some readers examine only version 1 data.
|
||||
As a partial workaround, a writer can output as much version 1
|
||||
data as possible.
|
||||
However, a reader should ignore version 1 data, and should use
|
||||
version 2+ data even if the reader's native timestamps have only
|
||||
32 bits.
|
||||
.It
|
||||
Some readers designed for version 2 might mishandle
|
||||
timestamps after a version 3 or higher file's last transition, because
|
||||
they cannot parse extensions to POSIX in the TZ-like string.
|
||||
As a partial workaround, a writer can output more transitions
|
||||
than necessary, so that only far-future timestamps are
|
||||
mishandled by version 2 readers.
|
||||
.It
|
||||
Some readers designed for version 2 do not support
|
||||
permanent daylight saving time with transitions after 24:00
|
||||
\(en e.g., a TZ string
|
||||
.Dq "EST5EDT,0/0,J365/25"
|
||||
denoting permanent Eastern Daylight Time
|
||||
(\-04).
|
||||
As a workaround, a writer can substitute standard time
|
||||
for two time zones east, e.g.,
|
||||
.Dq "XXX3EDT4,0/0,J365/23"
|
||||
for a time zone with a never-used standard time (XXX, \-03)
|
||||
and negative daylight saving time (EDT, \-04) all year.
|
||||
Alternatively,
|
||||
as a partial workaround a writer can substitute standard time
|
||||
for the next time zone east \(en e.g.,
|
||||
.Dq "AST4"
|
||||
for permanent
|
||||
Atlantic Standard Time (\-04).
|
||||
.It
|
||||
Some readers designed for version 2 or 3, and that require strict
|
||||
conformance to RFC 8536, reject version 4 files whose leap second
|
||||
tables are truncated at the start or that end in expiration times.
|
||||
.It
|
||||
Some readers ignore the footer, and instead predict future
|
||||
timestamps from the time type of the last transition.
|
||||
As a partial workaround, a writer can output more transitions
|
||||
than necessary.
|
||||
.It
|
||||
Some readers do not use time type 0 for timestamps before
|
||||
the first transition, in that they infer a time type using a
|
||||
heuristic that does not always select time type 0.
|
||||
As a partial workaround, a writer can output a dummy (no-op)
|
||||
first transition at an early time.
|
||||
.It
|
||||
Some readers mishandle timestamps before the first
|
||||
transition that has a timestamp not less than \-2**31.
|
||||
Readers that support only 32-bit timestamps are likely to be
|
||||
more prone to this problem, for example, when they process
|
||||
64-bit transitions only some of which are representable in 32
|
||||
bits.
|
||||
As a partial workaround, a writer can output a dummy
|
||||
transition at timestamp \-2**31.
|
||||
.It
|
||||
Some readers mishandle a transition if its timestamp has
|
||||
the minimum possible signed 64-bit value.
|
||||
Timestamps less than \-2**59 are not recommended.
|
||||
.It
|
||||
Some readers mishandle POSIX-style TZ strings that
|
||||
contain
|
||||
.Dq "<"
|
||||
or
|
||||
.Dq ">".
|
||||
As a partial workaround, a writer can avoid using
|
||||
.Dq "<"
|
||||
or
|
||||
.Dq ">"
|
||||
for time zone abbreviations containing only alphabetic
|
||||
characters.
|
||||
.It
|
||||
Many readers mishandle time zone abbreviations that contain
|
||||
non-ASCII characters.
|
||||
These characters are not recommended.
|
||||
.It
|
||||
Some readers may mishandle time zone abbreviations that
|
||||
contain fewer than 3 or more than 6 characters, or that
|
||||
contain ASCII characters other than alphanumerics,
|
||||
.Dq "\*-",
|
||||
and
|
||||
.Dq "+".
|
||||
These abbreviations are not recommended.
|
||||
.It
|
||||
Some readers mishandle TZif files that specify
|
||||
daylight-saving time UT offsets that are less than the UT
|
||||
offsets for the corresponding standard time.
|
||||
These readers do not support locations like Ireland, which
|
||||
uses the equivalent of the POSIX TZ string
|
||||
.Dq "IST\*-1GMT0,M10.5.0,M3.5.0/1" ,
|
||||
observing standard time
|
||||
(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
|
||||
As a partial workaround, a writer can output data for the
|
||||
equivalent of the POSIX TZ string
|
||||
.Dq "GMT0IST,M3.5.0/1,M10.5.0" ,
|
||||
thus swapping standard and daylight saving time.
|
||||
Although this workaround misidentifies which part of the year
|
||||
uses daylight saving time, it records UT offsets and time zone
|
||||
abbreviations correctly.
|
||||
.It
|
||||
Some readers generate ambiguous timestamps for positive leap seconds
|
||||
that occur when the UTC offset is not a multiple of 60 seconds.
|
||||
For example, in a timezone with UTC offset +01:23:45 and with
|
||||
a positive leap second 78796801 (1972-06-30 23:59:60 UTC), some readers will
|
||||
map both 78796800 and 78796801 to 01:23:45 local time the next day
|
||||
instead of mapping the latter to 01:23:46, and they will map 78796815 to
|
||||
01:23:59 instead of to 01:23:60.
|
||||
This has not yet been a practical problem, since no civil authority
|
||||
has observed such UTC offsets since leap seconds were
|
||||
introduced in 1972.
|
||||
.El
|
||||
.Pp
|
||||
Some interoperability problems are reader bugs that
|
||||
are listed here mostly as warnings to developers of readers.
|
||||
.Bl -bullet
|
||||
.It
|
||||
Some readers do not support negative timestamps.
|
||||
Developers of distributed applications should keep this
|
||||
in mind if they need to deal with pre-1970 data.
|
||||
.It
|
||||
Some readers mishandle timestamps before the first
|
||||
transition that has a nonnegative timestamp.
|
||||
Readers that do not support negative timestamps are likely to
|
||||
be more prone to this problem.
|
||||
.It
|
||||
Some readers mishandle time zone abbreviations like
|
||||
.Dq "\*-08"
|
||||
that contain
|
||||
.Dq "+" ,
|
||||
.Dq "\*-" ,
|
||||
or digits.
|
||||
.It
|
||||
Some readers mishandle UT offsets that are out of the
|
||||
traditional range of \-12 through +12 hours, and so do not
|
||||
support locations like Kiritimati that are outside this
|
||||
range.
|
||||
.It
|
||||
Some readers mishandle UT offsets in the range [\-3599, \-1]
|
||||
seconds from UT, because they integer-divide the offset by
|
||||
3600 to get 0 and then display the hour part as
|
||||
.Dq "+00" .
|
||||
.It
|
||||
Some readers mishandle UT offsets that are not a multiple
|
||||
of one hour, or of 15 minutes, or of 1 minute.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr time 3 ,
|
||||
.Xr localtime 3 ,
|
||||
.Xr tzset 3 ,
|
||||
.Xr tzsetup 8 ,
|
||||
.Xr zic 8 ,
|
||||
.Xr zdump 8
|
||||
.Rs
|
||||
.%A A. Olson
|
||||
.%A P. Eggert
|
||||
.%A K. Murchison
|
||||
.%T "The Time Zone Information Format (TZif)"
|
||||
.%R RFC 8536
|
||||
.%D February 2019
|
||||
.%U https://datatracker.ietf.org/doc/html/rfc8536
|
||||
.%U https://doi.org/10.17487/RFC8536
|
||||
.Re
|
125
contrib/tzcode/tzfile.h
Normal file
125
contrib/tzcode/tzfile.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* Layout and location of TZif files. */
|
||||
|
||||
#ifndef TZFILE_H
|
||||
#define TZFILE_H
|
||||
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
**
|
||||
** $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is for use ONLY with the time conversion code.
|
||||
** There is no guarantee that it will remain unchanged,
|
||||
** or that it will remain at all.
|
||||
** Do NOT copy it to any system include directory.
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
/*
|
||||
** Information about time zone files.
|
||||
*/
|
||||
|
||||
#ifndef TZDIR
|
||||
# define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
|
||||
#endif /* !defined TZDIR */
|
||||
|
||||
#ifndef TZDEFAULT
|
||||
# define TZDEFAULT "/etc/localtime"
|
||||
#endif /* !defined TZDEFAULT */
|
||||
|
||||
#ifndef TZDEFRULES
|
||||
# define TZDEFRULES "posixrules"
|
||||
#endif /* !defined TZDEFRULES */
|
||||
|
||||
|
||||
/* See Internet RFC 8536 for more details about the following format. */
|
||||
|
||||
/*
|
||||
** Each file begins with. . .
|
||||
*/
|
||||
|
||||
#define TZ_MAGIC "TZif"
|
||||
|
||||
struct tzhead {
|
||||
char tzh_magic[4]; /* TZ_MAGIC */
|
||||
char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */
|
||||
char tzh_reserved[15]; /* reserved; must be zero */
|
||||
char tzh_ttisutcnt[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 */
|
||||
char tzh_timecnt[4]; /* coded number of transition times */
|
||||
char tzh_typecnt[4]; /* coded number of local time types */
|
||||
char tzh_charcnt[4]; /* coded number of abbr. chars */
|
||||
};
|
||||
|
||||
/*
|
||||
** . . .followed by. . .
|
||||
**
|
||||
** tzh_timecnt (char [4])s coded transition times a la time(2)
|
||||
** tzh_timecnt (unsigned char)s types of local time starting at above
|
||||
** tzh_typecnt repetitions of
|
||||
** one (char [4]) coded UT offset in seconds
|
||||
** one (unsigned char) used to set tm_isdst
|
||||
** one (unsigned char) that's an abbreviation list index
|
||||
** tzh_charcnt (char)s '\0'-terminated zone abbreviations
|
||||
** tzh_leapcnt repetitions of
|
||||
** one (char [4]) coded leap second transition times
|
||||
** one (char [4]) total correction after above
|
||||
** tzh_ttisstdcnt (char)s indexed by type; if 1, transition
|
||||
** time is standard time, if 0,
|
||||
** transition time is local (wall clock)
|
||||
** time; if absent, transition times are
|
||||
** assumed to be local time
|
||||
** tzh_ttisutcnt (char)s indexed by type; if 1, transition
|
||||
** time is UT, if 0, transition time is
|
||||
** local time; if absent, transition
|
||||
** times are assumed to be local time.
|
||||
** When this is 1, the corresponding
|
||||
** std/wall indicator must also be 1.
|
||||
*/
|
||||
|
||||
/*
|
||||
** 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).
|
||||
**
|
||||
** If tz_version is '3' or greater, the above is extended as follows.
|
||||
** First, the POSIX TZ string's hour offset may range from -167
|
||||
** through 167 as compared to the POSIX-required 0 through 24.
|
||||
** Second, its DST start time may be January 1 at 00:00 and its stop
|
||||
** time December 31 at 24:00 plus the difference between DST and
|
||||
** standard time, indicating DST all year.
|
||||
*/
|
||||
|
||||
/*
|
||||
** In the current implementation, "tzset()" refuses to deal with files that
|
||||
** exceed any of the limits below.
|
||||
*/
|
||||
|
||||
#ifndef TZ_MAX_TIMES
|
||||
# define TZ_MAX_TIMES 2000
|
||||
#endif /* !defined TZ_MAX_TIMES */
|
||||
|
||||
#ifndef TZ_MAX_TYPES
|
||||
/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
|
||||
# define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
|
||||
#endif /* !defined TZ_MAX_TYPES */
|
||||
|
||||
#ifndef TZ_MAX_CHARS
|
||||
# define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
||||
/* (limited by what unsigned chars can hold) */
|
||||
#endif /* !defined TZ_MAX_CHARS */
|
||||
|
||||
#ifndef TZ_MAX_LEAPS
|
||||
# define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
|
||||
#endif /* !defined TZ_MAX_LEAPS */
|
||||
|
||||
#endif /* !defined TZFILE_H */
|
125
contrib/tzcode/tzselect.8
Normal file
125
contrib/tzcode/tzselect.8
Normal file
|
@ -0,0 +1,125 @@
|
|||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.TH TZSELECT 8
|
||||
.SH NAME
|
||||
tzselect \- select a timezone
|
||||
.SH SYNOPSIS
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.ds d " degrees
|
||||
.ds m " minutes
|
||||
.ds s " seconds
|
||||
.ds _ " \&
|
||||
.if t \{\
|
||||
. if \n(.g .if c \(de .if c \(fm .if c \(sd \{\
|
||||
. ds d \(de
|
||||
. ds m \(fm
|
||||
. ds s \(sd
|
||||
. ds _ \|
|
||||
. \}
|
||||
.\}
|
||||
.B tzselect
|
||||
[
|
||||
.B \*-c
|
||||
.I coord
|
||||
] [
|
||||
.B \*-n
|
||||
.I limit
|
||||
] [
|
||||
.B \*-\*-help
|
||||
] [
|
||||
.B \*-\*-version
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B tzselect
|
||||
program asks the user for information about the current location,
|
||||
and outputs the resulting timezone to standard output.
|
||||
The output is suitable as a value for the TZ environment variable.
|
||||
.PP
|
||||
All interaction with the user is done via standard input and standard error.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "\*-c " coord
|
||||
Instead of asking for continent and then country and then city,
|
||||
ask for selection from time zones whose largest cities
|
||||
are closest to the location with geographical coordinates
|
||||
.I coord.
|
||||
Use ISO 6709 notation for
|
||||
.I coord,
|
||||
that is, a latitude immediately followed by a longitude. The latitude
|
||||
and longitude should be signed integers followed by an optional
|
||||
decimal point and fraction: positive numbers represent north and east,
|
||||
negative south and west. Latitudes with two and longitudes with three
|
||||
integer digits are treated as degrees; latitudes with four or six and
|
||||
longitudes with five or seven integer digits are treated as
|
||||
.I "DDMM, DDDMM, DDMMSS,"
|
||||
or
|
||||
.I DDDMMSS
|
||||
representing
|
||||
.I DD
|
||||
or
|
||||
.I DDD
|
||||
degrees,
|
||||
.I MM
|
||||
minutes,
|
||||
and zero or
|
||||
.I SS
|
||||
seconds, with any trailing fractions represent fractional minutes or
|
||||
(if
|
||||
.I SS
|
||||
is present) seconds. The decimal point is that of the current locale.
|
||||
For example, in the (default) C locale,
|
||||
.B "\*-c\ +40.689\*-074.045"
|
||||
specifies 40.689\*d\*_N, 74.045\*d\*_W,
|
||||
.B "\*-c\ +4041.4\*-07402.7"
|
||||
specifies 40\*d\*_41.4\*m\*_N, 74\*d\*_2.7\*m\*_W, and
|
||||
.B "\*-c\ +404121\*-0740240"
|
||||
specifies 40\*d\*_41\*m\*_21\*s\*_N, 74\*d\*_2\*m\*_40\*s\*_W.
|
||||
If
|
||||
.I coord
|
||||
is not one of the documented forms, the resulting behavior is unspecified.
|
||||
.TP
|
||||
.BI "\*-n " limit
|
||||
When
|
||||
.B \*-c
|
||||
is used, display the closest
|
||||
.I limit
|
||||
locations (default 10).
|
||||
.TP
|
||||
.B "\*-\*-help"
|
||||
Output help information and exit.
|
||||
.TP
|
||||
.B "\*-\*-version"
|
||||
Output version information and exit.
|
||||
.SH "ENVIRONMENT VARIABLES"
|
||||
.TP
|
||||
\f3AWK\fP
|
||||
Name of a Posix-compliant
|
||||
.B awk
|
||||
program (default:
|
||||
.BR awk ).
|
||||
.TP
|
||||
\f3TZDIR\fP
|
||||
Name of the directory containing timezone data files (default:
|
||||
.BR /usr/share/zoneinfo ).
|
||||
.SH FILES
|
||||
.TP
|
||||
\f2TZDIR\fP\f3/iso3166.tab\fP
|
||||
Table of ISO 3166 2-letter country codes and country names.
|
||||
.TP
|
||||
\f2TZDIR\fP\f3/zone1970.tab\fP
|
||||
Table of country codes, latitude and longitude, timezones, and
|
||||
descriptive comments.
|
||||
.TP
|
||||
\f2TZDIR\fP\f3/\fP\f2TZ\fP
|
||||
Timezone data file for timezone \f2TZ\fP.
|
||||
.SH "EXIT STATUS"
|
||||
The exit status is zero if a timezone was successfully obtained from the user,
|
||||
nonzero otherwise.
|
||||
.SH "SEE ALSO"
|
||||
newctime(3), tzfile(5), zdump(8), zic(8)
|
||||
.SH NOTES
|
||||
Applications should not assume that
|
||||
.BR tzselect 's
|
||||
output matches the user's political preferences.
|
586
contrib/tzcode/tzselect.ksh
Normal file
586
contrib/tzcode/tzselect.ksh
Normal file
|
@ -0,0 +1,586 @@
|
|||
#!/bin/bash
|
||||
# Ask the user about the time zone, and output the resulting TZ value to stdout.
|
||||
# Interact with the user via stderr and stdin.
|
||||
|
||||
PKGVERSION='(tzcode) '
|
||||
TZVERSION=see_Makefile
|
||||
REPORT_BUGS_TO=tz@iana.org
|
||||
|
||||
# Contributed by Paul Eggert. This file is in the public domain.
|
||||
|
||||
# Porting notes:
|
||||
#
|
||||
# This script requires a Posix-like shell and prefers the extension of a
|
||||
# 'select' statement. The 'select' statement was introduced in the
|
||||
# Korn shell and is available in Bash and other shell implementations.
|
||||
# If your host lacks both Bash and the Korn shell, you can get their
|
||||
# source from one of these locations:
|
||||
#
|
||||
# Bash <https://www.gnu.org/software/bash/>
|
||||
# Korn Shell <http://www.kornshell.com/>
|
||||
# MirBSD Korn Shell <http://www.mirbsd.org/mksh.htm>
|
||||
#
|
||||
# For portability to Solaris 10 /bin/sh (supported by Oracle through
|
||||
# January 2024) this script avoids some POSIX features and common
|
||||
# extensions, such as $(...) (which works sometimes but not others),
|
||||
# $((...)), ! CMD, ${#ID}, ${ID##PAT}, ${ID%%PAT}, and $10.
|
||||
|
||||
#
|
||||
# This script also uses several features of modern awk programs.
|
||||
# If your host lacks awk, or has an old awk that does not conform to Posix,
|
||||
# you can use either of the following free programs instead:
|
||||
#
|
||||
# Gawk (GNU awk) <https://www.gnu.org/software/gawk/>
|
||||
# mawk <https://invisible-island.net/mawk/>
|
||||
# nawk <https://github.com/onetrueawk/awk>
|
||||
|
||||
|
||||
# Specify default values for environment variables if they are unset.
|
||||
: ${AWK=awk}
|
||||
: ${TZDIR=`pwd`}
|
||||
|
||||
# Output one argument as-is to standard output.
|
||||
# Safer than 'echo', which can mishandle '\' or leading '-'.
|
||||
say() {
|
||||
printf '%s\n' "$1"
|
||||
}
|
||||
|
||||
# Check for awk Posix compliance.
|
||||
($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
|
||||
[ $? = 123 ] || {
|
||||
say >&2 "$0: Sorry, your '$AWK' program is not Posix compatible."
|
||||
exit 1
|
||||
}
|
||||
|
||||
coord=
|
||||
location_limit=10
|
||||
zonetabtype=zone1970
|
||||
|
||||
usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT]
|
||||
Select a timezone interactively.
|
||||
|
||||
Options:
|
||||
|
||||
-c COORD
|
||||
Instead of asking for continent and then country and then city,
|
||||
ask for selection from time zones whose largest cities
|
||||
are closest to the location with geographical coordinates COORD.
|
||||
COORD should use ISO 6709 notation, for example, '-c +4852+00220'
|
||||
for Paris (in degrees and minutes, North and East), or
|
||||
'-c -35-058' for Buenos Aires (in degrees, South and West).
|
||||
|
||||
-n LIMIT
|
||||
Display at most LIMIT locations when -c is used (default $location_limit).
|
||||
|
||||
--version
|
||||
Output version information.
|
||||
|
||||
--help
|
||||
Output this help.
|
||||
|
||||
Report bugs to $REPORT_BUGS_TO."
|
||||
|
||||
# Ask the user to select from the function's arguments,
|
||||
# and assign the selected argument to the variable 'select_result'.
|
||||
# Exit on EOF or I/O error. Use the shell's 'select' builtin if available,
|
||||
# falling back on a less-nice but portable substitute otherwise.
|
||||
if
|
||||
case $BASH_VERSION in
|
||||
?*) : ;;
|
||||
'')
|
||||
# '; exit' should be redundant, but Dash doesn't properly fail without it.
|
||||
(eval 'set --; select x; do break; done; exit') </dev/null 2>/dev/null
|
||||
esac
|
||||
then
|
||||
# Do this inside 'eval', as otherwise the shell might exit when parsing it
|
||||
# even though it is never executed.
|
||||
eval '
|
||||
doselect() {
|
||||
select select_result
|
||||
do
|
||||
case $select_result in
|
||||
"") echo >&2 "Please enter a number in range." ;;
|
||||
?*) break
|
||||
esac
|
||||
done || exit
|
||||
}
|
||||
'
|
||||
else
|
||||
doselect() {
|
||||
# Field width of the prompt numbers.
|
||||
select_width=`expr $# : '.*'`
|
||||
|
||||
select_i=
|
||||
|
||||
while :
|
||||
do
|
||||
case $select_i in
|
||||
'')
|
||||
select_i=0
|
||||
for select_word
|
||||
do
|
||||
select_i=`expr $select_i + 1`
|
||||
printf >&2 "%${select_width}d) %s\\n" $select_i "$select_word"
|
||||
done ;;
|
||||
*[!0-9]*)
|
||||
echo >&2 'Please enter a number in range.' ;;
|
||||
*)
|
||||
if test 1 -le $select_i && test $select_i -le $#; then
|
||||
shift `expr $select_i - 1`
|
||||
select_result=$1
|
||||
break
|
||||
fi
|
||||
echo >&2 'Please enter a number in range.'
|
||||
esac
|
||||
|
||||
# Prompt and read input.
|
||||
printf >&2 %s "${PS3-#? }"
|
||||
read select_i || exit
|
||||
done
|
||||
}
|
||||
fi
|
||||
|
||||
while getopts c:n:t:-: opt
|
||||
do
|
||||
case $opt$OPTARG in
|
||||
c*)
|
||||
coord=$OPTARG ;;
|
||||
n*)
|
||||
location_limit=$OPTARG ;;
|
||||
t*) # Undocumented option, used for developer testing.
|
||||
zonetabtype=$OPTARG ;;
|
||||
-help)
|
||||
exec echo "$usage" ;;
|
||||
-version)
|
||||
exec echo "tzselect $PKGVERSION$TZVERSION" ;;
|
||||
-*)
|
||||
say >&2 "$0: -$opt$OPTARG: unknown option; try '$0 --help'"; exit 1 ;;
|
||||
*)
|
||||
say >&2 "$0: try '$0 --help'"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift `expr $OPTIND - 1`
|
||||
case $# in
|
||||
0) ;;
|
||||
*) say >&2 "$0: $1: unknown argument"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# Make sure the tables are readable.
|
||||
TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab
|
||||
TZ_ZONE_TABLE=$TZDIR/$zonetabtype.tab
|
||||
for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
|
||||
do
|
||||
<"$f" || {
|
||||
say >&2 "$0: time zone files are not set up correctly"
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
# If the current locale does not support UTF-8, convert data to current
|
||||
# locale's format if possible, as the shell aligns columns better that way.
|
||||
# Check the UTF-8 of U+12345 CUNEIFORM SIGN URU TIMES KI.
|
||||
$AWK 'BEGIN { u12345 = "\360\222\215\205"; exit length(u12345) != 1 }' || {
|
||||
{ tmp=`(mktemp -d) 2>/dev/null` || {
|
||||
tmp=${TMPDIR-/tmp}/tzselect.$$ &&
|
||||
(umask 77 && mkdir -- "$tmp")
|
||||
};} &&
|
||||
trap 'status=$?; rm -fr -- "$tmp"; exit $status' 0 HUP INT PIPE TERM &&
|
||||
(iconv -f UTF-8 -t //TRANSLIT <"$TZ_COUNTRY_TABLE" >$tmp/iso3166.tab) \
|
||||
2>/dev/null &&
|
||||
TZ_COUNTRY_TABLE=$tmp/iso3166.tab &&
|
||||
iconv -f UTF-8 -t //TRANSLIT <"$TZ_ZONE_TABLE" >$tmp/$zonetabtype.tab &&
|
||||
TZ_ZONE_TABLE=$tmp/$zonetabtype.tab
|
||||
}
|
||||
|
||||
newline='
|
||||
'
|
||||
IFS=$newline
|
||||
|
||||
|
||||
# Awk script to read a time zone table and output the same table,
|
||||
# with each column preceded by its distance from 'here'.
|
||||
output_distances='
|
||||
BEGIN {
|
||||
FS = "\t"
|
||||
while (getline <TZ_COUNTRY_TABLE)
|
||||
if ($0 ~ /^[^#]/)
|
||||
country[$1] = $2
|
||||
country["US"] = "US" # Otherwise the strings get too long.
|
||||
}
|
||||
function abs(x) {
|
||||
return x < 0 ? -x : x;
|
||||
}
|
||||
function min(x, y) {
|
||||
return x < y ? x : y;
|
||||
}
|
||||
function convert_coord(coord, deg, minute, ilen, sign, sec) {
|
||||
if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9][0-9][0-9]([^0-9]|$)/) {
|
||||
degminsec = coord
|
||||
intdeg = degminsec < 0 ? -int(-degminsec / 10000) : int(degminsec / 10000)
|
||||
minsec = degminsec - intdeg * 10000
|
||||
intmin = minsec < 0 ? -int(-minsec / 100) : int(minsec / 100)
|
||||
sec = minsec - intmin * 100
|
||||
deg = (intdeg * 3600 + intmin * 60 + sec) / 3600
|
||||
} else if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9]([^0-9]|$)/) {
|
||||
degmin = coord
|
||||
intdeg = degmin < 0 ? -int(-degmin / 100) : int(degmin / 100)
|
||||
minute = degmin - intdeg * 100
|
||||
deg = (intdeg * 60 + minute) / 60
|
||||
} else
|
||||
deg = coord
|
||||
return deg * 0.017453292519943296
|
||||
}
|
||||
function convert_latitude(coord) {
|
||||
match(coord, /..*[-+]/)
|
||||
return convert_coord(substr(coord, 1, RLENGTH - 1))
|
||||
}
|
||||
function convert_longitude(coord) {
|
||||
match(coord, /..*[-+]/)
|
||||
return convert_coord(substr(coord, RLENGTH))
|
||||
}
|
||||
# Great-circle distance between points with given latitude and longitude.
|
||||
# Inputs and output are in radians. This uses the great-circle special
|
||||
# case of the Vicenty formula for distances on ellipsoids.
|
||||
function gcdist(lat1, long1, lat2, long2, dlong, x, y, num, denom) {
|
||||
dlong = long2 - long1
|
||||
x = cos(lat2) * sin(dlong)
|
||||
y = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlong)
|
||||
num = sqrt(x * x + y * y)
|
||||
denom = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(dlong)
|
||||
return atan2(num, denom)
|
||||
}
|
||||
# Parallel distance between points with given latitude and longitude.
|
||||
# This is the product of the longitude difference and the cosine
|
||||
# of the latitude of the point that is further from the equator.
|
||||
# I.e., it considers longitudes to be further apart if they are
|
||||
# nearer the equator.
|
||||
function pardist(lat1, long1, lat2, long2) {
|
||||
return abs(long1 - long2) * min(cos(lat1), cos(lat2))
|
||||
}
|
||||
# The distance function is the sum of the great-circle distance and
|
||||
# the parallel distance. It could be weighted.
|
||||
function dist(lat1, long1, lat2, long2) {
|
||||
return gcdist(lat1, long1, lat2, long2) + pardist(lat1, long1, lat2, long2)
|
||||
}
|
||||
BEGIN {
|
||||
coord_lat = convert_latitude(coord)
|
||||
coord_long = convert_longitude(coord)
|
||||
}
|
||||
/^[^#]/ {
|
||||
here_lat = convert_latitude($2)
|
||||
here_long = convert_longitude($2)
|
||||
line = $1 "\t" $2 "\t" $3
|
||||
sep = "\t"
|
||||
ncc = split($1, cc, /,/)
|
||||
for (i = 1; i <= ncc; i++) {
|
||||
line = line sep country[cc[i]]
|
||||
sep = ", "
|
||||
}
|
||||
if (NF == 4)
|
||||
line = line " - " $4
|
||||
printf "%g\t%s\n", dist(coord_lat, coord_long, here_lat, here_long), line
|
||||
}
|
||||
'
|
||||
|
||||
# Begin the main loop. We come back here if the user wants to retry.
|
||||
while
|
||||
|
||||
echo >&2 'Please identify a location' \
|
||||
'so that time zone rules can be set correctly.'
|
||||
|
||||
continent=
|
||||
country=
|
||||
region=
|
||||
|
||||
case $coord in
|
||||
?*)
|
||||
continent=coord;;
|
||||
'')
|
||||
|
||||
# Ask the user for continent or ocean.
|
||||
|
||||
echo >&2 'Please select a continent, ocean, "coord", or "TZ".'
|
||||
|
||||
quoted_continents=`
|
||||
$AWK '
|
||||
function handle_entry(entry) {
|
||||
entry = substr(entry, 1, index(entry, "/") - 1)
|
||||
if (entry == "America")
|
||||
entry = entry "s"
|
||||
if (entry ~ /^(Arctic|Atlantic|Indian|Pacific)$/)
|
||||
entry = entry " Ocean"
|
||||
printf "'\''%s'\''\n", entry
|
||||
}
|
||||
BEGIN { FS = "\t" }
|
||||
/^[^#]/ {
|
||||
handle_entry($3)
|
||||
}
|
||||
/^#@/ {
|
||||
ncont = split($2, cont, /,/)
|
||||
for (ci = 1; ci <= ncont; ci++) {
|
||||
handle_entry(cont[ci])
|
||||
}
|
||||
}
|
||||
' <"$TZ_ZONE_TABLE" |
|
||||
sort -u |
|
||||
tr '\n' ' '
|
||||
echo ''
|
||||
`
|
||||
|
||||
eval '
|
||||
doselect '"$quoted_continents"' \
|
||||
"coord - I want to use geographical coordinates." \
|
||||
"TZ - I want to specify the timezone using the Posix TZ format."
|
||||
continent=$select_result
|
||||
case $continent in
|
||||
Americas) continent=America;;
|
||||
*" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''`
|
||||
esac
|
||||
'
|
||||
esac
|
||||
|
||||
case $continent in
|
||||
TZ)
|
||||
# Ask the user for a Posix TZ string. Check that it conforms.
|
||||
while
|
||||
echo >&2 'Please enter the desired value' \
|
||||
'of the TZ environment variable.'
|
||||
echo >&2 'For example, AEST-10 is abbreviated' \
|
||||
'AEST and is 10 hours'
|
||||
echo >&2 'ahead (east) of Greenwich,' \
|
||||
'with no daylight saving time.'
|
||||
read TZ
|
||||
$AWK -v TZ="$TZ" 'BEGIN {
|
||||
tzname = "(<[[:alnum:]+-]{3,}>|[[:alpha:]]{3,})"
|
||||
time = "(2[0-4]|[0-1]?[0-9])" \
|
||||
"(:[0-5][0-9](:[0-5][0-9])?)?"
|
||||
offset = "[-+]?" time
|
||||
mdate = "M([1-9]|1[0-2])\\.[1-5]\\.[0-6]"
|
||||
jdate = "((J[1-9]|[0-9]|J?[1-9][0-9]" \
|
||||
"|J?[1-2][0-9][0-9])|J?3[0-5][0-9]|J?36[0-5])"
|
||||
datetime = ",(" mdate "|" jdate ")(/" time ")?"
|
||||
tzpattern = "^(:.*|" tzname offset "(" tzname \
|
||||
"(" offset ")?(" datetime datetime ")?)?)$"
|
||||
if (TZ ~ tzpattern) exit 1
|
||||
exit 0
|
||||
}'
|
||||
do
|
||||
say >&2 "'$TZ' is not a conforming Posix timezone string."
|
||||
done
|
||||
TZ_for_date=$TZ;;
|
||||
*)
|
||||
case $continent in
|
||||
coord)
|
||||
case $coord in
|
||||
'')
|
||||
echo >&2 'Please enter coordinates' \
|
||||
'in ISO 6709 notation.'
|
||||
echo >&2 'For example, +4042-07403 stands for'
|
||||
echo >&2 '40 degrees 42 minutes north,' \
|
||||
'74 degrees 3 minutes west.'
|
||||
read coord;;
|
||||
esac
|
||||
distance_table=`$AWK \
|
||||
-v coord="$coord" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
"$output_distances" <"$TZ_ZONE_TABLE" |
|
||||
sort -n |
|
||||
sed "${location_limit}q"
|
||||
`
|
||||
regions=`say "$distance_table" | $AWK '
|
||||
BEGIN { FS = "\t" }
|
||||
{ print $NF }
|
||||
'`
|
||||
echo >&2 'Please select one of the following timezones,' \
|
||||
echo >&2 'listed roughly in increasing order' \
|
||||
"of distance from $coord".
|
||||
doselect $regions
|
||||
region=$select_result
|
||||
TZ=`say "$distance_table" | $AWK -v region="$region" '
|
||||
BEGIN { FS="\t" }
|
||||
$NF == region { print $4 }
|
||||
'`
|
||||
;;
|
||||
*)
|
||||
# Get list of names of countries in the continent or ocean.
|
||||
countries=`$AWK \
|
||||
-v continent_re="^$continent/" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
BEGIN { FS = "\t" }
|
||||
/^#$/ { next }
|
||||
/^#[^@]/ { next }
|
||||
{
|
||||
commentary = $0 ~ /^#@/
|
||||
if (commentary) {
|
||||
col1ccs = substr($1, 3)
|
||||
conts = $2
|
||||
} else {
|
||||
col1ccs = $1
|
||||
conts = $3
|
||||
}
|
||||
ncc = split(col1ccs, cc, /,/)
|
||||
ncont = split(conts, cont, /,/)
|
||||
for (i = 1; i <= ncc; i++) {
|
||||
elsewhere = commentary
|
||||
for (ci = 1; ci <= ncont; ci++) {
|
||||
if (cont[ci] ~ continent_re) {
|
||||
if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i]
|
||||
elsewhere = 0
|
||||
}
|
||||
}
|
||||
if (elsewhere) {
|
||||
for (i = 1; i <= ncc; i++) {
|
||||
cc_elsewhere[cc[i]] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
END {
|
||||
while (getline <TZ_COUNTRY_TABLE) {
|
||||
if ($0 !~ /^#/) cc_name[$1] = $2
|
||||
}
|
||||
for (i = 1; i <= ccs; i++) {
|
||||
country = cc_list[i]
|
||||
if (cc_elsewhere[country]) continue
|
||||
if (cc_name[country]) {
|
||||
country = cc_name[country]
|
||||
}
|
||||
print country
|
||||
}
|
||||
}
|
||||
' <"$TZ_ZONE_TABLE" | sort -f`
|
||||
|
||||
|
||||
# If there's more than one country, ask the user which one.
|
||||
case $countries in
|
||||
*"$newline"*)
|
||||
echo >&2 'Please select a country' \
|
||||
'whose clocks agree with yours.'
|
||||
doselect $countries
|
||||
country=$select_result;;
|
||||
*)
|
||||
country=$countries
|
||||
esac
|
||||
|
||||
|
||||
# Get list of timezones in the country.
|
||||
regions=`$AWK \
|
||||
-v country="$country" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
BEGIN {
|
||||
FS = "\t"
|
||||
cc = country
|
||||
while (getline <TZ_COUNTRY_TABLE) {
|
||||
if ($0 !~ /^#/ && country == $2) {
|
||||
cc = $1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
/^#/ { next }
|
||||
$1 ~ cc { print $4 }
|
||||
' <"$TZ_ZONE_TABLE"`
|
||||
|
||||
|
||||
# If there's more than one region, ask the user which one.
|
||||
case $regions in
|
||||
*"$newline"*)
|
||||
echo >&2 'Please select one of the following timezones.'
|
||||
doselect $regions
|
||||
region=$select_result;;
|
||||
*)
|
||||
region=$regions
|
||||
esac
|
||||
|
||||
# Determine TZ from country and region.
|
||||
TZ=`$AWK \
|
||||
-v country="$country" \
|
||||
-v region="$region" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
BEGIN {
|
||||
FS = "\t"
|
||||
cc = country
|
||||
while (getline <TZ_COUNTRY_TABLE) {
|
||||
if ($0 !~ /^#/ && country == $2) {
|
||||
cc = $1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
/^#/ { next }
|
||||
$1 ~ cc && $4 == region { print $3 }
|
||||
' <"$TZ_ZONE_TABLE"`
|
||||
esac
|
||||
|
||||
# Make sure the corresponding zoneinfo file exists.
|
||||
TZ_for_date=$TZDIR/$TZ
|
||||
<"$TZ_for_date" || {
|
||||
say >&2 "$0: time zone files are not set up correctly"
|
||||
exit 1
|
||||
}
|
||||
esac
|
||||
|
||||
|
||||
# Use the proposed TZ to output the current date relative to UTC.
|
||||
# Loop until they agree in seconds.
|
||||
# Give up after 8 unsuccessful tries.
|
||||
|
||||
extra_info=
|
||||
for i in 1 2 3 4 5 6 7 8
|
||||
do
|
||||
TZdate=`LANG=C TZ="$TZ_for_date" date`
|
||||
UTdate=`LANG=C TZ=UTC0 date`
|
||||
TZsec=`expr "$TZdate" : '.*:\([0-5][0-9]\)'`
|
||||
UTsec=`expr "$UTdate" : '.*:\([0-5][0-9]\)'`
|
||||
case $TZsec in
|
||||
$UTsec)
|
||||
extra_info="
|
||||
Selected time is now: $TZdate.
|
||||
Universal Time is now: $UTdate."
|
||||
break
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
# Output TZ info and ask the user to confirm.
|
||||
|
||||
echo >&2 ""
|
||||
echo >&2 "The following information has been given:"
|
||||
echo >&2 ""
|
||||
case $country%$region%$coord in
|
||||
?*%?*%) say >&2 " $country$newline $region";;
|
||||
?*%%) say >&2 " $country";;
|
||||
%?*%?*) say >&2 " coord $coord$newline $region";;
|
||||
%%?*) say >&2 " coord $coord";;
|
||||
*) say >&2 " TZ='$TZ'"
|
||||
esac
|
||||
say >&2 ""
|
||||
say >&2 "Therefore TZ='$TZ' will be used.$extra_info"
|
||||
say >&2 "Is the above information OK?"
|
||||
|
||||
doselect Yes No
|
||||
ok=$select_result
|
||||
case $ok in
|
||||
Yes) break
|
||||
esac
|
||||
do coord=
|
||||
done
|
||||
|
||||
case $SHELL in
|
||||
*csh) file=.login line="setenv TZ '$TZ'";;
|
||||
*) file=.profile line="TZ='$TZ'; export TZ"
|
||||
esac
|
||||
|
||||
test -t 1 && say >&2 "
|
||||
You can make this change permanent for yourself by appending the line
|
||||
$line
|
||||
to the file '$file' in your home directory; then log out and log in again.
|
||||
|
||||
Here is that TZ value again, this time on standard output so that you
|
||||
can use the $0 command in shell scripts:"
|
||||
|
||||
say "$TZ"
|
1
contrib/tzcode/version
Normal file
1
contrib/tzcode/version
Normal file
|
@ -0,0 +1 @@
|
|||
2022g
|
3
contrib/tzcode/version.h
Normal file
3
contrib/tzcode/version.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
static char const PKGVERSION[]="(tzcode) ";
|
||||
static char const TZVERSION[]="2022g";
|
||||
static char const REPORT_BUGS_TO[]="tz@iana.org";
|
41
contrib/tzcode/workman.sh
Normal file
41
contrib/tzcode/workman.sh
Normal file
|
@ -0,0 +1,41 @@
|
|||
#! /bin/sh
|
||||
# Convert manual page troff stdin to formatted .txt stdout.
|
||||
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
|
||||
if (type nroff && type perl) >/dev/null 2>&1; then
|
||||
|
||||
# Tell groff not to emit SGR escape sequences (ANSI color escapes).
|
||||
GROFF_NO_SGR=1
|
||||
export GROFF_NO_SGR
|
||||
|
||||
echo ".am TH
|
||||
.hy 0
|
||||
.na
|
||||
..
|
||||
.rm }H
|
||||
.rm }F" | nroff -man - ${1+"$@"} | perl -ne '
|
||||
binmode STDIN, '\'':encoding(utf8)'\'';
|
||||
binmode STDOUT, '\'':encoding(utf8)'\'';
|
||||
chomp;
|
||||
s/.\010//g;
|
||||
s/\s*$//;
|
||||
if (/^$/) {
|
||||
$sawblank = 1;
|
||||
next;
|
||||
} else {
|
||||
if ($sawblank && $didprint) {
|
||||
print "\n";
|
||||
$sawblank = 0;
|
||||
}
|
||||
print "$_\n";
|
||||
$didprint = 1;
|
||||
}
|
||||
'
|
||||
elif (type mandoc && type col) >/dev/null 2>&1; then
|
||||
mandoc -man -T ascii "$@" | col -bx
|
||||
else
|
||||
echo >&2 "$0: please install nroff and perl, or mandoc and col"
|
||||
exit 1
|
||||
fi
|
231
contrib/tzcode/zdump.8
Normal file
231
contrib/tzcode/zdump.8
Normal file
|
@ -0,0 +1,231 @@
|
|||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 15, 2022
|
||||
.Dt ZDUMP 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm zdump
|
||||
.Nd timezone dumper
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl -help
|
||||
.Op Fl -version
|
||||
.Op Fl ivV
|
||||
.Oo
|
||||
.Fl c
|
||||
.Op Ar loyear , Ns
|
||||
.Ar hiyear
|
||||
.Oc
|
||||
.Oo
|
||||
.Fl t
|
||||
.Op Ar lotime , Ns
|
||||
.Ar hitime
|
||||
.Oc
|
||||
.Op Ar timezone ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program prints the current time in each
|
||||
.Ar timezone
|
||||
named on the command line.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl -version
|
||||
Output version information and exit.
|
||||
.It Fl -help
|
||||
Output short usage message and exit.
|
||||
.It Fl i
|
||||
Output a description of time intervals.
|
||||
For each
|
||||
.Ar timezone
|
||||
on the command line, output an interval-format description of the
|
||||
timezone.
|
||||
See
|
||||
.Sx "INTERVAL FORMAT"
|
||||
below.
|
||||
.It Fl v
|
||||
Output a verbose description of time intervals.
|
||||
For each
|
||||
.Ar timezone
|
||||
on the command line,
|
||||
print the times at the two extreme time values,
|
||||
the times (if present) at and just beyond the boundaries of years that
|
||||
.Xr localtime 3
|
||||
and
|
||||
.Xr gmtime 3
|
||||
can represent, and
|
||||
the times both one second before and exactly at
|
||||
each detected time discontinuity.
|
||||
Each line is followed by
|
||||
.Cm isdst= Ns Ar D
|
||||
where
|
||||
.Ar D
|
||||
is positive, zero, or negative depending on whether
|
||||
the given time is daylight saving time, standard time,
|
||||
or an unknown time type, respectively.
|
||||
Each line is also followed by
|
||||
.Cm gmtoff= Ns Ar N
|
||||
if the given local time is known to be
|
||||
.Ar N
|
||||
seconds east of Greenwich.
|
||||
.It Fl V
|
||||
Like
|
||||
.Fl v ,
|
||||
except omit output concerning extreme time and year values.
|
||||
This generates output that is easier to compare to that of
|
||||
implementations with different time representations.
|
||||
.It Fl c Oo Ar loyear , Oc Ns Ar hiyear
|
||||
Cut off interval output at the given year(s).
|
||||
Cutoff times are computed using the proleptic Gregorian calendar with year 0
|
||||
and with Universal Time (UT) ignoring leap seconds.
|
||||
Cutoffs are at the start of each year, where the lower-bound
|
||||
timestamp is inclusive and the upper is exclusive; for example,
|
||||
.Ql "-c 1970,2070"
|
||||
selects transitions on or after 1970-01-01 00:00:00 UTC
|
||||
and before 2070-01-01 00:00:00 UTC.
|
||||
The default cutoff is
|
||||
.Ql -500,2500 .
|
||||
.It Fl t Oo Ar lotime , Oc Ns Ar hitime
|
||||
Cut off interval output at the given time(s),
|
||||
given in decimal seconds since 1970-01-01 00:00:00
|
||||
Coordinated Universal Time (UTC).
|
||||
The
|
||||
.Ar timezone
|
||||
determines whether the count includes leap seconds.
|
||||
As with
|
||||
.Fl c ,
|
||||
the cutoff's lower bound is inclusive and its upper bound is exclusive.
|
||||
.El
|
||||
.Sh "INTERVAL FORMAT"
|
||||
The interval format is a compact text representation that is intended
|
||||
to be both human- and machine-readable.
|
||||
It consists of an empty line,
|
||||
then a line
|
||||
.Dq "TZ=\fIstring\fP"
|
||||
where
|
||||
.Ar string
|
||||
is a double-quoted string giving the timezone, a second line
|
||||
.Dq "\*- \*- \fIinterval\fP"
|
||||
describing the time interval before the first transition if any, and
|
||||
zero or more following lines
|
||||
.Dq "\fIdate time interval\fP",
|
||||
one line for each transition time and following interval.
|
||||
Fields are
|
||||
separated by single tabs.
|
||||
.Pp
|
||||
Dates are in
|
||||
.Ql "yyyy - mm - dd"
|
||||
format and times are in 24-hour
|
||||
.Ql "hh : mm : ss"
|
||||
format where
|
||||
.Ql "hh <24" .
|
||||
Times are in local time immediately after the transition.
|
||||
A
|
||||
time interval description consists of a UT offset in signed
|
||||
.Ql "\(+- hhmmss"
|
||||
format, a time zone abbreviation, and an isdst flag.
|
||||
An abbreviation
|
||||
that equals the UT offset is omitted; other abbreviations are
|
||||
double-quoted strings unless they consist of one or more alphabetic
|
||||
characters.
|
||||
An isdst flag is omitted for standard time, and otherwise
|
||||
is a decimal integer that is unsigned and positive (typically 1) for
|
||||
daylight saving time and negative for unknown.
|
||||
.Pp
|
||||
In times and in UT offsets with absolute value less than 100 hours,
|
||||
the seconds are omitted if they are zero, and
|
||||
the minutes are also omitted if they are also zero.
|
||||
Positive UT
|
||||
offsets are east of Greenwich.
|
||||
The UT offset \*-00 denotes a UT
|
||||
placeholder in areas where the actual offset is unspecified; by
|
||||
convention, this occurs when the UT offset is zero and the time zone
|
||||
abbreviation begins with
|
||||
.Dq "-"
|
||||
or is
|
||||
.Dq "zzz".
|
||||
.Pp
|
||||
In double-quoted strings, escape sequences represent unusual
|
||||
characters.
|
||||
The escape sequences are \es for space, and \e", \e\e,
|
||||
\ef, \en, \er, \et, and \ev with their usual meaning in the C
|
||||
programming language.
|
||||
E.g., the double-quoted string
|
||||
\*(lq"CET\es\e"\e\e"\*(rq represents the character sequence \*(lqCET
|
||||
"\e\*(rq.\""
|
||||
.Pp
|
||||
Here is an example of the output, with the leading empty line omitted.
|
||||
(This example is shown with tab stops set far enough apart so that the
|
||||
tabbed columns line up.)
|
||||
.Bd -literal -offset indent
|
||||
TZ="Pacific/Honolulu"
|
||||
- - -103126 LMT
|
||||
1896-01-13 12:01:26 -1030 HST
|
||||
1933-04-30 03 -0930 HDT 1
|
||||
1933-05-21 11 -1030 HST
|
||||
1942-02-09 03 -0930 HWT 1
|
||||
1945-08-14 13:30 -0930 HPT 1
|
||||
1945-09-30 01 -1030 HST
|
||||
1947-06-08 02:30 -10 HST
|
||||
.Ed
|
||||
.Pp
|
||||
Here, local time begins 10 hours, 31 minutes and 26 seconds west of
|
||||
UT, and is a standard time abbreviated LMT.
|
||||
Immediately after the
|
||||
first transition, the date is 1896-01-13 and the time is 12:01:26, and
|
||||
the following time interval is 10.5 hours west of UT, a standard time
|
||||
abbreviated HST.
|
||||
Immediately after the second transition, the date is
|
||||
1933-04-30 and the time is 03:00:00 and the following time interval is
|
||||
9.5 hours west of UT, is abbreviated HDT, and is daylight saving time.
|
||||
Immediately after the last transition the date is 1947-06-08 and the
|
||||
time is 02:30:00, and the following time interval is 10 hours west of
|
||||
UT, a standard time abbreviated HST.
|
||||
.Pp
|
||||
Here are excerpts from another example:
|
||||
.Bd -literal -offset indent
|
||||
TZ="Europe/Astrakhan"
|
||||
- - +031212 LMT
|
||||
1924-04-30 23:47:48 +03
|
||||
1930-06-21 01 +04
|
||||
1981-04-01 01 +05 1
|
||||
1981-09-30 23 +04
|
||||
\&...
|
||||
2014-10-26 01 +03
|
||||
2016-03-27 03 +04
|
||||
.Ed
|
||||
.Pp
|
||||
This time zone is east of UT, so its UT offsets are positive.
|
||||
Also,
|
||||
many of its time zone abbreviations are omitted since they duplicate
|
||||
the text of the UT offset.
|
||||
.Sh LIMITATIONS
|
||||
Time discontinuities are found by sampling the results returned by
|
||||
.Xr localtime 3
|
||||
at twelve-hour intervals.
|
||||
This works in all real-world cases;
|
||||
one can construct artificial time zones for which this fails.
|
||||
.Pp
|
||||
In the
|
||||
.Fl v
|
||||
and
|
||||
.Fl V
|
||||
output,
|
||||
.Dq "UT"
|
||||
denotes the value returned by
|
||||
.Xr gmtime 3 ,
|
||||
which uses UTC for modern timestamps and some other UT flavor for
|
||||
timestamps that predate the introduction of UTC.
|
||||
No attempt is currently made to have the output use
|
||||
.Dq "UTC"
|
||||
for newer and
|
||||
.Dq "UT"
|
||||
for older timestamps, partly because the exact date of the
|
||||
introduction of UTC is problematic.
|
||||
.Sh SEE ALSO
|
||||
.Xr tzfile 5 ,
|
||||
.Xr zic 8
|
1257
contrib/tzcode/zdump.c
Normal file
1257
contrib/tzcode/zdump.c
Normal file
File diff suppressed because it is too large
Load diff
856
contrib/tzcode/zic.8
Normal file
856
contrib/tzcode/zic.8
Normal file
|
@ -0,0 +1,856 @@
|
|||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 15, 2022
|
||||
.Dt ZIC 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm zic
|
||||
.Nd timezone compiler
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl -help
|
||||
.Op Fl -version
|
||||
.Op Fl Dsv
|
||||
.Op Fl b Ar slim | fat
|
||||
.Op Fl d Ar directory
|
||||
.Op Fl g Ar gid
|
||||
.Op Fl l Ar localtime
|
||||
.Op Fl L Ar leapseconds
|
||||
.Op Fl m Ar mode
|
||||
.Op Fl p Ar posixrules
|
||||
.Oo
|
||||
.Fl r
|
||||
.Op @ Ns Ar lo Ns
|
||||
.Op /@ Ns Ar hi
|
||||
.Oc
|
||||
.Op Fl R @ Ns Ar hi
|
||||
.Op Fl t Ar localtime-link
|
||||
.Op Fl u Ar uid
|
||||
.Op Ar filename ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program reads text from the file(s) named on the command line
|
||||
and creates the timezone information format (TZif) files
|
||||
specified in this input.
|
||||
If a
|
||||
.Ar filename
|
||||
is
|
||||
.Dq "-" ,
|
||||
standard input is read.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl -version
|
||||
Output version information and exit.
|
||||
.It Fl -help
|
||||
Output short usage message and exit.
|
||||
.It Fl b Ar bloat
|
||||
Output backward-compatibility data as specified by
|
||||
.Ar bloat .
|
||||
If
|
||||
.Ar bloat
|
||||
is
|
||||
.Cm fat ,
|
||||
generate additional data entries that work around potential bugs or
|
||||
incompatibilities in older software, such as software that mishandles
|
||||
the 64-bit generated data.
|
||||
If
|
||||
.Ar bloat
|
||||
is
|
||||
.Cm slim ,
|
||||
keep the output files small; this can help check for the bugs
|
||||
and incompatibilities.
|
||||
The default is
|
||||
.Cm slim ,
|
||||
as software that mishandles 64-bit data typically
|
||||
mishandles timestamps after the year 2038 anyway.
|
||||
Also see the
|
||||
.Fl r
|
||||
option for another way to alter output size.
|
||||
.It Fl d Ar directory
|
||||
Create time conversion information files in the named directory rather than
|
||||
in the standard directory named below.
|
||||
.It Fl l Ar timezone
|
||||
Use
|
||||
.Ar timezone
|
||||
as local time.
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
will act as if the input contained a link line of the form
|
||||
.Bd -literal -offset indent
|
||||
Link timezone localtime
|
||||
.Ed
|
||||
.Pp
|
||||
If
|
||||
.Ar timezone
|
||||
is
|
||||
.Ql - ,
|
||||
any already-existing link is removed.
|
||||
.It Fl L Ar filename
|
||||
Read leap second information from the file with the given name.
|
||||
If this option is not used,
|
||||
no leap second information appears in output files.
|
||||
.It Fl p Ar timezone
|
||||
Use
|
||||
.Ar timezone 's
|
||||
rules when handling nonstandard
|
||||
TZ strings like
|
||||
.Dq "EET\-2EEST"
|
||||
that lack transition rules.
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
will act as if the input contained a link line of the form
|
||||
.Bd -literal -offset indent
|
||||
Link \fItimezone\fP posixrules
|
||||
.Ed
|
||||
.Pp
|
||||
This feature is obsolete and poorly supported.
|
||||
Among other things it should not be used for timestamps after the year 2037,
|
||||
and it should not be combined with
|
||||
.Fl b Cm slim
|
||||
if
|
||||
.Ar timezone 's
|
||||
transitions are at standard time or Universal Time (UT) instead of local time.
|
||||
.Pp
|
||||
If
|
||||
.Ar timezone
|
||||
is
|
||||
.Ql - ,
|
||||
any already-existing link is removed.
|
||||
.It Fl r Oo @ Ns Ar lo Oc Ns Oo /@ Ns Ar hi Oc
|
||||
Limit the applicability of output files
|
||||
to timestamps in the range from
|
||||
.Ar lo
|
||||
(inclusive) to
|
||||
.Ar hi
|
||||
(exclusive), where
|
||||
.Ar lo
|
||||
and
|
||||
.Ar hi
|
||||
are possibly-signed decimal counts of seconds since the Epoch
|
||||
(1970-01-01 00:00:00 UTC).
|
||||
Omitted counts default to extreme values.
|
||||
The output files use UT offset 0 and abbreviation
|
||||
.Dq "\-00"
|
||||
in place of the omitted timestamp data.
|
||||
For example,
|
||||
.Fl r @0
|
||||
omits data intended for negative timestamps (i.e., before the Epoch), and
|
||||
.Fl r @0/@2147483648
|
||||
outputs data intended only for nonnegative timestamps that fit into
|
||||
31-bit signed integers.
|
||||
Although this option typically reduces the output file's size,
|
||||
the size can increase due to the need to represent the timestamp range
|
||||
boundaries, particularly if
|
||||
.Ar hi
|
||||
causes a TZif file to contain explicit entries for
|
||||
.Em pre-
|
||||
.Ar hi
|
||||
transitions rather than concisely representing them
|
||||
with an extended POSIX TZ string.
|
||||
Also see the
|
||||
.Fl b Cm slim
|
||||
option for another way to shrink output size.
|
||||
.It Fl R @ Ns Ar hi
|
||||
Generate redundant trailing explicit transitions for timestamps
|
||||
that occur less than
|
||||
.Ar hi
|
||||
seconds since the Epoch, even though the transitions could be
|
||||
more concisely represented via the extended POSIX TZ string.
|
||||
This option does not affect the represented timestamps.
|
||||
Although it accommodates nonstandard TZif readers
|
||||
that ignore the extended POSIX TZ string,
|
||||
it increases the size of the altered output files.
|
||||
.It Fl t Ar file
|
||||
When creating local time information, put the configuration link in
|
||||
the named file rather than in the standard location.
|
||||
.It Fl v
|
||||
Be more verbose, and complain about the following situations:
|
||||
.Bl -bullet
|
||||
.It
|
||||
The input specifies a link to a link,
|
||||
something not supported by some older parsers, including
|
||||
.Nm
|
||||
itself through release 2022e.
|
||||
.It
|
||||
A year that appears in a data file is outside the range
|
||||
of representable years.
|
||||
.It
|
||||
A time of 24:00 or more appears in the input.
|
||||
Pre-1998 versions of
|
||||
.Nm
|
||||
prohibit 24:00, and pre-2007 versions prohibit times greater than 24:00.
|
||||
.It
|
||||
A rule goes past the start or end of the month.
|
||||
Pre-2004 versions of
|
||||
.Nm
|
||||
prohibit this.
|
||||
.It
|
||||
A time zone abbreviation uses a
|
||||
.Ql %z
|
||||
format.
|
||||
Pre-2015 versions of
|
||||
.Nm
|
||||
do not support this.
|
||||
.It
|
||||
A timestamp contains fractional seconds.
|
||||
Pre-2018 versions of
|
||||
.Nm
|
||||
do not support this.
|
||||
.It
|
||||
The input contains abbreviations that are mishandled by pre-2018 versions of
|
||||
.Nm
|
||||
due to a longstanding coding bug.
|
||||
These abbreviations include
|
||||
.Dq L
|
||||
for
|
||||
.Dq Link ,
|
||||
.Dq mi
|
||||
for
|
||||
.Dq min ,
|
||||
.Dq Sa
|
||||
for
|
||||
.Dq Sat ,
|
||||
and
|
||||
.Dq Su
|
||||
for
|
||||
.Dq Sun .
|
||||
.It
|
||||
The output file does not contain all the information about the
|
||||
long-term future of a timezone, because the future cannot be summarized as
|
||||
an extended POSIX TZ string.
|
||||
For example, as of 2019 this problem
|
||||
occurs for Iran's daylight-saving rules for the predicted future, as
|
||||
these rules are based on the Iranian calendar, which cannot be
|
||||
represented.
|
||||
.It
|
||||
The output contains data that may not be handled properly by client
|
||||
code designed for older
|
||||
.Nm
|
||||
output formats.
|
||||
These compatibility issues affect only timestamps
|
||||
before 1970 or after the start of 2038.
|
||||
.It
|
||||
The output contains a truncated leap second table,
|
||||
which can cause some older TZif readers to misbehave.
|
||||
This can occur if the
|
||||
.Fl L
|
||||
option is used, and either an Expires line is present or
|
||||
the
|
||||
.Fl r
|
||||
option is also used.
|
||||
.It
|
||||
The output file contains more than 1200 transitions,
|
||||
which may be mishandled by some clients.
|
||||
The current reference client supports at most 2000 transitions;
|
||||
pre-2014 versions of the reference client support at most 1200
|
||||
transitions.
|
||||
.It
|
||||
A time zone abbreviation has fewer than 3 or more than 6 characters.
|
||||
POSIX requires at least 3, and requires implementations to support
|
||||
at least 6.
|
||||
.It
|
||||
An output file name contains a byte that is not an ASCII letter,
|
||||
.Dq "\-" ,
|
||||
.Dq "/" ,
|
||||
or
|
||||
.Dq "_" ;
|
||||
or it contains a file name component that contains more than 14 bytes
|
||||
or that starts with
|
||||
.Dq "\-" .
|
||||
.El
|
||||
.El
|
||||
.RE
|
||||
.Sh FILES
|
||||
Input files use the format described in this section; output files use
|
||||
.Xr tzfile 5
|
||||
format.
|
||||
.Pp
|
||||
Input files should be text files, that is, they should be a series of
|
||||
zero or more lines, each ending in a newline byte and containing at
|
||||
most 2048 bytes counting the newline, and without any NUL bytes.
|
||||
The input text's encoding
|
||||
is typically UTF-8 or ASCII; it should have a unibyte representation
|
||||
for the POSIX Portable Character Set (PPCS)
|
||||
\*<https://pubs\*:.opengroup\*:.org/\*:onlinepubs/\*:9699919799/\*:basedefs/\*:V1_chap06\*:.html\*>
|
||||
and the encoding's non-unibyte characters should consist entirely of
|
||||
non-PPCS bytes.
|
||||
Non-PPCS characters typically occur only in comments:
|
||||
although output file names and time zone abbreviations can contain
|
||||
nearly any character, other software will work better if these are
|
||||
limited to the restricted syntax described under the
|
||||
.Fl v
|
||||
option.
|
||||
.Pp
|
||||
Input lines are made up of fields.
|
||||
Fields are separated from one another by one or more white space characters.
|
||||
The white space characters are space, form feed, carriage return, newline,
|
||||
tab, and vertical tab.
|
||||
Leading and trailing white space on input lines is ignored.
|
||||
An unquoted sharp character (\(sh) in the input introduces a comment which extends
|
||||
to the end of the line the sharp character appears on.
|
||||
White space characters and sharp characters may be enclosed in double quotes
|
||||
(\(dq) if they're to be used as part of a field.
|
||||
Any line that is blank (after comment stripping) is ignored.
|
||||
Nonblank lines are expected to be of one of three types:
|
||||
rule lines, zone lines, and link lines.
|
||||
.Pp
|
||||
Names must be in English and are case insensitive.
|
||||
They appear in several contexts, and include month and weekday names
|
||||
and keywords such as
|
||||
.Dq "maximum" ,
|
||||
.Dq "only" ,
|
||||
.Dq "Rolling" ,
|
||||
and
|
||||
.Dq "Zone" .
|
||||
A name can be abbreviated by omitting all but an initial prefix; any
|
||||
abbreviation must be unambiguous in context.
|
||||
.Pp
|
||||
A rule line has the form
|
||||
.Bd -literal -offset indent
|
||||
Rule NAME FROM TO \- IN ON AT SAVE LETTER/S
|
||||
.Ed
|
||||
.Pp
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
Rule US 1967 1973 \- Apr lastSun 2:00w 1:00d D
|
||||
.Ed
|
||||
.Pp
|
||||
The fields that make up a rule line are:
|
||||
.Bl -tag -width "LETTER/S"
|
||||
.It NAME
|
||||
Gives the name of the rule set that contains this line.
|
||||
The name must start with a character that is neither
|
||||
an ASCII digit nor
|
||||
.Dq \-
|
||||
nor
|
||||
.Dq + .
|
||||
To allow for future extensions,
|
||||
an unquoted name should not contain characters from the set
|
||||
.Dq Ql "!$%&'()*,/:;<=>?@[\]^`{|}~" .
|
||||
.It FROM
|
||||
Gives the first year in which the rule applies.
|
||||
Any signed integer year can be supplied; the proleptic Gregorian calendar
|
||||
is assumed, with year 0 preceding year 1.
|
||||
The word
|
||||
.Cm minimum
|
||||
(or an abbreviation) means the indefinite past.
|
||||
The word
|
||||
.Cm maximum
|
||||
(or an abbreviation) means the indefinite future.
|
||||
Rules can describe times that are not representable as time values,
|
||||
with the unrepresentable times ignored; this allows rules to be portable
|
||||
among hosts with differing time value types.
|
||||
.It TO
|
||||
Gives the final year in which the rule applies.
|
||||
In addition to
|
||||
.Cm minimum
|
||||
and
|
||||
.Cm maximum
|
||||
(as above),
|
||||
the word
|
||||
.Cm only
|
||||
(or an abbreviation)
|
||||
may be used to repeat the value of the
|
||||
.Ar FROM
|
||||
field.
|
||||
.It \-
|
||||
Is a reserved field and should always contain
|
||||
.Ql \-
|
||||
for compatibility with older versions of
|
||||
.Nm .
|
||||
It was previously known as the
|
||||
.Ar TYPE
|
||||
field, which could contain values to allow a
|
||||
separate script to further restrict in which
|
||||
.Dq types
|
||||
of years the rule would apply.
|
||||
.It IN
|
||||
Names the month in which the rule takes effect.
|
||||
Month names may be abbreviated.
|
||||
.It ON
|
||||
Gives the day on which the rule takes effect.
|
||||
Recognized forms include:
|
||||
.Bl -tag -compact -width "Sun<=25"
|
||||
.It 5
|
||||
the fifth of the month
|
||||
.It lastSun
|
||||
the last Sunday in the month
|
||||
.It lastMon
|
||||
the last Monday in the month
|
||||
.It Sun>=8
|
||||
first Sunday on or after the eighth
|
||||
.It Sun<=25
|
||||
last Sunday on or before the 25th
|
||||
.El
|
||||
.Pp
|
||||
A weekday name (e.g.,
|
||||
.Ql "Sunday" )
|
||||
or a weekday name preceded by
|
||||
.Dq "last"
|
||||
(e.g.,
|
||||
.Ql "lastSunday" )
|
||||
may be abbreviated or spelled out in full.
|
||||
There must be no white space characters within the
|
||||
.Ar ON
|
||||
field.
|
||||
The
|
||||
.Dq <=
|
||||
and
|
||||
.Dq >=
|
||||
constructs can result in a day in the neighboring month;
|
||||
for example, the IN-ON combination
|
||||
.Dq "Oct Sun>=31"
|
||||
stands for the first Sunday on or after October 31,
|
||||
even if that Sunday occurs in November.
|
||||
.It AT
|
||||
Gives the time of day at which the rule takes effect,
|
||||
relative to 00:00, the start of a calendar day.
|
||||
Recognized forms include:
|
||||
.Bl -tag -compact -width "00:19:32.13"
|
||||
.It 2
|
||||
time in hours
|
||||
.It 2:00
|
||||
time in hours and minutes
|
||||
.It 01:28:14
|
||||
time in hours, minutes, and seconds
|
||||
.It 00:19:32.13
|
||||
time with fractional seconds
|
||||
.It 12:00
|
||||
midday, 12 hours after 00:00
|
||||
.It 15:00
|
||||
3 PM, 15 hours after 00:00
|
||||
.It 24:00
|
||||
end of day, 24 hours after 00:00
|
||||
.It 260:00
|
||||
260 hours after 00:00
|
||||
.It \-2:30
|
||||
2.5 hours before 00:00
|
||||
.It \-
|
||||
equivalent to 0
|
||||
.El
|
||||
.Pp
|
||||
Although
|
||||
.Nm
|
||||
rounds times to the nearest integer second
|
||||
(breaking ties to the even integer), the fractions may be useful
|
||||
to other applications requiring greater precision.
|
||||
The source format does not specify any maximum precision.
|
||||
Any of these forms may be followed by the letter
|
||||
.Ql w
|
||||
if the given time is local or
|
||||
.Dq "wall clock"
|
||||
time,
|
||||
.Ql s
|
||||
if the given time is standard time without any adjustment for daylight saving,
|
||||
or
|
||||
.Ql u
|
||||
(or
|
||||
.Ql g
|
||||
or
|
||||
.Ql z )
|
||||
if the given time is universal time;
|
||||
in the absence of an indicator,
|
||||
local (wall clock) time is assumed.
|
||||
These forms ignore leap seconds; for example,
|
||||
if a leap second occurs at 00:59:60 local time,
|
||||
.Ql "1:00"
|
||||
stands for 3601 seconds after local midnight instead of the usual 3600 seconds.
|
||||
The intent is that a rule line describes the instants when a
|
||||
clock/calendar set to the type of time specified in the
|
||||
.Ar AT
|
||||
field would show the specified date and time of day.
|
||||
.It SAVE
|
||||
Gives the amount of time to be added to local standard time when the rule is in
|
||||
effect, and whether the resulting time is standard or daylight saving.
|
||||
This field has the same format as the
|
||||
.Ar AT
|
||||
field
|
||||
except with a different set of suffix letters:
|
||||
.Ql s
|
||||
for standard time and
|
||||
.Ql d
|
||||
for daylight saving time.
|
||||
The suffix letter is typically omitted, and defaults to
|
||||
.Ql s
|
||||
if the offset is zero and to
|
||||
.Ql d
|
||||
otherwise.
|
||||
Negative offsets are allowed; in Ireland, for example, daylight saving
|
||||
time is observed in winter and has a negative offset relative to
|
||||
Irish Standard Time.
|
||||
The offset is merely added to standard time; for example,
|
||||
.Nm
|
||||
does not distinguish a 10:30 standard time plus an 0:30
|
||||
.Ar SAVE
|
||||
from a 10:00 standard time plus a 1:00
|
||||
.Ar SAVE .
|
||||
.It LETTER/S
|
||||
Gives the
|
||||
.Dq "variable part"
|
||||
(for example, the
|
||||
.Dq "S"
|
||||
or
|
||||
.Dq "D"
|
||||
in
|
||||
.Dq "EST"
|
||||
or
|
||||
.Dq "EDT" )
|
||||
of time zone abbreviations to be used when this rule is in effect.
|
||||
If this field is
|
||||
.Ql \- ,
|
||||
the variable part is null.
|
||||
.El
|
||||
.Pp
|
||||
A zone line has the form
|
||||
.Bd -literal -offset indent
|
||||
Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
.Ed
|
||||
.Pp
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
Zone Asia/Amman 2:00 Jordan EE%sT 2017 Oct 27 01:00
|
||||
.Ed
|
||||
.Pp
|
||||
The fields that make up a zone line are:
|
||||
.Bl -tag -width "STDOFF"
|
||||
.It NAME
|
||||
The name of the timezone.
|
||||
This is the name used in creating the time conversion information file for the
|
||||
timezone.
|
||||
It should not contain a file name component
|
||||
.Dq ".\&"
|
||||
or
|
||||
.Dq ".." ;
|
||||
a file name component is a maximal substring that does not contain
|
||||
.Dq "/" .
|
||||
.It STDOFF
|
||||
The amount of time to add to UT to get standard time,
|
||||
without any adjustment for daylight saving.
|
||||
This field has the same format as the
|
||||
.Ar AT
|
||||
and
|
||||
.Ar SAVE
|
||||
fields of rule lines, except without suffix letters;
|
||||
begin the field with a minus sign if time must be subtracted from UT.
|
||||
.It RULES
|
||||
The name of the rules that apply in the timezone or,
|
||||
alternatively, a field in the same format as a rule-line SAVE column,
|
||||
giving the amount of time to be added to local standard time
|
||||
and whether the resulting time is standard or daylight saving.
|
||||
If this field is
|
||||
.Ql \-
|
||||
then standard time always applies.
|
||||
When an amount of time is given, only the sum of standard time and
|
||||
this amount matters.
|
||||
.It FORMAT
|
||||
The format for time zone abbreviations.
|
||||
The pair of characters
|
||||
.Ql %s
|
||||
is used to show where the
|
||||
.Dq "variable part"
|
||||
of the time zone abbreviation goes.
|
||||
Alternatively, a format can use the pair of characters
|
||||
.Ql %z
|
||||
to stand for the UT offset in the form
|
||||
.Ar \(+- hh ,
|
||||
.Ar \(+- hhmm ,
|
||||
or
|
||||
.Ar \(+- hhmmss ,
|
||||
using the shortest form that does not lose information, where
|
||||
.Ar hh ,
|
||||
.Ar mm ,
|
||||
and
|
||||
.Ar ss
|
||||
are the hours, minutes, and seconds east (+) or west (\-) of UT.
|
||||
Alternatively,
|
||||
a slash (/)
|
||||
separates standard and daylight abbreviations.
|
||||
To conform to POSIX, a time zone abbreviation should contain only
|
||||
alphanumeric ASCII characters,
|
||||
.Ql "+"
|
||||
and
|
||||
.Ql "\-".
|
||||
By convention, the time zone abbreviation
|
||||
.Ql "\-00"
|
||||
is a placeholder that means local time is unspecified.
|
||||
.It UNTIL
|
||||
The time at which the UT offset or the rule(s) change for a location.
|
||||
It takes the form of one to four fields
|
||||
.Ar YEAR Op Ar MONTH Op Ar DAY Op Ar TIME .
|
||||
If this is specified,
|
||||
the time zone information is generated from the given UT offset
|
||||
and rule change until the time specified, which is interpreted using
|
||||
the rules in effect just before the transition.
|
||||
The month, day, and time of day have the same format as the
|
||||
.Ar IN ,
|
||||
.Ar ON ,
|
||||
and
|
||||
.Ar AT
|
||||
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
|
||||
string
|
||||
.Dq "Zone"
|
||||
and the name are omitted, as the continuation line will
|
||||
place information starting at the time specified as the
|
||||
.Dq "until"
|
||||
information in the previous line in the file used by the previous line.
|
||||
Continuation lines may contain
|
||||
.Dq "until"
|
||||
information, just as zone lines do, indicating that the next line is a further
|
||||
continuation.
|
||||
.El
|
||||
.Pp
|
||||
If a zone changes at the same instant that a rule would otherwise take
|
||||
effect in the earlier zone or continuation line, the rule is ignored.
|
||||
A zone or continuation line
|
||||
.Ar L
|
||||
with a named rule set starts with standard time by default:
|
||||
that is, any of
|
||||
.Ar L 's
|
||||
timestamps preceding
|
||||
.Ar L 's
|
||||
earliest rule use the rule in effect after
|
||||
.Ar L 's
|
||||
first transition into standard time.
|
||||
In a single zone it is an error if two rules take effect at the same
|
||||
instant, or if two zone changes take effect at the same instant.
|
||||
.Pp
|
||||
If a continuation line subtracts
|
||||
.Ar N
|
||||
seconds from the UT offset after a transition that would be
|
||||
interpreted to be later if using the continuation line's UT offset and
|
||||
rules, the
|
||||
.Dq "until"
|
||||
time of the previous zone or continuation line is interpreted
|
||||
according to the continuation line's UT offset and rules, and any rule
|
||||
that would otherwise take effect in the next
|
||||
.Ar N
|
||||
seconds is instead assumed to take effect simultaneously.
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
# Rule NAME FROM TO \*- IN ON AT SAVE LETTER/S
|
||||
Rule US 1967 2006 - Oct lastSun 2:00 0 S
|
||||
Rule US 1967 1973 - Apr lastSun 2:00 1:00 D
|
||||
|
||||
# Zone\0\0NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone\0\0America/Menominee \*-5:00 \*- EST 1973 Apr 29 2:00
|
||||
\*-6:00 US C%sT
|
||||
.Ed
|
||||
Here, an incorrect reading would be there were two clock changes on 1973-04-29,
|
||||
the first from 02:00 EST (\-05) to 01:00 CST (\-06),
|
||||
and the second an hour later from 02:00 CST (\-06) to 03:00 CDT (\-05).
|
||||
However,
|
||||
.Nm
|
||||
interprets this more sensibly as a single transition from 02:00 CST (\-05) to
|
||||
02:00 CDT (\-05).
|
||||
.Pp
|
||||
A link line has the form
|
||||
.Bd -literal -offset indent
|
||||
Link TARGET LINK-NAME
|
||||
.Ed
|
||||
.Pp
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
Link Europe/Istanbul Asia/Istanbul
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Ar TARGET
|
||||
field should appear as the
|
||||
.Ar NAME
|
||||
field in some zone line or as the
|
||||
.Ar LINK-NAME
|
||||
field in some link line.
|
||||
The
|
||||
.Ar LINK-NAME
|
||||
field is used as an alternative name for that zone;
|
||||
it has the same syntax as a zone line's
|
||||
.Ar NAME
|
||||
field.
|
||||
Links can chain together, although the behavior is unspecified if a
|
||||
chain of one or more links does not terminate in a Zone name.
|
||||
A link line can appear before the line that defines the link target.
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
Link Greenwich G_M_T
|
||||
Link Etc/GMT Greenwich
|
||||
Zone Etc/GMT\0\00\0\0\-\0\0GMT
|
||||
.Ed
|
||||
.Pp
|
||||
The two links are chained together, and G_M_T, Greenwich, and Etc/GMT
|
||||
all name the same zone.
|
||||
.Pp
|
||||
Except for continuation lines,
|
||||
lines may appear in any order in the input.
|
||||
However, the behavior is unspecified if multiple zone or link lines
|
||||
define the same name.
|
||||
.Pp
|
||||
The file that describes leap seconds can have leap lines and an
|
||||
expiration line.
|
||||
Leap lines have the following form:
|
||||
.Bd -literal -offset indent
|
||||
Leap YEAR MONTH DAY HH:MM:SS CORR R/S
|
||||
.Ed
|
||||
.Pp
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
Leap 2016 Dec 31 23:59:60 + S
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Ar YEAR ,
|
||||
.Ar MONTH ,
|
||||
.Ar DAY ,
|
||||
and
|
||||
.Ar HH:MM:SS
|
||||
fields tell when the leap second happened.
|
||||
The
|
||||
.Ar CORR
|
||||
field
|
||||
should be
|
||||
.Ql "+"
|
||||
if a second was added
|
||||
or
|
||||
.Ql "\-"
|
||||
if a second was skipped.
|
||||
The
|
||||
.Ar R/S
|
||||
field
|
||||
should be (an abbreviation of)
|
||||
.Dq "Stationary"
|
||||
if the leap second time given by the other fields should be interpreted as UTC
|
||||
or
|
||||
(an abbreviation of)
|
||||
.Dq "Rolling"
|
||||
if the leap second time given by the other fields should be interpreted as
|
||||
local (wall clock) time.
|
||||
.Pp
|
||||
Rolling leap seconds were implemented back when it was not
|
||||
clear whether common practice was rolling or stationary,
|
||||
with concerns that one would see
|
||||
Times Square ball drops where there'd be a
|
||||
.Dq "3... 2... 1... leap... Happy New Year"
|
||||
countdown, placing the leap second at
|
||||
midnight New York time rather than midnight UTC.
|
||||
However, this countdown style does not seem to have caught on,
|
||||
which means rolling leap seconds are not used in practice;
|
||||
also, they are not supported if the
|
||||
.Fl r
|
||||
option is used.
|
||||
.Pp
|
||||
The expiration line, if present, has the form:
|
||||
.Bd -literal -offset indent
|
||||
Expires YEAR MONTH DAY HH:MM:SS
|
||||
.Ed
|
||||
.Pp
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
Expires 2020 Dec 28 00:00:00
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Ar YEAR ,
|
||||
.Ar MONTH ,
|
||||
.Ar DAY ,
|
||||
and
|
||||
.Ar HH:MM:SS
|
||||
fields give the expiration timestamp in UTC for the leap second table.
|
||||
.Sh "EXTENDED EXAMPLE"
|
||||
Here is an extended example of
|
||||
.Nm
|
||||
input, intended to illustrate many of its features.
|
||||
.Bd -literal -offset indent
|
||||
# Rule NAME FROM TO \- IN ON AT SAVE LETTER/S
|
||||
Rule Swiss 1941 1942 \- May Mon>=1 1:00 1:00 S
|
||||
Rule Swiss 1941 1942 \- Oct Mon>=1 2:00 0 \-
|
||||
|
||||
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 \-
|
||||
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Europe/Zurich 0:34:08 \- LMT 1853 Jul 16
|
||||
0:29:45.50 \- BMT 1894 Jun
|
||||
1:00 Swiss CE%sT 1981
|
||||
1:00 EU CE%sT
|
||||
|
||||
Link Europe/Zurich Europe/Vaduz
|
||||
.Ed
|
||||
.Pp
|
||||
In this example, the EU rules are for the European Union
|
||||
and for its predecessor organization, the European Communities.
|
||||
The timezone is named Europe/Zurich and it has the alias Europe/Vaduz.
|
||||
This example says that Zurich was 34 minutes and 8
|
||||
seconds east of UT until 1853-07-16 at 00:00, when the legal offset
|
||||
was changed to
|
||||
7\(de26\(fm22.50\(sd,
|
||||
which works out to 0:29:45.50;
|
||||
.Nm
|
||||
treats this by rounding it to 0:29:46.
|
||||
After 1894-06-01 at 00:00 the UT offset became one hour
|
||||
and Swiss daylight saving rules (defined with lines beginning with
|
||||
.Dq "Rule Swiss")
|
||||
apply.
|
||||
From 1981 to the present, EU daylight saving rules have
|
||||
applied, and the UTC offset has remained at one hour.
|
||||
.Pp
|
||||
In 1941 and 1942, daylight saving time applied from the first Monday
|
||||
in May at 01:00 to the first Monday in October at 02: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,
|
||||
.Dq "LMT"
|
||||
and
|
||||
.Dq "BMT"
|
||||
were initially used, respectively.
|
||||
Since
|
||||
Swiss rules and later EU rules were applied, the time zone abbreviation
|
||||
has been CET for standard time and CEST for daylight saving
|
||||
time.
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/usr/share/zoneinfo"
|
||||
.It Pa /etc/localtime
|
||||
Default local timezone file.
|
||||
.It Pa /usr/share/zoneinfo
|
||||
Default timezone information directory.
|
||||
.El
|
||||
.Sh NOTES
|
||||
For areas with more than two types of local time,
|
||||
you may need to use local standard time in the
|
||||
.Ar 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 timezone,
|
||||
a clock advance caused by the start of daylight saving
|
||||
coincides with and is equal to
|
||||
a clock retreat caused by a change in UT offset,
|
||||
.Nm
|
||||
produces a single transition to daylight saving at the new UT offset
|
||||
without any change in local (wall clock) time.
|
||||
To get separate transitions
|
||||
use multiple zone continuation lines
|
||||
specifying transition instants using universal time.
|
||||
.Sh SEE ALSO
|
||||
.Xr tzfile 5 ,
|
||||
.Xr zdump 8
|
4051
contrib/tzcode/zic.c
Normal file
4051
contrib/tzcode/zic.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,88 +0,0 @@
|
|||
@(#)README 8.3
|
||||
This file is in the public domain, so clarified as of
|
||||
2009-05-17 by Arthur David Olson.
|
||||
|
||||
$FreeBSD$
|
||||
|
||||
"What time is it?" -- Richard Deacon as The King
|
||||
"Any time you want it to be." -- Frank Baxter as The Scientist
|
||||
(from the Bell System film "About Time")
|
||||
|
||||
The 1989 update of the time zone package featured
|
||||
|
||||
* POSIXization (including interpretation of POSIX-style TZ environment
|
||||
variables, provided by Guy Harris),
|
||||
* ANSIfication (including versions of "mktime" and "difftime"),
|
||||
* SVIDulation (an "altzone" variable)
|
||||
* MACHination (the "gtime" function)
|
||||
* corrections to some time zone data (including corrections to the rules
|
||||
for Great Britain and New Zealand)
|
||||
* reference data from the United States Naval Observatory for folks who
|
||||
want to do additional time zones
|
||||
* and the 1989 data for Saudi Arabia.
|
||||
|
||||
(Since this code will be treated as "part of the implementation" in some places
|
||||
and as "part of the application" in others, there's no good way to name
|
||||
functions, such as timegm, that are not part of the proposed ANSI C standard;
|
||||
such functions have kept their old, underscore-free names in this update.)
|
||||
|
||||
And the "dysize" function has disappeared; it was present to allow compilation
|
||||
of the "date" command on old BSD systems, and a version of "date" is now
|
||||
provided in the package. The "date" command is not created when you "make all"
|
||||
since it may lack options provided by the version distributed with your
|
||||
operating system, or may not interact with the system in the same way the
|
||||
native version does.
|
||||
|
||||
Since POSIX frowns on correct leap second handling, the default behavior of
|
||||
the "zic" command (in the absence of a "-L" option) has been changed to omit
|
||||
leap second information from its output files.
|
||||
|
||||
Here is a recipe for acquiring, building, installing, and testing the
|
||||
tz distribution on a GNU/Linux or similar host.
|
||||
|
||||
mkdir tz
|
||||
cd tz
|
||||
wget 'ftp://elsie.nci.nih.gov/pub/tz*.tar.gz'
|
||||
gzip -dc tzcode*.tar.gz | tar -xf -
|
||||
gzip -dc tzdata*.tar.gz | tar -xf -
|
||||
|
||||
Be sure to read the comments in "Makefile" and make any changes needed
|
||||
to make things right for your system, especially if you are using some
|
||||
platform other than GNU/Linux. Then run the following commands,
|
||||
substituting your desired installation directory for "$HOME/tzdir":
|
||||
|
||||
make TOPDIR=$HOME/tzdir install
|
||||
$HOME/tzdir/etc/zdump -v America/Los_Angeles
|
||||
|
||||
To use the new functions, use a "-ltz" option when compiling or linking.
|
||||
|
||||
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
|
||||
expected in the future;
|
||||
|
||||
* provide a test of the generality of the local time rule description
|
||||
system.
|
||||
|
||||
The information in the time zone data files is by no means authoritative;
|
||||
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!
|
||||
|
||||
Thanks to these Timezone Caballeros who've made major contributions to the
|
||||
time conversion package: Keith Bostic; Bob Devine; Paul Eggert; Robert Elz;
|
||||
Guy Harris; Mark Horton; John Mackin; and Bradley White. Thanks also to
|
||||
Michael Bloom, Art Neilson, Stephen Prince, John Sovereign, and Frank Wales
|
||||
for testing work, and to Gwillim Law for checking local mean time data.
|
||||
None of them are responsible for remaining errors.
|
||||
|
||||
Look in the ~ftp/pub directory of elsie.nci.nih.gov
|
||||
for updated versions of these files.
|
||||
|
||||
Please send comments or information to tz@elsie.nci.nih.gov.
|
|
@ -1,570 +0,0 @@
|
|||
@(#)Theory 8.4
|
||||
This file is in the public domain, so clarified as of
|
||||
2009-05-17 by Arthur David Olson.
|
||||
$FreeBSD$
|
||||
|
||||
----- Outline -----
|
||||
|
||||
Time and date functions
|
||||
Names of time zone regions
|
||||
Time zone abbreviations
|
||||
Calendrical issues
|
||||
Time and time zones on Mars
|
||||
|
||||
----- Time and date functions -----
|
||||
|
||||
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 is:
|
||||
|
||||
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 has the following properties and limitations.
|
||||
|
||||
* 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 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 TZ string takes the following form:
|
||||
|
||||
stdoffset[dst[offset],date[/time],date[/time]]
|
||||
|
||||
where:
|
||||
|
||||
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
|
||||
ahead of standard time.
|
||||
date[/time],date[/time]
|
||||
specifies the beginning and end of DST. If this is absent,
|
||||
the system supplies its own rules for DST, and these can
|
||||
differ from year to year; typically US DST rules are used.
|
||||
time
|
||||
takes the form `hh:[mm[:ss]]' and defaults to 02:00.
|
||||
date
|
||||
takes one of the following forms:
|
||||
Jn (1<=n<=365)
|
||||
origin-1 day number not counting February 29
|
||||
n (0<=n<=365)
|
||||
origin-0 day number counting February 29 if present
|
||||
Mm.n.d (0[Sunday]<=d<=6[Saturday], 1<=n<=5, 1<=m<=12)
|
||||
for the dth day of week n of month m of the year,
|
||||
where week 1 is the first week in which day d appears,
|
||||
and `5' stands for the last week in which day d appears
|
||||
(which may be either the 4th or 5th week).
|
||||
|
||||
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, 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
|
||||
variable. While an administrator can "do everything in UTC" to get
|
||||
around the problem, doing so is inconvenient and precludes handling
|
||||
daylight saving time shifts--as might be required to limit phone
|
||||
calls to off-peak hours.)
|
||||
|
||||
* POSIX requires that systems ignore leap seconds.
|
||||
|
||||
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
|
||||
POSIX); "TZ" is no longer constrained to be a three-letter time zone
|
||||
name followed by a number of hours and an optional three-letter
|
||||
daylight time zone name. The daylight saving time rules to be used
|
||||
for a particular time zone are encoded in the time zone file;
|
||||
the format of the file allows U.S., Australian, and other rules to be
|
||||
encoded, and allows for situations where more than two time zone
|
||||
abbreviations are used.
|
||||
|
||||
It was recognized that allowing the "TZ" environment variable to
|
||||
take on values such as "America/New_York" might cause "old" programs
|
||||
(that expect "TZ" to have a certain form) to operate incorrectly;
|
||||
consideration was given to using some other environment variable
|
||||
(for example, "TIMEZONE") to hold the string used to generate the
|
||||
time zone information file name. In the end, however, it was decided
|
||||
to continue using "TZ": it is widely used for time zone purposes;
|
||||
separately maintaining both "TZ" and "TIMEZONE" seemed a nuisance;
|
||||
and systems where "new" forms of "TZ" might cause problems can simply
|
||||
use TZ values such as "EST5EDT" which can be used both by
|
||||
"new" programs (a la POSIX) and "old" programs (as zone names and
|
||||
offsets).
|
||||
|
||||
* 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, 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
|
||||
conversion, the "daylight" and "timezone" variables are no longer
|
||||
needed. (These variables are defined and set by "tzset"; however, their
|
||||
values will not be used by "localtime.")
|
||||
|
||||
* The "localtime" function has been set up to deliver correct results
|
||||
for near-minimum or near-maximum time_t values. (A comment in the
|
||||
source code tells how to get compatibly wrong results).
|
||||
|
||||
* A function "tzsetwall" has been added to arrange for the system's
|
||||
best approximation to local wall clock time to be delivered by
|
||||
subsequent calls to "localtime." Source code for portable
|
||||
applications that "must" run on local wall clock time should call
|
||||
"tzsetwall();" if such code is moved to "old" systems that don't
|
||||
provide tzsetwall, you won't be able to generate an executable program.
|
||||
(These time zone functions also arrange for local wall clock time to be
|
||||
used if tzset is called--directly or indirectly--and there's no "TZ"
|
||||
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.
|
||||
|
||||
Points of interest to folks with other systems:
|
||||
|
||||
* This package is already part of many POSIX-compliant hosts,
|
||||
including BSD, HP, Linux, Network Appliance, SCO, SGI, and Sun.
|
||||
On such hosts, the primary use of this package
|
||||
is to update obsolete time zone rule tables.
|
||||
To do this, you may need to compile the time zone compiler
|
||||
`zic' supplied with this package instead of using the system `zic',
|
||||
since the format of zic's input changed slightly in late 1994,
|
||||
and many vendors still do not support the new input format.
|
||||
|
||||
* The UNIX Version 7 "timezone" function is not present in this package;
|
||||
it's impossible to reliably map timezone's arguments (a "minutes west
|
||||
of GMT" value and a "daylight saving time in effect" flag) to a
|
||||
time zone abbreviation, and we refuse to guess.
|
||||
Programs that in the past used the timezone function may now examine
|
||||
tzname[localtime(&clock)->tm_isdst] to learn the correct time
|
||||
zone abbreviation to use. Alternatively, use
|
||||
localtime(&clock)->tm_zone if this has been enabled.
|
||||
|
||||
* The 4.2BSD gettimeofday function is not used in this package.
|
||||
This formerly let users obtain the current UTC offset and DST flag,
|
||||
but this functionality was removed in later versions of BSD.
|
||||
|
||||
* In SVR2, time conversion fails for near-minimum or near-maximum
|
||||
time_t values when doing conversions for places that don't use UTC.
|
||||
This package takes care to do these conversions correctly.
|
||||
|
||||
The functions that are conditionally compiled if STD_INSPIRED is defined
|
||||
should, at this point, be looked on primarily as food for thought. They are
|
||||
not in any sense "standard compatible"--some are not, in fact, specified in
|
||||
*any* standard. They do, however, represent responses of various authors to
|
||||
standardization proposals.
|
||||
|
||||
Other time conversion proposals, in particular the one developed by folks at
|
||||
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, to ensure its broad acceptability. If
|
||||
more powerful time conversion functions can be standardized, so much the
|
||||
better.
|
||||
|
||||
|
||||
----- Names of time zone rule files -----
|
||||
|
||||
The time zone rule file naming conventions attempt to strike a balance
|
||||
among the following goals:
|
||||
|
||||
* Uniquely identify every national region where clocks have all
|
||||
agreed since 1970. This is essential for the intended use: static
|
||||
clocks keeping local civil time.
|
||||
|
||||
* Indicate to humans as to where that region is. This simplifes use.
|
||||
|
||||
* Be robust in the presence of political changes. This reduces the
|
||||
number of updates and backward-compatibility hacks. For example,
|
||||
names of countries are ordinarily not used, to avoid
|
||||
incompatibilities when countries change their name
|
||||
(e.g. Zaire->Congo) or when locations change countries
|
||||
(e.g. Hong Kong from UK colony to China).
|
||||
|
||||
* Be portable to a wide variety of implementations.
|
||||
This promotes use of the technology.
|
||||
|
||||
* Use a consistent naming convention over the entire world.
|
||||
This simplifies both use and maintenance.
|
||||
|
||||
This naming convention is not intended for use by inexperienced users
|
||||
to select TZ values by themselves (though they can of course examine
|
||||
and reuse existing settings). Distributors should provide
|
||||
documentation and/or a simple selection interface that explains the
|
||||
names; see the 'tzselect' program supplied with this distribution for
|
||||
one example.
|
||||
|
||||
Names normally have the form AREA/LOCATION, where AREA is the name
|
||||
of a continent or ocean, and LOCATION is the name of a specific
|
||||
location within that region. North and South America share the same
|
||||
area, `America'. Typical names are `Africa/Cairo', `America/New_York',
|
||||
and `Pacific/Honolulu'.
|
||||
|
||||
Here are the general rules used for choosing location names,
|
||||
in decreasing order of importance:
|
||||
|
||||
Use only valid POSIX file name components (i.e., the parts of
|
||||
names other than `/'). Within a file name component,
|
||||
use only ASCII letters, `.', `-' and `_'. Do not use
|
||||
digits, as that might create an ambiguity with POSIX
|
||||
TZ strings. A file name component must not exceed 14
|
||||
characters or start with `-'. E.g., prefer `Brunei'
|
||||
to `Bandar_Seri_Begawan'.
|
||||
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.
|
||||
Otherwise these tables would become annoyingly large.
|
||||
If a name is ambiguous, use a less ambiguous alternative;
|
||||
e.g. many cities are named San Jose and Georgetown, so
|
||||
prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'.
|
||||
Keep locations compact. Use cities or small islands, not countries
|
||||
or regions, so that any future time zone changes do not split
|
||||
locations into different time zones. E.g. prefer `Paris'
|
||||
to `France', since France has had multiple time zones.
|
||||
Use mainstream English spelling, e.g. prefer `Rome' to `Roma', and
|
||||
prefer `Athens' to the true name (which uses Greek letters).
|
||||
The POSIX file name restrictions encourage this rule.
|
||||
Use the most populous among locations in a country's time zone,
|
||||
e.g. prefer `Shanghai' to `Beijing'. Among locations with
|
||||
similar populations, pick the best-known location,
|
||||
e.g. prefer `Rome' to `Milan'.
|
||||
Use the singular form, e.g. prefer `Canary' to `Canaries'.
|
||||
Omit common suffixes like `_Islands' and `_City', unless that
|
||||
would lead to ambiguity. E.g. prefer `Cayman' to
|
||||
`Cayman_Islands' and `Guatemala' to `Guatemala_City',
|
||||
but prefer `Mexico_City' to `Mexico' because the country
|
||||
of Mexico has several time zones.
|
||||
Use `_' to represent a space.
|
||||
Omit `.' from abbreviations in names, e.g. prefer `St_Helena'
|
||||
to `St._Helena'.
|
||||
Do not change established names if they only marginally
|
||||
violate the above rules. For example, don't change
|
||||
the existing name `Rome' to `Milan' merely because
|
||||
Milan's population has grown to be somewhat greater
|
||||
than Rome's.
|
||||
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. 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.
|
||||
See the file `backward' for most of these older names
|
||||
(e.g. `US/Eastern' instead of `America/New_York').
|
||||
The other old-fashioned names still supported are
|
||||
`WET', `CET', `MET', `EET' (see the file `europe'),
|
||||
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.
|
||||
Here are the general rules used for choosing time zone abbreviations,
|
||||
in decreasing order of importance:
|
||||
|
||||
Use abbreviations that consist of three or more ASCII letters.
|
||||
Previous editions of this database also used characters like
|
||||
' ' and '?', but these characters have a special meaning to
|
||||
the shell and cause commands like
|
||||
set `date`
|
||||
to have unexpected effects.
|
||||
Previous editions of this rule required upper-case letters,
|
||||
but the Congressman who introduced Chamorro Standard Time
|
||||
preferred "ChST", so the rule has been relaxed.
|
||||
|
||||
This rule guarantees that all abbreviations could have
|
||||
been specified by a POSIX TZ string. POSIX
|
||||
requires at least three characters for an
|
||||
abbreviation. POSIX through 2000 says that an abbreviation
|
||||
cannot start with ':', and cannot contain ',', '-',
|
||||
'+', 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.
|
||||
|
||||
Use abbreviations that are in common use among English-speakers,
|
||||
e.g. `EST' for Eastern Standard Time in North America.
|
||||
We assume that applications translate them to other languages
|
||||
as part of the normal localization process; for example,
|
||||
a French application might translate `EST' to `HNE'.
|
||||
|
||||
For zones whose times are taken from a city's longitude, use the
|
||||
traditional xMT notation, e.g. `PMT' for Paris Mean Time.
|
||||
The only name like this in current use is `GMT'.
|
||||
|
||||
If there is no common English abbreviation, abbreviate the English
|
||||
translation of the usual phrase used by native speakers.
|
||||
If this is not available or is a phrase mentioning the country
|
||||
(e.g. ``Cape Verde Time''), then:
|
||||
|
||||
When a country has a single or principal time zone region,
|
||||
append `T' to the country's ISO code, e.g. `CVT' for
|
||||
Cape Verde Time. For summer time append `ST';
|
||||
for double summer time append `DST'; etc.
|
||||
When a country has multiple time zones, take the first three
|
||||
letters of an English place name identifying each zone
|
||||
and then append `T', `ST', etc. as before;
|
||||
e.g. `VLAST' for VLAdivostok Summer Time.
|
||||
|
||||
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
|
||||
it does in the United States. In new applications, it's often better
|
||||
to use numeric UTC offsets like `-0500' instead of time zone
|
||||
abbreviations like `EST'; this avoids the ambiguity.
|
||||
|
||||
|
||||
----- Calendrical issues -----
|
||||
|
||||
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.iit.edu/home/reingold/calendar-book/third-edition/">
|
||||
Calendrical Calculations: Third Edition
|
||||
</a>, Cambridge University Press (2008). Other information and
|
||||
sources are given below. They sometimes disagree.
|
||||
|
||||
|
||||
France
|
||||
|
||||
Gregorian calendar adopted 1582-12-20.
|
||||
French Revolutionary calendar used 1793-11-24 through 1805-12-31,
|
||||
and (in Paris only) 1871-05-06 through 1871-05-23.
|
||||
|
||||
|
||||
Russia
|
||||
|
||||
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
|
||||
Gregorian calendar while retaining the 6-day week; on 1940-06-27 it
|
||||
reverted to the 7-day week. With the 6-day week the usual days
|
||||
off were the 6th, 12th, 18th, 24th and 30th of the month.
|
||||
(Source: Evitiar Zerubavel, _The Seven Day Circle_)
|
||||
|
||||
|
||||
Mark Brader reported a similar story in "The Book of Calendars", edited
|
||||
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
|
||||
...
|
||||
|
||||
If your source is correct, how come documents between 1929 -- 1940 were
|
||||
still dated using the conventional, Gregorian calendar?
|
||||
|
||||
I can post a scan of a document dated December 1, 1934, signed by
|
||||
Yenukidze, the secretary, on behalf of Kalinin, the President of the
|
||||
Executive Committee of the Supreme Soviet, if you like.
|
||||
|
||||
|
||||
|
||||
Sweden (and Finland)
|
||||
|
||||
From: Mark Brader
|
||||
<a href="news:1996Jul6.012937.29190@sq.com">
|
||||
Subject: Re: Gregorian reform -- a part of locale?
|
||||
</a>
|
||||
Date: 1996-07-06
|
||||
|
||||
In 1700, Denmark made the transition from Julian to Gregorian. Sweden
|
||||
decided to *start* a transition in 1700 as well, but rather than have one of
|
||||
those unsightly calendar gaps :-), they simply decreed that the next leap
|
||||
year after 1696 would be in 1744 -- putting the whole country on a calendar
|
||||
different from both Julian and Gregorian for a period of 40 years.
|
||||
|
||||
However, in 1704 something went wrong and the plan was not carried through;
|
||||
they did, after all, have a leap year that year. And one in 1708. In 1712
|
||||
they gave it up and went back to Julian, putting 30 days in February that
|
||||
year!...
|
||||
|
||||
Then in 1753, Sweden made the transition to Gregorian in the usual manner,
|
||||
getting there only 13 years behind the original schedule.
|
||||
|
||||
(A previous posting of this story was challenged, and Swedish readers
|
||||
produced the following references to support it: "Tiderakning och historia"
|
||||
by Natanael Beckman (1924) and "Tid, en bok om tiderakning och
|
||||
kalendervasen" by Lars-Olof Lode'n (no date was given).)
|
||||
|
||||
|
||||
Grotefend's data
|
||||
|
||||
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
|
||||
...
|
||||
|
||||
The following is a(n incomplete) listing, arranged chronologically, of
|
||||
European states, with the date they converted from the Julian to the
|
||||
Gregorian calendar:
|
||||
|
||||
04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman
|
||||
Catholics and Danzig only)
|
||||
09/20 Dec 1582 - France, Lorraine
|
||||
|
||||
21 Dec 1582/
|
||||
01 Jan 1583 - Holland, Brabant, Flanders, Hennegau
|
||||
10/21 Feb 1583 - bishopric of Liege (L"uttich)
|
||||
13/24 Feb 1583 - bishopric of Augsburg
|
||||
04/15 Oct 1583 - electorate of Trier
|
||||
05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg,
|
||||
Salzburg, Brixen
|
||||
13/24 Oct 1583 - Austrian Oberelsass and Breisgau
|
||||
20/31 Oct 1583 - bishopric of Basel
|
||||
02/13 Nov 1583 - duchy of J"ulich-Berg
|
||||
02/13 Nov 1583 - electorate and city of K"oln
|
||||
04/15 Nov 1583 - bishopric of W"urzburg
|
||||
11/22 Nov 1583 - electorate of Mainz
|
||||
16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden
|
||||
17/28 Nov 1583 - bishopric of M"unster and duchy of Cleve
|
||||
14/25 Dec 1583 - Steiermark
|
||||
|
||||
06/17 Jan 1584 - Austria and Bohemia
|
||||
11/22 Jan 1584 - Luzern, Uri, Schwyz, Zug, Freiburg, Solothurn
|
||||
12/23 Jan 1584 - Silesia and the Lausitz
|
||||
22 Jan/
|
||||
02 Feb 1584 - Hungary (legally on 21 Oct 1587)
|
||||
Jun 1584 - Unterwalden
|
||||
01/12 Jul 1584 - duchy of Westfalen
|
||||
|
||||
16/27 Jun 1585 - bishopric of Paderborn
|
||||
|
||||
14/25 Dec 1590 - Transylvania
|
||||
|
||||
22 Aug/
|
||||
02 Sep 1612 - duchy of Prussia
|
||||
|
||||
13/24 Dec 1614 - Pfalz-Neuburg
|
||||
|
||||
1617 - duchy of Kurland (reverted to the Julian calendar in
|
||||
1796)
|
||||
|
||||
1624 - bishopric of Osnabr"uck
|
||||
|
||||
1630 - bishopric of Minden
|
||||
|
||||
15/26 Mar 1631 - bishopric of Hildesheim
|
||||
|
||||
1655 - Kanton Wallis
|
||||
|
||||
05/16 Feb 1682 - city of Strassburg
|
||||
|
||||
18 Feb/
|
||||
01 Mar 1700 - Protestant Germany (including Swedish possessions in
|
||||
Germany), Denmark, Norway
|
||||
30 Jun/
|
||||
12 Jul 1700 - Gelderland, Zutphen
|
||||
10 Nov/
|
||||
12 Dec 1700 - Utrecht, Overijssel
|
||||
|
||||
31 Dec 1700/
|
||||
12 Jan 1701 - Friesland, Groningen, Z"urich, Bern, Basel, Geneva,
|
||||
Turgau, and Schaffhausen
|
||||
|
||||
1724 - Glarus, Appenzell, and the city of St. Gallen
|
||||
|
||||
01 Jan 1750 - Pisa and Florence
|
||||
|
||||
02/14 Sep 1752 - Great Britain
|
||||
|
||||
17 Feb/
|
||||
01 Mar 1753 - Sweden
|
||||
|
||||
1760-1812 - Graub"unden
|
||||
|
||||
The Russian empire (including Finland and the Baltic states) did not
|
||||
convert to the Gregorian calendar until the Soviet revolution of 1917.
|
||||
|
||||
Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen
|
||||
Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend
|
||||
(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28.
|
||||
|
||||
|
||||
----- Time and time zones on Mars -----
|
||||
|
||||
Some people have adjusted their work schedules to fit Mars time.
|
||||
Dozens of special Mars watches were built for Jet Propulsion
|
||||
Laboratory workers who kept Mars time during the Mars Exploration
|
||||
Rovers mission (2004). These timepieces look like normal Seikos and
|
||||
Citizens but use Mars seconds rather than terrestrial seconds.
|
||||
|
||||
A Mars solar day is called a "sol" and has a mean period equal to
|
||||
about 24 hours 39 minutes 35.244 seconds in terrestrial time. It is
|
||||
divided into a conventional 24-hour clock, so each Mars second equals
|
||||
about 1.02749125 terrestrial seconds.
|
||||
|
||||
The prime meridian of Mars goes through the center of the crater
|
||||
Airy-0, named in honor of the British astronomer who built the
|
||||
Greenwich telescope that defines Earth's prime meridian. Mean solar
|
||||
time on the Mars prime meridian is called Mars Coordinated Time (MTC).
|
||||
|
||||
Each landed mission on Mars has adopted a different reference for
|
||||
solar time keeping, so there is no real standard for Mars time zones.
|
||||
For example, the Mars Exploration Rover project (2004) defined two
|
||||
time zones "Local Solar Time A" and "Local Solar Time B" for its two
|
||||
missions, each zone designed so that its time equals local true solar
|
||||
time at approximately the middle of the nominal mission. Such a "time
|
||||
zone" is not particularly suited for any application other than the
|
||||
mission itself.
|
||||
|
||||
Many calendars have been proposed for Mars, but none have achieved
|
||||
wide acceptance. Astronomers often use Mars Sol Date (MSD) which is a
|
||||
sequential count of Mars solar days elapsed since about 1873-12-29
|
||||
12:00 GMT.
|
||||
|
||||
The tz database does not currently support Mars time, but it is
|
||||
documented here in the hopes that support will be added eventually.
|
||||
|
||||
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-07-30).
|
||||
|
||||
Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times
|
||||
(2004-01-14), pp A1, A20-A21.
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2006-07-17 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static const char elsieid[] = "@(#)ialloc.c 8.30";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#define nonzero(n) (((n) == 0) ? 1 : (n))
|
||||
|
||||
char *
|
||||
imalloc(n)
|
||||
const int n;
|
||||
{
|
||||
return malloc((size_t) nonzero(n));
|
||||
}
|
||||
|
||||
char *
|
||||
icalloc(nelem, elsize)
|
||||
int nelem;
|
||||
int elsize;
|
||||
{
|
||||
if (nelem == 0 || elsize == 0)
|
||||
nelem = elsize = 1;
|
||||
return calloc((size_t) nelem, (size_t) elsize);
|
||||
}
|
||||
|
||||
void *
|
||||
irealloc(pointer, size)
|
||||
void * const pointer;
|
||||
const int size;
|
||||
{
|
||||
if (pointer == NULL)
|
||||
return imalloc(size);
|
||||
return realloc((void *) pointer, (size_t) nonzero(size));
|
||||
}
|
||||
|
||||
char *
|
||||
icatalloc(old, new)
|
||||
char * const old;
|
||||
const char * const new;
|
||||
{
|
||||
register char * result;
|
||||
register int oldsize, newsize;
|
||||
|
||||
newsize = (new == NULL) ? 0 : strlen(new);
|
||||
if (old == NULL)
|
||||
oldsize = 0;
|
||||
else if (newsize == 0)
|
||||
return old;
|
||||
else oldsize = strlen(old);
|
||||
if ((result = irealloc(old, oldsize + newsize + 1)) != NULL)
|
||||
if (new != NULL)
|
||||
(void) strcpy(result + oldsize, new);
|
||||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
icpyalloc(string)
|
||||
const char * const string;
|
||||
{
|
||||
return icatalloc((char *) NULL, string);
|
||||
}
|
||||
|
||||
void
|
||||
ifree(p)
|
||||
char * const p;
|
||||
{
|
||||
if (p != NULL)
|
||||
(void) free(p);
|
||||
}
|
||||
|
||||
void
|
||||
icfree(p)
|
||||
char * const p;
|
||||
{
|
||||
if (p != NULL)
|
||||
(void) free(p);
|
||||
}
|
|
@ -1,272 +0,0 @@
|
|||
#ifndef PRIVATE_H
|
||||
|
||||
#define PRIVATE_H
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
/*
|
||||
* FreeBSD modifications: separate libc's privates from zic's.
|
||||
* This makes it easier when we need to update one but not the other.
|
||||
* I have removed all of the ifdef spaghetti which is not relevant to
|
||||
* zic from this file.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is for use ONLY with the time conversion code.
|
||||
** There is no guarantee that it will remain unchanged,
|
||||
** or that it will remain at all.
|
||||
** Do NOT copy it to any system include directory.
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
/*
|
||||
** ID
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static const char privatehid[] = "@(#)private.h 8.6";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
#define GRANDPARENTED "Local time zone must be set--use tzsetup"
|
||||
|
||||
/*
|
||||
** Defaults for preprocessor symbols.
|
||||
** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_GETTEXT
|
||||
#define HAVE_GETTEXT 0
|
||||
#endif /* !defined HAVE_GETTEXT */
|
||||
|
||||
#ifndef HAVE_SYMLINK
|
||||
#define HAVE_SYMLINK 1
|
||||
#endif /* !defined HAVE_SYMLINK */
|
||||
|
||||
#ifndef HAVE_SYS_STAT_H
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#endif /* !defined HAVE_SYS_STAT_H */
|
||||
|
||||
#ifndef HAVE_SYS_WAIT_H
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
#endif /* !defined HAVE_SYS_WAIT_H */
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif /* !defined HAVE_UNISTD_H */
|
||||
|
||||
/*
|
||||
** Nested includes
|
||||
*/
|
||||
|
||||
#include "sys/types.h" /* for time_t */
|
||||
#include "stdio.h"
|
||||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "limits.h" /* for CHAR_BIT et al. */
|
||||
#include "time.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#if HAVE_GETTEXT
|
||||
#include "libintl.h"
|
||||
#endif /* HAVE_GETTEXT */
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
|
||||
#endif /* HAVE_SYS_WAIT_H */
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include "unistd.h" /* for F_OK and R_OK, and other POSIX goodness */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#ifndef F_OK
|
||||
#define F_OK 0
|
||||
#endif /* !defined F_OK */
|
||||
#ifndef R_OK
|
||||
#define R_OK 4
|
||||
#endif /* !defined R_OK */
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Some time.h implementations don't declare asctime_r.
|
||||
** Others might define it as a macro.
|
||||
** Fix the former without affecting the latter.
|
||||
*/
|
||||
#ifndef asctime_r
|
||||
extern char * asctime_r(struct tm const *, char *);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Private function declarations.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* !defined TRUE */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* !defined FALSE */
|
||||
|
||||
#ifndef TYPE_BIT
|
||||
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
|
||||
#endif /* !defined TYPE_BIT */
|
||||
|
||||
#ifndef TYPE_SIGNED
|
||||
#define TYPE_SIGNED(type) (((type) -1) < 0)
|
||||
#endif /* !defined TYPE_SIGNED */
|
||||
|
||||
/*
|
||||
** 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.
|
||||
** Subtract one for the sign bit if the type is signed;
|
||||
** add one for integer division truncation;
|
||||
** add one more for a minus sign if the type is signed.
|
||||
*/
|
||||
#define INT_STRLEN_MAXIMUM(type) \
|
||||
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
|
||||
1 + TYPE_SIGNED(type))
|
||||
#endif /* !defined INT_STRLEN_MAXIMUM */
|
||||
|
||||
/*
|
||||
** INITIALIZE(x)
|
||||
*/
|
||||
|
||||
#ifndef GNUC_or_lint
|
||||
#ifdef lint
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined lint */
|
||||
#ifndef lint
|
||||
#ifdef __GNUC__
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined __GNUC__ */
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
|
||||
#ifndef INITIALIZE
|
||||
#ifdef GNUC_or_lint
|
||||
#define INITIALIZE(x) ((x) = 0)
|
||||
#endif /* defined GNUC_or_lint */
|
||||
#ifndef GNUC_or_lint
|
||||
#define INITIALIZE(x)
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
#endif /* !defined INITIALIZE */
|
||||
|
||||
/*
|
||||
** For the benefit of GNU folk...
|
||||
** `_(MSGID)' uses the current locale's message library string for MSGID.
|
||||
** The default is to use gettext if available, and use MSGID otherwise.
|
||||
*/
|
||||
|
||||
#ifndef _
|
||||
#if HAVE_GETTEXT
|
||||
#define _(msgid) gettext(msgid)
|
||||
#else /* !HAVE_GETTEXT */
|
||||
#define _(msgid) msgid
|
||||
#endif /* !HAVE_GETTEXT */
|
||||
#endif /* !defined _ */
|
||||
|
||||
#ifndef TZ_DOMAIN
|
||||
#define TZ_DOMAIN "tz"
|
||||
#endif /* !defined TZ_DOMAIN */
|
||||
|
||||
/*
|
||||
** UNIX was a registered trademark of The Open Group in 2003.
|
||||
*/
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
#endif /* !defined PRIVATE_H */
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2006-07-17 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static const char elsieid[] = "@(#)scheck.c 8.19";
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined NOID */
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
const char *
|
||||
scheck(string, format)
|
||||
const char * const string;
|
||||
const char * const format;
|
||||
{
|
||||
register char * fbuf;
|
||||
register const char * fp;
|
||||
register char * tp;
|
||||
register int c;
|
||||
register const char * result;
|
||||
char dummy;
|
||||
|
||||
result = "";
|
||||
if (string == NULL || format == NULL)
|
||||
return result;
|
||||
fbuf = imalloc((int) (2 * strlen(format) + 4));
|
||||
if (fbuf == NULL)
|
||||
return result;
|
||||
fp = format;
|
||||
tp = fbuf;
|
||||
while ((*tp++ = c = *fp++) != '\0') {
|
||||
if (c != '%')
|
||||
continue;
|
||||
if (*fp == '%') {
|
||||
*tp++ = *fp++;
|
||||
continue;
|
||||
}
|
||||
*tp++ = '*';
|
||||
if (*fp == '*')
|
||||
++fp;
|
||||
while (is_digit(*fp))
|
||||
*tp++ = *fp++;
|
||||
if (*fp == 'l' || *fp == 'h')
|
||||
*tp++ = *fp++;
|
||||
else if (*fp == '[')
|
||||
do *tp++ = *fp++;
|
||||
while (*fp != '\0' && *fp != ']');
|
||||
if ((*tp++ = *fp++) == '\0')
|
||||
break;
|
||||
}
|
||||
*(tp - 1) = '%';
|
||||
*tp++ = 'c';
|
||||
*tp = '\0';
|
||||
if (sscanf(string, fbuf, &dummy) != 1)
|
||||
result = (char *) format;
|
||||
ifree(fbuf);
|
||||
return result;
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
.\"
|
||||
.\" @(#)zdump.8 8.2
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 20, 2004
|
||||
.Dt ZDUMP 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm zdump
|
||||
.Nd timezone dumper
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl -version
|
||||
.Op Fl v
|
||||
.Op Fl c Ar [loyear,]hiyear
|
||||
.Op Ar zonename ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility prints the current time in each
|
||||
.Ar zonename
|
||||
named on the command line.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl -version
|
||||
Output version information and exit.
|
||||
.It Fl v
|
||||
For each
|
||||
.Ar zonename
|
||||
on the command line,
|
||||
print the time at the lowest possible time value,
|
||||
the time one day after the lowest possible time value,
|
||||
the times both one second before and exactly at
|
||||
each detected time discontinuity,
|
||||
the time at one day less than the highest possible time value,
|
||||
and the time at the highest possible time value,
|
||||
Each line ends with
|
||||
.Em isdst=1
|
||||
if the given time is Daylight Saving Time or
|
||||
.Em isdst=0
|
||||
otherwise.
|
||||
.It Fl c Ar loyear,hiyear
|
||||
Cut off 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
|
||||
.Fl 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
|
|
@ -1,668 +0,0 @@
|
|||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2009-05-17 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
static char elsieid[] = "@(#)zdump.c 8.10";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
** This code has been made independent of the rest of the time
|
||||
** conversion package to increase confidence in the verification it provides.
|
||||
** You can use this code to help in verifying other implementations.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h> /* for stdout, stderr */
|
||||
#include <stdlib.h> /* for exit, malloc, atoi */
|
||||
#include <string.h> /* for strcpy */
|
||||
#include <sys/types.h> /* for time_t */
|
||||
#include <time.h> /* for struct tm */
|
||||
#include <unistd.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
|
||||
#endif /* !defined MAX_STRING_LENGTH */
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* !defined TRUE */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* !defined FALSE */
|
||||
|
||||
#ifndef EXIT_SUCCESS
|
||||
#define EXIT_SUCCESS 0
|
||||
#endif /* !defined EXIT_SUCCESS */
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
#endif /* !defined EXIT_FAILURE */
|
||||
|
||||
#ifndef SECSPERMIN
|
||||
#define SECSPERMIN 60
|
||||
#endif /* !defined SECSPERMIN */
|
||||
|
||||
#ifndef MINSPERHOUR
|
||||
#define MINSPERHOUR 60
|
||||
#endif /* !defined MINSPERHOUR */
|
||||
|
||||
#ifndef SECSPERHOUR
|
||||
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
|
||||
#endif /* !defined SECSPERHOUR */
|
||||
|
||||
#ifndef HOURSPERDAY
|
||||
#define HOURSPERDAY 24
|
||||
#endif /* !defined HOURSPERDAY */
|
||||
|
||||
#ifndef EPOCH_YEAR
|
||||
#define EPOCH_YEAR 1970
|
||||
#endif /* !defined EPOCH_YEAR */
|
||||
|
||||
#ifndef TM_YEAR_BASE
|
||||
#define TM_YEAR_BASE 1900
|
||||
#endif /* !defined TM_YEAR_BASE */
|
||||
|
||||
#ifndef DAYSPERNYEAR
|
||||
#define DAYSPERNYEAR 365
|
||||
#endif /* !defined DAYSPERNYEAR */
|
||||
|
||||
#ifndef isleap
|
||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||
#endif /* !defined isleap */
|
||||
|
||||
#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 */
|
||||
|
||||
#ifndef GNUC_or_lint
|
||||
#ifdef lint
|
||||
#define GNUC_or_lint
|
||||
#else /* !defined lint */
|
||||
#ifdef __GNUC__
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined __GNUC__ */
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
|
||||
#ifndef INITIALIZE
|
||||
#ifdef GNUC_or_lint
|
||||
#define INITIALIZE(x) ((x) = 0)
|
||||
#else /* !defined GNUC_or_lint */
|
||||
#define INITIALIZE(x)
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
#endif /* !defined INITIALIZE */
|
||||
|
||||
/*
|
||||
** For the benefit of GNU folk...
|
||||
** `_(MSGID)' uses the current locale's message library string for MSGID.
|
||||
** The default is to use gettext if available, and use MSGID otherwise.
|
||||
*/
|
||||
|
||||
#ifndef _
|
||||
#if HAVE_GETTEXT
|
||||
#define _(msgid) gettext(msgid)
|
||||
#else /* !(HAVE_GETTEXT) */
|
||||
#define _(msgid) msgid
|
||||
#endif /* !(HAVE_GETTEXT) */
|
||||
#endif /* !defined _ */
|
||||
|
||||
#ifndef TZ_DOMAIN
|
||||
#define TZ_DOMAIN "tz"
|
||||
#endif /* !defined TZ_DOMAIN */
|
||||
|
||||
extern char ** environ;
|
||||
extern char * tzname[2];
|
||||
|
||||
static time_t absolute_min_time;
|
||||
static time_t absolute_max_time;
|
||||
static size_t longest;
|
||||
static char * progname;
|
||||
static int warned;
|
||||
|
||||
static void usage(FILE *stream, int status);
|
||||
static 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);
|
||||
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) &&
|
||||
(isalnum((unsigned char)*cp) || *cp == '-' || *cp == '+'))
|
||||
++cp;
|
||||
if (cp - abbrp < 3)
|
||||
wp = _("has fewer than 3 characters");
|
||||
else if (cp - abbrp > 6)
|
||||
wp = _("has more than 6 characters");
|
||||
else if (*cp)
|
||||
wp = "has characters other than ASCII alphanumerics, '-' or '+'";
|
||||
else
|
||||
return;
|
||||
(void) fflush(stdout);
|
||||
(void) fprintf(stderr,
|
||||
_("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"),
|
||||
progname, zone, abbrp, wp);
|
||||
warned = TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char * argv[];
|
||||
{
|
||||
register int i;
|
||||
register int c;
|
||||
register int vflag;
|
||||
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;
|
||||
struct tm tm;
|
||||
struct tm newtm;
|
||||
register struct tm * tmp;
|
||||
register struct tm * newtmp;
|
||||
|
||||
progname=argv[0];
|
||||
INITIALIZE(cutlotime);
|
||||
INITIALIZE(cuthitime);
|
||||
#if HAVE_GETTEXT
|
||||
(void) setlocale(LC_MESSAGES, "");
|
||||
#ifdef TZ_DOMAINDIR
|
||||
(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
|
||||
#endif /* TEXTDOMAINDIR */
|
||||
(void) textdomain(TZ_DOMAIN);
|
||||
#endif /* HAVE_GETTEXT */
|
||||
for (i = 1; i < argc; ++i)
|
||||
if (strcmp(argv[i], "--version") == 0) {
|
||||
errx(EXIT_SUCCESS, "%s", elsieid);
|
||||
} else if (strcmp(argv[i], "--help") == 0) {
|
||||
usage(stdout, EXIT_SUCCESS);
|
||||
}
|
||||
vflag = 0;
|
||||
cutarg = NULL;
|
||||
while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
|
||||
if (c == 'v')
|
||||
vflag = 1;
|
||||
else cutarg = optarg;
|
||||
if ((c != -1) ||
|
||||
(optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
|
||||
usage(stderr, EXIT_FAILURE);
|
||||
}
|
||||
if (vflag) {
|
||||
if (cutarg != NULL) {
|
||||
long lo;
|
||||
long hi;
|
||||
char dummy;
|
||||
|
||||
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]);
|
||||
{
|
||||
register int from;
|
||||
register int to;
|
||||
|
||||
for (i = 0; environ[i] != NULL; ++i)
|
||||
continue;
|
||||
fakeenv = (char **) malloc((size_t) ((i + 2) *
|
||||
sizeof *fakeenv));
|
||||
if (fakeenv == NULL ||
|
||||
(fakeenv[0] = (char *) malloc((size_t) (longest +
|
||||
4))) == NULL)
|
||||
errx(EXIT_FAILURE,
|
||||
_("malloc() failed"));
|
||||
to = 0;
|
||||
(void) strcpy(fakeenv[to++], "TZ=");
|
||||
for (from = 0; environ[from] != NULL; ++from)
|
||||
if (strncmp(environ[from], "TZ=", 3) != 0)
|
||||
fakeenv[to++] = environ[from];
|
||||
fakeenv[to] = NULL;
|
||||
environ = fakeenv;
|
||||
}
|
||||
for (i = optind; i < argc; ++i) {
|
||||
static char buf[MAX_STRING_LENGTH];
|
||||
|
||||
(void) strcpy(&fakeenv[0][3], argv[i]);
|
||||
if (!vflag) {
|
||||
show(argv[i], now, FALSE);
|
||||
continue;
|
||||
}
|
||||
warned = FALSE;
|
||||
t = absolute_min_time;
|
||||
show(argv[i], t, TRUE);
|
||||
t += SECSPERHOUR * HOURSPERDAY;
|
||||
show(argv[i], t, TRUE);
|
||||
if (t < cutlotime)
|
||||
t = cutlotime;
|
||||
tmp = my_localtime(&t);
|
||||
if (tmp != NULL) {
|
||||
tm = *tmp;
|
||||
(void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
|
||||
}
|
||||
for ( ; ; ) {
|
||||
if (t >= cuthitime || t >= cuthitime - SECSPERHOUR * 12)
|
||||
break;
|
||||
newt = t + SECSPERHOUR * 12;
|
||||
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)) {
|
||||
newt = hunt(argv[i], t, newt);
|
||||
newtmp = localtime(&newt);
|
||||
if (newtmp != NULL) {
|
||||
newtm = *newtmp;
|
||||
(void) strncpy(buf,
|
||||
abbr(&newtm),
|
||||
(sizeof buf) - 1);
|
||||
}
|
||||
}
|
||||
t = newt;
|
||||
tm = newtm;
|
||||
tmp = newtmp;
|
||||
}
|
||||
t = absolute_max_time;
|
||||
t -= SECSPERHOUR * HOURSPERDAY;
|
||||
show(argv[i], t, TRUE);
|
||||
t += SECSPERHOUR * HOURSPERDAY;
|
||||
show(argv[i], t, TRUE);
|
||||
}
|
||||
if (fflush(stdout) || ferror(stdout))
|
||||
errx(EXIT_FAILURE, _("error writing standard output"));
|
||||
exit(EXIT_SUCCESS);
|
||||
/* If exit fails to exit... */
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
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
|
||||
yeartot(y)
|
||||
const long y;
|
||||
{
|
||||
register long myy;
|
||||
register long seconds;
|
||||
register time_t t;
|
||||
|
||||
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 void
|
||||
usage(FILE *stream, int status)
|
||||
{
|
||||
fprintf(stream,
|
||||
_("usage: %s [--version] [-v] [--help] [-c [loyear,]hiyear] zonename ...\n\
|
||||
\n\
|
||||
Report bugs to tz@elsie.nci.nih.gov.\n"), progname);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
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;
|
||||
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)) {
|
||||
lot = t;
|
||||
lotm = tm;
|
||||
lotmp = tmp;
|
||||
} else hit = t;
|
||||
}
|
||||
show(name, lot, TRUE);
|
||||
show(name, hit, TRUE);
|
||||
return hit;
|
||||
}
|
||||
|
||||
/*
|
||||
** Thanks to Paul Eggert for logic used in delta.
|
||||
*/
|
||||
|
||||
static long
|
||||
delta(newp, oldp)
|
||||
struct tm * newp;
|
||||
struct tm * oldp;
|
||||
{
|
||||
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_sum(tmy, TM_YEAR_BASE);
|
||||
result += newp->tm_yday - oldp->tm_yday;
|
||||
result *= HOURSPERDAY;
|
||||
result += newp->tm_hour - oldp->tm_hour;
|
||||
result *= MINSPERHOUR;
|
||||
result += newp->tm_min - oldp->tm_min;
|
||||
result *= SECSPERMIN;
|
||||
result += newp->tm_sec - oldp->tm_sec;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
show(char *zone, time_t t, int v)
|
||||
{
|
||||
register struct tm * tmp;
|
||||
|
||||
(void) printf("%-*s ", (int) longest, zone);
|
||||
if (v) {
|
||||
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);
|
||||
#endif /* defined TM_GMTOFF */
|
||||
}
|
||||
}
|
||||
(void) printf("\n");
|
||||
if (tmp != NULL && *abbr(tmp) != '\0')
|
||||
abbrok(abbr(tmp), zone);
|
||||
}
|
||||
|
||||
static char *
|
||||
abbr(tmp)
|
||||
struct tm * tmp;
|
||||
{
|
||||
register char * result;
|
||||
static char nada;
|
||||
|
||||
if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
|
||||
return &nada;
|
||||
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));
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= zdump
|
||||
MAN= zdump.8
|
||||
SRCS= zdump.c ialloc.c scheck.c
|
||||
|
||||
CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS
|
||||
CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir
|
||||
CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,468 +0,0 @@
|
|||
.\" $FreeBSD$
|
||||
.Dd June 20, 2004
|
||||
.Dt ZIC 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm zic
|
||||
.Nd timezone compiler
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl -version
|
||||
.Op Fl Dsv
|
||||
.Op Fl d Ar directory
|
||||
.Op Fl g Ar group
|
||||
.Op Fl L Ar leapsecondfilename
|
||||
.Op Fl l Ar localtime
|
||||
.Op Fl m Ar mode
|
||||
.Op Fl p Ar posixrules
|
||||
.Op Fl u Ar user
|
||||
.Op Fl y Ar command
|
||||
.Op Ar filename ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility reads text from the file(s) named on the command line
|
||||
and creates the time conversion information files specified in this input.
|
||||
If a
|
||||
.Ar filename
|
||||
is
|
||||
.Em - ,
|
||||
the standard input is read.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl -version
|
||||
Output version information and exit.
|
||||
.It Fl D
|
||||
Do not automatically create directories.
|
||||
If the input file(s) specify
|
||||
an output file in a directory which does not already exist, the
|
||||
default behavior is to attempt to create the directory.
|
||||
If
|
||||
.Fl D
|
||||
is specified,
|
||||
.Nm
|
||||
will instead error out immediately.
|
||||
.It Fl d Ar directory
|
||||
Create time conversion information files in the named directory rather than
|
||||
in the standard directory named below.
|
||||
.It Fl g Ar group
|
||||
After creating each output file, change its group ownership to the
|
||||
specified
|
||||
.Ar group
|
||||
(which can be either a name or a numeric group ID).
|
||||
.It Fl L Ar leapsecondfilename
|
||||
Read leap second information from the file with the given name.
|
||||
If this option is not used,
|
||||
no leap second information appears in output files.
|
||||
.It Fl l Ar timezone
|
||||
Use the given
|
||||
.Ar time zone
|
||||
as local time.
|
||||
The
|
||||
.Nm
|
||||
utility will act as if the input contained a link line of the form
|
||||
.Pp
|
||||
.D1 No "Link timezone localtime"
|
||||
.Pp
|
||||
(Note that this action has no effect on
|
||||
.Fx ,
|
||||
since the local time zone is specified in
|
||||
.Pa /etc/localtime
|
||||
and not
|
||||
.Pa /usr/share/zoneinfo/localtime . )
|
||||
.It Fl m Ar mode
|
||||
After creating each output file, change its access mode to
|
||||
.Ar mode .
|
||||
Both numeric and alphabetic modes are accepted
|
||||
(see
|
||||
.Xr chmod 1 ) .
|
||||
.It Fl p Ar timezone
|
||||
Use the given
|
||||
.Ar "time zone" Ns 's
|
||||
rules when handling POSIX-format
|
||||
time zone environment variables.
|
||||
The
|
||||
.Nm
|
||||
utility will act as if the input contained a link line of the form
|
||||
.Pp
|
||||
.D1 No "Link timezone posixrules"
|
||||
.It Fl u Ar user
|
||||
After creating each output file, change its owner to
|
||||
.Ar user
|
||||
(which can be either a name or a numeric user ID).
|
||||
.It Fl v
|
||||
Complain if a year that appears in a data file is outside the range
|
||||
of years representable by
|
||||
.Xr time 3
|
||||
values.
|
||||
.It Fl s
|
||||
Limit time values stored in output files to values that are the same
|
||||
whether they are taken to be signed or unsigned.
|
||||
You can use this option to generate SVVS-compatible files.
|
||||
.It Fl y Ar command
|
||||
Use the given
|
||||
.Ar command
|
||||
rather than
|
||||
.Em yearistype
|
||||
when checking year types (see below).
|
||||
.El
|
||||
.Pp
|
||||
Input lines are made up of fields.
|
||||
Fields are separated from one another by any number of white space characters.
|
||||
Leading and trailing white space on input lines is ignored.
|
||||
An unquoted sharp character (#) in the input introduces a comment which extends
|
||||
to the end of the line the sharp character appears on.
|
||||
White space characters and sharp characters may be enclosed in double quotes
|
||||
(") if they are to be used as part of a field.
|
||||
Any line that is blank (after comment stripping) is ignored.
|
||||
Non-blank lines are expected to be of one of three types:
|
||||
rule lines, zone lines, and link lines.
|
||||
.Pp
|
||||
Names (such as month names) must be in English and are case insensitive.
|
||||
Abbreviations, if used, must be unambiguous in context.
|
||||
.Pp
|
||||
A rule line has the form:
|
||||
.Dl "Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S"
|
||||
For example:
|
||||
.Dl "Rule US 1967 1973 \- Apr lastSun 2:00 1:00 D"
|
||||
.Pp
|
||||
The fields that make up a rule line are:
|
||||
.Bl -tag -width "LETTER/S" -offset indent
|
||||
.It NAME
|
||||
Give the (arbitrary) name of the set of rules this rule is part of.
|
||||
.It FROM
|
||||
Give the first year in which the rule applies.
|
||||
Any integer year can be supplied; the Gregorian calendar is assumed.
|
||||
The word
|
||||
.Em minimum
|
||||
(or an abbreviation) means the minimum year representable as an integer.
|
||||
The word
|
||||
.Em maximum
|
||||
(or an abbreviation) means the maximum year representable as an integer.
|
||||
Rules can describe times that are not representable as time values,
|
||||
with the unrepresentable times ignored; this allows rules to be portable
|
||||
among hosts with differing time value types.
|
||||
.It TO
|
||||
Give the final year in which the rule applies.
|
||||
In addition to
|
||||
.Em minimum
|
||||
and
|
||||
.Em maximum
|
||||
(as above),
|
||||
the word
|
||||
.Em only
|
||||
(or an abbreviation)
|
||||
may be used to repeat the value of the
|
||||
.Em FROM
|
||||
field.
|
||||
.It TYPE
|
||||
Give the type of year in which the rule applies.
|
||||
If
|
||||
.Em TYPE
|
||||
is
|
||||
.Em \-
|
||||
then the rule applies in all years between
|
||||
.Em FROM
|
||||
and
|
||||
.Em TO
|
||||
inclusive.
|
||||
If
|
||||
.Em TYPE
|
||||
is something else, then
|
||||
.Nm
|
||||
executes the command
|
||||
.Li yearistype Ar year Ar type
|
||||
to check the type of a year:
|
||||
an exit status of zero is taken to mean that the year is of the given type;
|
||||
an exit status of one is taken to mean that the year is not of the given type.
|
||||
.It IN
|
||||
Name the month in which the rule takes effect.
|
||||
Month names may be abbreviated.
|
||||
.It ON
|
||||
Give the day on which the rule takes effect.
|
||||
Recognized forms include:
|
||||
.Pp
|
||||
.Bl -tag -width lastSun -compact -offset indent
|
||||
.It \&5
|
||||
the fifth of the month
|
||||
.It lastSun
|
||||
the last Sunday in the month
|
||||
.It lastMon
|
||||
the last Monday in the month
|
||||
.It Sun>=8
|
||||
first Sunday on or after the eighth
|
||||
.It Sun<=25
|
||||
last Sunday on or before the 25th
|
||||
.El
|
||||
.Pp
|
||||
Names of days of the week may be abbreviated or spelled out in full.
|
||||
Note that there must be no spaces within the
|
||||
.Em ON
|
||||
field.
|
||||
.It AT
|
||||
Give the time of day at which the rule takes effect.
|
||||
Recognized forms include:
|
||||
.Pp
|
||||
.Bl -tag -width "\&1:28:14" -offset indent -compact
|
||||
.It 2
|
||||
time in hours
|
||||
.It 2:00
|
||||
time in hours and minutes
|
||||
.It 15:00
|
||||
24-hour format time (for times after noon)
|
||||
.It 1:28:14
|
||||
time in hours, minutes, and seconds
|
||||
.El
|
||||
.Pp
|
||||
where hour 0 is midnight at the start of the day,
|
||||
and hour 24 is midnight at the end of the day.
|
||||
Any of these forms may be followed by the letter
|
||||
.Sq Li w
|
||||
if the given time is local
|
||||
.Dq "wall clock"
|
||||
time,
|
||||
.Sq Li s
|
||||
if the given time is local
|
||||
.Dq standard
|
||||
time, or
|
||||
.Sq Li u
|
||||
(or
|
||||
.Sq Li g
|
||||
or
|
||||
.Sq Li z )
|
||||
if the given time is universal time;
|
||||
in the absence of an indicator,
|
||||
wall clock time is assumed.
|
||||
.It SAVE
|
||||
Give the amount of time to be added to local standard time when the rule is in
|
||||
effect.
|
||||
This field has the same format as the
|
||||
.Em AT
|
||||
field
|
||||
(although, of course, the
|
||||
.Sq Li w
|
||||
and
|
||||
.Sq Li s
|
||||
suffixes are not used).
|
||||
.It LETTER/S
|
||||
Give the
|
||||
.Dq "variable part"
|
||||
(for example, the
|
||||
.Dq S
|
||||
or
|
||||
.Dq D
|
||||
in
|
||||
.Dq EST
|
||||
or
|
||||
.Dq EDT )
|
||||
of time zone abbreviations to be used when this rule is in effect.
|
||||
If this field is
|
||||
.Em \- ,
|
||||
the variable part is null.
|
||||
.El
|
||||
.Pp
|
||||
A zone line has the form:
|
||||
.Dl "Zone NAME GMTOFF RULES/SAVE FORMAT [UNTILYEAR [MONTH [DAY [TIME]]]]"
|
||||
For example:
|
||||
.Dl "Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00"
|
||||
The fields that make up a zone line are:
|
||||
.Bl -tag -width indent
|
||||
.It NAME
|
||||
The name of the time zone.
|
||||
This is the name used in creating the time conversion information file for the
|
||||
zone.
|
||||
.It GMTOFF
|
||||
The amount of time to add to UTC to get standard time in this zone.
|
||||
This field has the same format as the
|
||||
.Em AT
|
||||
and
|
||||
.Em SAVE
|
||||
fields of rule lines;
|
||||
begin the field with a minus sign if time must be subtracted from UTC.
|
||||
.It RULES/SAVE
|
||||
The name of the rule(s) that apply in the time zone or,
|
||||
alternately, an amount of time to add to local standard time.
|
||||
If this field is
|
||||
.Em \-
|
||||
then standard time always applies in the time zone.
|
||||
.It FORMAT
|
||||
The format for time zone abbreviations in this time zone.
|
||||
The pair of characters
|
||||
.Em %s
|
||||
is used to show where the
|
||||
.Dq "variable part"
|
||||
of the time zone abbreviation goes.
|
||||
Alternately,
|
||||
a slash (/)
|
||||
separates standard and daylight abbreviations.
|
||||
.It 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
|
||||
fields of a rule; trailing fields can be omitted, and default to the
|
||||
earliest possible value for the missing fields.
|
||||
.Pp
|
||||
The next line must be a
|
||||
.Dq continuation
|
||||
line; this has the same form as a zone line except that the
|
||||
string
|
||||
.Dq Zone
|
||||
and the name are omitted, as the continuation line will
|
||||
place information starting at the time specified as the
|
||||
.Em until
|
||||
information in the previous line in the file used by the previous line.
|
||||
Continuation lines may contain
|
||||
.Em until
|
||||
information, just as zone lines do, indicating that the next line is a further
|
||||
continuation.
|
||||
.El
|
||||
.Pp
|
||||
A link line has the form
|
||||
.Dl "Link LINK-FROM LINK-TO"
|
||||
For example:
|
||||
.Dl "Link Europe/Istanbul Asia/Istanbul"
|
||||
The
|
||||
.Em LINK-FROM
|
||||
field should appear as the
|
||||
.Em NAME
|
||||
field in some zone line;
|
||||
the
|
||||
.Em LINK-TO
|
||||
field is used as an alternate name for that zone.
|
||||
.Pp
|
||||
Except for continuation lines,
|
||||
lines may appear in any order in the input.
|
||||
.Pp
|
||||
Lines in the file that describes leap seconds have the following form:
|
||||
.Dl "Leap YEAR MONTH DAY HH:MM:SS CORR R/S"
|
||||
For example:
|
||||
.Dl "Leap 1974 Dec 31 23:59:60 + S"
|
||||
The
|
||||
.Em YEAR ,
|
||||
.Em MONTH ,
|
||||
.Em DAY ,
|
||||
and
|
||||
.Em HH:MM:SS
|
||||
fields tell when the leap second happened.
|
||||
The
|
||||
.Em CORR
|
||||
field
|
||||
should be
|
||||
.Dq +
|
||||
if a second was added
|
||||
or
|
||||
.Dq -
|
||||
if a second was skipped.
|
||||
.\" There's no need to document the following, since it's impossible for more
|
||||
.\" than one leap second to be inserted or deleted at a time.
|
||||
.\" The C Standard is in error in suggesting the possibility.
|
||||
.\" See Terry J Quinn, The BIPM and the accurate measure of time,
|
||||
.\" Proc IEEE 79, 7 (July 1991), 894-905.
|
||||
.\" or
|
||||
.\" .q ++
|
||||
.\" if two seconds were added
|
||||
.\" or
|
||||
.\" .q --
|
||||
.\" if two seconds were skipped.
|
||||
The
|
||||
.Em R/S
|
||||
field
|
||||
should be (an abbreviation of)
|
||||
.Dq Stationary
|
||||
if the leap second time given by the other fields should be interpreted as UTC
|
||||
or
|
||||
(an abbreviation of)
|
||||
.Dq Rolling
|
||||
if the leap second time given by the other fields should be interpreted as
|
||||
local wall clock time.
|
||||
.Sh "EXTENDED EXAMPLE"
|
||||
Here is an extended example of
|
||||
.Nm
|
||||
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,
|
||||
.Nm
|
||||
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
|
||||
.Bl -tag -width /usr/share/zoneinfo -compact
|
||||
.It /usr/share/zoneinfo
|
||||
standard directory used for created files
|
||||
.El
|
||||
.Sh "SEE ALSO"
|
||||
.Xr ctime 3 ,
|
||||
.Xr tzfile 5 ,
|
||||
.Xr zdump 8
|
||||
.\" @(#)zic.8 8.6
|
||||
.\" 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
|
@ -1,16 +0,0 @@
|
|||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= zic
|
||||
MAN= zic.8
|
||||
SRCS= zic.c ialloc.c scheck.c
|
||||
|
||||
CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS
|
||||
CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir
|
||||
CFLAGS+= -DHAVE_STRERROR -DHAVE_UNISTD_H
|
||||
CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,19 +1,21 @@
|
|||
# Makefile.inc,v 1.2 1994/09/13 21:26:01 wollman Exp
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${LIBC_SRCTOP}/stdtime ${SRCTOP}/contrib/tzcode/stdtime
|
||||
.PATH: ${LIBC_SRCTOP}/stdtime ${SRCTOP}/contrib/tzcode
|
||||
|
||||
SRCS+= asctime.c difftime.c localtime.c strftime.c strptime.c timelocal.c \
|
||||
time32.c
|
||||
|
||||
SYM_MAPS+= ${LIBC_SRCTOP}/stdtime/Symbol.map
|
||||
|
||||
CFLAGS+= -I${SRCTOP}/contrib/tzcode/stdtime -I${LIBC_SRCTOP}/stdtime
|
||||
CFLAGS+= -I${SRCTOP}/contrib/tzcode -I${LIBC_SRCTOP}/stdtime
|
||||
|
||||
CFLAGS.localtime.c= -fwrapv
|
||||
|
||||
CFLAGS.localtime.c+= -DALL_STATE -DTHREAD_SAFE
|
||||
CFLAGS.localtime.c+= -DHAVE_TZNAME=2 -DUSG_COMPAT=0 -DALTZONE=0
|
||||
CFLAGS.localtime.c+= -DNETBSD_INSPIRED=0 -DSTD_INSPIRED=1
|
||||
.if ${MK_DETECT_TZ_CHANGES} != "no"
|
||||
CFLAGS+= -DDETECT_TZ_CHANGES
|
||||
CFLAGS.localtime.c+= -DDETECT_TZ_CHANGES
|
||||
.endif
|
||||
|
||||
MAN+= ctime.3 strftime.3 strptime.3 time2posix.3
|
||||
|
|
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include "tzfile.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include "un-namespace.h"
|
||||
#include "timelocal.h"
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include "private.h"
|
||||
#include "un-namespace.h"
|
||||
#include "libc_private.h"
|
||||
#include "timelocal.h"
|
||||
|
|
|
@ -101,6 +101,7 @@ SUBDIR= adduser \
|
|||
wake \
|
||||
watch \
|
||||
watchdogd \
|
||||
zdump \
|
||||
zic \
|
||||
zonectl
|
||||
|
||||
|
|
12
usr.sbin/zdump/Makefile
Normal file
12
usr.sbin/zdump/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
# $FreeBSD$
|
||||
|
||||
.PATH: ${SRCTOP}/contrib/tzcode
|
||||
|
||||
PROG= zdump
|
||||
MAN= zdump.8
|
||||
SRCS= zdump.c
|
||||
|
||||
CFLAGS+= -DNETBSD_INSPIRED=0 -DSTD_INSPIRED=1
|
||||
CFLAGS+= -I${SRCTOP}/contrib/tzcode
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,7 +1,12 @@
|
|||
# $FreeBSD$
|
||||
|
||||
# Vendor contact: tz@elsie.nci.nih.gov
|
||||
.PATH: ${SRCTOP}/contrib/tzcode
|
||||
|
||||
SUBDIR= zic zdump
|
||||
PROG= zic
|
||||
MAN= zic.8
|
||||
SRCS= zic.c
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
CFLAGS+= -DNETBSD_INSPIRED=0 -DSTD_INSPIRED=1
|
||||
CFLAGS+= -I${SRCTOP}/contrib/tzcode
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# $FreeBSD$
|
||||
|
||||
.include "${SRCTOP}/usr.sbin/Makefile.inc"
|
|
@ -1,88 +0,0 @@
|
|||
@(#)README 8.3
|
||||
This file is in the public domain, so clarified as of
|
||||
2009-05-17 by Arthur David Olson.
|
||||
|
||||
$FreeBSD$
|
||||
|
||||
"What time is it?" -- Richard Deacon as The King
|
||||
"Any time you want it to be." -- Frank Baxter as The Scientist
|
||||
(from the Bell System film "About Time")
|
||||
|
||||
The 1989 update of the time zone package featured
|
||||
|
||||
* POSIXization (including interpretation of POSIX-style TZ environment
|
||||
variables, provided by Guy Harris),
|
||||
* ANSIfication (including versions of "mktime" and "difftime"),
|
||||
* SVIDulation (an "altzone" variable)
|
||||
* MACHination (the "gtime" function)
|
||||
* corrections to some time zone data (including corrections to the rules
|
||||
for Great Britain and New Zealand)
|
||||
* reference data from the United States Naval Observatory for folks who
|
||||
want to do additional time zones
|
||||
* and the 1989 data for Saudi Arabia.
|
||||
|
||||
(Since this code will be treated as "part of the implementation" in some places
|
||||
and as "part of the application" in others, there's no good way to name
|
||||
functions, such as timegm, that are not part of the proposed ANSI C standard;
|
||||
such functions have kept their old, underscore-free names in this update.)
|
||||
|
||||
And the "dysize" function has disappeared; it was present to allow compilation
|
||||
of the "date" command on old BSD systems, and a version of "date" is now
|
||||
provided in the package. The "date" command is not created when you "make all"
|
||||
since it may lack options provided by the version distributed with your
|
||||
operating system, or may not interact with the system in the same way the
|
||||
native version does.
|
||||
|
||||
Since POSIX frowns on correct leap second handling, the default behavior of
|
||||
the "zic" command (in the absence of a "-L" option) has been changed to omit
|
||||
leap second information from its output files.
|
||||
|
||||
Here is a recipe for acquiring, building, installing, and testing the
|
||||
tz distribution on a GNU/Linux or similar host.
|
||||
|
||||
mkdir tz
|
||||
cd tz
|
||||
wget 'ftp://elsie.nci.nih.gov/pub/tz*.tar.gz'
|
||||
gzip -dc tzcode*.tar.gz | tar -xf -
|
||||
gzip -dc tzdata*.tar.gz | tar -xf -
|
||||
|
||||
Be sure to read the comments in "Makefile" and make any changes needed
|
||||
to make things right for your system, especially if you are using some
|
||||
platform other than GNU/Linux. Then run the following commands,
|
||||
substituting your desired installation directory for "$HOME/tzdir":
|
||||
|
||||
make TOPDIR=$HOME/tzdir install
|
||||
$HOME/tzdir/etc/zdump -v America/Los_Angeles
|
||||
|
||||
To use the new functions, use a "-ltz" option when compiling or linking.
|
||||
|
||||
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
|
||||
expected in the future;
|
||||
|
||||
* provide a test of the generality of the local time rule description
|
||||
system.
|
||||
|
||||
The information in the time zone data files is by no means authoritative;
|
||||
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!
|
||||
|
||||
Thanks to these Timezone Caballeros who've made major contributions to the
|
||||
time conversion package: Keith Bostic; Bob Devine; Paul Eggert; Robert Elz;
|
||||
Guy Harris; Mark Horton; John Mackin; and Bradley White. Thanks also to
|
||||
Michael Bloom, Art Neilson, Stephen Prince, John Sovereign, and Frank Wales
|
||||
for testing work, and to Gwillim Law for checking local mean time data.
|
||||
None of them are responsible for remaining errors.
|
||||
|
||||
Look in the ~ftp/pub directory of elsie.nci.nih.gov
|
||||
for updated versions of these files.
|
||||
|
||||
Please send comments or information to tz@elsie.nci.nih.gov.
|
|
@ -1,15 +0,0 @@
|
|||
# $FreeBSD$
|
||||
|
||||
.PATH: ${SRCTOP}/contrib/tzcode/zic
|
||||
|
||||
PROG= zdump
|
||||
MAN= zdump.8
|
||||
SRCS= zdump.c ialloc.c scheck.c
|
||||
|
||||
CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS
|
||||
CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"${SHAREDIR}/zoneinfo\" -Demkdir=mkdir
|
||||
CFLAGS+= -I${.CURDIR:H} -I${SRCTOP}/contrib/tzcode/stdtime
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,22 +0,0 @@
|
|||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
.PATH: ${SRCTOP}/contrib/tzcode/zic
|
||||
|
||||
PROG= zic
|
||||
MAN= zic.8
|
||||
SRCS= zic.c ialloc.c scheck.c
|
||||
|
||||
CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS
|
||||
CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"${SHAREDIR}/zoneinfo\" -Demkdir=mkdir
|
||||
CFLAGS+= -DHAVE_STRERROR -DHAVE_UNISTD_H
|
||||
CFLAGS+= -I${.CURDIR:H} -I${SRCTOP}/contrib/tzcode/stdtime
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
.if ${COMPILER_TYPE} == "gcc"
|
||||
CWARNFLAGS+= -Wno-error=strict-overflow
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
Loading…
Reference in a new issue