287 lines
13 KiB
Plaintext
287 lines
13 KiB
Plaintext
# $NetBSD: Theory,v 1.2 1998/01/09 04:11:55 perry Exp $
|
|
from: @(#)Theory 7.5
|
|
|
|
|
|
----- Outline -----
|
|
|
|
Time and date functions
|
|
Names of time zone regions
|
|
Time zone abbreviations
|
|
|
|
|
|
----- Time and date functions -----
|
|
|
|
These time and date functions are upwards compatible with POSIX.1,
|
|
an international standard for Unix-like systems.
|
|
As of this writing, the current edition of POSIX.1 is:
|
|
|
|
Information technology --Portable Operating System Interface (POSIX (R))
|
|
-- Part 1: System Application Program Interface (API) [C Language]
|
|
ISO/IEC 9945-1:1996
|
|
ANSI/IEEE Std 1003.1, 1996 Edition
|
|
1996-07-12
|
|
|
|
POSIX.1 has the following properties and limitations.
|
|
|
|
* In POSIX.1, time display in a process is controlled by the
|
|
environment variable TZ. Unfortunately, the POSIX.1 TZ string takes
|
|
a form that is hard to describe and is error-prone in practice.
|
|
Also, POSIX.1 TZ strings can't deal with other (for example, Israeli)
|
|
daylight saving time rules, or situations where more than two
|
|
time zone abbreviations are used in an area.
|
|
|
|
The POSIX.1 TZ string takes the following form:
|
|
|
|
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.
|
|
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).
|
|
|
|
* In POSIX.1, when a TZ value like "EST5EDT" is parsed,
|
|
typically the current US DST rules are used,
|
|
but this means that the US DST rules are compiled into each program
|
|
that does time conversion. This means that when US time conversion
|
|
rules change (as in the United States in 1987), all programs that
|
|
do time conversion must be recompiled to ensure proper results.
|
|
|
|
* In POSIX.1, there's no tamper-proof way for a process to learn the
|
|
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 GMT" 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.1 requires that systems ignore leap seconds.
|
|
|
|
These are the extensions that have been made to the POSIX.1 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.1, 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
|
|
(bww@k.cs.cmu.edu).
|
|
|
|
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 GMT.
|
|
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.1, 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 names of this package's installed time zone rule files are chosen to
|
|
help minimize possible future incompatibilities due to political events.
|
|
Ordinarily, names of countries are 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).
|
|
|
|
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 names. Use only Ascii letters, digits, `.',
|
|
`-' and `_'. Do 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.
|
|
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 traditional 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'.
|
|
|
|
The file `zone.tab' lists the geographical locations used to name
|
|
time zone rule files.
|
|
|
|
Older versions of this package used a different naming scheme,
|
|
and these older names are still supported.
|
|
See the file `backwards' 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.1.
|
|
Here are the general rules used for choosing time zone abbreviations,
|
|
in decreasing order of importance:
|
|
|
|
Use abbreviations that consist of 3 or more upper-case Ascii letters,
|
|
except use "___" for locations while uninhabited.
|
|
Posix.1 requires at least 3 characters, and the restriction to
|
|
upper-case Ascii letters follows most traditions.
|
|
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. In theory, the character set could
|
|
be !%./@A-Z^_a-z{}, but these tables use only upper-case
|
|
Ascii letters (and "___").
|
|
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.
|
|
|
|
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 GMT offsets like `-0500' instead of time zone
|
|
abbreviations like `EST'; this avoids the ambiguity.
|