diff options
Diffstat (limited to 'time')
-rw-r--r-- | time/Makefile | 318 | ||||
-rw-r--r-- | time/README.time | 73 | ||||
-rw-r--r-- | time/Theory | 120 | ||||
-rw-r--r-- | time/africa | 603 | ||||
-rw-r--r-- | time/antarctica | 19 | ||||
-rw-r--r-- | time/asctime.c | 56 | ||||
-rw-r--r-- | time/asia | 803 | ||||
-rw-r--r-- | time/australasia | 783 | ||||
-rw-r--r-- | time/backward | 75 | ||||
-rw-r--r-- | time/date.1 | 153 | ||||
-rw-r--r-- | time/date.c | 900 | ||||
-rw-r--r-- | time/difftime.c | 74 | ||||
-rw-r--r-- | time/emkdir.c | 85 | ||||
-rw-r--r-- | time/etcetera | 54 | ||||
-rw-r--r-- | time/europe | 2072 | ||||
-rw-r--r-- | time/factory | 8 | ||||
-rw-r--r-- | time/getopt.c | 93 | ||||
-rw-r--r-- | time/ialloc.c | 103 | ||||
-rw-r--r-- | time/leapseconds | 41 | ||||
-rw-r--r-- | time/localtime.c | 1569 | ||||
-rw-r--r-- | time/logwtmp.c | 65 | ||||
-rw-r--r-- | time/newctime.3 | 220 | ||||
-rw-r--r-- | time/newtzset.3 | 236 | ||||
-rw-r--r-- | time/northamerica | 953 | ||||
-rw-r--r-- | time/optind.c | 10 | ||||
-rw-r--r-- | time/pacificnew | 26 | ||||
-rw-r--r-- | time/private.h | 210 | ||||
-rw-r--r-- | time/scheck.c | 62 | ||||
-rw-r--r-- | time/solar87 | 386 | ||||
-rw-r--r-- | time/solar88 | 386 | ||||
-rw-r--r-- | time/solar89 | 391 | ||||
-rw-r--r-- | time/southamerica | 397 | ||||
-rw-r--r-- | time/strftime.c | 576 | ||||
-rw-r--r-- | time/systemv | 35 | ||||
-rw-r--r-- | time/time2posix.3 | 119 | ||||
-rw-r--r-- | time/tzfile.5 | 123 | ||||
-rw-r--r-- | time/tzfile.h | 170 | ||||
-rw-r--r-- | time/usno1988 | 111 | ||||
-rw-r--r-- | time/usno1989 | 452 | ||||
-rw-r--r-- | time/usno1989a | 452 | ||||
-rw-r--r-- | time/yearistype.sh | 26 | ||||
-rw-r--r-- | time/zdump.8 | 40 | ||||
-rw-r--r-- | time/zdump.c | 331 | ||||
-rw-r--r-- | time/zic.8 | 406 | ||||
-rw-r--r-- | time/zic.c | 1956 |
45 files changed, 16141 insertions, 0 deletions
diff --git a/time/Makefile b/time/Makefile new file mode 100644 index 000000000..117e99d7e --- /dev/null +++ b/time/Makefile @@ -0,0 +1,318 @@ +# @(#)Makefile 7.29 +# Revised: Sun Feb 26 22:05:06 1995 by faith@cs.unc.edu +# FOR LINUX + +include ../MCONFIG + +# Change the line below for your time zone (after finding the zone you want in +# the time zone files, or adding it to a time zone file). +# Alternately, if you discover you've got the wrong time zone, you can just +# zic -l rightzone +# to correct things. +# Use the command +# make zonenames +# to get a list of the values you can use for LOCALTIME. + +LOCALTIME= US/Eastern # Factory + +# If you want something other than Eastern United States time as a template +# for handling POSIX-style time zone environment variables, +# change the line below (after finding the zone you want in the +# time zone files, or adding it to a time zone file). +# (When a POSIX-style environment variable is handled, the rules in the template +# file are used to determine "spring forward" and "fall back" days and +# times; the environment variable itself specifies GMT offsets of standard and +# summer time.) +# Alternately, if you discover you've got the wrong time zone, you can just +# zic -p rightzone +# to correct things. +# Use the command +# make zonenames +# to get a list of the values you can use for POSIXRULES. +# If you want POSIX compatibility, use "America/New_York". + +POSIXRULES= America/New_York + +# Everything gets put in subdirectories of. . . + +TOPDIR= /usr + +# "Compiled" time zone information is placed in the "TZDIR" directory +# (and subdirectories). +# Use an absolute path name for TZDIR unless you're just testing the software. + +TZDIR= $(TOPDIR)/lib/zoneinfo + +LIBDIR= $(TOPDIR)/lib +TZLIB= $(LIBDIR)/libz.a + +# If you always want time values interpreted as "seconds since the epoch +# (not counting leap seconds)", use +# REDO= posix_only +# below. If you always want right time values interpreted as "seconds since +# the epoch" (counting leap seconds)", use +# REDO= right_only +# below. If you want both sets of data available, with leap seconds not +# counted normally, use +# REDO= posix_right +# below. If you want both sets of data available, with leap seconds counted +# normally, use +# REDO= right_posix +# below. +# POSIX mandates that leap seconds not be counted; for compatibility with it, +# use either "posix_only" or "posix_right". + +REDO= posix_right + +# Since "." may not be in PATH... + +YEARISTYPE= ./yearistype + +# If you're on an AT&T-based system (rather than a BSD-based system), add +# -DUSG +# to the end of the "CFLAGS=" line. +# +# If you're running on a system where "strchr" is known as "index" +# (for example, a 4.[012]BSD system), add +# -Dstrchr=index +# to the end of the "CFLAGS=" line. +# +# If you're running on a system with a "mkdir" function, feel free to add +# -Demkdir=mkdir +# to the end of the "CFLAGS=" line +# +# If you want to use System V compatibility code, add +# -DUSG_COMPAT +# to the end of the "CFLAGS=" line. This arrange for "timezone" and "daylight" +# variables to be kept up-to-date by the time conversion functions. Neither +# "timezone" nor "daylight" is described in X3J11's work. +# +# If your system has a "GMT offset" field in its "struct tm"s +# (or if you decide to add such a field in your system's "time.h" file), +# add the name to a define such as +# -DTM_GMTOFF=tm_gmtoff +# or +# -DTM_GMTOFF=_tm_gmtoff +# to the end of the "CFLAGS=" line. +# Neither tm_gmtoff nor _tm_gmtoff is described in X3J11's work; +# in its work, use of "tm_gmtoff" is described as non-conforming. +# Both UCB and Sun have done the equivalent of defining TM_GMTOFF in +# their recent releases. +# +# If your system has a "zone abbreviation" field in its "struct tm"s +# (or if you decide to add such a field in your system's "time.h" file), +# add the name to a define such as +# -DTM_ZONE=tm_zone +# or +# -DTM_ZONE=_tm_zone +# to the end of the "CFLAGS=" line. +# Neither tm_zone nor _tm_zone is described in X3J11's work; +# in its work, use of "tm_zone" is described as non-conforming. +# Both UCB and Sun have done the equivalent of defining TM_ZONE in +# their recent releases. +# +# If you want functions that were inspired by early versions of X3J11's work, +# add +# -DSTD_INSPIRED +# to the end of the "CFLAGS=" line. This arranges for the functions +# "tzsetwall", "offtime", "timelocal", "timegm", "timeoff", +# "posix2time", and "time2posix" to be added to the time conversion library. +# "tzsetwall" is like "tzset" except that it arranges for local wall clock +# time (rather than the time specified in the TZ environment variable) +# to be used. +# "offtime" is like "gmtime" except that it accepts a second (long) argument +# that gives an offset to add to the time_t when converting it. +# "timelocal" is equivalent to "mktime". +# "timegm" is like "timelocal" except that it turns a struct tm into +# a time_t using GMT (rather than local time as "timelocal" does). +# "timeoff" is like "timegm" except that it accepts a second (long) argument +# that gives an offset to use when converting to a time_t. +# "posix2time" and "time2posix" are described in an included manual page. +# None of these functions are described in X3J11's current work. +# Sun has provided "tzsetwall", "timelocal", and "timegm" in SunOS 4.0. +# These functions may well disappear in future releases of the time +# conversion package. +# +# If you want Source Code Control System ID's left out of object modules, add +# -DNOID +# to the end of the "CFLAGS=" line. +# +# If you'll never want to handle solar-time-based time zones, add +# -DNOSOLAR +# to the end of the "CFLAGS=" line +# (and comment out the "SDATA=" line below). +# This reduces (slightly) the run-time data-space requirements of +# the time conversion functions; it may reduce the acceptability of your system +# to folks in oil- and cash-rich places. +# +# If you want to allocate state structures in localtime, add +# -DALL_STATE +# to the end of the "CFLAGS=" line. Storage is obtained by calling malloc. +# +# If you want an "altzone" variable (a la System V Release 3.1), add +# -DALTZONE +# to the end of the "CFLAGS=" line. +# This variable is not described in X3J11's work. +# +# If you want a "gtime" function (a la MACH), add +# -DCMUCS +# to the end of the "CFLAGS=" line +# This function is not described in X3J11's work. +# +# NIST-PCTS:151-2, Version 1.4, (1993-12-03) is a test suite put +# out by the National Institute of Standards and Technology +# which claims to test C and Posix conformance. If you want to pass PCTS, add +# -DPCTS +# to the end of the "CFLAGS=" line. +# +# If you want strict compliance with XPG4 as of April 9, 1994, add +# -DXPG4_1994_04_09 +# to the end of the "CFLAGS=" line. This causes "strftime" to always return +# 53 as a week number (rather than 52 or 53) for those days in January that +# before the first Monday in January when a "%V" format is used and January 1 +# falls on a Friday, Saturday, or Sunday. +# +# If your compiler supports the `long double' type, add +# -DHAVE_LONG_DOUBLE +# to the end of the "CFLAGS=" line. +# +# XXX--note about LOCALE_HOME here +# XXX--note about HAVE_SETLOCALE here + +LFLAGS=$(LDFLAGS) + +################################################################################ + +CC= gcc -DTZDIR=\"$(TZDIR)\" + +TZCSRCS= \ + zic.c localtime.c asctime.c scheck.c ialloc.c emkdir.c getopt.c optind.c +TZCOBJS= \ + zic.o localtime.o asctime.o scheck.o ialloc.o emkdir.o getopt.o optind.o +TZDSRCS= zdump.c localtime.c asctime.c ialloc.c getopt.c optind.c +TZDOBJS= zdump.o localtime.o asctime.o ialloc.o getopt.o optind.o +DATESRCS= \ + date.c localtime.c getopt.c optind.c logwtmp.c strftime.c asctime.c +DATEOBJS= \ + date.o localtime.o getopt.o optind.o logwtmp.o strftime.o asctime.o +LIBSRCS= localtime.c asctime.c difftime.c +LIBOBJS= localtime.o asctime.o difftime.o +HEADERS= tzfile.h private.h +NONLIBSRCS= zic.c zdump.c scheck.c ialloc.c emkdir.c getopt.c optind.c +NEWUCBSRCS= date.c logwtmp.c strftime.c +SOURCES= $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) +MANS= newctime.3 newtzset.3 time2posix.3 tzfile.5 zic.8 zdump.8 +DOCS= README Theory $(MANS) date.1 Makefile +YDATA= africa antarctica asia australasia \ + europe northamerica southamerica pacificnew etcetera factory \ + backward +NDATA= systemv +SDATA= solar87 solar88 solar89 +TDATA= $(YDATA) $(NDATA) $(SDATA) +DATA= $(YDATA) $(NDATA) $(SDATA) leapseconds yearistype.sh +USNO= usno1988 usno1989 usno1989a +ENCHILADA= $(DOCS) $(SOURCES) $(DATA) $(USNO) + +# And for the benefit of csh users on systems that assume the user +# shell should be used to handle commands in Makefiles. . . + +SHELL= /bin/sh + +all: zic zdump $(LIBOBJS) + +ALL: all date + +install: all $(DATA) $(REDO) $(TZLIB) $(MANS) + ./zic -y $(YEARISTYPE) \ + -d $(TZDIR) -l $(LOCALTIME) -p $(POSIXRULES) + $(INSTALLDIR) $(USRSBINDIR) + $(INSTALLBIN) zic zdump $(USRSBINDIR) + $(INSTALLDIR) $(MAN3DIR) $(MAN5DIR) $(MAN8DIR) + -rm -f $(MAN3DIR)/newctime.3 \ + $(MAN3DIR)/newtzset.3 \ + $(MAN5DIR)/tzfile.5 \ + $(MAN8DIR)/zdump.8 \ + $(MAN8DIR)/zic.8 + $(INSTALLMAN) newctime.3 newtzset.3 $(MAN3DIR) + $(INSTALLMAN) tzfile.5 $(MAN5DIR) + $(INSTALLMAN) zdump.8 zic.8 $(MAN8DIR) + +INSTALL: ALL install date.1 + $(INSTALLDIR) $(BINDIR) + $(INSTALLBIN) date $(BINDIR) + $(INSTALLDIR) $(MAN1DIR) + -rm -f $(MAN1DIR)/date.1 + $(INSTALLMAN) date.1 $(MAN1DIR) + +zdump: $(TZDOBJS) + $(CC) $(CFLAGS) $(LFLAGS) $(TZDOBJS) -o $@ + +zic: $(TZCOBJS) yearistype + $(CC) $(CFLAGS) $(LFLAGS) $(TZCOBJS) -o $@ + +yearistype: yearistype.sh + cp yearistype.sh yearistype + chmod +x yearistype + +posix_only: zic $(TDATA) + ./zic -y $(YEARISTYPE) -d $(TZDIR) -L /dev/null $(TDATA) + +right_only: zic leapseconds $(TDATA) + ./zic -y $(YEARISTYPE) -d $(TZDIR) -L leapseconds $(TDATA) + +other_two: zic leapseconds $(TDATA) + ./zic -y $(YEARISTYPE) -d $(TZDIR)/posix -L /dev/null $(TDATA) + ./zic -y $(YEARISTYPE) \ + -d $(TZDIR)/right -L leapseconds $(TDATA) + +posix_right: posix_only other_two + +right_posix: right_only other_two + +# The "ar d"s below ensure that obsolete object modules +# (based on source provided with earlier versions of the time conversion stuff) +# are removed from the library. + +$(TZLIB): $(LIBOBJS) + -mkdir $(TOPDIR) $(LIBDIR) + sleep 3 + ar ru $@ $(LIBOBJS) + if ar t $@ timemk.o 2>/dev/null ; then ar d $@ timemk.o ; fi + if ar t $@ ctime.o 2>/dev/null ; then ar d $@ ctime.o ; fi + if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \ + then ranlib $@ ; fi + +# We use the system's getopt and logwtmp in preference to ours if available. + +date: $(DATEOBJS) + ar r ,lib.a getopt.o optind.o logwtmp.o + if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \ + then ranlib ,lib.a ; fi + $(CC) $(CFLAGS) date.o localtime.o asctime.o strftime.o \ + -lc ,lib.a -o $@ + rm -f ,lib.a + +clean: + rm -f core *~ *.o *.out zdump zic yearistype date ,* *.tar.gz + +names: + @echo $(ENCHILADA) + +public: $(ENCHILADA) + tar cf - $(DOCS) $(SOURCES) $(USNO) | gzip -9 > tzcode.tar.gz + tar cf - $(DATA) | gzip -9 > tzdata.tar.gz + +zonenames: $(TDATA) + @awk '/^Zone/ { print $$2 } /^Link/ { print $$3 }' $(TDATA) + +asctime.o: private.h tzfile.h +date.o: private.h +difftime.o: private.h +emkdir.o: private.h +ialloc.o: private.h +localtime.o: private.h tzfile.h +scheck.o: private.h +strftime.o: tzfile.h +zic.o: private.h tzfile.h + +.KEEP_STATE: diff --git a/time/README.time b/time/README.time new file mode 100644 index 000000000..809defde5 --- /dev/null +++ b/time/README.time @@ -0,0 +1,73 @@ +@(#)README 7.6 + +"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 on 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.) + +Support for the tz_abbr variable has been eliminated from this version +(to forestall "kitchen sink" complaints from certain quarters :-). + +Support for Turbo C compilation has also been eliminated; it was present to +allow checking in an ANSI-style environment, and such checking is now done with +gcc. + +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. + +Be sure to read the comments in "Makefile" and make any changes +needed to make things right for your system. + +To use the new functions, use a "-lz" option when compiling or linking. + +Historical local time information has been included here not because it +is particularly useful, but rather to: + +* 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; +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. diff --git a/time/Theory b/time/Theory new file mode 100644 index 000000000..93a07c0f7 --- /dev/null +++ b/time/Theory @@ -0,0 +1,120 @@ +@(#)Theory 7.2 + +These time and date functions are much like the System V Release 2.0 (SVR2) +time and date functions; there are a few additions and changes to extend +the usefulness of the SVR2 functions: + +* In SVR2, time display in a process is controlled by the environment + variable TZ, which "must be a three-letter time zone name, followed + by a number representing the difference between local time and + Greenwich Mean Time in hours, followed by an optional three-letter + name for a daylight time zone;" when the optional daylight time zone is + present, "standard U.S.A. Daylight Savings Time conversion is applied." + This means that SVR2 can't deal with other (for example, Australian) + daylight savings time rules, or situations where more than two + time zone abbreviations are used in an area. + +* In SVR2, time conversion information is compiled into each program + that does time conversion. This means that when 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 SVR2, time conversion fails for near-minimum or near-maximum + time_t values when doing conversions for places that don't use GMT. + +* In SVR2, 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 savings time shifts--as might be required to limit phone + calls to off-peak hours.) + +* These functions can account for leap seconds, thanks to Bradley White + (bww@k.cs.cmu.edu). + +These are the changes that have been made to the SVR2 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 "US/Eastern" 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 SVR2, 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 or supported. (You can use a compile-time option to cause + these variables to be defined and to be 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.) + +Points of interest to folks with Version 7 or BSD systems: + +* The BSD "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 BSD gettimeofday function is not used in this package; + this lets users control the time zone used in doing time conversions. + Users who don't try to control things (that is, users who do not set + the environment variable TZ) get the time conversion specified in the + file "/etc/zoneinfo/localtime"; see the time zone compiler writeup for + information on how to initialize this file. + +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 +close to SVR2 (with the exceptions outlined above) to ensure its broad +acceptability. If more powerful time conversion functions can be standardized, +so much the better. diff --git a/time/africa b/time/africa new file mode 100644 index 000000000..a9786670b --- /dev/null +++ b/time/africa @@ -0,0 +1,603 @@ +# @(#)africa 7.6 + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# I added so many Zone names that the old, mostly flat name space was unwieldy. +# So I renamed the Zones to 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. +# For example, the old zone name `Egypt' is now `Africa/Cairo'. +# +# Here are the general rules I 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 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'. +# +# We typically use traditional English time zone abbreviations, +# and assume that applications translate them to other languages +# as part of the normal localization process. +# +# I made up the following time zone abbreviations; corrections are welcome! +# LMT Local Mean Time +# -2:00 CVT Cape Verde Time (no longer used) +# -1:00 AAT Atlantic Africa Time +# 0:00 WAT West Africa Time +# 1:00 CAT Central Africa Time +# 2:00 SAT South Africa Time +# 3:00 EAT East Africa Time +# 4:00 SMT Seychelles and Mascarene Time +# The final `T' is replaced by `ST' for summer time, e.g. `SAST'. +# BEAT is British East Africa Time, which was 2:30 before 1948 and 2:45 after. + + +# Algeria +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Algeria 1911 only - Jan 1 0:00s 0 - +Rule Algeria 1916 only - Jun 14 23:00s 1:00 " DST" +Rule Algeria 1916 1919 - Oct Sun<=7 23:00s 0 - +Rule Algeria 1917 only - Mar 24 23:00s 1:00 " DST" +Rule Algeria 1918 only - Mar 9 23:00s 1:00 " DST" +Rule Algeria 1919 only - Mar 1 23:00s 1:00 " DST" +Rule Algeria 1920 only - Feb 14 23:00s 1:00 " DST" +Rule Algeria 1920 only - Oct 23 23:00s 0 - +Rule Algeria 1921 only - Mar 14 23:00s 1:00 " DST" +Rule Algeria 1921 only - Jun 21 23:00s 0 - +Rule Algeria 1939 only - Sep 11 23:00s 1:00 " DST" +Rule Algeria 1939 only - Nov 19 1:00 0 - +Rule Algeria 1944 1945 - Apr Mon<=7 2:00 1:00 " DST" +Rule Algeria 1944 only - Oct 8 2:00 0 - +Rule Algeria 1945 only - Sep 16 1:00 0 - +Rule Algeria 1971 only - Apr 25 23:00s 1:00 " DST" +Rule Algeria 1971 only - Sep 26 23:00s 0 - +Rule Algeria 1977 only - May 6 0:00 1:00 " DST" +Rule Algeria 1977 only - Oct 21 0:00 0 - +Rule Algeria 1978 only - Mar 24 1:00 1:00 " DST" +Rule Algeria 1978 only - Sep 22 3:00 0 - +Rule Algeria 1980 only - Apr 25 0:00 1:00 " DST" +Rule Algeria 1980 only - Oct 31 2:00 0 - +# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Algiers 0:12:12 - LMT 1891 Mar 15 0:01 + 0:09:05 - PMT 1911 Mar 11 # Paris Mean Time + 0:00 Algeria WET%s 1940 Feb 25 2:00 + 1:00 Algeria MET%s 1946 Oct 7 + 0:00 - WET 1956 Jan 29 + 1:00 - MET 1963 Apr 14 + 0:00 Algeria WET%s 1977 Oct 21 + 1:00 Algeria MET%s 1979 Oct 26 + 0:00 Algeria WET%s 1981 May + 1:00 - MET + +# Angola +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Luanda 0:52:56 - LMT 1892 + 0:52 - LMT 1911 May 26 # Luanda Mean Time + 1:00 - CAT + +# Benin +# Whitman says they switched to 1:00 in 1946, not 1934; go with Shanks. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Porto-Novo 0:10:28 - LMT 1912 + 0:00 - WAT 1934 Feb 26 + 1:00 - CAT + +# Botswana +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Gaborone 1:43:40 - LMT 1885 + 2:00 - SAT 1943 Sep 19 2:00 + 2:00 1:00 SAST 1944 Mar 19 2:00 + 2:00 - SAT + +# Burkina Faso +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Ouagadougou -0:06:04 - LMT 1912 + 0:00 - WAT + +# Burundi +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Bujumbura 1:57:28 - LMT 1890 + 2:00 - SAT + +# Cameroon +# Whitman says they switched to 1:00 in 1920; go with Shanks. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Douala 0:38:48 - LMT 1912 + 1:00 - CAT + +# Cape Verde +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Cape_Verde -1:34:04 - LMT 1907 # Praia + -2:00 - CVT 1942 Sep + -2:00 1:00 CVST 1945 Oct 15 + -2:00 - CVT 1975 Nov 25 2:00 + -1:00 - AAT + +# Central African Republic +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Bangui 1:14:20 - LMT 1912 + 1:00 - CAT + +# Chad +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Ndjamena 1:00:12 - LMT 1912 + 1:00 - CAT 1979 Oct 14 + 1:00 1:00 CAST 1980 Mar 8 + 1:00 - CAT + +# Comoros +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Comoro 2:53:04 - LMT 1911 Jul # Moroni, Gran Comoro + 3:00 - EAT + +# Congo +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Brazzaville 1:01:08 - LMT 1912 + 1:00 - CAT + +# Cote D'Ivoire +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Abidjan -0:16:08 - LMT 1912 + 0:00 - WAT + +# Djibouti +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Djibouti 2:52:36 - LMT 1911 Jul + 3:00 - EAT + +############################################################################### + +# Egypt + +# From Bob Devine (January 28, 1988): +# Egypt: DST from first day of May to first of October (ending may +# also be on Sept 30th not 31st -- you might want to ask one of the +# soc.* groups, you might hit someone who could ask an embassy). +# DST since 1960 except for 1981-82. + +# From U. S. Naval Observatory (January 19, 1989): +# EGYPT 2 H AHEAD OF UTC +# EGYPT 3 H AHEAD OF UTC MAY 17 - SEP 30 (AFTER +# EGYPT RAMADAN) + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Egypt 1900 only - Oct 1 0:00 0 - +Rule Egypt 1940 only - Jul 15 0:00 1:00 " DST" +Rule Egypt 1940 only - Oct 1 0:00 0 - +Rule Egypt 1941 only - Apr 15 0:00 1:00 " DST" +Rule Egypt 1941 only - Sep 16 0:00 0 - +Rule Egypt 1942 1944 - Apr 1 0:00 1:00 " DST" +Rule Egypt 1942 only - Oct 27 0:00 0 - +Rule Egypt 1943 1945 - Nov 1 0:00 0 - +Rule Egypt 1945 only - Apr 16 0:00 1:00 " DST" +Rule Egypt 1957 only - May 10 0:00 1:00 " DST" +Rule Egypt 1957 1958 - Oct 1 0:00 0 - +Rule Egypt 1958 only - May 1 0:00 1:00 " DST" +Rule Egypt 1959 1981 - May 1 1:00 1:00 " DST" +Rule Egypt 1959 1965 - Sep 30 3:00 0 - +Rule Egypt 1966 max - Oct 1 3:00 0 - +Rule Egypt 1982 only - Jul 25 1:00 1:00 " DST" +Rule Egypt 1983 only - Jul 12 1:00 1:00 " DST" +Rule Egypt 1984 1988 - May 1 1:00 1:00 " DST" +Rule Egypt 1989 only - May 6 1:00 1:00 " DST" +Rule Egypt 1990 max - May 1 1:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Cairo 2:05:00 - LMT 1900 Oct + 2:00 Egypt EET%s + +# Equatorial Guinea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Malabo 0:35:08 - LMT 1912 + 0:00 - WAT 1963 Dec 15 + 1:00 - CAT + +# Eritrea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Asmera 2:35:32 - LMT 1870 + 2:36 - AMT 1890 # Asmera Mean Time + 2:35 - AAMT 1936 May 5 # Addis Ababa MT + 3:00 - EAT + +# Ethiopia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Addis_Ababa 2:34:48 - LMT 1870 + 2:35 - AAMT 1936 May 5 # Addis Ababa MT + 3:00 - EAT + +# Gabon +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Libreville 0:37:48 - LMT 1912 + 1:00 - CAT + +# Gambia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Banjul -1:06:36 - LMT 1912 + -1:07 - BMT 1935 # Banjul Mean Time + -1:00 - AAT 1964 + 0:00 - WAT + +# Ghana +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# WATDT is my invention for ``West Africa one-Third Daylight Time''. +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Ghana 1918 only - Jan 1 0:00 0 WAT +# Whitman says DST was observed from 1931 to ``the present''; go with Shanks. +Rule Ghana 1936 1942 - Sep 1 0:00 0:20 WATDT +Rule Ghana 1936 1942 - Dec 31 0:00 0 WAT +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Accra -0:00:52 - LMT 1918 + 0:00 Ghana %s + +# Guinea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Conakry -0:54:52 - LMT 1912 + 0:00 - WAT 1934 Feb 26 + 1:00 - CAT 1960 + 0:00 - WAT + +# Guinea-Bissau +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Bissau -1:02:20 - LMT 1911 May 26 + 1:00 - CAT 1975 + 0:00 - WAT + +# Kenya +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks says the transition to 2:45 was in 1940, but it must have been 1948. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Nairobi 2:27:16 - LMT 1928 Jul + 3:00 - EAT 1930 + 2:30 - BEAT 1948 + 2:45 - BEAT 1960 + 3:00 - EAT + +# Lesotho +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Maseru 1:50:00 - LMT 1903 Mar + 2:00 - SAT 1943 Sep 19 2:00 + 2:00 1:00 SAST 1944 Mar 19 2:00 + 2:00 - SAT + +# Liberia +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# In 1972 Liberia was the last country to switch +# from a GMT offset that was not a multiple of 15 minutes. +# Time magazine reported that it was in honor of their leader's birthday. +# For Liberia before 1972, Shanks reports -0:44, and Whitman reports -0:44:30; +# go with Whitman. +# +# From Shanks (1991), as corrected by Whitman: +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Monrovia -0:43:08 - LMT 1882 + -0:43:08 - MMT 1919 Mar # Monrovia Mean Time + -0:44:30 - LST 1972 May # Liberia Standard Time + 0:00 - WAT + +############################################################################### + +# Libya + +# From Bob Devine (January 28 1988): +# Libya: Since 1982 April 1st to September 30th (?) + +# From U. S. Naval Observatory (January 19, 1989): +# LIBYAN ARAB 1 H AHEAD OF UTC JAMAHIRIYA/LIBYA +# LIBYAN ARAB 2 H AHEAD OF UTC APR 1 - SEP 30 JAMAHIRIYA/LIBYA + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Libya 1920 only - Jan 1 0:00 0 - +Rule Libya 1951 only - Oct 14 2:00 1:00 " DST" +Rule Libya 1952 only - Jan 1 0:00 0 - +Rule Libya 1953 only - Oct 9 2:00 1:00 " DST" +Rule Libya 1954 only - Jan 1 0:00 0 - +Rule Libya 1955 only - Sep 30 0:00 1:00 " DST" +Rule Libya 1956 only - Jan 1 0:00 0 - +Rule Libya 1982 1984 - Apr 1 0:00 1:00 " DST" +Rule Libya 1982 1985 - Oct 1 0:00 0 - +Rule Libya 1985 only - Apr 6 0:00 1:00 " DST" +Rule Libya 1986 only - Apr 4 0:00 1:00 " DST" +Rule Libya 1986 only - Oct 3 0:00 0 - +Rule Libya 1987 1989 - Apr 1 0:00 1:00 " DST" +Rule Libya 1987 1990 - Oct 1 0:00 0 - +Rule Libya 1990 only - May 4 0:00 1:00 " DST" +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Here's a guess for years starting with 1991. +Rule Libya 1991 max - Apr 1 0:00 1:00 " DST" +Rule Libya 1991 max - Oct 1 0:00 0 - + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Tripoli 0:52:44 - LMT 1920 + 1:00 Libya MET%s 1959 + 2:00 - EET 1982 + 1:00 Libya MET%s + +# Madagascar +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Antananarivo 3:10:04 - LMT 1911 Jul + 3:00 - EAT 1954 Feb 27 23:00s + 3:00 1:00 EAST 1954 May 29 23:00s + 3:00 - EAT + +# Malawi +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Blantyre 2:20:00 - LMT 1903 Mar + 2:00 - SAT + +# Mali +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Bamako -0:32:00 - LMT 1912 + 0:00 - WAT 1934 Feb 26 + -1:00 - AAT 1960 Jun 20 + 0:00 - WAT +# no longer different from Bamako, but too famous to omit +Zone Africa/Timbuktu -0:12:04 - LMT 1912 + 0:00 - WAT + +# Mauritania +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Nouakchott -1:03:48 - LMT 1912 + 0:00 - WAT 1934 Feb 26 + -1:00 - AAT 1960 Jun 20 + 0:00 - WAT + +# Mauritius +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis + 4:00 - SMT +# Agalega Is, Rodriguez +# no information; probably like Indian/Mauritius + +# Mayotte +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Mayotte 3:01:08 - LMT 1911 Jul # Dzaoudzi + 3:00 - EAT + +# Morocco +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Morocco 1913 only - Oct 26 0:00 0 - +Rule Morocco 1939 only - Sep 12 0:00 1:00 " DST" +Rule Morocco 1939 only - Nov 19 0:00 0 - +Rule Morocco 1940 only - Feb 25 0:00 1:00 " DST" +Rule Morocco 1945 only - Nov 18 0:00 0 - +Rule Morocco 1950 only - Jun 11 0:00 1:00 " DST" +Rule Morocco 1950 only - Oct 29 0:00 0 - +Rule Morocco 1967 only - Jun 3 12:00 1:00 " DST" +Rule Morocco 1967 only - Oct 1 0:00 0 - +Rule Morocco 1974 only - Jun 24 0:00 1:00 " DST" +Rule Morocco 1974 only - Sep 1 0:00 0 - +Rule Morocco 1976 1977 - May 1 0:00 1:00 " DST" +Rule Morocco 1976 only - Aug 1 0:00 0 - +Rule Morocco 1977 only - Sep 28 0:00 0 - +Rule Morocco 1978 only - Jun 1 0:00 1:00 " DST" +Rule Morocco 1978 only - Aug 4 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26 + 0:00 Morocco WET%s 1984 Mar 16 + 1:00 - MET 1986 + 0:00 - WET +# The following are controlled by Spain, and are like Europe/Madrid: +# Alboran, Alhucemas Is, Ceuta, Chafarinas Is, Mellila. + +# Mozambique +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Maputo 2:10:20 - LMT 1903 Mar + 2:00 - SAT + +# Namibia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8 + 1:30 - SWAT 1903 Mar # SW Africa Time + 2:00 - SAT 1942 Sep 20 2:00 + 2:00 1:00 SAST 1943 Mar 21 2:00 + 2:00 - SAT + +# Niger +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Niamey 0:08:28 - LMT 1912 + 1:00 - CAT 1934 Feb 26 + 0:00 - WAT 1960 + 1:00 - CAT + +# Nigeria +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Lagos 0:13:36 - LMT 1919 Sep + 1:00 - CAT + +# Reunion +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Reunion 3:41:52 - LMT 1911 Jun # St Denis + 4:00 - SMT + +# Rwanda +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Kigali 2:00:16 - LMT 1935 Jun + 2:00 - SAT + +# St Helena +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/St_Helena -0:22:48 - LMT 1890 # Jamestown + -0:06 - ?MT 1951 # a typo in Shanks? + 0:00 - GMT +# Whitman says Tristan da Cunha is on GMT, like Atlantic/St_Helena. +# +# Ascension, Gough, Inaccessible, Nightingale +# no information; probably like Atlantic/St_Helena + +# Sao Tome and Principe +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Sao_Tome 0:26:56 - LMT 1884 + -0:37 - ?MT 1912 # a typo in Shanks? + 0:00 - WAT + +# Senegal +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Dakar -1:09:44 - LMT 1912 + -1:00 - AAT 1941 Jun + 0:00 - WAT + +# Seychelles +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Mahe 3:41:48 - LMT 1906 Jun # Victoria + 4:00 - SMT + +# Sierra Leone +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule SL 1913 only - Oct 26 0:00 0 - +# Whitman gives Mar 31 - Aug 31 for 1931 on; go with Shanks. +Rule SL 1935 1942 - Jun 1 0:00 1:00 S +Rule SL 1935 1942 - Oct 1 0:00 0 - +Rule SL 1957 1962 - Jun 1 0:00 1:00 S +Rule SL 1957 1962 - Sep 1 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Freetown -0:53:00 - LMT 1882 + -0:53 - FMT 1913 Jun + -1:00 SL AA%sT 1957 + 0:00 SL WA%sT + +# Somalia +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks omits the 1948 transition to 2:45; this is probably a typo. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Mogadishu 3:01:28 - LMT 1893 Nov + 3:00 - EAT 1931 + 2:30 - BEAT 1948 + 2:45 - BEAT 1957 # not in Shanks + 3:00 - EAT + +# South Africa +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule SA 1892 only - Feb 8 0:00 0 - +Rule SA 1942 1943 - Sep Sun>=15 2:00 1:00 S +Rule SA 1943 1944 - Mar Sun>=15 2:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Johannesburg 1:52:00 - LMT 1892 Feb 8 + 1:30 - SAT 1903 Mar + 2:00 SA SA%sT +# Prince Edward Is +# no information + +# Sudan +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Sudan 1931 only - Feb 8 0:00 0 - +Rule Sudan 1970 only - May 1 0:00 1:00 " DST" +Rule Sudan 1970 max - Oct 15 0:00 0 - +Rule Sudan 1971 only - Apr 30 0:00 1:00 " DST" +Rule Sudan 1972 max - Apr lastSun 0:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Khartoum 2:10:08 - LMT 1931 + 2:00 Sudan EET%s + +# Swaziland +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Mbabane 2:04:24 - LMT 1903 Mar + 2:00 - SAT + +# Tanzania +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Dar_es_Salaam 2:37:08 - LMT 1931 + 3:00 - EAT 1948 + 2:45 - BEAT 1961 + 3:00 - EAT + +# Togo +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Lome 0:04:52 - LMT 1893 + 0:00 - WAT + +# Tunisia +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Tunisia 1911 only - Mar 9 0:00 0 - +Rule Tunisia 1939 only - Apr 15 23:00s 1:00 " DST" +Rule Tunisia 1939 only - Nov 18 23:00s 0 - +Rule Tunisia 1940 only - Feb 25 23:00s 1:00 " DST" +Rule Tunisia 1941 only - Oct 6 0:00 0 - +Rule Tunisia 1942 only - Mar 9 0:00 1:00 " DST" +Rule Tunisia 1942 only - Nov 2 3:00 0 - +Rule Tunisia 1943 only - Mar 29 2:00 1:00 " DST" +Rule Tunisia 1943 only - Apr 17 2:00 0 - +Rule Tunisia 1943 only - Apr 25 2:00 1:00 " DST" +Rule Tunisia 1943 only - Oct 4 2:00 0 - +Rule Tunisia 1944 1945 - Apr Mon>=1 2:00 1:00 " DST" +Rule Tunisia 1944 only - Oct 8 0:00 0 - +Rule Tunisia 1945 only - Sep 16 0:00 0 - +Rule Tunisia 1977 only - Apr 30 0:00s 1:00 " DST" +Rule Tunisia 1977 only - Sep 24 0:00s 0 - +Rule Tunisia 1978 only - May 1 0:00s 1:00 " DST" +Rule Tunisia 1978 only - Oct 1 0:00s 0 - +Rule Tunisia 1988 only - Jun 1 0:00s 1:00 " DST" +Rule Tunisia 1988 max - Sep lastSun 0:00s 0 - +Rule Tunisia 1989 only - Mar 26 0:00s 1:00 " DST" +Rule Tunisia 1990 only - May 1 0:00s 1:00 " DST" +Rule Tunisia 1991 max - Mar lastSun 0:00s 1:00 " DST" +# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Tunis 0:40:44 - LMT 1881 May 12 + 0:09:05 - PMT 1911 Mar 9 # Paris Mean Time + 1:00 Tunisia MET%s + +# Uganda +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Kampala 2:09:40 - LMT 1928 Jul + 3:00 - EAT 1930 + 2:30 - BEAT 1948 + 2:45 - BEAT 1957 + 3:00 - EAT + +# Zaire +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Kinshasa 1:01:12 - LMT 1897 Nov 9 + 1:00 - CAT +Zone Africa/Lumumbashi 1:49:52 - LMT 1897 Nov 9 + 2:00 - SAT + +# Zambia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Lusaka 1:53:08 - LMT 1903 Mar + 2:00 - SAT + +# Zimbabwe +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Harare 2:04:12 - LMT 1903 Mar + 2:00 - SAT diff --git a/time/antarctica b/time/antarctica new file mode 100644 index 000000000..f5ed31370 --- /dev/null +++ b/time/antarctica @@ -0,0 +1,19 @@ +# @(#)antarctica 7.2 + +# From Arthur David Olson (February 13, 1988): +# No data available. + +# Balleny Is + +# British Antarctic Territories include +# South Orkney Is +# South Shetland Is + +# Amsterdam Island +# Bouvet +# Crozet Is +# Heard and McDonald Is +# Kerguelen Is +# St Paul Island +# Peter I Island +# Scott Island diff --git a/time/asctime.c b/time/asctime.c new file mode 100644 index 000000000..880915ed3 --- /dev/null +++ b/time/asctime.c @@ -0,0 +1,56 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)asctime.c 7.6"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/*LINTLIBRARY*/ + +#include "private.h" +#include "tzfile.h" + +/* +** A la X3J11, with core dump avoidance. +*/ + +char * +asctime(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" + }; + /* + ** Big enough for something such as + ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n + ** (two three-character abbreviations, five strings denoting integers, + ** three explicit spaces, two explicit colons, a newline, + ** and a trailing ASCII nul). + */ + static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + + 3 + 2 + 1 + 1]; + register const char * wn; + register const char * mn; + + if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) + wn = "???"; + else wn = wday_name[timeptr->tm_wday]; + if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR) + mn = "???"; + else mn = mon_name[timeptr->tm_mon]; + /* + ** The X3J11-suggested format is + ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n" + ** Since the .2 in 02.2d is ignored, we drop it. + */ + (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n", + wn, mn, + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec, + TM_YEAR_BASE + timeptr->tm_year); + return result; +} diff --git a/time/asia b/time/asia new file mode 100644 index 000000000..78ecb30d9 --- /dev/null +++ b/time/asia @@ -0,0 +1,803 @@ +# @(#)asia 7.12 + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (August 18, 1994): +# +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# A reliable and entertaining source about time zones is +# Derek Howse, Greenwich time and the discovery of the longitude, +# Oxford University Press (1980). +# +# I invented the abbreviations marked `*' in the following table; +# the rest are from earlier versions of this file, or from other sources. +# Corrections are welcome! +# std dst +# LMT Local Mean Time +# LST Local Star Time (Russian ``mestnoe zvezdnoe vremya'') +# 2:00 EET EET DST Eastern European Time +# 2:00 IST IDT Israel +# 3:00 AST ADT Arabia* +# 3:00 MSK MSD Moscow +# 3:30 IST IDT Iran +# 4:00 BSK BSD Baku* +# 4:00 GST GDT Gulf* +# 4:30 AFT Afghanistan* +# 5:00 ASK ASD Ashkhabad* +# 5:00 PKT Pakistan* +# 5:30 IST IST India +# 5:45 NPT Nepal* +# 6:00 BGT Bengal, Bangladesh* +# 6:00 TSK TSD Tashkent* +# 6:30 BMT Burma* +# 7:00 ICT Indochina* +# 7:00 JVT Java* +# 8:00 BNT Borneo, Brunei* +# 8:00 CST CDT China +# 8:00 HKT HKST Hong Kong +# 8:00 PST PDT Philippines* +# 8:00 SGT Singapore +# 8:00 UST UDT Ulan Bator* +# 9:00 JST Japan +# 9:00 KST KDT Korea +# 9:00 MLT Moluccas* +# 9:30 CST Australian Central Standard Time +# +# See the `europe' file for Russia and Turkey in Asia. +# +# See the `africa' file for Zone naming conventions. + +# From Guy Harris: +# Incorporates data for Singapore from Robert Elz' asia 1.1, as well as +# additional information from Tom Yap, Sun Microsystems Intercontinental +# Technical Support (including a page from the Official Airline Guide - +# Worldwide Edition). The names for time zones are guesses. + +############################################################################### + +# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): +# We don't know what happened to the clocks in the Caucausus and the ex-Soviet +# Central Asia after 1990. Until we get more info, stick with the pre-1991 rules. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Russia 1981 1984 - Apr 1 0:00 1:00 D +Rule Russia 1981 1983 - Oct 1 0:00 0 K +Rule Russia 1984 max - Sep lastSun 3:00 0 K +Rule Russia 1985 max - Mar lastSun 2:00 1:00 D + +# Afghanistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Kabul 4:36:48 - LMT 1890 + 4:00 - GST 1945 + 4:30 - AFT + +# Armenia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2 + 3:00 - MSK 1957 Mar + 4:00 Russia BS%s + +# Azerbaijan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Baku 3:19:24 - LMT 1924 May 2 + 3:00 - MSK 1957 Mar + 4:00 Russia BS%s + +# Bahrain +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Bahrain 3:22:20 - LMT 1920 # Al-Manamah + 4:00 - GST 1972 Jun + 3:00 - AST + +# Bangladesh +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Dacca 6:01:40 - LMT 1890 + 5:53 - CMT 1941 Oct # Calcutta Mean Time + 6:30 - BMT 1942 May 15 + 5:30 - IST 1942 Sep + 6:30 - BMT 1951 Sep 30 + 6:00 - BGT + +# Bhutan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Thimbu 5:58:36 - LMT 1947 Aug 15 + 5:30 - IST 1987 Oct + 6:00 - BGT + +# British Indian Ocean Territory +# From Whitman: +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Chagos 5:00 - PKT + +# Brunei +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Bandar Seri Begawan + 7:30 - BNT 1933 + 8:00 - BNT + +# Burma +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Rangoon 6:24:40 - LMT 1880 + 6:25 - RMT 1920 + 6:30 - BMT 1942 May + 9:00 - JST 1945 May 3 + 6:30 - BMT + +# Cambodia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Phnom_Penh 6:59:40 - LMT 1906 Jun 9 + 7:06 - SMT 1911 Mar 11 0:01 # Saigon MT + 7:00 - ICT 1912 May + 8:00 - ICT 1931 May + 7:00 - ICT + +# People's Republic of China + +# From Guy Harris: +# People's Republic of China. Yes, they really have only one time zone. + +# From Bob Devine (January 28, 1988): +# No they don't. See TIME mag, February 17, 1986 p.52. Even though +# China is across 4 physical time zones, before Feb 1, 1986 only the +# Peking (Bejing) time zone was recognized. Since that date, China +# has two of 'em -- Peking's and Urumqi (named after the capital of +# the Xinjiang Uighur Autonomous Region). I don't know about DST for it. +# +# . . .I just deleted the DST table and this editor makes it too +# painful to suck in another copy.. So, here is what I have for +# DST start/end dates for Peking's time zone (info from AP): +# +# 1986 May 4 - Sept 14 +# 1987 mid-April - ?? + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# According to Shanks, China started using DST in 1986, +# but it's still all one big happy time zone. + +# From U. S. Naval Observatory (January 19, 1989): +# CHINA 8 H AHEAD OF UTC ALL OF CHINA, INCL TAIWAN +# CHINA 9 H AHEAD OF UTC APR 17 - SEP 10 + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks writes that China switched from the Chinese calendar on 1912 Feb 12. +# He also writes that China has had a single time zone since 1980 May 1, +# and that they instituted DST on 1986 May 4; this contradicts Devine's +# note about Time magazine, though apparently _something_ happened in 1986. + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Shang 1928 only - Jan 1 0:00 0 S +Rule Shang 1940 only - Jun 3 0:00 1:00 D +Rule Shang 1940 1941 - Oct 1 0:00 0 S +Rule Shang 1941 only - Mar 16 0:00 1:00 D +Rule PRC 1949 only - Jan 1 0:00 0 S +Rule PRC 1986 only - May 4 0:00 1:00 D +Rule PRC 1986 max - Sep Sun>=11 0:00 0 S +Rule PRC 1987 max - Apr Sun>=10 0:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Shanghai 8:05:52 - LMT 1928 + 8:00 Shang C%sT 1949 + 8:00 PRC C%sT + +############################################################################### + +# Republic of China + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Taiwan 1896 only - Jan 1 0:00 0 S +Rule Taiwan 1945 1951 - May 1 0:00 1:00 D +Rule Taiwan 1945 1951 - Oct 1 0:00 0 S +Rule Taiwan 1952 only - Mar 1 0:00 1:00 D +Rule Taiwan 1952 1954 - Nov 1 0:00 0 S +Rule Taiwan 1953 1959 - Apr 1 0:00 1:00 D +Rule Taiwan 1955 1961 - Oct 1 0:00 0 S +Rule Taiwan 1960 1961 - Jun 1 0:00 1:00 D +Rule Taiwan 1974 1975 - Apr 1 0:00 1:00 D +Rule Taiwan 1974 1975 - Oct 1 0:00 0 S +Rule Taiwan 1980 only - Jun 30 0:00 1:00 D +Rule Taiwan 1980 only - Sep 30 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Taipei 8:06:00 - LMT 1896 + 8:00 Taiwan C%sT + +############################################################################### +# Hong Kong +# Presumably Hong Kong will have DST again when it merges with China, +# but it's too early to predict the details. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule HK 1904 only - Oct 30 0:00 0 - +Rule HK 1946 only - Apr 20 3:30 1:00 S +Rule HK 1946 only - Dec 1 3:30 0 - +Rule HK 1947 only - Apr 13 3:30 1:00 S +Rule HK 1947 only - Dec 30 3:30 0 - +Rule HK 1948 only - May 2 3:30 1:00 S +Rule HK 1948 1952 - Oct lastSun 3:30 0 - +Rule HK 1949 1953 - Apr Sun>=1 3:30 1:00 S +Rule HK 1953 only - Nov 1 3:30 0 - +Rule HK 1954 1964 - Mar Sun>=18 3:30 1:00 S +Rule HK 1954 only - Oct 31 3:30 0 - +Rule HK 1955 1964 - Nov Sun>=1 3:30 0 - +Rule HK 1965 1977 - Apr Sun>=16 3:30 1:00 S +Rule HK 1965 1977 - Oct Sun>=16 3:30 0 - +Rule HK 1979 1980 - May Sun>=8 3:30 1:00 S +Rule HK 1979 1980 - Oct Sun>=16 3:30 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Hong_Kong 7:36:36 - LMT 1904 Oct 30 + 8:00 HK HK%sT + +# Macao +# Presumably Macao will have DST again when it merges with China, +# but it's too early to predict the details. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Macao 1912 only - Jan 1 0:00 0 S +Rule Macao 1961 1962 - Mar Sun>=16 3:30 1:00 D +Rule Macao 1961 1964 - Nov Sun>=1 3:30 0 S +Rule Macao 1963 only - Mar Sun>=16 0:00 1:00 D +Rule Macao 1964 only - Mar Sun>=16 3:30 1:00 D +Rule Macao 1965 only - Mar Sun>=16 0:00 1:00 D +Rule Macao 1965 only - Oct 31 0:00 0 S +Rule Macao 1966 1971 - Apr Sun>=16 3:30 1:00 D +Rule Macao 1966 1971 - Oct Sun>=16 3:30 0 S +Rule Macao 1972 1974 - Apr Sun>=15 0:00 1:00 D +Rule Macao 1972 1973 - Oct Sun>=15 0:00 0 S +Rule Macao 1974 1977 - Oct Sun>=15 3:30 0 S +Rule Macao 1975 1977 - Apr Sun>=15 3:30 1:00 D +Rule Macao 1978 1980 - Apr Sun>=15 0:00 1:00 D +Rule Macao 1978 1980 - Oct Sun>=15 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Macao 7:34:20 - LMT 1912 + 8:00 Macao C%sT + + +############################################################################### + +# Cyprus +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Cyprus 1921 only - Nov 14 0:00 0 - +Rule Cyprus 1975 only - Apr 13 0:00 1:00 " DST" +Rule Cyprus 1975 only - Oct 12 0:00 0 - +Rule Cyprus 1976 only - May 15 0:00 1:00 " DST" +Rule Cyprus 1976 only - Oct 11 0:00 0 - +Rule Cyprus 1977 1980 - Apr Sun>=1 0:00 1:00 " DST" +Rule Cyprus 1977 only - Sep 25 0:00 0 - +Rule Cyprus 1978 only - Oct 2 0:00 0 - +Rule Cyprus 1979 max - Sep lastSun 0:00 0 - +Rule Cyprus 1981 max - Mar lastSun 0:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Nicosia 2:13:28 - LMT 1921 Nov 14 + 2:00 Cyprus EET%s + +# Georgia +# From Paul Eggert <eggert@twinsun.com> (1994-11-19): +# Today's _Economist_ (p 60) reports that Georgia moved its clocks forward +# an hour recently, due to a law proposed by Zurab Murvanidze, +# an MP who went on a hunger strike for 11 days to force discussion about it! +# Alas, we have no details. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tbilisi 2:59:16 - LMT 1880 + 2:59 - LST 1924 May 2 + 3:00 - MSK 1957 Mar + 4:00 Russia BS%s + +# India +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Calcutta 5:53:28 - LMT 1880 + 5:53 - CMT 1941 Oct # Calcutta Mean Time + 6:30 - BMT 1942 May 15 + 5:30 - IST 1942 Sep + 5:30 1:00 IST 1945 Oct 15 + 5:30 - IST +# The following are like Asia/Calcutta: +# Andaman Is +# Lakshadweep (Laccadive, Minicoy and Amindivi Is) +# Nicobar Is + +# Indonesia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Jakarta 7:07:12 - LMT 1867 Aug 10 + 7:07 - JMT 1924 Jan 1 0:13 + 7:20 - JVT 1932 Nov + 7:30 - JVT 1942 Mar 23 + 9:00 - JST 1945 Aug + 7:30 - JVT 1948 May + 8:00 - JVT 1950 May + 7:30 - JVT 1964 + 7:00 - JVT +Zone Asia/Ujung_Pandang 7:57:36 - LMT 1920 + 7:58 - MMT 1932 Nov # Macassar Mean Time + 8:00 - BNT 1942 Feb 9 + 9:00 - JST 1945 Aug + 8:00 - BNT +Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov + 9:00 - MLT 1944 + 9:30 - CST 1964 + 9:00 - MLT + +# Iran + +# Shanks has no record of DST after 1980. + +# From Bob Devine (January 28, 1988): +# Iran: Last Sunday in March to third (?) Sunday in +# September. Since the revolution, the official calendar is Monarchic +# calendar; I have no idea what the correspondence between dates are. + +# From U. S. Naval Observatory (January 19, 1989): +# IRAN 3.5H AHEAD OF UTC + +# From Shanks (1991), with corrections from Devine: +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Iran 1977 only - Nov 1 0:00 0 S +Rule Iran 1978 1980 - Mar 21 0:00 1:00 D +Rule Iran 1978 only - Oct 21 0:00 0 S +Rule Iran 1979 only - Sep 19 0:00 0 S +Rule Iran 1980 only - Sep 23 0:00 0 S +Rule Iran 1988 max - Mar lastSun 2:00 1:00 D +Rule Iran 1988 max - Sep Sun>=15 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tehran 3:25:44 - LMT 1916 + 3:26 - TMT 1946 + 3:30 - IST 1977 Nov + 4:00 Iran G%sT 1979 + 3:30 Iran I%sT + +# Iraq +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Iraq 1982 only - May 1 0:00 1:00 D +Rule Iraq 1982 1984 - Oct 1 0:00 0 S +Rule Iraq 1983 only - Mar 31 0:00 1:00 D +Rule Iraq 1984 1985 - Apr 1 0:00 1:00 D +Rule Iraq 1985 max - Sep lastSun 1:00s 0 S +Rule Iraq 1986 max - Mar lastSun 1:00s 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Baghdad 2:57:40 - LMT 1890 + 2:58 - BMT 1918 # Baghdad Mean Time + 3:00 - AST 1982 May + 3:00 Iraq A%sT + + +############################################################################### + +# Israel + +# From U. S. Naval Observatory (January 19, 1989): +# ISRAEL 2 H AHEAD OF UTC +# ISRAEL 3 H AHEAD OF UTC APR 10 - SEP 3 + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# +# Shanks gives the following rules for Jerusalem from 1918 through 1991. +# After 1989 Shanks often disagrees with Silverberg; we go with Silverberg. + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Zion 1918 only - Jan 1 0:00 0 S +Rule Zion 1940 only - Jun 1 0:00 1:00 D +Rule Zion 1942 1944 - Nov 1 0:00 0 S +Rule Zion 1943 only - Apr 1 2:00 1:00 D +Rule Zion 1944 only - Apr 1 0:00 1:00 D +Rule Zion 1945 only - Apr 16 0:00 1:00 D +Rule Zion 1945 only - Nov 1 2:00 0 S +Rule Zion 1946 only - Apr 16 2:00 1:00 D +Rule Zion 1946 only - Nov 1 0:00 0 S +Rule Zion 1948 only - May 23 0:00 2:00 DD +Rule Zion 1948 only - Sep 1 0:00 1:00 D +Rule Zion 1948 1949 - Nov 1 2:00 0 S +Rule Zion 1949 only - May 1 0:00 1:00 D +Rule Zion 1950 only - Apr 16 0:00 1:00 D +Rule Zion 1950 only - Sep 15 3:00 0 S +Rule Zion 1951 only - Apr 1 0:00 1:00 D +Rule Zion 1951 only - Nov 11 3:00 0 S +Rule Zion 1952 only - Apr 20 2:00 1:00 D +Rule Zion 1952 only - Oct 19 3:00 0 S +Rule Zion 1953 only - Apr 12 2:00 1:00 D +Rule Zion 1953 only - Sep 13 3:00 0 S +Rule Zion 1954 only - Jun 13 0:00 1:00 D +Rule Zion 1954 only - Sep 12 0:00 0 S +Rule Zion 1955 only - Jun 11 2:00 1:00 D +Rule Zion 1955 only - Sep 11 0:00 0 S +Rule Zion 1956 only - Jun 3 0:00 1:00 D +Rule Zion 1956 only - Sep 30 3:00 0 S +Rule Zion 1957 only - Apr 29 2:00 1:00 D +Rule Zion 1957 only - Sep 22 0:00 0 S +Rule Zion 1974 only - Jul 7 0:00 1:00 D +Rule Zion 1974 only - Oct 13 0:00 0 S +Rule Zion 1975 only - Apr 20 0:00 1:00 D +Rule Zion 1975 only - Aug 31 0:00 0 S +Rule Zion 1985 only - Apr 14 0:00 1:00 D +Rule Zion 1985 only - Sep 15 0:00 0 S +Rule Zion 1986 only - May 18 0:00 1:00 D +Rule Zion 1986 only - Sep 7 0:00 0 S +Rule Zion 1987 only - Apr 15 0:00 1:00 D +Rule Zion 1987 only - Sep 13 0:00 0 S +Rule Zion 1988 only - Apr 9 0:00 1:00 D +Rule Zion 1988 only - Sep 3 0:00 0 S +#Rule Zion 1989 only - Apr 29 0:00 1:00 D +#Rule Zion 1989 only - Sep 2 0:00 0 S +#Rule Zion 1990 only - Mar 25 0:00 1:00 D +#Rule Zion 1990 only - Aug 26 0:00 0 S +#Rule Zion 1991 only - Mar 10 0:00 1:00 D +#Rule Zion 1991 only - Sep 1 0:00 0 S + +# From Ephraim Silverberg (September 5, 1993): +# +# According to the Office of the Secretary General of the Ministry of +# Interior, there is NO set rule for Daylight-Savings/Standard time changes. +# Each year they decide anew what havoc to wreak on the country. However, +# there is a "supposed" set of rules which is subject to change depending +# on the party the Minister of Interior, the size of the coalition +# government, the phase of the moon and the direction of the wind. Hence, +# changes may need to be made on a semi-annual basis. One thing is entrenched +# in law, however: that there must be at least 150 days on daylight savings +# time annually. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Zion 1989 only - Apr 30 0:00 1:00 D +Rule Zion 1989 only - Sep 3 0:00 0:00 S +Rule Zion 1990 only - Mar 25 0:00 1:00 D +Rule Zion 1990 only - Aug 26 0:00 0:00 S +Rule Zion 1991 only - Mar 24 0:00 1:00 D +Rule Zion 1991 only - Sep 1 0:00 0:00 S +Rule Zion 1992 only - Mar 29 0:00 1:00 D +Rule Zion 1992 only - Sep 6 0:00 0:00 S +Rule Zion 1993 only - Apr 2 0:00 1:00 D +Rule Zion 1993 only - Sep 5 0:00 0:00 S + +# The dates for 1994-1995 were obtained from Office of the Spokeswoman for +# the Ministry of Interior, Jerusalem. There are no dates yet for 1996 and +# beyond so your guess is as good as theirs (those who are interested can +# call 972-2-701411 and ask for the spokeswoman). + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Zion 1994 only - Apr 1 0:00 1:00 D +Rule Zion 1994 only - Aug 28 0:00 0:00 S +Rule Zion 1995 only - Mar 31 0:00 1:00 D +Rule Zion 1995 only - Aug 27 0:00 0:00 S + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tel_Aviv 2:19:04 - LMT 1880 + 2:21 - JMT 1918 + 2:00 Zion I%sT + + +############################################################################### + +# Japan + +# `9:00' and `JST' is from Guy Harris. + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks says that the far southern Ryukyu Is (Nansei-Shoto) are 8:00, +# but we don't have a good location name for them; +# we don't even know the name of the principal town. +# There is no information for Marcus. +# Other Japanese possessions are probably like Asia/Tokyo. + +# From Shanks (1991): +# Japan switched from the Japanese calendar on 1893 Jan 1. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tokyo 9:19:04 - LMT 1896 + 9:00 - JST +#Zone Asia/South_Ryukyu 8:14:44 - LMT 1896 # Amitori +# 8:00 - CST + +# Jordan +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Most likely Shanks is merely guessing dates from 1992 on. +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Jordan 1931 only - Jan 1 0:00 0 - +Rule Jordan 1973 only - Jun 6 0:00 1:00 " DST" +Rule Jordan 1973 1975 - Oct 1 0:00 0 - +Rule Jordan 1974 1977 - May 1 0:00 1:00 " DST" +Rule Jordan 1976 only - Nov 1 0:00 0 - +Rule Jordan 1977 only - Oct 1 0:00 0 - +Rule Jordan 1978 only - Apr 30 0:00 1:00 " DST" +Rule Jordan 1978 only - Sep 30 0:00 0 - +Rule Jordan 1985 only - Apr 1 0:00 1:00 " DST" +Rule Jordan 1985 only - Oct 1 0:00 0 - +Rule Jordan 1986 1988 - Apr Fri>=1 0:00 1:00 " DST" +Rule Jordan 1986 1990 - Oct Fri>=1 0:00 0 - +Rule Jordan 1989 only - May 8 0:00 1:00 " DST" +Rule Jordan 1990 only - Apr 27 0:00 1:00 " DST" +Rule Jordan 1991 only - Apr 19 0:00 1:00 " DST" +Rule Jordan 1991 only - Sep 27 0:00 0 - +Rule Jordan 1992 max - Apr Fri>=1 0:00 1:00 " DST" +Rule Jordan 1992 max - Oct Fri>=1 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Amman 2:23:44 - LMT 1931 + 2:00 Jordan EET%s + +# Kazakhstan +# From Shanks (1991): +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Alma-Ata 5:07:48 - LMT 1924 May 2 + 5:00 - TSK 1957 Mar + 6:00 Russia TS%s + +# Kirgizstan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2 + 5:00 - TSK 1957 Mar + 6:00 Russia TS%s + +############################################################################### + +# Korea + +# From Guy Harris: +# According to someone at the Korean Times in San Francisco, +# Daylight Savings Time was not observed until 1987. He did not know +# at what time of day DST starts or ends. + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule ROK 1960 only - May 15 0:00 1:00 D +Rule ROK 1960 only - Sep 13 0:00 0 S +Rule ROK 1987 1988 - May Sun<=14 0:00 1:00 D +Rule ROK 1987 1988 - Oct Sun<=14 0:00 0 S + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Seoul 8:27:52 - LMT 1890 + 8:30 - KST 1904 Dec + 9:00 - KST 1928 + 8:30 - KST 1932 + 9:00 - KST 1954 Mar 21 + 8:00 ROK K%sT 1961 Aug 10 + 8:30 - KST 1968 Oct + 9:00 ROK K%sT +Zone Asia/Pyongyang 8:23:00 - LMT 1890 + 8:30 - KST 1904 Dec + 9:00 - KST 1928 + 8:30 - KST 1932 + 9:00 - KST 1954 Mar 21 + 8:00 - KST 1961 Aug 10 + 9:00 - KST + +############################################################################### + +# Kuwait +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Kuwait 3:11:56 - LMT 1950 + 3:00 - AST + +# Laos +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Vientiane 6:50:24 - LMT 1906 Jun 9 + 7:06 - SMT 1911 Mar 11 0:01 # Saigon MT + 7:00 - ICT 1912 May + 8:00 - ICT 1931 May + 7:00 - ICT + +# Lebanon +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Lebanon 1880 only - Jan 1 0:00 0 - +Rule Lebanon 1920 only - Mar 28 0:00 1:00 " DST" +Rule Lebanon 1920 only - Oct 25 0:00 0 - +Rule Lebanon 1921 only - Apr 3 0:00 1:00 " DST" +Rule Lebanon 1921 only - Oct 3 0:00 0 - +Rule Lebanon 1922 only - Mar 26 0:00 1:00 " DST" +Rule Lebanon 1922 only - Oct 8 0:00 0 - +Rule Lebanon 1923 only - Apr 22 0:00 1:00 " DST" +Rule Lebanon 1923 only - Sep 16 0:00 0 - +Rule Lebanon 1957 1961 - May 1 0:00 1:00 " DST" +Rule Lebanon 1957 1961 - Oct 1 0:00 0 - +Rule Lebanon 1972 only - Jun 22 0:00 1:00 " DST" +Rule Lebanon 1972 1977 - Oct 1 0:00 0 - +Rule Lebanon 1973 1977 - May 1 0:00 1:00 " DST" +Rule Lebanon 1978 only - Apr 30 0:00 1:00 " DST" +Rule Lebanon 1978 only - Sep 30 0:00 0 - +Rule Lebanon 1984 1987 - May 1 0:00 1:00 " DST" +Rule Lebanon 1984 max - Oct 16 0:00 0 - +Rule Lebanon 1988 only - Jun 1 0:00 1:00 " DST" +Rule Lebanon 1989 only - May 10 0:00 1:00 " DST" +Rule Lebanon 1990 max - May 1 0:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Beirut 2:22:00 - LMT 1880 + 2:00 Lebanon EET%s + +# Malaysia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Kuala_Lumpur 6:46:48 - LMT 1880 + 6:55 - SMT 1905 Jun + 7:00 - SGT 1933 + 7:20 - SGT 1942 Feb 15 + 9:00 - JST 1945 Sep 2 + 7:20 - SGT 1950 + 7:30 - SGT 1982 May + 8:00 - SGT + +# Maldives +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Maldives 4:54:00 - LMT 1880 # Male + 4:54 - MMT 1960 + 5:00 - PKT + +# Mongolia +# Let's comment out the western and eastern Mongolian time zones +# till we know what their principal towns are. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Mongol 1978 only - Jan 1 0:00 0 S +Rule Mongol 1981 1984 - Apr 1 0:00 1:00 T +Rule Mongol 1981 1984 - Oct 1 0:00 0 S +Rule Mongol 1985 max - Mar lastSun 2:00 1:00 T +Rule Mongol 1985 max - Sep lastSun 3:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +#Zone Asia/Dariv 6:14:32 - LMT 1905 Aug +# 6:00 - DST 1978 +# 7:00 Mongol D%sT +Zone Asia/Ulan_Bator 7:07:32 - LMT 1905 Aug + 7:00 - UST 1978 + 8:00 Mongol U%sT +#Zone Asia/Baruun-Urt 7:33:00 - LMT 1905 Aug +# 8:00 - BST 1978 +# 9:00 Mongol B%sT + +# Nepal +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Katmandu 5:41:16 - LMT 1920 + 5:30 - IST 1986 + 5:45 - NPT + +# Oman +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Muscat 3:54:20 - LMT 1920 + 4:00 - GST + +# Pakistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Karachi 4:28:12 - LMT 1907 + 5:30 - IST 1942 Sep + 5:30 1:00 IST 1945 Oct 15 + 5:30 - IST 1951 Sep 30 + 5:00 - PKT + +# Palestine +# These rules for Egypt are stolen from the `africa' file. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Egypt 1957 only - May 10 0:00 1:00 " DST" +Rule Egypt 1957 1958 - Oct 1 0:00 0 - +Rule Egypt 1958 only - May 1 0:00 1:00 " DST" +Rule Egypt 1959 1981 - May 1 1:00 1:00 " DST" +Rule Egypt 1959 1965 - Sep 30 3:00 0 - +Rule Egypt 1966 max - Oct 1 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Gaza 2:17:52 - LMT 1900 Oct + 2:00 - EET 1957 May 10 + 2:00 Egypt EET%s 1967 Jun 30 + 2:00 Zion I%sT +# This will undoubtedly change soon. + +# Philippines +# Howse writes (p 162) that until 1844 the Philippines kept American date. +# The rest of this data is from Shanks. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Phil 1899 only - May 11 0:00 0 S +Rule Phil 1936 only - Nov 1 0:00 1:00 D +Rule Phil 1937 only - Feb 1 0:00 0 S +Rule Phil 1954 only - Apr 12 0:00 1:00 D +Rule Phil 1954 only - Jul 1 0:00 0 S +Rule Phil 1978 only - Mar 22 0:00 1:00 D +Rule Phil 1978 only - Sep 21 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Manila -15:56:00 - LMT 1844 + 8:04:00 - LMT 1899 May 11 + 8:00 Phil P%sT 1942 May + 9:00 - JST 1944 Nov + 8:00 Phil P%sT + +# Qatar +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah + 4:00 - GST 1972 Jun + 3:00 - AST + +# Saudi Arabia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Riyadh 3:06:52 - LMT 1950 + 3:00 - AST + +# Singapore +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Singapore 6:55:24 - LMT 1880 + 6:55 - SMT 1905 Jun + 7:00 - SGT 1933 + 7:20 - SGT 1942 Feb 15 + 9:00 - JST 1945 Sep 2 + 7:20 - SGT 1950 + 7:30 - SGT 1982 May + 8:00 - SGT + +# Sri Lanka +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Colombo 5:19:24 - LMT 1880 + 5:20 - JMT 1906 + 5:30 - IST 1942 Jan 5 + 5:30 0:30 IHST 1942 Sep + 5:30 1:00 IST 1945 Oct 16 2:00 + 5:30 - IST + +# Syria +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Syria 1920 only - Jan 1 0:00 0 - +Rule Syria 1920 1923 - Apr Sun>=15 2:00 1:00 " DST" +Rule Syria 1920 1923 - Oct Sun>=1 2:00 0 - +Rule Syria 1962 only - Apr 29 2:00 1:00 " DST" +Rule Syria 1962 only - Oct 1 2:00 0 - +Rule Syria 1963 1965 - May 1 2:00 1:00 " DST" +Rule Syria 1963 only - Sep 30 2:00 0 - +Rule Syria 1964 only - Oct 1 2:00 0 - +Rule Syria 1965 only - Sep 30 2:00 0 - +Rule Syria 1966 only - Apr 24 2:00 1:00 " DST" +Rule Syria 1966 1976 - Oct 1 2:00 0 - +Rule Syria 1967 1978 - May 1 2:00 1:00 " DST" +Rule Syria 1977 1978 - Sep 1 2:00 0 - +Rule Syria 1983 1984 - Apr 9 2:00 1:00 " DST" +Rule Syria 1983 1984 - Oct 1 2:00 0 - +Rule Syria 1986 only - Feb 16 2:00 1:00 " DST" +Rule Syria 1986 only - Oct 9 2:00 0 - +Rule Syria 1987 only - Mar 1 2:00 1:00 " DST" +Rule Syria 1987 1988 - Oct 31 2:00 0 - +Rule Syria 1988 only - Mar 15 2:00 1:00 " DST" +Rule Syria 1989 only - Mar 31 2:00 1:00 " DST" +Rule Syria 1989 only - Oct 1 2:00 0 - +Rule Syria 1990 max - Apr 1 2:00 1:00 " DST" +Rule Syria 1990 max - Sep 30 2:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Damascus 2:25:12 - LMT 1920 + 2:00 Syria EET%s + +# Tajikistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2 + 5:00 - TSK 1957 Mar + 6:00 Russia TS%s + +# Thailand +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Bangkok 6:42:04 - LMT 1880 + 6:42 - BMT 1920 Apr + 7:00 - ICT + +# Turkmenistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Ashkhabad 3:53:32 - LMT 1924 May 2 + 4:00 - ASK 1957 Mar + 5:00 Russia AS%s + +# United Arab Emirates +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Dubai 3:41:12 - LMT 1920 + 4:00 - GST + +# Uzbekistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tashkent 4:37:12 - LMT 1924 May 2 + 5:00 - TSK 1957 Mar + 6:00 Russia TS%s + +# Vietnam +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Saigon's official name is Thanh-Pho Ho Chi Minh, but it's too long. +# We'll stick with the traditional name for now. +# From Shanks (1991): +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Saigon 7:06:40 - LMT 1906 Jun 9 + 7:06 - SMT 1911 Mar 11 0:01 # Saigon MT + 7:00 - ICT 1912 May + 8:00 - ICT 1931 May + 7:00 - ICT + +# Yemen +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Aden 3:00:48 - LMT 1950 + 3:00 - AST diff --git a/time/australasia b/time/australasia new file mode 100644 index 000000000..f9cde459e --- /dev/null +++ b/time/australasia @@ -0,0 +1,783 @@ +# @(#)australasia 7.21 +# This file also includes Pacific islands. + +# Notes are at the end of this file + +############################################################################### + +# Australia + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Aus 1895 only - Jan 1 0:00 0 - +# Shanks gives 1917 Jan 1 0:01; go with Whitman (and guess 2:00). +Rule Aus 1916 only - Oct 1 2:00 1:00 - +Rule Aus 1917 only - Mar 25 2:00 0 - +Rule Aus 1942 only - Jan 1 2:00 1:00 - +Rule Aus 1942 only - Mar 29 2:00 0 - +Rule Aus 1942 only - Sep 27 2:00 1:00 - +Rule Aus 1943 1944 - Mar lastSun 2:00 0 - +Rule Aus 1943 only - Oct 3 2:00 1:00 - +# Whitman says W Australia didn't use DST in 1943/1944, and that +# 1944/1945 was just like 1943/1944; go with Shanks. + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +# Northern Territory +Zone Australia/Darwin 8:43:20 - LMT 1895 Feb + 9:30 - CST 1917 Jan 1 0:01 + 9:30 Aus CST +# Western Australia +Zone Australia/Perth 7:43:24 - LMT 1895 Dec + 8:00 - WST 1917 Jan 1 0:01 + 8:00 Aus WST 1974 Oct lastSun 2:00 + 8:00 1:00 WST 1975 Mar Sun>=1 3:00 + 8:00 - WST 1983 Oct lastSun 2:00 + 8:00 1:00 WST 1984 Mar Sun>=1 3:00 + 8:00 - WST 1991 Nov 17 2:00 + 8:00 1:00 WST 1992 Mar Sun>=1 3:00 + 8:00 - WST +# Queensland +Zone Australia/Brisbane 10:12:08 - LMT 1895 + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1971 Oct lastSun 2:00 + 10:00 1:00 EST 1972 Feb lastSun 3:00 + 10:00 - EST 1989 Oct lastSun 2:00 + 10:00 1:00 EST 1990 Mar Sun>=1 3:00 + 10:00 - EST 1990 Oct lastSun 2:00 + 10:00 1:00 EST 1991 Mar Sun>=1 3:00 + 10:00 - EST 1991 Oct lastSun 2:00 + 10:00 1:00 EST 1992 Mar Sun>=1 3:00 + 10:00 - EST + +# South Australia +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule AS 1971 1985 - Oct lastSun 2:00 1:00 - +Rule AS 1986 only - Oct 19 2:00 1:00 - +Rule AS 1987 max - Oct lastSun 2:00 1:00 - +Rule AS 1972 only - Feb 27 3:00 0 - +Rule AS 1973 1985 - Mar Sun>=1 3:00 0 - +Rule AS 1986 1989 - Mar Sun>=15 3:00 0 - +Rule AS 1990 1994 even Mar Sun>=18 3:00 0 - +Rule AS 1990 1994 odd Mar Sun>=1 3:00 0 - +Rule AS 1995 max - Mar lastSun 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Adelaide 9:14:20 - LMT 1895 Feb + 9:00 - CST 1899 May + 9:30 - CST 1917 Jan 1 0:01 + 9:30 Aus CST 1971 Oct lastSun 2:00 + 9:30 AS CST + +# Tasmania +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule AT 1967 only - Oct 1 2:00 1:00 - +Rule AT 1968 only - Mar 31 3:00 0 - +Rule AT 1968 1985 - Oct lastSun 2:00 1:00 - +Rule AT 1969 1971 - Mar Sun>=8 3:00 0 - +Rule AT 1972 only - Feb 27 3:00 0 - +Rule AT 1973 1981 - Mar Sun>=1 3:00 0 - +Rule AT 1982 1983 - Mar lastSun 3:00 0 - +Rule AT 1984 1986 - Mar Sun>=1 3:00 0 - +Rule AT 1986 only - Oct 19 2:00 1:00 - +Rule AT 1987 1990 - Mar Sun>=15 3:00 0 - +Rule AT 1987 1990 - Oct lastSun 2:00 1:00 - +Rule AT 1991 max - Oct Sun>=1 2:00 1:00 - +Rule AT 1991 max - Mar lastSun 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Hobart 9:49:16 - LMT 1895 Sep + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1967 Oct 1 2:00 + 10:00 AT EST + +# Victoria +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule AV 1971 1985 - Oct lastSun 2:00 1:00 - +Rule AV 1972 only - Feb 27 3:00 0 - +Rule AV 1973 1985 - Mar Sun>=1 3:00 0 - +Rule AV 1986 1990 - Mar Sun>=15 3:00 0 - +Rule AV 1986 only - Oct 19 2:00 1:00 - +Rule AV 1987 max - Oct lastSun 2:00 1:00 - +Rule AV 1991 1994 - Mar Sun>=1 3:00 0 - +Rule AV 1995 max - Mar lastSun 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Melbourne 9:39:52 - LMT 1895 Feb + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1971 Oct 31 2:00 + 10:00 AV EST + +# New South Wales +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule AN 1971 1985 - Oct lastSun 2:00 1:00 - +Rule AN 1972 only - Feb 27 3:00 0 - +Rule AN 1973 1985 - Mar Sun>=1 3:00 0 - +Rule AN 1986 1989 - Mar Sun>=15 3:00 0 - +Rule AN 1986 only - Oct 19 2:00 1:00 - +Rule AN 1987 max - Oct lastSun 2:00 1:00 - +Rule AN 1990 max - Mar Sun>=1 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Sydney 10:04:52 - LMT 1895 Feb + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1971 Oct 31 2:00 + 10:00 AN EST +Zone Australia/Broken_Hill 9:25:48 - LMT 1895 Feb + 10:00 - EST 1896 Aug 23 + 9:00 - CST 1899 May + 9:30 - CST 1917 Jan 1 0:01 + 9:30 Aus CST 1971 Oct 31 2:00 + 9:30 AN CST + +# Australian Capital Territory +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Canberra 9:56:32 - LMT 1895 Feb + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1971 Oct 31 2:00 + 10:00 AN EST 1981 Oct 25 2:00 + 10:00 1:00 EST 1982 Apr 4 3:00 + 10:00 AN EST + +# Australian miscellany +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Lord_Howe 10:36:20 - LMT 1895 Feb + 10:00 - EST 1981 Mar + 10:30 AN LHST +Zone Indian/Christmas 7:02:52 - LMT 1895 Feb + 7:00 - JVT +# +# Ashmore Is, Cartier +# no information; probably like Australia/Perth +# +# Macquarie, Manihiki, Penrhyn, Rakehanga +# no information + + +# Cook Is +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Cook 1978 only - Nov 12 0:00 0:30 HD +Rule Cook 1979 max - Mar Sun>=1 0:00 0 H +Rule Cook 1979 max - Oct lastSun 0:00 0:30 HD +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Rarotonga -10:39:04 - LMT 1901 # Avarua + -10:30 - CIST 1978 Nov 12 # Cook Is ST + -10:00 Cook T%sT + +# Cocos +# From USNO (1989): +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Cocos 6:30 - CCT + +# Fiji +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Fiji 11:53:40 - LMT 1915 Oct 26 # Suva + 12:00 - NZST + +# French Polynesia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Gambier -8:59:48 - LMT 1912 Oct # Rikitea + -9:00 - GBT +Zone Pacific/Marquesas -9:18:00 - LMT 1912 Oct + -9:30 - MQT +Zone Pacific/Tahiti -9:58:16 - LMT 1912 Oct # Papeete + -10:00 - THT + +# Guam +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Guam 9:39:00 - LMT 1901 # Agana + 10:00 - GST + +# Howland, Baker +# no information; probably like Pacific/Samoa + +# Jarvis +# no information; probably like Pacific/Kiritimati + +# Johnston +# no information; probably like Pacific/Honolulu + +# Kiribati +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Tarawa 11:32:04 - LMT 1901 # Bairiki + 12:00 - NZST +Zone Pacific/Enderbury -11:24:20 - LMT 1901 + -12:00 - KJT 1979 Oct + -11:00 - SST +Zone Pacific/Kiritimati -10:29:20 - LMT 1901 + -10:40 - LIT 1979 Oct # Line Is Time + -10:00 - THT + +# Nauru +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Nauru 11:07:40 - LMT 1921 Jan 15 # Uaobe + 11:30 - NST 1942 Mar 15 + 9:00 - JST 1944 Aug 15 + 11:30 - NST 1979 May + 12:00 - NZST + +# New Caledonia +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule NC 1912 only - Jan 13 0:00 0 S +Rule NC 1977 1978 - Dec Sun>=1 0:00 1:00 D +Rule NC 1978 1979 - Feb 27 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Noumea 11:05:48 - LMT 1912 Jan 13 + 11:00 NC NC%sT + + +############################################################################### + +# New Zealand + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule NZ 1868 only - Jan 1 0:00 0 S +# Shanks gives 1927 Nov 6 - 1928 Mar 4, 1928 Oct 14 - 1929 Mar 17, +# 1929 Oct 13 - 1930 Mar 16; go with Whitman. +Rule NZ 1927 only - Nov 26 2:00 1:00 D +Rule NZ 1928 1929 - Mar Sun>=1 2:00 0 S +Rule NZ 1928 only - Nov 4 2:00 1:00 D +Rule NZ 1929 only - Oct 30 2:00 1:00 D +Rule NZ 1930 1933 - Mar Sun>=15 2:00 0 S +Rule NZ 1930 1933 - Oct Sun>=8 2:00 1:00 D +# Shanks says DST stopped 1940 Sep lastSun; go with Whitman for war years. +Rule NZ 1934 1944 - Apr lastSun 2:00 0 S +Rule NZ 1934 1944 - Sep lastSun 2:00 1:00 D +Rule NZ 1974 only - Nov 3 2:00s 1:00 D +Rule NZ 1975 1988 - Oct lastSun 2:00s 1:00 D +Rule NZ 1989 only - Oct 8 2:00s 1:00 D +Rule NZ 1990 max - Oct Sun>=1 2:00s 1:00 D +Rule NZ 1975 only - Feb 23 2:00s 0 S +Rule NZ 1976 1989 - Mar Sun>=1 2:00s 0 S +Rule NZ 1990 max - Mar Sun>=15 2:00s 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Auckland 11:39:04 - LMT 1868 + # Shanks gives 1940 Sep 29 2:00; + # go with Whitman. + 11:30 NZ NZ%sT 1945 Apr 29 2:00 + 12:00 NZ NZ%sT +Zone Pacific/Chatham 12:45 - NZ-CHAT + + +# Antipodes Is, Kermadec Is +# no information; probably like Pacific/Auckland + +############################################################################### + + +# Niue +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Niue -11:19:40 - LMT 1901 # Alofi + -11:20 - NIT 1951 # Niue I Time + -11:30 - NIT 1978 Oct 1 + -11:00 - SST + +# Norfolk +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Norfolk 11:11:52 - LMT 1901 # Kingston + 11:12 - NMT 1951 + 11:30 - NRFT + +# Pacific Islands Trust Territories +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Majuro 11:24:48 - LMT 1901 + 11:00 - NCST 1969 Oct + 12:00 - NZST +Zone Pacific/Kwajalein 11:09:20 - LMT 1901 + 11:00 - NCST 1969 Oct + -12:00 - KJT 1993 Aug 20 + 12:00 - NZST +Zone Pacific/Truk 10:07:08 - LMT 1901 + 10:00 - GST 1978 Oct + 11:00 - NCST +Zone Pacific/Ponape 10:33:00 - LMT 1901 + 11:00 - NCST +Zone Pacific/Yap 9:12:24 - LMT 1901 + 9:00 - PLT 1969 Oct + 10:00 - GST + +# Palau +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Palau 8:57:56 - LMT 1901 # Koror + 9:00 - PLT + +# Palmyra +# no information; probably like Pacific/Kiritmati + +# Papua New Guinea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 + 9:49 - PMMT 1895 + 10:00 - EST + +# Pitcairn +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Pitcairn -8:40:20 - LMT 1901 # Adamstown + -8:30 - PIT + +# Solomon Is +# excludes Bougainville, for which see Papua New Guinea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct # Honiara + 11:00 - NCST + +# Tokelau Is +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Fakaofo -11:24:56 - LMT 1901 + -10:00 - THT + +# Tonga +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Tongatapu 12:19:20 - LMT 1901 + 12:20 - TMT 1968 Oct + 13:00 - TGT + +# Tuvalu +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Funafuti 11:56:52 - LMT 1901 + 12:00 - NZST + +# Vanuatu +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Vanuatu 1912 only - Jan 13 0:00 0 S +Rule Vanuatu 1983 only - Sep 25 0:00 1:00 D +Rule Vanuatu 1984 max - Mar Sun>=23 0:00 0 S +Rule Vanuatu 1984 only - Oct 23 0:00 1:00 D +Rule Vanuatu 1985 max - Sep Sun>=23 0:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila + 11:00 - NCST + +# Wake +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Wake 11:06:28 - LMT 1901 + 12:00 - NZST + +# Wallis and Futuna +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Wallis 12:15:20 - LMT 1901 + 12:00 - NZST + +# Western Samoa +# See Pacific/Samoa in the `northamerica' file, of all places. + +############################################################################### + +# NOTES + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (August 18, 1994): +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where noted, it is the source for the data above. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# A reliable and entertaining source about time zones is +# Derek Howse, Greenwich time and the discovery of the longitude, +# Oxford University Press (1980). +# +# I invented the abbreviations marked `*' in the following table; +# the rest are from earlier versions of this file, or from other sources. +# Corrections are welcome! +# std dst +# LMT Local Mean Time +# 6:30 CCT Cocos* +# 7:00 JVT Java* +# 8:00 WST WST Western Australia +# 9:00 JST Japan +# 9:00 PLT Palau* +# 9:30 CST CST Central Australia +# 10:00 EST EST Eastern Australia +# 10:00 GST Guam* +# 10:30 LHST LHST Lord Howe* +# 11:00 NCST NCDT New Caledonia* +# 11:30 NRFT Norfolk* +# 12:00 NZST NZDT New Zealand +# 12:45 NZ-CHAT Chatham +# 13:00 TGT Tongatapu* +# -12:00 KJT Kwajalein (no longer used)* +# -11:00 SST Samoa +# -10:40 LIT Line Is (no longer used)* +# -10:00 THT Tahiti* +# - 9:30 MQT Marquesas* +# - 9:00 GBT Gambier* +# - 8:30 PIT Pitcairn* +# +# See the `northamerica' file for Hawaii and Samoa. +# See the `southamerica' file for Easter I and the Galapagos Is. +# +# See the `africa' file for Zone naming conventions. + +############################################################################### + +# Australia + +# From John Mackin (March 6, 1991): +# We in Australia have _never_ referred to DST as `daylight' time. +# It is called `summer' time. Now by a happy coincidence, `summer' +# and `standard' happen to start with the same letter; hence, the +# abbreviation does _not_ change... +# The legislation does not actually define abbreviations, at least +# in this State, but the abbreviation is just commonly taken to be the +# initials of the phrase, and the legislation here uniformly uses +# the phrase `summer time' and does not use the phrase `daylight +# time'. +# Announcers on the Commonwealth radio network, the ABC (for Australian +# Broadcasting Commission), use the phrases `Eastern Standard Time' +# or `Eastern Summer Time'. (Note, though, that as I say in the +# current australasia file, there is really no such thing.) Announcers +# on its overseas service, Radio Australia, use the same phrases +# prefixed by the word `Australian' when referring to local times; +# time announcements on that service, naturally enough, are made in UTC. + +# From Arthur David Olson (March 8 1992): +# Given the above, what's chosen for year-round use is: +# CST for any place operating at a GMTOFF of 9:30 +# WST for any place operating at a GMTOFF of 8:00 +# EST for any place operating at a GMTOFF of 10:00 + +# From Paul Eggert (November 8, 1994): +# Shanks reports 2:00 for all autumn changes in Australia and New Zealand. +# Mark Prior <mrp@itd.adelaide.edu.au> writes that his newspaper +# reports that NSW's fall 1995 change will occur at 2:00, +# but Robert Elz says it's been 3:00 in Victoria since 1970 +# and perhaps the newspaper's `2:00' is referring to standard time. +# And Robert Uzgalis <buz@cs.aukuni.ac.nz> says that the New Zealand Daylight +# Savings Time Order in Council dated 1990-06-18 specifies 2:00 standard +# time on both the first Sunday in October and the third Sunday in March. +# For now we'll continue to assume 3:00 for changes since 1970. + +# Northern Territory + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The NORTHERN TERRITORY.. [ Courtesy N.T. Dept of the Chief Minister ] +# # [ Nov 1990 ] +# # N.T. have never utilised any DST due to sub-tropical/tropical location. +# ... +# Zone Australia/North 9:30 - CST + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# the Northern Territory do[es] not have daylight saving. + +# Western Australia + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of WESTERN AUSTRALIA.. [ Courtesy W.A. dept Premier+Cabinet ] +# # [ Nov 1990 ] +# # W.A. suffers from a great deal of public and political opposition to +# # DST in principle. A bill is brought before parliament in most years, but +# # usually defeated either in the upper house, or in party caucus +# # before reaching parliament. +# ... +# Zone Australia/West 8:00 AW %sST +# ... +# Rule AW 1974 only - Oct lastSun 2:00 1:00 D +# Rule AW 1975 only - Mar Sun>=1 3:00 0 W +# Rule AW 1983 only - Oct lastSun 2:00 1:00 D +# Rule AW 1984 only - Mar Sun>=1 3:00 0 W + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# Western Australia...do[es] not have daylight saving. + +# From John D. Newman via Bradley White (November 2, 1991): +# Western Australia is still on "winter time". Some DH in Sydney +# rang me at home a few days ago at 6.00am. (He had just arrived at +# work at 9.00am.) +# W.A. is switching to Summer Time on Nov 17th just to confuse +# everybody again. + +# From Arthur David Olson (March 8, 1992): +# The 1992 ending date used in the rules is a best guess; +# it matches what was used in the past. + +# Queensland +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of QUEENSLAND.. [ Courtesy Qld. Dept Premier Econ&Trade Devel ] +# # [ Dec 1990 ] +# ... +# Zone Australia/Queensland 10:00 AQ %sST +# ... +# Rule AQ 1971 only - Oct lastSun 2:00 1:00 D +# Rule AQ 1972 only - Feb lastSun 3:00 0 E +# Rule AQ 1989 max - Oct lastSun 2:00 1:00 D +# Rule AQ 1990 max - Mar Sun>=1 3:00 0 E + +# From Bradley White (December 24, 1989): +# "Australia/Queensland" now observes daylight time (i.e. from +# October 1989). + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# ...Queensland...[has] agreed to end daylight saving +# at 3am tomorrow (March 3)... + +# From John Mackin (March 6, 1991): +# I can certainly confirm for my part that Daylight Saving in NSW did in fact +# end on Sunday, 3 March. I don't know at what hour, though. (It surprised +# me.) + +# From Bradley White (March 8, 1992): +# ...there was recently a referendum in Queensland which resulted +# in the experimental daylight saving system being abandoned. So, ... +# ... +# Rule QLD 1989 1991 - Oct lastSun 2:00 1:00 D +# Rule QLD 1990 1992 - Mar Sun>=1 3:00 0 S +# ... + +# From Arthur David Olson (March 8, 1992): +# The chosen rules the union of the 1971/1972 change and the 1989-1992 changes. + +# South Australia, Tasmania, Victoria + +# From Arthur David Olson (March 8, 1992): +# The rules from version 7.1 follow. +# There are lots of differences between these rules and +# the Shepherd et al. rules. Since the Shepherd et al. rules +# and Bradley White's newspaper article are in agreement on +# current DST ending dates, no worries. +# +# Rule Oz 1971 1985 - Oct lastSun 2:00 1:00 - +# Rule Oz 1986 max - Oct Sun<=24 2:00 1:00 - +# Rule Oz 1972 only - Feb 27 3:00 0 - +# Rule Oz 1973 1986 - Mar Sun>=1 3:00 0 - +# Rule Oz 1987 max - Mar Sun<=21 3:00 0 - +# Zone Australia/Tasmania 10:00 Oz EST +# Zone Australia/South 9:30 Oz CST +# Zone Australia/Victoria 10:00 Oz EST 1985 Oct lastSun 2:00 +# 10:00 1:00 EST 1986 Mar Sun<=21 3:00 +# 10:00 Oz EST + +# From Robert Elz (March 6, 1991): +# I believe that the current start date for DST is "lastSun" in Oct... +# that changed Oct 89. That is, we're back to the +# original rule, and that rule currently applies in all the states +# that have dst, incl Qld. (Certainly it was true in Vic). +# The file I'm including says that happened in 1988, I think +# that's incorrect, but I'm not 100% certain. + +# South Australia + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# ...South Australia...[has] agreed to end daylight saving +# at 3am tomorrow (March 3)... + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of SOUTH AUSTRALIA....[ Courtesy of S.A. Dept of Labour ] +# # [ Nov 1990 ] +# ... +# Zone Australia/South 9:30 AS %sST +# ... +# Rule AS 1971 max - Oct lastSun 2:00 1:00 D +# Rule AS 1972 1985 - Mar Sun>=1 3:00 0 C +# Rule AS 1986 1990 - Mar Sun<=21 3:00 0 C +# Rule AS 1991 max - Mar Sun>=1 3:00 0 C + +# From Bradley White (March 11, 1992): +# Recent correspondence with a friend in Adelaide +# contained the following exchange: "Due to the Adelaide Festival, +# South Australia delays setting back our clocks for a few weeks." + +# From Robert Elz (March 13, 1992): +# I heard that apparently (or at least, it appears that) +# South Aus will have an extra 3 weeks daylight saving every even +# numbered year (from 1990). That's when the Adelaide Festival +# is on... + +# From Robert Elz (March 16, 1992, 00:57:07 +1000): +# DST didn't end in Adelaide today (yesterday).... +# But whether it's "4th Sunday" or "2nd last Sunday" I have no idea whatever... +# (it's just as likely to be "the Sunday we pick for this year"...). + +# From Bradley White (April 11, 1994): +# If Sun, 15 March, 1992 was at +1030 as kre asserts, but yet Sun, 20 March, +# 1994 was at +0930 as John Connolly's customer seems to assert, then I can +# only conclude that the actual rule is more complicated.... + +# From John Warburton <jwarb@SACBH.com.au> (1994-10-07): +# The new Daylight Savings dates for South Australia ... +# was gazetted in the Government Hansard on Sep 26 1994.... +# start on last Sunday in October and end in last sunday in March. + +# Tasmania + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# ...Tasmania will revert to Australian Eastern Standard Time on March 31... + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of TASMANIA.. [Courtesy Tasmanian Dept of Premier + Cabinet ] +# # [ Nov 1990 ] +# ... +# Zone Australia/Tasmania 10:00 AT %sST +# ... +# Rule AT 1967 only - Oct Sun>=1 2:00 1:00 D +# Rule AT 1968 only - Mar lastSun 3:00 0 E +# Rule AT 1968 1985 - Oct lastSun 2:00 1:00 D +# Rule AT 1969 1971 - Mar Sun>=8 3:00 0 E +# Rule AT 1972 only - Feb lastSun 3:00 0 E +# Rule AT 1973 1981 - Mar Sun>=1 3:00 0 E +# Rule AT 1982 1983 - Mar lastSun 3:00 0 E +# Rule AT 1984 1986 - Mar Sun>=1 3:00 0 E +# Rule AT 1986 only - Oct Sun>=15 2:00 1:00 D +# Rule AT 1987 1990 - Mar Sun>=15 3:00 0 E +# Rule AT 1987 only - Oct Sun>=22 2:00 1:00 D +# Rule AT 1988 1990 - Oct lastSun 2:00 1:00 D +# Rule AT 1991 max - Oct Sun>=1 2:00 1:00 D +# Rule AT 1991 max - Mar lastSun 3:00 0 E + +# From Bill Hart via Alexander Dupuy and Guy Harris (October 10, 1991): +# My state Government in there eagerness to get a few more bucks for the +# tourist industry industry decided to change the daylight savings times +# yet again (we now have almost 6 months per year)... +# ... +# Rule Oz 1986 1990 - Oct Sun<=24 2:00 1:00 - +# Rule Oz 1991 max - Oct Sun>=1 2:00 1:00 - +# ... +# Rule Oz 1987 1990 - Mar Sun<=21 3:00 0 - +# Rule Oz 1991 max - Mar Sun<=31 3:00 0 - + +# From Bill Hart via Guy Harris (October 10, 1991): +# Oh yes, the new daylight savings rules are uniquely tasmanian, we have +# 6 weeks a year now when we are out of sync with the rest of Australia +# (but nothing new about that). + +# Victoria + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# ...Victoria...[has] agreed to end daylight saving at 3am tomorrow (March 3)... + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of VICTORIA.. [ Courtesy of Vic. Dept of Premier + Cabinet ] +# # [ Nov 1990 ] +# ... +# Zone Australia/Victoria 10:00 AV %sST +# ... +# Rule AV 1971 1985 - Oct lastSun 2:00 1:00 D +# Rule AV 1972 only - Feb lastSun 3:00 0 E +# Rule AV 1973 1985 - Mar Sun>=1 3:00 0 E +# Rule AV 1986 1990 - Mar Sun>=15 3:00 0 E +# Rule AV 1986 1987 - Oct Sun>=15 2:00 1:00 D +# Rule AV 1988 max - Oct lastSun 2:00 1:00 D +# Rule AV 1991 max - Mar Sun>=1 3:00 0 E + +# New South Wales + +# From Arthur David Olson: +# New South Wales and subjurisdictions have their own ideas of a fun time. +# Based on law library research by John Mackin (john@basser.cs.su.oz), +# who notes: +# In Australia, time is not legislated federally, but rather by the +# individual states. Thus, while such terms as ``Eastern Standard Time'' +# [I mean, of course, Australian EST, not any other kind] are in common +# use, _they have NO REAL MEANING_, as they are not defined in the +# legislation. This is very important to understand. +# I have researched New South Wales time only... + +# From Dave Davey (March 3, 1990): +# Rule NSW 1988 only - Mar Sun>=1 3:00 0 - +# Rule NSW 1989 only - Mar Sun<=21 3:00 0 - + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# NSW...[has] agreed to end daylight saving at 3am tomorrow (March 3)... + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of NEW SOUTH WALES.. [confirmed by Attorney General's Dept N.S.W] +# # [ Dec 1990 ] +# ... +# Rule AN 1988 1989 - Mar Sun<=21 3:00 0 E +# ... + +# From John Mackin (March 9, 1991) +# I have confirmed the accuracy of the historical data for NSW in the +# file Robert forwarded + +# From Arthur David Olson (March 8, 1992): +# Sources differ on whether DST ended March 6 or March 20 in 1988; +# March 20 (the "confirmed" date) is in the chosen rules. + +# Yancowinna + +# From John Basser (January 4, 1989): +# `Broken Hill' means the County of Yancowinna. + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # YANCOWINNA.. [ Confirmation courtesy of Broken Hill Postmaster ] +# # [ Dec 1990 ] +# ... +# # Yancowinna uses Central Standard Time, despite it's location on the +# # New South Wales side of the S.A. border. Most business and social dealings +# # are with CST zones, therefore CST is legislated by local government +# # although the switch to Summer Time occurs in line with N.S.W. There have +# # been years when this did not apply, but the historical data is not +# # presently available. +# Zone Australia/Yancowinna 9:30 AY %sST +# ... +# Rule AY 1971 1985 - Oct lastSun 2:00 1:00 D +# Rule AY 1972 only - Feb lastSun 3:00 0 C +# [followed by other Rules] + +# Lord Howe Island + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# LHI... [ Courtesy of Pauline Van Winsen.. pauline@Aus ] +# [ Dec 1990 ] +# Lord Howe Island is located off the New South Wales coast, and is half an +# hour ahead of NSW time. + +############################################################################### + +# New Zealand, from Elz' asia 1.1 +# Elz says "no guarantees" + +# From Mark Davies (October 3, 1990): +# the 1989/90 year was a trial of an extended "daylight saving" period. +# This trial was deemed successful and the extended period adopted for +# subsequent years (with the addition of a further week at the start). +# source -- phone call to Ministry of Internal Affairs Head Office. + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The Country of New Zealand (Australia's east island -) Gee they hate that! +# # or is Australia the west island of N.Z. +# # [ courtesy of Geoff Tribble.. Geofft@Aus.. Auckland N.Z. ] +# # [ Nov 1990 ] +# ... +# Rule NZ 1974 1988 - Oct lastSun 2:00 1:00 D +# Rule NZ 1989 max - Oct Sun>=1 2:00 1:00 D +# Rule NZ 1975 1989 - Mar Sun>=1 3:00 0 S +# Rule NZ 1990 max - Mar lastSun 3:00 0 S +# ... +# Zone NZ 12:00 NZ NZ%sT # New Zealand +# Zone NZ-CHAT 12:45 - NZ-CHAT # Chatham Island + +# From Arthur David Olson (March 8, 1992): +# The chosen rules use the Davies October 8 values for the start of DST in 1989 +# rather than the October 1 value. + +############################################################################### + +# Fiji + +# Howse writes (p 162) that in 1879 the British governor of Fiji +# enacted an ordinance standardizing the islands on +12:00. +# Perhaps it didn't take. We go with Shanks's more precise date in 1915. + +# Kwajalein + +# In comp.risks 14.87 (26 August 1993), Peter Neumann writes: +# I wonder what happened in Kwajalein, where there was NO Friday, +# August 20, 1993. Thursday night at midnight Kwajalein switched sides with +# respect to the International Date Line, to rejoin its fellow islands, +# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink. + +# Pacific Islands Trust Territories + +# Howse writes (p 162) ``The Spaniards, on the other hand, reached the +# Philippines and the Ladrones from America,'' and implies that the Ladrones +# (now called the Marianas) kept American date for quite some time. +# Ignore this for now, as we have no hard data. See also Asia/Manila. diff --git a/time/backward b/time/backward new file mode 100644 index 000000000..9298788b3 --- /dev/null +++ b/time/backward @@ -0,0 +1,75 @@ +# @(#)backward 7.6 + +# This file provides links between late-1993-vintage names for time zones +# and their previous names. + +Link Australia/Sydney Australia/ACT +Link Australia/Lord_Howe Australia/LHI +Link Australia/Sydney Australia/NSW +Link Australia/Darwin Australia/North +Link Australia/Brisbane Australia/Queensland +Link Australia/Adelaide Australia/South +Link Australia/Hobart Australia/Tasmania +Link Australia/Melbourne Australia/Victoria +Link Australia/Perth Australia/West +Link Australia/Broken_Hill Australia/Yancowinna +Link America/Porto_Acre Brazil/Acre +Link America/Noronha Brazil/DeNoronha +Link America/Sao_Paulo Brazil/East +Link America/Manaus Brazil/West +Link America/Halifax Canada/Atlantic +Link America/Winnipeg Canada/Central +Link America/Regina Canada/East-Saskatchewan +Link America/Montreal Canada/Eastern +Link America/Edmonton Canada/Mountain +Link America/St_Johns Canada/Newfoundland +Link America/Vancouver Canada/Pacific +Link America/Regina Canada/Saskatchewan +Link America/Whitehorse Canada/Yukon +Link America/Santiago Chile/Continental +Link Pacific/Easter Chile/EasterIsland +Link America/Havana Cuba +Link Africa/Cairo Egypt +Link Europe/Dublin Eire +Link Europe/London GB +Link Etc/GMT GMT +Link Etc/GMT+0 GMT+0 +Link Etc/GMT-0 GMT-0 +Link Etc/GMT0 GMT0 +Link Etc/Greenwich Greenwich +Link Asia/Hong_Kong Hongkong +Link Atlantic/Reykjavik Iceland +Link Asia/Tehran Iran +Link Asia/Tel_Aviv Israel +Link America/Jamaica Jamaica +Link Asia/Tokyo Japan +Link Pacific/Kwajalein Kwajalein +Link Africa/Tripoli Libya +Link America/Tijuana Mexico/BajaNorte +Link America/Mazatlan Mexico/BajaSur +Link America/Mexico_City Mexico/General +Link Pacific/Auckland NZ +Link Pacific/Chatham NZ-CHAT +Link Asia/Shanghai PRC +Link Europe/Warsaw Poland +Link Europe/Lisbon Portugal +Link Asia/Taipei ROC +Link Asia/Seoul ROK +Link Asia/Singapore Singapore +Link Europe/Istanbul Turkey +Link Etc/UCT UCT +Link America/Anchorage US/Alaska +Link America/Atka US/Aleutian +Link America/Phoenix US/Arizona +Link America/Chicago US/Central +Link America/Fort_Wayne US/East-Indiana +Link America/New_York US/Eastern +Link Pacific/Honolulu US/Hawaii +Link America/Knox_IN US/Indiana-Starke +Link America/Detroit US/Michigan +Link America/Denver US/Mountain +Link America/Los_Angeles US/Pacific +Link Pacific/Samoa US/Samoa +Link Etc/UTC UTC +Link Etc/Universal Universal +Link Etc/Zulu Zulu diff --git a/time/date.1 b/time/date.1 new file mode 100644 index 000000000..e3bff1b0d --- /dev/null +++ b/time/date.1 @@ -0,0 +1,153 @@ +.TH DATE 1 +.SH NAME +date \- show and set date and time +.SH SYNOPSIS +.if n .nh +.if n .na +.B date +[ +.B \-u +] [ +.B \-c +] [ +.B \-n +] [ +.B \-d +dsttype +] [ +.B \-t +minutes-west +] [ +\fB\-a \fR[\fB+\fR|\fB-]\fIsss\fB.\fIfff\fR +] [ +.BI + format +] [ +\fR[\fIyyyy\fR]\fImmddhhmm\fR[\fIyy\fR][\fB.\fIss\fR] +] +.SH DESCRIPTION +.I Date +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). +.PP +If a command-line argument starts with a plus sign +.RB (` + '), +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 +.RB (` % ') +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 +.if t .in +.5i +.if n .in +2 +.ta \w'%M\0\0'u +\w'Wed Mar 8 14:54:40 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 03/08/89 14:54:40 Month/day/year Hour:minute:second +%C Wed Mar 8 14:54:40 1989 a la \fIasctime\^\fP(3) +%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 Month/day/year (eight characters) +%X 14:54:40 Hour:minute:second +%y 89 Last two digits of year +%Y 1989 Year in full +%Z EST Time zone abbreviation +.if t .in -.5i +.if n .in -2 +.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 ``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 GMT when setting and showing the date and time. +.TP +.B \-n +Do not notify other networked systems of the time change. +.TP +.BI "\-d " dsttype +Set the kernel-stored Daylight Saving Time type to the given value. +(The kernel-stored DST type is used mostly by ``old'' binaries.) +.TP +.BI "\-t " minutes-west +Set the kernel-stored ``minutes west of GMT'' value to the one given on the +command line. +(The kernel-stored DST type is used mostly by ``old'' binaries.) +.TP +.BI "\-a " adjustment +Change the time forward (or backward) by the number of seconds +(and fractions thereof) specified in the +.I adjustment\^ +argument. +Either the seconds part or the fractions part of the argument (but not both) +may be omitted. +On BSD-based systems, +the adjustment is made by changing the rate at which time advances; +on System-V-based systems, the adjustment is made by changing the time. +.\" @(#)date.1 7.2 diff --git a/time/date.c b/time/date.c new file mode 100644 index 000000000..493b87849 --- /dev/null +++ b/time/date.c @@ -0,0 +1,900 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)date.c 7.13"; +/* +** Modified from the UCB version with the SCCS ID appearing below. +*/ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* + * Copyright (c) 1985, 1987, 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANT[A]BILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1985, 1987, 1988 The Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)date.c 4.23 (Berkeley) 9/20/88"; +#endif /* not lint */ + +#ifndef USG +#include "sys/time.h" /* for DST_NONE */ +#endif /* !defined USG */ +#include "private.h" +#include "utmp.h" /* for OLD_TIME (or its absence) */ + +/* +** The two things date knows about time are. . . +*/ + +#ifndef TM_YEAR_BASE +#define TM_YEAR_BASE 1900 +#endif /* !defined TM_YEAR_BASE */ + +#ifndef SECSPERMIN +#define SECSPERMIN 60 +#endif /* !defined SECSPERMIN */ + +extern double atof(); +extern char ** environ; +extern char * getlogin(); +extern int logwtmp(); +extern time_t mktime(); +extern char * optarg; +extern int optind; +extern char * strchr(); +extern time_t time(); +extern char * tzname[2]; + +static int retval = EXIT_SUCCESS; + +static void checkfinal P((const char *, int, time_t, time_t)); +static int comptm P((const struct tm *, const struct tm *)); +static time_t convert P((const char *, int, time_t)); +static void display P((const char *)); +static void dogmt P((void)); +static void errensure P((void)); +static void iffy P((time_t, time_t, const char *, const char *)); +int main P((int, char**)); +static const char * nondigit P((const char *)); +static void oops P((const char *)); +static void reset P((time_t, int)); +static void timeout P((FILE *, const char *, const struct tm *)); +static void usage P((void)); +static void wildinput P((const char *, const char *, const char *)); + +int +main(argc, argv) +const int argc; +char * argv[]; +{ + register const char * format; + register const char * value; + register const char * cp; + register int ch; + register int dousg; + register int aflag = 0; + register int dflag = 0; + register int nflag = 0; + register int tflag = 0; + register int minuteswest; + register int dsttime; + register float adjust; + time_t now; + time_t t; + + INITIALIZE(dousg); + INITIALIZE(minuteswest); + INITIALIZE(dsttime); + INITIALIZE(adjust); + INITIALIZE(t); + (void) time(&now); + format = value = NULL; + while ((ch = getopt(argc, argv, "ucnd:t:a:")) != EOF) { + switch (ch) { + default: + usage(); + case 'u': /* do it in GMT */ + case 'c': + dogmt(); + break; + case 'n': /* don't set network */ + nflag = 1; + break; + case 'd': /* daylight savings time */ + if (dflag) { + (void) fprintf(stderr, + "date: error: multiple -d's used"); + usage(); + } + dflag = 1; + cp = optarg; + dsttime = atoi(cp); + if (*cp == '\0' || *nondigit(cp) != '\0') + wildinput("-t value", optarg, + "must be a non-negative number"); + break; + case 't': /* minutes west of GMT */ + if (tflag) { + (void) fprintf(stderr, + "date: error: multiple -t's used"); + usage(); + } + tflag = 1; + cp = optarg; + minuteswest = atoi(cp); + if (*cp == '+' || *cp == '-') + ++cp; + if (*cp == '\0' || *nondigit(cp) != '\0') + wildinput("-d value", optarg, + "must be a number"); + break; + case 'a': /* adjustment */ + if (aflag) { + (void) fprintf(stderr, + "date: error: multiple -a's used"); + usage(); + } + aflag = 1; + cp = optarg; + adjust = atof(cp); + if (*cp == '+' || *cp == '-') + ++cp; + if (*cp == '\0' || strcmp(cp, ".") == 0) + wildinput("-a value", optarg, + "must be a number"); + cp = nondigit(cp); + if (*cp == '.') + ++cp; + if (*nondigit(cp) != '\0') + wildinput("-a value", optarg, + "must be a number"); + break; + } + } + while (optind < argc) { + cp = argv[optind++]; + if (*cp == '+') + if (format == NULL) + format = cp + 1; + else { + (void) fprintf(stderr, +"date: error: multiple formats in command line\n"); + usage(); + } + else if (value == NULL) + value = cp; + else { + (void) fprintf(stderr, +"date: error: multiple values in command line\n"); + usage(); + } + } + if (value != NULL) { + /* + ** This order ensures that "reasonable" twelve-digit inputs + ** (such as 120203042006) won't be misinterpreted + ** even if time_t's range all the way back to the thirteenth + ** century. Do not change the order. + */ + t = convert(value, (dousg = TRUE), now); + if (t == -1) + t = convert(value, (dousg = FALSE), now); + if (t == -1) { + /* + ** Out of range values, + ** or time that falls in a DST transition hole? + */ + if ((cp = strchr(value, '.')) != NULL) { + /* + ** Ensure that the failure of + ** TZ=US/Eastern date 8712312359.60 + ** doesn't get misdiagnosed. (It was + ** TZ=US/Eastern date 8712311859.60 + ** when the leap second was inserted.) + ** The normal check won't work since + ** the given time is valid in GMT. + */ + if (atoi(cp + 1) >= SECSPERMIN) + wildinput("time", value, + "out of range seconds given"); + } + dogmt(); + t = convert(value, FALSE, now); + if (t == -1) + t = convert(value, TRUE, now); + wildinput("time", value, + (t == -1) ? + "out of range value given" : + "time skipped when clock springs forward"); + } + } + /* + ** Entire command line has now been checked. + */ + if (aflag) { +#ifdef DST_NONE + struct timeval tv; + + tv.tv_sec = (int) adjust; + tv.tv_usec = (int) ((adjust - tv.tv_sec) * 1000000); + if (adjtime(&tv, (struct timeval *) NULL) != 0) + oops("date: error: adjtime"); +#endif /* defined DST_NONE */ +#ifndef DST_NONE + reset((time_t) (now + adjust), nflag); +#endif /* !defined DST_NONE */ + /* + ** Sun silently ignores everything else; we follow suit. + */ + (void) exit(retval); + } + if (dflag || tflag) { +#ifdef DST_NONE + struct timezone tz; + + if (!dflag || !tflag) + if (gettimeofday((struct timeval *) NULL, &tz) != 0) + oops("date: error: gettimeofday"); + if (dflag) + tz.tz_dsttime = dsttime; + if (tflag) + tz.tz_minuteswest = minuteswest; + if (settimeofday((struct timeval *) NULL, &tz) != 0) + oops("date: error: settimeofday"); +#endif /* defined DST_NONE */ +#ifndef DST_NONE + (void) fprintf(stderr, +"date: warning: kernel doesn't keep -d/-t information, option ignored\n"); +#endif /* !defined DST_NONE */ + } + + if (value == NULL) + display(format); + + reset(t, nflag); + + checkfinal(value, dousg, t, now); + +#ifdef EBUG + { + struct tm tm; + + tm = *localtime(&t); + timeout(stdout, "%c\n", &tm); + (void) exit(retval); + } +#endif /* defined EBUG */ + + display(format); + + /* gcc -Wall pacifier */ + for ( ; ; ) + continue; +} + +static void +dogmt() +{ + static char ** fakeenv; + + if (fakeenv == NULL) { + register int from, to, n; + + for (n = 0; environ[n] != NULL; ++n) + continue; + fakeenv = (char **) malloc((alloc_size_T) (n + 2) * + sizeof *fakeenv); + if (fakeenv == NULL) { + (void) perror("Memory exhausted"); + errensure(); + (void) exit(retval); + } + to = 0; + fakeenv[to++] = "TZ=GMT0"; + for (from = 1; environ[from] != NULL; ++from) + if (strncmp(environ[from], "TZ=", 3) != 0) + fakeenv[to++] = environ[from]; + fakeenv[to] = NULL; + environ = fakeenv; + } +} + +#ifdef OLD_TIME + +/* +** We assume we're on a System-V-based system, +** should use stime, +** should write System-V-format utmp entries, +** and don't have network notification to worry about. +*/ + +#include "fcntl.h" /* for O_WRONLY, O_APPEND */ + +/*ARGSUSED*/ +static void +reset(newt, nflag) +const time_t newt; +const int nflag; +{ + register int fid; + time_t oldt; + static struct { + struct utmp before; + struct utmp after; + } s; + + /* + ** Wouldn't it be great if stime returned the old time? + */ + (void) time(&oldt); + if (stime(&newt) != 0) + oops("date: error: stime"); + s.before.ut_type = OLD_TIME; + s.before.ut_time = oldt; + (void) strcpy(s.before.ut_line, OTIME_MSG); + s.after.ut_type = NEW_TIME; + s.after.ut_time = newt; + (void) strcpy(s.after.ut_line, NTIME_MSG); + fid = open(WTMP_FILE, O_WRONLY | O_APPEND); + if (fid < 0) + oops("date: error: log file open"); + if (write(fid, (char *) &s, sizeof s) != sizeof s) + oops("date: error: log file write"); + if (close(fid) != 0) + oops("date: error: log file close"); + pututline(&s.before); + pututline(&s.after); +} + +#endif /* defined OLD_TIME */ +#ifndef OLD_TIME + +/* +** We assume we're on a BSD-based system, +** should use settimeofday, +** should write BSD-format utmp entries (using logwtmp), +** and may get to worry about network notification. +** The "time name" changes between 4.3-tahoe and 4.4; +** we include sys/param.h to determine which we should use. +*/ + +#ifndef TIME_NAME +#include "sys/param.h" +#ifdef BSD4_4 +#define TIME_NAME "date" +#endif /* defined BSD4_4 */ +#ifndef BSD4_4 +#define TIME_NAME "" +#endif /* !defined BSD4_4 */ +#endif /* !defined TIME_NAME */ + +#include "syslog.h" +#include "sys/socket.h" +#include "netinet/in.h" +#include "netdb.h" +#define TSPTYPES +#include "protocols/timed.h" + +#ifndef TSP_SETDATE +/*ARGSUSED*/ +#endif /* !defined TSP_SETDATE */ +static void +reset(newt, nflag) +const time_t newt; +const int nflag; +{ + register const char * username; + static struct timeval tv; /* static so tv_usec is 0 */ + +#ifdef EBUG + return; +#endif /* defined EBUG */ + username = getlogin(); + if (username == NULL || *username == '\0') /* single-user or no tty */ + username = "root"; + tv.tv_sec = newt; +#ifdef TSP_SETDATE + if (nflag || !netsettime(tv)) +#endif /* defined TSP_SETDATE */ + { + /* + ** "old" entry is always written, for compatibility. + */ + logwtmp("|", TIME_NAME, ""); + if (settimeofday(&tv, (struct timezone *) NULL) == 0) { + logwtmp("{", TIME_NAME, ""); /* } */ + syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", + username); + } else oops("date: error: settimeofday"); + } +} + +#endif /* !defined OLD_TIME */ + +static void +wildinput(item, value, reason) +const char * const item; +const char * const value; +const char * const reason; +{ + (void) fprintf(stderr, "date: error: bad command line %s \"%s\", %s\n", + item, value, reason); + usage(); +} + +static void +errensure P((void)) +{ + if (retval == EXIT_SUCCESS) + retval = EXIT_FAILURE; +} + +static const char * +nondigit(cp) +register const char * cp; +{ + while (isdigit(*cp)) + ++cp; + return cp; +} + +static void +usage P((void)) +{ + (void) fprintf(stderr, "date: usage is date "); + (void) fprintf(stderr, "[-u] "); + (void) fprintf(stderr, "[-c] "); + (void) fprintf(stderr, "[-n] "); + (void) fprintf(stderr, "[-d dst] "); + (void) fprintf(stderr, "[-t min-west] "); + (void) fprintf(stderr, "[-a sss.fff] "); + (void) fprintf(stderr, "[[yyyy]mmddhhmm[yyyy][.ss]] "); + (void) fprintf(stderr, "[+format]\n"); + errensure(); + (void) exit(retval); +} + +static void +oops(string) +const char * const string; +{ + (void) perror(string); + errensure(); + display((char *) NULL); +} + +static void +display(format) +const char * const format; +{ + struct tm tm; + time_t now; + + (void) time(&now); + tm = *localtime(&now); + if (format == NULL) { + timeout(stdout, "%a %b ", &tm); + (void) printf("%2d ", tm.tm_mday); + timeout(stdout, "%X %Z %Y", &tm); + } else timeout(stdout, format, &tm); + (void) putchar('\n'); + (void) fflush(stdout); + (void) fflush(stderr); + if (ferror(stdout) || ferror(stderr)) { + (void) fprintf(stderr, + "date: error: couldn't write results\n"); + errensure(); + } + (void) exit(retval); +} + +extern size_t strftime(); + +#define INCR 1024 + +static void +timeout(fp, format, tmp) +FILE * const fp; +const char * const format; +const struct tm * const tmp; +{ + char * cp; + size_t result; + size_t size; + + if (*format == '\0') + return; + size = INCR; + cp = malloc((alloc_size_T) size); + for ( ; ; ) { + if (cp == NULL) { + (void) fprintf(stderr, + "date: error: can't get memory\n"); + errensure(); + (void) exit(retval); + } + result = strftime(cp, size, format, tmp); + if (result != 0) + break; + size += INCR; + cp = realloc(cp, (alloc_size_T) size); + } + (void) fwrite(cp, 1, result, fp); + free(cp); +} + +static int +comptm(atmp, btmp) +register const struct tm * const atmp; +register const struct tm * const btmp; +{ + register int result; + + if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && + (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +/* +** convert -- +** convert user's input into a time_t. +*/ + +#define ATOI2(ar) (ar[0] - '0') * 10 + (ar[1] - '0'); ar += 2; + +static time_t +convert(value, dousg, t) +register const char * const value; +const int dousg; +const time_t t; +{ + register const char * cp; + register char * dotp; + register int cent, year_in_cent, month, hour, day, mins, secs; + struct tm tm, outtm; + time_t outt; + + tm = *localtime(&t); + cent = (tm.tm_year + TM_YEAR_BASE) / 100; + year_in_cent = (tm.tm_year + TM_YEAR_BASE) - cent * 100; + month = tm.tm_mon + 1; + day = tm.tm_mday; + hour = tm.tm_hour; + mins = tm.tm_min; + secs = 0; + + dotp = strchr(value, '.'); + for (cp = value; *cp != '\0'; ++cp) + if (!isdigit(*cp) && cp != dotp) + wildinput("time", value, "contains a nondigit"); + + if (dotp == NULL) + dotp = strchr(value, '\0'); + else { + cp = dotp + 1; + if (strlen(cp) != 2) + wildinput("time", value, + "seconds part is not two digits"); + secs = ATOI2(cp); + } + + cp = value; + switch (dotp - cp) { + default: + wildinput("time", value, "main part is wrong length"); + case 12: + if (!dousg) { + cent = ATOI2(cp); + year_in_cent = ATOI2(cp); + } + month = ATOI2(cp); + day = ATOI2(cp); + hour = ATOI2(cp); + mins = ATOI2(cp); + if (dousg) { + cent = ATOI2(cp); + year_in_cent = ATOI2(cp); + } + break; + case 8: /* mmddhhmm */ + month = ATOI2(cp); + /* fall through to. . . */ + case 6: /* ddhhmm */ + day = ATOI2(cp); + /* fall through to. . . */ + case 4: /* hhmm */ + hour = ATOI2(cp); + mins = ATOI2(cp); + break; + case 10: + if (!dousg) { + year_in_cent = ATOI2(cp); + } + month = ATOI2(cp); + day = ATOI2(cp); + hour = ATOI2(cp); + mins = ATOI2(cp); + if (dousg) { + year_in_cent = ATOI2(cp); + } + break; + } + + tm.tm_year = cent * 100 + year_in_cent - TM_YEAR_BASE; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = mins; + tm.tm_sec = secs; + tm.tm_isdst = -1; + outtm = tm; + outt = mktime(&outtm); + return (comptm(&tm, &outtm) == 0) ? outt : -1; +} + +/* +** Code from here on out is either based on code provided by UCB +** or is only called just before the program exits. +*/ + +/* +** Check for iffy input. +*/ + +static void +checkfinal(value, didusg, t, oldnow) +const char * const value; +const int didusg; +const time_t t; +const time_t oldnow; +{ + time_t othert; + struct tm tm; + struct tm othertm; + register int pass; + register long offset; + + /* + ** See if there's both a USG and a BSD interpretation. + */ + othert = convert(value, !didusg, oldnow); + if (othert != -1 && othert != t) + iffy(t, othert, value, "year could be at start or end"); + /* + ** See if there's both a DST and a STD version. + */ + tm = *localtime(&t); + othertm = tm; + othertm.tm_isdst = !tm.tm_isdst; + othert = mktime(&othertm); + if (othert != -1 && othertm.tm_isdst != tm.tm_isdst && + comptm(&tm, &othertm) == 0) + iffy(t, othert, value, + "both standard and summer time versions exist"); +/* +** Final check. +** +** If a jurisdiction shifts time *without* shifting whether time is +** summer or standard (as Hawaii, the United Kingdom, and Saudi Arabia +** have done), routine checks for iffy times may not work. +** So we perform this final check, deferring it until after the time has +** been set--it may take a while, and we don't want to introduce an unnecessary +** lag between the time the user enters their command and the time that +** stime/settimeofday is called. +** +** We just check nearby times to see if any have the same representation +** as the time that convert returned. We work our way out from the center +** for quick response in solar time situations. We only handle common cases-- +** offsets of at most a minute, and offsets of exact numbers of minutes +** and at most an hour. +*/ + for (offset = 1; offset <= 60; ++offset) + for (pass = 1; pass <= 4; ++pass) { + if (pass == 1) + othert = t + offset; + else if (pass == 2) + othert = t - offset; + else if (pass == 3) + othert = t + 60 * offset; + else othert = t - 60 * offset; + othertm = *localtime(&othert); + if (comptm(&tm, &othertm) == 0) + iffy(t, othert, value, + "multiple matching times exist"); + } +} + +static void +iffy(thist, thatt, value, reason) +const time_t thist; +const time_t thatt; +const char * const value; +const char * const reason; +{ + struct tm tm; + + (void) fprintf(stderr, "date: warning: ambiguous time \"%s\", %s.\n", + value, reason); + tm = *gmtime(&thist); + (void) fprintf(stderr, "Time was set as if you used\n"); + /* + ** Avoid running afoul of SCCS! + */ + timeout(stderr, "\tdate -u ", &tm); + timeout(stderr, "%m%d%H", &tm); + timeout(stderr, "%M", &tm); + timeout(stderr, "%Y.%S\n", &tm); + tm = *localtime(&thist); + timeout(stderr, "to get %c", &tm); + (void) fprintf(stderr, " (%s time)", + tm.tm_isdst ? "summer" : "standard"); + (void) fprintf(stderr, ". Use\n"); + tm = *gmtime(&thatt); + timeout(stderr, "\tdate -u ", &tm); + timeout(stderr, "%m%d%H", &tm); + timeout(stderr, "%M", &tm); + timeout(stderr, "%Y.%S\n", &tm); + tm = *localtime(&thatt); + timeout(stderr, "to get %c", &tm); + (void) fprintf(stderr, " (%s time)", + tm.tm_isdst ? "summer" : "standard"); + (void) fprintf(stderr, ".\n"); + errensure(); + (void) exit(retval); +} + +#ifdef TSP_SETDATE +#define WAITACK 2 /* seconds */ +#define WAITDATEACK 5 /* seconds */ + +#ifndef errno +extern int errno; +#endif /* !defined errno */ +/* + * Set the date in the machines controlled by timedaemons + * by communicating the new date to the local timedaemon. + * If the timedaemon is in the master state, it performs the + * correction on all slaves. If it is in the slave state, it + * notifies the master that a correction is needed. + * Returns 1 on success, 0 on failure. + */ +netsettime(ntv) + struct timeval ntv; +{ + int s, length, port, timed_ack, found, err; + long waittime; + fd_set ready; + char hostname[MAXHOSTNAMELEN]; + struct timeval tout; + struct servent *sp; + struct tsp msg; + struct sockaddr_in sin, dest, from; + + sp = getservbyname("timed", "udp"); + if (sp == 0) { + fputs("udp/timed: unknown service\n", stderr); + retval = 2; + return (0); + } + dest.sin_port = sp->s_port; + dest.sin_family = AF_INET; + dest.sin_addr.s_addr = htonl((u_long)INADDR_ANY); + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + if (errno != EPROTONOSUPPORT) + perror("date: socket"); + goto bad; + } + bzero((char *)&sin, sizeof (sin)); + sin.sin_family = AF_INET; + for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) { + sin.sin_port = htons((u_short)port); + if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0) + break; + if (errno != EADDRINUSE) { + if (errno != EADDRNOTAVAIL) + perror("date: bind"); + goto bad; + } + } + if (port == IPPORT_RESERVED / 2) { + fputs("date: All ports in use\n", stderr); + goto bad; + } + msg.tsp_type = TSP_SETDATE; + msg.tsp_vers = TSPVERSION; + if (gethostname(hostname, sizeof (hostname))) { + perror("gethostname"); + goto bad; + } + (void) strncpy(msg.tsp_name, hostname, sizeof (hostname)); + msg.tsp_seq = htons((u_short)0); + msg.tsp_time.tv_sec = htonl((u_long)ntv.tv_sec); + msg.tsp_time.tv_usec = htonl((u_long)ntv.tv_usec); + length = sizeof (struct sockaddr_in); + if (connect(s, &dest, length) < 0) { + perror("date: connect"); + goto bad; + } + if (send(s, (char *)&msg, sizeof (struct tsp), 0) < 0) { + if (errno != ECONNREFUSED) + perror("date: send"); + goto bad; + } + timed_ack = -1; + waittime = WAITACK; +loop: + tout.tv_sec = waittime; + tout.tv_usec = 0; + FD_ZERO(&ready); + FD_SET(s, &ready); + found = select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout); + length = sizeof(err); + if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *)&err, &length) == 0 + && err) { + errno = err; + if (errno != ECONNREFUSED) + perror("date: send (delayed error)"); + goto bad; + } + if (found > 0 && FD_ISSET(s, &ready)) { + length = sizeof (struct sockaddr_in); + if (recvfrom(s, (char *)&msg, sizeof (struct tsp), 0, &from, + &length) < 0) { + if (errno != ECONNREFUSED) + perror("date: recvfrom"); + goto bad; + } + msg.tsp_seq = ntohs(msg.tsp_seq); + msg.tsp_time.tv_sec = ntohl(msg.tsp_time.tv_sec); + msg.tsp_time.tv_usec = ntohl(msg.tsp_time.tv_usec); + switch (msg.tsp_type) { + + case TSP_ACK: + timed_ack = TSP_ACK; + waittime = WAITDATEACK; + goto loop; + + case TSP_DATEACK: + (void)close(s); + return (1); + + default: + fprintf(stderr, + "date: Wrong ack received from timed: %s\n", + tsptype[msg.tsp_type]); + timed_ack = -1; + break; + } + } + if (timed_ack == -1) + fputs("date: Can't reach time daemon, time set locally.\n", + stderr); +bad: + (void)close(s); + retval = 2; + return (0); +} +#endif /* defined TSP_SETDATE */ diff --git a/time/difftime.c b/time/difftime.c new file mode 100644 index 000000000..18325862d --- /dev/null +++ b/time/difftime.c @@ -0,0 +1,74 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)difftime.c 7.5"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/*LINTLIBRARY*/ + +#include "private.h" + +/* +** Algorithm courtesy Paul Eggert (eggert@twinsun.com). +*/ + +#ifdef HAVE_LONG_DOUBLE +#define long_double long double +#endif /* defined HAVE_LONG_DOUBLE */ +#ifndef HAVE_LONG_DOUBLE +#define long_double double +#endif /* !defined HAVE_LONG_DOUBLE */ + +double +difftime(time1, time0) +const time_t time1; +const time_t time0; +{ + time_t delta; + time_t hibit; + + if (sizeof(time_t) < sizeof(double)) + return (double) time1 - (double) time0; + if (sizeof(time_t) < sizeof(long_double)) + return (long_double) time1 - (long_double) time0; + if (time1 < time0) + return -difftime(time0, time1); + /* + ** As much as possible, avoid loss of precision + ** by computing the difference before converting to double. + */ + delta = time1 - time0; + if (delta >= 0) + return delta; + /* + ** Repair delta overflow. + */ + hibit = 1; + while ((hibit <<= 1) > 0) + continue; + /* + ** The following expression rounds twice, which means + ** the result may not be the closest to the true answer. + ** For example, suppose time_t is 64-bit signed int, + ** long_double is IEEE 754 double with default rounding, + ** time1 = 9223372036854775807 and time0 = -1536. + ** Then the true difference is 9223372036854777343, + ** which rounds to 9223372036854777856 + ** with a total error of 513. + ** But delta overflows to -9223372036854774273, + ** which rounds to -9223372036854774784, and correcting + ** this by subtracting 2 * (long_double) hibit + ** (i.e. by adding 2**64 = 18446744073709551616) + ** yields 9223372036854776832, which + ** rounds to 9223372036854775808 + ** with a total error of 1535 instead. + ** This problem occurs only with very large differences. + ** It's too painful to fix this portably. + ** We are not alone in this problem; + ** many C compilers round twice when converting + ** large unsigned types to small floating types, + ** so if time_t is unsigned the "return delta" above + ** has the same double-rounding problem. + */ + return delta - 2 * (long_double) hibit; +} diff --git a/time/emkdir.c b/time/emkdir.c new file mode 100644 index 000000000..5cc62d29e --- /dev/null +++ b/time/emkdir.c @@ -0,0 +1,85 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)emkdir.c 8.23"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#ifndef emkdir + +/*LINTLIBRARY*/ + +#include "private.h" + +extern char * imalloc P((int n)); +extern void ifree P((char * p)); + +static char * +quoted(name) +register const char * name; +{ + register char * result; + register char * cp; + register int c; + + if (name == NULL) + name = ""; + result = imalloc((int) (4 * strlen(name) + 3)); + if (result == NULL) + return NULL; + cp = result; +#ifdef unix + *cp++ = '\''; + while ((c = *name++) != '\0') + if (c == '\'') { + *cp++ = c; + *cp++ = '\\'; + *cp++ = c; + *cp++ = c; + } else *cp++ = c; + *cp++ = '\''; +#endif /* defined unix */ +#ifndef unix + while ((c = *name++) != '\0') + if (c == '/') + *cp++ = '\\'; + else *cp++ = c; +#endif /* !defined unix */ + *cp = '\0'; + return result; +} + +int +emkdir(name, mode) +const char * name; +const int mode; +{ + register int result; + register const char * format; + register char * command; + register char * qname; + + if ((qname = quoted(name)) == NULL) + return -1; +#ifdef unix + format = "mkdir 2>&- %s && chmod 2>&- %o %s"; +#endif /* defined unix */ +#ifndef unix + format = "mkdir %s"; +#endif /* !defined unix */ + command = imalloc((int) (strlen(format) + 2 * strlen(qname) + 20 + 1)); + if (command == NULL) { + ifree(qname); + return -1; + } + (void) sprintf(command, format, qname, mode, qname); + ifree(qname); + result = system(command); + ifree(command); + return (result == 0) ? 0 : -1; +} + +/* +** UNIX was a registered trademark of UNIX System Laboratories in 1993. +*/ + +#endif /* !defined emkdir */ diff --git a/time/etcetera b/time/etcetera new file mode 100644 index 000000000..ed619aecf --- /dev/null +++ b/time/etcetera @@ -0,0 +1,54 @@ +# @(#)etcetera 7.4 + +# All of these are set up just so people can "zic -l" to a timezone +# that's right for their area, even if it doesn't have a name or DST rules +# (half hour zones are too much to bother with -- when someone asks!) + +Zone Etc/GMT 0 - GMT +Link Etc/GMT Etc/UTC +Link Etc/GMT Etc/UCT +Link Etc/GMT Etc/Universal +Link Etc/GMT Etc/Greenwich +Link Etc/GMT Etc/Zulu +Link Etc/GMT Etc/GMT-0 +Link Etc/GMT Etc/GMT+0 +Link Etc/GMT Etc/GMT0 + +# We use POSIX-style signedness in the names and output, +# internal-style signedness in the specifications. +# For example, TZ=Etc/GMT+4 corresponds to 4 hours _behind_ GMT; +# it is equivalent to TZ=GMT+4, which is implemented directly as per POSIX. + +# Earlier incarnations of this package were not POSIX-compliant, +# and had lines such as +# Zone GMT-12 -12 - GMT-1200 +# We did not want things to change quietly if someone accustomed to the old +# way does a +# zic -l GMT-12 +# so we moved the names into the Etc subdirectory. + +Zone Etc/GMT-13 13 - GMT-13 # 12 hours ahead of GMT, plus DST +Zone Etc/GMT-12 12 - GMT-12 +Zone Etc/GMT-11 11 - GMT-11 +Zone Etc/GMT-10 10 - GMT-10 +Zone Etc/GMT-9 9 - GMT-9 +Zone Etc/GMT-8 8 - GMT-8 +Zone Etc/GMT-7 7 - GMT-7 +Zone Etc/GMT-6 6 - GMT-6 +Zone Etc/GMT-5 5 - GMT-5 +Zone Etc/GMT-4 4 - GMT-4 +Zone Etc/GMT-3 3 - GMT-3 +Zone Etc/GMT-2 2 - GMT-2 +Zone Etc/GMT-1 1 - GMT-1 +Zone Etc/GMT+1 -1 - GMT+1 +Zone Etc/GMT+2 -2 - GMT+2 +Zone Etc/GMT+3 -3 - GMT+3 +Zone Etc/GMT+4 -4 - GMT+4 +Zone Etc/GMT+5 -5 - GMT+5 +Zone Etc/GMT+6 -6 - GMT+6 +Zone Etc/GMT+7 -7 - GMT+7 +Zone Etc/GMT+8 -8 - GMT+8 +Zone Etc/GMT+9 -9 - GMT+9 +Zone Etc/GMT+10 -10 - GMT+10 +Zone Etc/GMT+11 -11 - GMT+11 +Zone Etc/GMT+12 -12 - GMT+12 diff --git a/time/europe b/time/europe new file mode 100644 index 000000000..a802cfec8 --- /dev/null +++ b/time/europe @@ -0,0 +1,2072 @@ +# @(#)europe 7.17 + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# I invented the abbreviations marked `*' in the following table; +# the rest are from earlier versions of this file, or from other sources. +# The starred Russian names are dubious. Corrections are welcome! +# std dst +# LMT Local Mean Time +# LST Local Star Time (Russian ``mestnoe zvezdnoe vremya'') +# -4:00 AST Atlantic +# -3:00 WGT+DST Western Greenland* +# -2:00 MGT+DST Middle Greenland* +# -1:00 EGT+DST Eastern Greenland* +# -1:00 ACT+DST Azores and Canaries* +# -1:00 IST IDT Iceland (no longer used)* +# 0:00 GMT BST Greenwich, British Summer +# 0:00 WET+DST Western Europe +# 1:00 MET+DST Middle Europe +# 2:00 EET+DST Eastern Europe +# 3:00 MSK MSD Moscow +# 3:00 TUR+DST Turkey (no longer used)* +# 4:00 KSK KSD Kuybyshev* +# 5:00 ESK ESD Yekaterinburg* +# 6:00 OSK OSD Omsk* +# 6:00 NSK NSD Novosibirsk (was 7:00 until 1994) +# 7:00 TSK TSD Tomsk* +# 8:00 ISK ISD Irkutsk* +# 9:00 YSK YSD Yakutsk* +# 10:00 VSK VSD Vladivostok* +# 11:00 GSK GSD Magadan* +# 12:00 PSK PSD Petropavlovsk-Kamchatski* +# 13:00 ASK ASD Anadyr* +# +# See the `africa' file for Zone naming conventions. +# +# A reliable and entertaining source about time zones, especially in Britain, +# is Derek Howse, Greenwich time and the discovery of the longitude, +# Oxford University Press (1980). + +# From Andrew A. Chernov <ache@astral.msk.su> (November 12, 1993): +# LST is Local Star Time (``mestnoe zvezdnoe vremya''). + +# From Peter Ilieve <peter@memex.co.uk> (December 4, 1994), +# The original six [EU members]: Belguim, France, (West) Germany, Italy, +# Luxembourg, the Netherlands. +# Plus, from 1 Jan 73: Denmark, Ireland, United Kingdom. +# Plus, from 1 Jan 81: Greece. +# Plus, from 1 Jan 86: Spain, Portugal. +# Plus, from 1 Jan 95: Austria, Finland, Sweden. (Norway negotiated terms for +# entry but in a referendum on 28 Nov 94 the people voted No by 52.2% to 47.8% +# on a turnout of 88.6%. This was almost the same result as Norway's previous +# referendum in 1972, they are the only country to have said No twice. +# Referendums in the other three countries voted Yes.) +# ... +# The only [current nonmember using EU rules] I can speak for is Estonia, +# which uses EU dates but not at 01:00 GMT, they use midnight GMT. I don't +# think they know yet what they will do from 1996 onwards. +# ... +# There shouldn't be any [current members who are not using EU rules]. +# A Directive has the force of law, member states are obliged to enact +# national law to implement it. The only contentious issue was the +# different end date for the UK and Ireland, and this was always allowed +# in the Directive. + +############################################################################### + +# United Kingdom + +# From Peter Ilieve <peter@memex.co.uk> (July 6, 1994): +# +# On 17 Jan 1994 the Independent, a UK quality newspaper, had a piece about +# historical vistas along the Thames in west London. There was a photo +# and a sketch map showing some of the sightlines involved. One paragraph +# of the text said: +# +# `An old stone obelisk marking a forgotten terrestrial meridian stands +# beside the river at Kew. In the 18th century, before time and longditude +# was standardised by the Royal Observatory in Greenwich, scholars observed +# this stone and the movement of stars from Kew Observatory nearby. They +# made their calculations and set the time for the Horse Guards and Parliament, +# but now the stone is obscured by scrubwood and can only be seen by walking +# along the towpath within a few yards of it.' +# +# I have a one inch to one mile map of London and my estimate of the stone's +# position is 51 deg. 28' 30" N, 0 deg. 18' 45" W. The longditude should +# be within about +-2". The Ordnance Survey grid reference is TQ172761. +# +# [This yields GMTOFF = -0:01:15 for London LMT in the 18th century.] + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# +# Howse writes that Britain was the first country to use standard time. +# The railways cared most about the inconsistencies of local mean time, +# and it was they who forced a uniform time on the country. +# The original idea was credited to Dr. William Hyde Wollaston (1766-1828); +# it was popularized in 1840 by Capt. Basil Hall, RN (1788-1844), +# famed explorer and former Commissioner for Longitude. +# The first railway to adopt London time was the Great Western Railway +# in November 1840; other railways followed suit, and by 1847 most +# (though not all) railways used London time. On 1847 Sep 22 the +# Railway Clearing House, an industry standards body, recommended that GMT be +# adopted at all stations; the January 1848 Bradshaw's lists most major +# railways as using GMT. By 1855 the vast majority of public +# clocks in Britain were set to GMT (though some, like the Great Clock +# in Tom Tower at Christ Church, Oxford, were fitted with two minute hands, +# one for local time and one for GMT). The last major holdout was the legal +# system, which stubbornly stuck to local time for many years, leading +# to oddities like polls opening at 08:13 and closing at 16:13. +# The legal system finally switched to GMT when the Statutes (Definition +# of Time) Act took effect; it received the Royal Assent on 1880 Aug 2. +# +# In the tables below, we condense this complicated story into a single +# transition date for London, namely 1847 Sep 22. We don't know as much +# about Dublin, so we use 1880 Aug 2, the legal transition time. + +# From Arthur David Olson (January 19, 1989): +# +# A source at the British Information Office in New York avers that it's +# known as "British" Summer Time in all parts of the United Kingdom. + +# Date: 4 Jan 89 08:57:25 GMT (Wed) +# From: Jonathan Leffler <nih-csl!uunet!mcvax!sphinx.co.uk!john> +# [British Summer Time] is fixed annually by Act of Parliament. +# If you can predict what Parliament will do, you should be in +# politics making a fortune, not computing. + +# From Peter Ilieve <peter@memex.co.uk> (September 3, 1993): +# +# Our Government...couldn't...make a decision after the 1989 consultation +# exercise about the UK changing its timezone so it just let things drift +# (different from deciding to keep the status quo). According to the +# Summer Time Order 1992 (SI 1992/1729) the dates of Summer Time for 1993 +# and 1994 are: +# Start End +# 1993 28 March 24 October +# 1994 27 March 23 October +# All start and end times are at 01:00 GMT. +# +# There [was] an error in your tables for the start and end times prior to 1981. +# The UK always used to change at 02:00 GMT. In 1981 it changed to 01:00 GMT +# as a part of EC harmonisation and has remained at that time since. +# +# I have found the default algorithm for UK Summer Time, it is in the +# Summer Time Act 1972. Section 1 states that in the absence of an Order +# in Council Summer Time starts at 02:00 GMT on the morning of the day +# after the third Saturday in March, unless that day is Easter Day, in +# which case it is the morning of the day after the second Saturday. +# It ends at 02:00 GMT on the morning of the day after the fourth Saturday +# in October. (All the redundant `morning of the day ...' is in the Act.) +# This is only of passing interest now as it will always be overridden by +# an Order in Council (a Statutary Instrument, the SI thing mentioned above) +# to specify the EC specified dates. + +# From Peter Ilieve <peter@memex.co.uk> (October 18, 1993): +# +# My contact in the Ministry of Defence Public Relations department +# accepted the challenge of looking into this and produced the following, +# from Hansard (the official record of the UK Parliament), Oral Answers, +# 1 March 1945, cols 1559--60: +# +# `58. Major Sir Goronwy Owen asked the Secretary of State for the Home +# Department if he is now able to state the Government's proposals +# regarding double summer time. +# +# [two other similar questions omitted] +# +# Mr. H. Morrison: The Government, in reviewing the matter, have +# considered, [...] the conclusion has been reached that the adoption of +# double summer time from the beginning of April is essential to the +# maintenance of the war effort. [...] As 1st April is Easter Sunday, +# when very early services are held in many churches, it is proposed that +# double summer time shall start not in the night preceding Easter +# Sunday, but in the night of Sunday- Monday so that it will operate from +# Monday, 2nd April.' + +# From Peter Ilieve <peter@memex.co.uk> (September 3, 1993): +# +# > # Current rules +# > Rule GB-Eire 1981 max - Mar lastSun 1:00s 1:00 BST +# > Rule GB-Eire 1981 max - Oct Sun>=23 1:00s 0 GMT +# +# The ending rule here doesn't match the EC rules, which specify the fourth +# Sunday in October for the UK and Eire. The `fourth Sunday' rule wasn't +# followed in 1989, but then the sixth EC directive wasn't in force then +# and I don't know what previous ones said. 1995 is the next year with +# the 4th Sun on 22 Oct, but that year isn't covered by the UK Summer Time +# Order or the sixth EC directive. Your Oct Sun>=23 rule matches history +# and with things only announced for 2 years or so in advance who knows +# what will happen. +# +# There are renewed rumours that the Government here will make another +# attempt at resolving this issue, which is what prompted me to start +# asking the Home Office and the EC about it again. The EC categorically +# state they are not asking anybody to change timezone, they only want +# common start/end dates. The UK Govt. seem to want to change our zone +# and blame the resulting fuss on the EC. Me, I think we should scrap +# summer time completely, noon is when the Sun is overhead, and that should +# be the end of it. + +# From Peter Ilieve <peter@memex.co.uk> (October 22, 1993): +# +# I now have the text of the Summer Time Act 1916, the granddaddy of them all. +# It is headed: `An Act to provide for the Time in Great Britain and Ireland +# being in advance of Greenwich and Dublin mean time respectively in the +# summer months'. +# +# It specifies 21 May and 1 October for 1916 (both at 02:00 GMT) and whatever +# dates an Order in Council may specify for subsequent years. +# +# Section 4 states: `This act shall apply to Ireland in like manner as it +# applies to Great Britain, with the substitution however of references +# to Dublin mean time for references to Greenwich mean time.' +# +# Lorna, my learned legal friend who supplied it, also offers this quote +# from Halsbury's Statutes on the extent of Acts: +# +# `An Act of the United Kingdom Parliament is to be construed prima facie +# to apply to the whole of the United Kingdom and not to any place outside. +# [...] The expression "United Kingdom" for this purpose includes (since +# 1922) Great Britain (ie. England, Wales and Scotland) and Northern Ireland, +# but it does not include the Channel Islands or the Isle of Man.' +# +# She goes on to say the seminal event of 1922 was the establishment of +# the Irish Free State, now called Eire. +# +# The Act doesn't say anything about Wales (or Scotland) so I would assert +# that Shanks is wrong here. I would like to know why he thinks Wales +# was different. +# +# It also confirms the fact that Ireland followed Dublin time back then, +# and 25 minutes behind Greenwich, as Shanks has it, would be correct. + +# From Peter Ilieve <peter@memex.co.uk> (October 28, 1993): +# +# I now have before me, thanks to my learned legal friend Lorna, the text of +# the Time (Ireland) Act 1916. +# +# It says that as from 2 AM Dublin Mean Time on 1 October 1916 the time +# for general purposes in Ireland shall be the same as the rest of Great +# Britain (ie. GMT with the Summer Time periods specified by the Summer Time +# Act 1916).... As Ireland was behind GMT/BST at 02:00 DMT on 1 Oct GB would +# have already put the clocks back. Using DST as Dublin Summer Time the +# sequence would have been: +# Dublin London +# 02:34 DST 02:59 BST +# 02:35 DST 02:00 GMT +# 02:59 DST 02:24 GMT +# 02:25 GMT 02:25 GMT +# with the transition 03:00 DST -> 02:00 DMT -> 02:25 GMT all at once. +# +# In a table of repeals in the Schedule to the Act it mentions the +# Statutes (Definition of Time) Act 1880. This is presumably the source +# of the 1880 date in Shanks. The little bit of it that is repealed +# also refers solely to Ireland and Dublin Mean Time. + +# From Peter Ilieve <peter@memex.co.uk> (October 29, 1993): +# +# My case is that, with the sole exception of Ireland in 1916 using Dublin +# Mean Time, Summer Time has been uniform throughout the United Kingdom +# ever since it first started in 1916. +# +# The United Kingdom is England, Wales and Scotland plus all of Ireland from +# 1916 up to and including 1921, or plus Northern Ireland from 1922 to date. +# +# The dates used are those specified in the table in Summer Time: A Consultation +# Document (Cm 722, 1989) that are now included in the europe file, with a +# change to a single date, the start in 1924. I made a typo in my 1989 mail +# and the table itself is also wrong. The correct date is 13 April. +# The times were 02:00 GMT up to and including 1980, 01:00 GMT from 1981 on, +# except for wartime double summer time. +# +# As evidence I would cite: +# +# - The Summer Time Act, 1916. +# +# This specifically states that it applies to Ireland, specifies dates of +# 21 May and 1 October and times of 02:00, and says that in Ireland the +# times relate to Dublin mean time. It specifies an offset of 1 hour. +# +# - The Time (Ireland) Act, 1916 +# +# This abolishes Dublin mean time on 02:00 DMT 1 October 1916. +# It repeals that section of the Statutes (Definition of Time) Act, 1880 +# that specifies DMT. It is therefore a safe bet that DMT existed at least +# from 1880 and was the only alternative standard time in the UK. +# +# - The Summer Time Act, 1922 +# +# This specifies an offset of 1 hour and dates of the day after the third +# Saturday in April, unless that be Easter, in which case it is the day after +# the second Saturday, and the day after the third Saturday in September. +# The time is 02:00 GMT. It applied in 1922 and 1923, and longer if Parliament +# so approved. +# +# It specifically states that it applies to Northern Ireland, the Channel +# Islands, and the Isle of Man. +# +# - The Summer Time Act, 1925 +# +# This makes the 1922 Act permanent, with a change to the end date to the +# day after the first Saturday in October. It says nothing about extent, +# so that part of the 1922 Act will still apply. +# +# - The Defence (Summer Time) Regulations, 1939, SR&O 1939 No. 1379 +# [SR&O == Statutary Regulation and Order] +# +# These were made under the Emergency Powers (Defence) Act, 1939. +# It changes the end date to be the day after the third Saturday in November. +# It makes consequential changes to some vehicle lighting legislation, +# which includes the Motor Vehicles and Road Traffic (Northern Ireland) Act, +# 1934, so it seems clear it applies in Northern Ireland. +# +# - An Order in Council amending the The Defence (Summer Time) Regulations, +# 1939, SR&O 1940 No. 1883 +# +# This continues summer time throughout the year after it starts in 1940. +# It says nothing about extent and has no consequential changes. +# +# - An Order in Council amending the The Defence (Summer Time) Regulations, +# 1939, SR&O 1941 No. 476 +# +# This introduces double summer time, starting at 01:00 GMT on the day after +# the first Saturday in May and ending at 01:00 GMT on the day after the +# second Saturday in August, offset another hour from normal summer time, +# which continues throughout the rest of the year. It goes on a lot about +# consequential changes to agricultural wages legislation, and says in part +# `... and in its application to Northern Ireland have effect as +# if for the references to the Agricultural Wages (Regulation) Acts, 1924 and +# 1940, there were substituted references to the Agricultural Wages (Regulation) +# Acts (Northern Ireland), 1939 and 1940, ...'. It also has a similar section +# for Scotland. Both sections substitute the local Agricultural Wages Board +# for the Agricultural Wages Board for England and Wales, showing that +# England and Wales were indivisible. +# +# - An Order in Council amending the The Defence (Summer Time) Regulations, +# 1939, SR&O 1942 No. 506 +# +# This changes the start date of double summer time to the day after the first +# Saturday in April. It says nothing about extent. +# +# - An Order in Council amending the The Defence (Summer Time) Regulations, +# 1939, SR&O 1944 No. 932 +# +# This changed the end date of double summer time to 17 September 1944. +# (I don't have the text of this, just a note of what it did, the text almost +# certainly had the `day after the nth Saturday' form.) +# +# (I am missing whatever regulations there were to change things in 1945 +# and the Summer Time Act, 1947.) +# +# - The British Standard Time Act, 1968 +# +# This came into force on 27 October 1968 and continued summer time throughout +# the year as an experiment until it expired on 31 October 1971. +# There was no double summer time so we didn't have to change the clocks at all. +# It specifically said it applied to Northern Ireland. It also said it +# applied to Jersey, Guernsey and the Isle of Man unless they passed +# measures saying it didn't. +# +# - The Manx Time Act, 1968 +# +# This is an Act of Tynwald (the Isle of Man Parliament) that said that +# henceforth Manx time would be the same as the time in Great Britain. +# +# - The Summer Time Act, 1972 +# +# This specified a reversion to normal summer time behaviour with a start +# date of the day after the third Saturday in March, unless that is Easter, +# when it is the day after the second Saturday, and an end date of the day +# after the fourth Saturday in October. Times are at 02:00 GMT, offset is +# 1 hour. +# +# It has the same wording about extent as the British Standard Time Act, 1968, +# applying to Northern Ireland unconditionally and to Jersey, Guernsey and the +# Isle of Man if they don't do something about it. +# +# (I am missing various Summer Time Orders that modified the 1972 Act to +# harmonise with the EC since 1981. The major change is that the time changes +# to 01:00 GMT.) +# +# - The Summer Time Order, 1992, SI 1992/1729 [SI == Statutary Instrument] +# +# This specifies dates of: +# Start End +# 1993 28 March 24 October +# 1994 27 March 23 October +# All start and end times are at 01:00 GMT.... +# +# - Some text on the extent of Acts, from Halsbury's Statutes +# +# `An Act of the United Kingdom Parliament is to be construed prima facie +# to apply to the whole of the United Kingdom and not to any place outside. +# [...] The expression "United Kingdom" for this purpose includes (since +# 1922) Great Britain (ie. England, Wales and Scotland) and Northern Ireland, +# but it does not include the Channel Islands or the Isle of Man.' +# +# So, many of these measures specifically include Northern Ireland, +# the Channel Islands and the Isle of Man. None of them exclude any +# part of the UK. The default interpretation of Acts is that they apply +# throughout the UK. +# +# With that, I rest my case Milud :-) +# +# Thanks are due to my learned legal friend Lorna Montgomerie, who dug out +# the dusty old statutes, and to Melanie Allison of the Ministry of Defence, +# who provided the wartime regulations and a snippet of Hansard explaining +# why double summer time started on a Monday in 1945 (it was Easter). + +# From Peter Ilieve <peter@memex.co.uk> (November 18, 1993) +# +# Here is a revised version of my tabrules file for the perl script I sent +# before. I have personally verified the various Orders back to 1953 and +# all the Acts. +# +# There are no changes to the dates we already have. +# +# My doubt about an early start in 1967 on 18 Feb was misplaced, the Order +# does say 18 Feb. This is an interesting case as the first Order gave a +# different date of 7 April 1967 for the Isle of Man but this was changed +# before it came into effect by another Order for the Isle of Man alone. +# +# I don't think I will be able to find any more of the earlier Orders. +# The annual volumes for 1949--52 do not contain the various Summer Time +# Orders. They therefore don't appear in the index. They rate a mention in +# italics in the numerical list at the start but that is all. +# I think what happens is that the annual volume is produced well after the +# end of the year in question, by which time the Summer Time Order is spent. +# They assume that nobody would ever be stupid enough to want to see it +# again so they leave it out. +# +# It might be a good idea to put this table, or the output of tabscript +# showing all the moves because of Easter, in the europe file comments in +# place of my old transcription of the Green Paper table [the UK Government +# paper "Summer Time: A Consultation Document" (HMSO Cm722 June 1989)]. +# +# Peter Ilieve peter@memex.co.uk +# +# +# ## control file for tabscript, a program to generate UK summer time dates +# ## matching the table in Cm 722, the 1989 Green Paper. +# ## Lines like this are comments. +# ## Lines with a single # at the start are copied into the output +# ## Control lines are of the form +# ## <years> <start date> <end date> <flags> <double start> <double end> +# ## <years> is either a single year or a hyphen separated range, with -- +# ## also accepted as I use this in TeX a lot. +# ## <start date> and <end date> are a digit followed bu a month name. +# ## It is either an nth Saturday or an explicit date, depending on <flags>. +# ## 0 and/or none are used when there is no date, as during 1968--71. +# ## <flags> can contain `fixed' to indicate explicit dates and `double' +# ## to indicate double summer time dates are present. +# ## At present double requires fixed as well. +# ## <double start> and <double end> are like the start and end dates, with +# ## the exception of the 0 and/or none feature. +# +# ## Blank lines are also ignored. +# +# ## Places where I am uncertain, not having personally verified the dates +# ## against the Act or Order, are marked ??? +# ## These dates are taken from the Cm 722 table. +# +# # Summer Time Act, 1916 +# 1916 21 May 1 October fixed +# +# ## I haven't yet looked for Orders for 1916--22 and I doubt I will find them. +# # unknown Order or Orders ??? +# 1917 8 apr 17 sep fixed +# 1918 24 mar 30 sep fixed +# 1919 30 mar 29 sep fixed +# # end date extended in 1920 from 27 Sep because of coal strike (from Cm 722) +# 1920 28 mar 25 oct fixed +# 1921 3 apr 3 oct fixed +# +# # Summer Time Act, 1922 +# # came into force 22 July 1922, too late for 1922, so missing Order ??? +# 1922 26 mar 8 oct fixed +# 1923-1924 3 April 3 September +# +# # Summer Time Act, 1925 +# 1925--1938 3 April 1 October +# +# # Defence (Summer Time) Regulations, 1939 +# 1939 3 April 3 November +# # 1940 amendment (SR&O 1940 Nos. 172 & 1883) +# 1940 4 feb 0 none +# # 1941 amendment (SR&O 1941 No. 476) +# 1941 0 none 0 none fixed,double 4 may 10 aug +# # 1942 amendment (SR&O 1942 No. 506) +# 1942 0 none 0 none fixed,double 5 apr 9 aug +# 1943 0 none 0 none fixed,double 4 apr 15 aug +# # 1944 amendment (SR&O 1944 No. 932) +# 1944 0 none 0 none fixed,double 2 apr 17 sep +# # 1945 dates from Hansard, Oral Answers, 1 March 1945 +# 1945 0 none 7 oct fixed,double 2 apr 15 jul +# +# # reversion to Summer Time Act, 1925 +# 1946 3 April 1 October +# +# # Summer Time Act, 1947 +# # Fixed dates for 1947 only, gives power to have double summer time +# 1947 16 mar 2 nov fixed,double 13 apr 10 aug +# ## I can't find any trace of the Order for 1948. +# # Unknown Order ??? +# 1948 14 mar 31 oct fixed +# ## I know the numbers for the 1949--52 ones but the text is missing from the +# ## annual volumes. I also don't know if the 49 Order was for 49 or 50, etc. +# # Summer Time Order, 1949 (SI1949/373) ??? +# 1949 3 apr 30 oct fixed +# # Summer Time Order, 1950 (SI1950/518) ??? +# 1950 16 apr 22 oct fixed +# # Summer Time Order, 1951 (SI1951/430) ??? +# 1951 15 apr 21 oct fixed +# # Summer Time Order, 1952 (SI1952/451) ??? +# 1952 20 apr 26 oct fixed +# +# # reversion to Summer Time Act, 1925 +# 1953--1960 3 April 1 October +# +# ## All Orders from here on specify fixed dates, not day after nth Sunday +# ## Start pattern looks like Mar lastSun up to 1963, Mar Sun>=19 up to 1967. +# ## End pattern looks like Oct Sun>=23 up to 1967. +# # Summer Time Order, 1961 (SI1961/71) +# 1961 26 March 29 October fixed +# # Summer Time (1962) Order, 1961 (SI1961/2465) +# 1962 25 Mar 28 Oct fixed +# # Summer Time Order, 1963 (SI1963/81) +# 1963 31 March 27 October fixed +# # Summer Time (1964) Order, 1963 (SI1963/2101) +# 1964 22 March 25 October fixed +# # Summer Time Order, 1964 (SI1964/1201) +# 1965 21 Mar 24 Oct fixed +# 1966 20 Mar 23 Oct fixed +# 1967 19 Mar 29 Oct fixed +# # Summer Time Order, 1967 (SI1967/1148) +# # Specifies different start date of 7 April for Isle of Man +# # Summer Time Order, 1968 (SI1968/117) +# # Changes Isle of Man start date to 18 Feb to match rest of UK +# # British Standard Time Act, 1968 +# 1968 18 feb 0 none fixed +# 1969--1970 0 none 0 none +# 1971 0 none 31 oct fixed +# +# # Summer Time Act, 1972 +# 1972-1980 3 March 4 October +# +# # The pattern here looks like Last Sun in Mar, day after 4th Sat in Oct +# # First EC Directive ??? +# # Summer Time Order, 1980 (SI1980/1089) +# 1981 29 Mar 25 Oct fixed +# 1982 28 Mar 24 Oct fixed +# # Second EC Directive ??? +# # Summer Time Order, 1982 (SI1982/1673) +# 1983 27 Mar 23 Oct fixed +# 1984 25 Mar 28 Oct fixed +# 1985 31 Mar 27 Oct fixed +# # Third EC Directive ??? +# # Summer Time Order, 1986 (SI1986/223) +# 1986 30 Mar 26 Oct fixed +# 1987 29 Mar 25 Oct fixed +# 1988 27 Mar 23 Oct fixed +# # Fourth EC Directive ??? +# # Summer Time Order, 1988 (SI1988/931) +# 1989 26 Mar 29 Oct fixed +# # Fifth EC Directive ??? +# # Summer Time Order, 1989 (SI1989/985) +# 1990 25 Mar 28 Oct fixed +# 1991 31 Mar 27 Oct fixed +# 1992 29 Mar 25 Oct fixed +# # Sixth EC Directive +# # Summer Time Order, 1992 (SI1992/1729) +# 1993 28 Mar 24 Oct fixed +# 1994 27 Mar 23 Oct fixed + +# From Peter Ilieve <peter@memex.co.uk> (August 18, 1994): +# I now have the text of the 7th EC directive on summer time arrangements +# (94/21/EC), which was approved on 30 May.... +# The major changes from existing practice are that 1995 will be the last year +# that the UK and Eire finish on a different date from everyone else, +# and the common end date from 1996 onwards will be the last Sunday in October. +# Year Start End End (UK & Eire, 1995 only) +# (rule) (last Sun) (last Sun) (4th Sun) +# 1995 26 March 24 September 22 October +# 1996 31 March 27 October +# 1997 30 March 26 October +# +# From Peter Ilieve <peter@memex.co.uk> (1994-12-01): +# The final piece of the legislative jigsaw for summer time in the UK for +# 1995-97 is now in place. The Summer Time Order 1994 (SI 1994/2798) +# came into force on 16 November. It restates the dates from the EC +# seventh Summer Time Directive.... + +# From Peter Ilieve <peter@memex.co.uk> (March 28, 1994): +# The UK/Eire end date of 22 October [1995] conflicts with your current rule of +# Oct Sun>=23, and the historical UK formula of Sun after 4th Sat. +# The last time 4th Sun and Sun after 4th Sat differed was in 1989, +# when 29 October was used. That year was covered by a UK Summer Time Order +# for only a single year and it looks as though there was a matching 4th EC +# directive for just this year. I don't have the text of the 5th EC +# directive (for 1990--92) but my guess would be it said 4th Sun. +# To maintain strict historical accuracy you could start a new UK ending rule +# of Oct Sun>=22 in 1990. + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# +# As Ilieve remarks, the date `20 April 1924' in the table of ``Summer Time: A +# Consultation Document'' (Cm 722, 1989) table is a transcription error; +# 20 April was an Easter Sunday. Shanks has 13 April, the correct date. +# Also, the table is not quite right for 1925 through 1938; the correct rules +# (which Shanks uses) are given in the Summer Time Acts of 1922 and 1925. +# Shanks and the UK Government paper disagree about the Apr 1956 transition; +# since we have no other data, and since Shanks was correct in the other +# points of disagreement about London, we'll believe Shanks for now. +# Also, for lack of other data, we'll follow Shanks for Eire in 1940-1948. +# +# Given Peter Ilieve's comments, the following claims by Shanks are incorrect: +# * Wales did not switch from GMT to daylight savings time until +# 1921 Apr 3, when they began to conform with the rest of Great Britain. +# Actually, Wales was identical after 1880. +# * Eire had two transitions on 1916 Oct 1. +# It actually just had one transition. +# * Northern Ireland used single daylight savings time throughout WW II. +# Actually, it conformed to Britain. +# +# The following claim by Shanks is possible though doubtful; +# we'll ignore it for now. +# * Jersey, Guernsey, and the Isle of Man did not switch from GMT +# to daylight savings time until 1921 Apr 3, when they began to +# conform with Great Britain. +# +# Whitman says Dublin Mean Time was -0:25:21, which is more precise than Shanks. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule GB-Eire 1847 only - Sep 22 0:00 0 GMT +# 1916 to 1925--irregular +Rule GB-Eire 1916 only - May 21 2:00s 1:00 BST +Rule GB-Eire 1916 only - Oct 1 2:00s 0 GMT +Rule GB-Eire 1917 only - Apr 8 2:00s 1:00 BST +Rule GB-Eire 1917 only - Sep 17 2:00s 0 GMT +Rule GB-Eire 1918 only - Mar 24 2:00s 1:00 BST +Rule GB-Eire 1918 only - Sep 30 2:00s 0 GMT +Rule GB-Eire 1919 only - Mar 30 2:00s 1:00 BST +Rule GB-Eire 1919 only - Sep 29 2:00s 0 GMT +Rule GB-Eire 1920 only - Mar 28 2:00s 1:00 BST +Rule GB-Eire 1920 only - Oct 25 2:00s 0 GMT +Rule GB-Eire 1921 only - Apr 3 2:00s 1:00 BST +Rule GB-Eire 1921 only - Oct 3 2:00s 0 GMT +Rule GB-Eire 1922 only - Mar 26 2:00s 1:00 BST +Rule GB-Eire 1922 only - Oct 8 2:00s 0 GMT +Rule GB-Eire 1923 only - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1923 1924 - Sep Sun>=16 2:00s 0 GMT +Rule GB-Eire 1924 only - Apr 13 2:00s 1:00 BST +# 1925 to 1939 start--regular, except for avoiding Easter +Rule GB-Eire 1925 1926 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1925 1938 - Oct Sun>=2 2:00s 0 GMT +Rule GB-Eire 1927 only - Apr 10 2:00s 1:00 BST +Rule GB-Eire 1928 1929 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1930 only - Apr 13 2:00s 1:00 BST +Rule GB-Eire 1931 1932 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1933 only - Apr 9 2:00s 1:00 BST +Rule GB-Eire 1934 only - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1935 only - Apr 14 2:00s 1:00 BST +Rule GB-Eire 1936 1937 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1938 only - Apr 10 2:00s 1:00 BST +Rule GB-Eire 1939 only - Apr Sun>=16 2:00s 1:00 BST +# 1939 end to 1947--irregular, and with double summer time +Rule GB-Eire 1939 only - Nov 19 2:00s 0 GMT +Rule GB-Eire 1940 only - Feb 25 2:00s 1:00 BST +Rule GB-Eire 1941 only - May Sun>=2 1:00s 2:00 DST +Rule GB-Eire 1941 1943 - Aug Sun>=9 1:00s 1:00 BST +Rule GB-Eire 1942 1944 - Apr Sun>=2 1:00s 2:00 DST +Rule GB-Eire 1944 only - Sep Sun>=16 1:00s 1:00 BST +# Double daylight starts on a Monday in 1945--see above. +Rule GB-Eire 1945 only - Apr 2 1:00s 2:00 DST +Rule GB-Eire 1945 only - Jul 15 1:00s 1:00 BST +Rule GB-Eire 1945 only - Oct 7 2:00s 0 GMT +Rule GB-Eire 1946 only - Apr 14 2:00s 1:00 BST +Rule GB-Eire 1946 only - Oct 6 2:00s 0 GMT +Rule GB-Eire 1947 only - Mar 16 2:00s 1:00 BST +Rule GB-Eire 1947 only - Apr 13 1:00s 2:00 DST +Rule GB-Eire 1947 only - Aug 10 1:00s 1:00 BST +Rule GB-Eire 1947 only - Nov 2 2:00s 0 GMT +# So much for double saving time. 1948 and 1949, irregular. +Rule GB-Eire 1948 only - Mar 14 2:00s 1:00 BST +Rule GB-Eire 1948 1949 - Oct lastSun 2:00s 0 GMT +Rule GB-Eire 1949 only - Apr 3 2:00s 1:00 BST +# 1950 through start of 1953, regular. +Rule GB-Eire 1950 1953 - Apr Sun>=14 2:00s 1:00 BST +Rule GB-Eire 1950 1952 - Oct Sun>=21 2:00s 0 GMT +# 1954 to 1980, starting rules +Rule GB-Eire 1954 only - Apr 11 2:00s 1:00 BST +Rule GB-Eire 1955 1956 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1957 only - Apr 14 2:00s 1:00 BST +Rule GB-Eire 1958 1959 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1960 only - Apr 10 2:00s 1:00 BST +Rule GB-Eire 1961 1963 - Mar lastSun 2:00s 1:00 BST +Rule GB-Eire 1964 1967 - Mar Sun>=19 2:00s 1:00 BST +Rule GB-Eire 1972 1980 - Mar Sun>=16 2:00s 1:00 BST +# 1953 to 1980, ending rules +Rule GB-Eire 1953 1960 - Oct Sun>=1 2:00s 0 GMT +Rule GB-Eire 1961 1967 - Oct Sun>=23 2:00s 0 GMT +Rule GB-Eire 1971 only - Oct 31 3:00 0 GMT +Rule GB-Eire 1972 1980 - Oct Sun>=23 2:00s 0 GMT +# 1981 on +Rule GB-Eire 1981 max - Mar lastSun 1:00s 1:00 BST +Rule GB-Eire 1981 1989 - Oct Sun>=23 1:00s 0 GMT +Rule GB-Eire 1990 1995 - Oct Sun>=22 1:00s 0 GMT +Rule GB-Eire 1996 max - Oct lastSun 1:00s 0 GMT +#Rule GB-Eire 1981 max - Mar lastSun 1:00u 1:00 BST +#Rule GB-Eire 1981 1989 - Oct Sun>=23 1:00u 0 GMT +#Rule GB-Eire 1990 1995 - Oct Sun>=22 1:00u 0 GMT +#Rule GB-Eire 1996 max - Oct lastSun 1:00u 0 GMT +# Also see W-Eur, which (starting 1996) differs only in LETTER/S. + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/London -0:01:15 - LMT 1847 Sep 22 + 0:00 GB-Eire %s 1968 Feb 18 2:00 + 1:00 - BST 1971 Oct 31 2:00 + 0:00 GB-Eire %s +Zone Europe/Belfast -0:23:40 - LMT 1880 Aug 2 + -0:25:21 - DMT 1916 May 21 2:00 # Dublin MT + -0:25:21 1:00 DST 1916 Oct 1 3:00 + 0:00 GB-Eire %s 1968 Feb 18 2:00 + 1:00 - BST 1971 Oct 31 3:00 + 0:00 GB-Eire %s +Zone Europe/Dublin -0:25:21 - LMT 1880 Aug 2 + -0:25:21 - DMT 1916 May 21 2:00 # Dublin MT + -0:25:21 1:00 DST 1916 Oct 1 3:00 + 0:00 GB-Eire %s 1940 Feb 25 2:00 + 0:00 1:00 BST 1946 Oct 6 2:00 + 0:00 - GMT 1947 Mar 16 2:00 + 0:00 1:00 BST 1947 Nov 2 2:00 + 0:00 - GMT 1948 Apr 18 2:00 + 0:00 GB-Eire %s 1968 Feb 18 2:00 + 1:00 - BST 1971 Oct 31 3:00 + 0:00 GB-Eire %s + +############################################################################### + +# Continental Europe + +# The *-Eur rules now correspond to the European Community (EC). +# Three rulesets are used because the EC changes at 01:00 UTC, not local time. +# Older *-Eur rules are for convenience in the tables. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule W-Eur 1800 only - Jan 1 0:00 0 - +Rule W-Eur 1977 1980 - Apr Sun>=1 1:00s 1:00 " DST" +Rule W-Eur 1977 only - Sep lastSun 1:00s 0 - +Rule W-Eur 1978 only - Oct 1 1:00s 0 - +Rule W-Eur 1979 1995 - Sep lastSun 1:00s 0 - +Rule W-Eur 1981 max - Mar lastSun 1:00s 1:00 " DST" +Rule W-Eur 1996 max - Oct lastSun 1:00s 0 - +# Also see GB-Eire, which (starting 1996) differs only in LETTER/S. + +Rule M-Eur 1800 only - Jan 1 0:00 0 - +Rule M-Eur 1916 only - Apr 30 23:00 1:00 " DST" +Rule M-Eur 1916 only - Oct 1 1:00 0 - +Rule M-Eur 1917 1918 - Apr Mon>=15 2:00s 1:00 " DST" +Rule M-Eur 1917 1918 - Sep Mon>=15 2:00s 0 - +Rule M-Eur 1940 only - Apr 1 2:00s 1:00 " DST" +# Shanks says DST was continuous from 1940 Apr 1 to 1942 Nov 2; go with Whitman. +Rule M-Eur 1940 only - Dec 31 2:00s 0 - +Rule M-Eur 1941 only - Feb 25 2:00s 1:00 " DST" +Rule M-Eur 1941 only - Oct 5 2:00s 0 - +Rule M-Eur 1942 only - Jan 1 2:00s 1:00 " DST" +Rule M-Eur 1942 only - Nov 2 2:00s 0 - +Rule M-Eur 1943 only - Mar 29 2:00s 1:00 " DST" +Rule M-Eur 1943 only - Oct 4 2:00s 0 - +Rule M-Eur 1944 only - Apr 3 2:00s 1:00 " DST" +# Whitman gives 1944 Oct 7; go with Shanks. +Rule M-Eur 1944 only - Oct 2 2:00s 0 - +Rule M-Eur 1977 1980 - Apr Sun>=1 2:00s 1:00 " DST" +Rule M-Eur 1977 only - Sep lastSun 2:00s 0 - +Rule M-Eur 1978 only - Oct 1 2:00s 0 - +Rule M-Eur 1979 1995 - Sep lastSun 2:00s 0 - +Rule M-Eur 1981 max - Mar lastSun 2:00s 1:00 " DST" +Rule M-Eur 1996 max - Oct lastSun 2:00s 0 - + +Rule E-Eur 1981 max - Mar lastSun 3:00s 1:00 " DST" +Rule E-Eur 1981 1995 - Sep lastSun 3:00s 0 - +Rule E-Eur 1996 max - Oct lastSun 3:00s 0 - + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Russia 1880 only - Jan 1 0:00 0 - +Rule Russia 1917 only - Jul 1 23:00 1:00 " DST" +Rule Russia 1917 only - Dec 28 0:00 0 - +Rule Russia 1918 only - May 31 22:00 2:00 " DDST" +Rule Russia 1918 only - Sep 17 0:00 1:00 " DST" +Rule Russia 1919 only - May 31 23:00 2:00 " DDST" +Rule Russia 1919 only - Jul 1 2:00 1:00 D +Rule Russia 1919 only - Aug 16 0:00 0 K +Rule Russia 1921 only - Feb 14 23:00 1:00 D +# Shanks gives 1921 Mar 21 for the following transition. +# From Andrew A. Chernov <ache@astral.msk.su> (November 12, 1993): +# My sources says, that it is Mar 20, not 21. +Rule Russia 1921 only - Mar 20 23:00 2:00 DD +Rule Russia 1921 only - Sep 1 0:00 1:00 D +Rule Russia 1921 only - Oct 1 0:00 0 K +Rule Russia 1981 1984 - Apr 1 0:00 1:00 D +Rule Russia 1981 1983 - Oct 1 0:00 0 K +Rule Russia 1984 max - Sep lastSun 2:00s 0 K +Rule Russia 1985 max - Mar lastSun 2:00s 1:00 D + +# These are for backward compatibility with older versions. + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone WET 0:00 W-Eur WET%s +Zone MET 1:00 M-Eur MET%s +Zone EET 2:00 E-Eur EET%s +Zone W-SU 3:00 M-Eur ???? + +# Tom Hoffman says that MET is also known as Central European Time + +Link MET CET + +# Albania +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Albania 1940 only - Jun 16 0:00 1:00 " DST" +Rule Albania 1942 only - Nov 2 3:00 0 - +Rule Albania 1943 only - Mar 29 2:00 1:00 " DST" +Rule Albania 1943 only - Apr 10 3:00 0 - +Rule Albania 1974 only - May 4 0:00 1:00 " DST" +Rule Albania 1974 only - Oct 2 0:00 0 - +Rule Albania 1975 only - May 1 0:00 1:00 " DST" +Rule Albania 1975 only - Oct 2 0:00 0 - +Rule Albania 1976 only - May 2 0:00 1:00 " DST" +Rule Albania 1976 only - Oct 3 0:00 0 - +Rule Albania 1977 only - May 8 0:00 1:00 " DST" +Rule Albania 1977 only - Oct 2 0:00 0 - +Rule Albania 1978 only - May 6 0:00 1:00 " DST" +Rule Albania 1978 only - Oct 1 0:00 0 - +Rule Albania 1979 only - May 5 0:00 1:00 " DST" +Rule Albania 1979 only - Sep 30 0:00 0 - +Rule Albania 1980 only - May 3 0:00 1:00 " DST" +Rule Albania 1980 only - Oct 4 0:00 0 - +Rule Albania 1981 only - Apr 26 0:00 1:00 " DST" +Rule Albania 1981 only - Sep 27 0:00 0 - +Rule Albania 1982 only - May 2 0:00 1:00 " DST" +Rule Albania 1982 only - Oct 3 0:00 0 - +Rule Albania 1983 only - Apr 18 0:00 1:00 " DST" +Rule Albania 1983 only - Oct 1 0:00 0 - +Rule Albania 1984 only - Apr 1 0:00 1:00 " DST" +Rule Albania 1984 only - Oct 1 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Tirane 1:19:20 - LMT 1914 + 1:00 - MET 1940 Jun 16 + 1:00 Albania MET%s 1985 Mar 31 1:00 + 1:00 W-Eur MET%s +# This may change to `M-Eur' soon, for EC compatibility. + +# Andorra +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Andorra 0:06:04 - LMT 1901 + 0:00 - WET 1946 Sep 30 + 1:00 - MET 1985 Mar 31 2:00 + 1:00 M-Eur MET%s + +# Austria +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Austria 1918 only - Jun 16 3:00 0 - +Rule Austria 1920 only - Apr 5 2:00s 1:00 " DST" +Rule Austria 1920 only - Sep 13 2:00s 0 - +Rule Austria 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Austria 1945 only - Nov 18 2:00s 0 - +Rule Austria 1946 only - Apr 14 2:00s 1:00 " DST" +Rule Austria 1946 1948 - Oct Sun>=1 2:00s 0 - +Rule Austria 1947 only - Apr 6 2:00s 1:00 " DST" +Rule Austria 1948 only - Apr 18 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Vienna 1:05:20 - LMT 1893 Apr + 1:00 M-Eur MET%s 1918 Jun 16 3:00 + 1:00 Austria MET%s 1940 Apr 1 2:00 + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Austria MET%s 1981 Mar 29 2:00 + 1:00 M-Eur MET%s + +# Belarus +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Minsk 1:50:16 - LMT 1880 + 2:31 Russia LST%s 1919 Jul 1 2:00 + 3:00 Russia MS%s 1922 Oct + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1991 Mar 31 2:00s +# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): A guess at recent dates: + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 - EET 1992 Jan 19 2:00s + 3:00 Russia MS%s + +# Belgium +# Whitman and Shanks disagree; go with Shanks, usually. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +# From Whitman: +Rule Belgium 1919 only - Mar 1 23:00s 1:00 " DST" +Rule Belgium 1919 only - Oct 4 23:00s 0 - +# Shanks gives 1920 Feb 14 23:00s; go with Whitman. +Rule Belgium 1920 1921 - Mar 14 23:00s 1:00 " DST" +Rule Belgium 1920 only - Oct 23 23:00s 0 - +Rule Belgium 1921 only - Oct 25 23:00s 0 - +Rule Belgium 1922 only - Mar 25 23:00s 1:00 " DST" +# Whitman gives 1927 Oct 1 2:00s and 1928 Oct 7 2:00s; go with Shanks. +Rule Belgium 1922 1928 - Oct Sat>=1 23:00s 0 - +Rule Belgium 1923 only - Apr 21 23:00s 1:00 " DST" +Rule Belgium 1924 only - Mar 29 23:00s 1:00 " DST" +Rule Belgium 1925 only - Apr 4 23:00s 1:00 " DST" +Rule Belgium 1926 only - Apr 17 23:00s 1:00 " DST" +Rule Belgium 1927 only - Apr 9 23:00s 1:00 " DST" +Rule Belgium 1928 only - Apr 14 23:00s 1:00 " DST" +Rule Belgium 1929 only - Apr 21 2:00s 1:00 " DST" +Rule Belgium 1929 1938 - Oct Sun>=2 2:00s 0 - +Rule Belgium 1930 only - Apr 13 2:00s 1:00 " DST" +Rule Belgium 1931 only - Apr 19 2:00s 1:00 " DST" +Rule Belgium 1932 only - Apr 17 2:00s 1:00 " DST" +Rule Belgium 1933 only - Mar 26 2:00s 1:00 " DST" +Rule Belgium 1934 only - Apr 8 2:00s 1:00 " DST" +Rule Belgium 1935 only - Mar 31 2:00s 1:00 " DST" +Rule Belgium 1936 only - Apr 19 2:00s 1:00 " DST" +# Whitman says 1937 Apr 18 2:00s; go with Shanks. +Rule Belgium 1937 only - Apr 4 2:00s 1:00 " DST" +# Whitman says 1938 Apr 10 2:00s; go with Shanks. +Rule Belgium 1938 only - Mar 27 2:00s 1:00 " DST" +Rule Belgium 1939 only - Apr 16 2:00s 1:00 " DST" +Rule Belgium 1939 only - Nov 19 2:00s 0 - +Rule Belgium 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Belgium 1945 only - Sep 16 2:00s 0 - +Rule Belgium 1946 only - May 19 2:00s 1:00 " DST" +Rule Belgium 1946 only - Oct 7 2:00s 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Brussels 0:17:20 - LMT 1880 + 0:17 - BST 1892 May 1 12:00 + 0:00 - WET 1914 Aug 4 + 1:00 M-Eur MET%s 1919 Mar 1 23:00 + 0:00 Belgium WET%s 1940 Feb 24 23:00 + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Belgium MET%s 1977 Apr 3 2:00 + 1:00 M-Eur MET%s + +# Bosnia and Herzegovina +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Sarajevo 1:13:40 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Bulgaria +# Part switched from the Julian to the Gregorian calendar on 1915 Nov 14; +# the rest switched on 1920 Sep 17. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Bulg 1979 only - Mar 31 23:00 1:00 " DST" +Rule Bulg 1979 only - Oct 1 1:00 0 - +Rule Bulg 1980 1982 - Apr Sat<=7 23:00 1:00 " DST" +Rule Bulg 1980 only - Sep 29 1:00 0 - +Rule Bulg 1981 only - Sep 27 2:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Sofia 1:33:16 - LMT 1880 + 1:57 - TST 1894 Nov 30 + 2:00 - EET 1942 Nov 2 3:00 + 1:00 M-Eur MET%s 1945 Apr 2 3:00 + 2:00 - EET 1979 Mar 31 23:00 + 2:00 Bulg EET%s 1982 Sep 26 2:00 + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Croatia +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Zagreb 1:03:52 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Czech Republic +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Czech 1944 only - Sep 17 2:00s 0 - +Rule Czech 1945 only - Apr 8 2:00s 1:00 " DST" +Rule Czech 1945 only - Nov 18 2:00s 0 - +Rule Czech 1946 only - May 6 2:00s 1:00 " DST" +Rule Czech 1946 1949 - Oct Sun>=1 2:00s 0 - +Rule Czech 1947 only - Apr 20 2:00s 1:00 " DST" +Rule Czech 1948 only - Apr 18 2:00s 1:00 " DST" +Rule Czech 1949 only - Apr 9 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Prague 0:57:44 - LMT 1850 + 0:58 - PMT 1891 Oct # Prague Mean Time + 1:00 M-Eur MET%s 1944 Sep 17 2:00s + 1:00 Czech MET%s 1979 Apr 1 2:00 + 1:00 M-Eur MET%s + +# Denmark +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Denmark 1916 only - May 14 23:00 1:00 " DST" +Rule Denmark 1916 only - Sep 30 23:00 0 - +Rule Denmark 1940 only - May 15 0:00 1:00 " DST" +Rule Denmark 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Denmark 1945 only - Aug 15 2:00s 0 - +Rule Denmark 1946 only - May 1 2:00s 1:00 " DST" +Rule Denmark 1946 only - Sep 1 2:00s 0 - +Rule Denmark 1947 only - May 4 2:00s 1:00 " DST" +Rule Denmark 1947 only - Aug 10 2:00s 0 - +Rule Denmark 1948 only - May 9 2:00s 1:00 " DST" +Rule Denmark 1948 only - Aug 8 2:00s 0 - +# Whitman also gives 1949 Apr 9 to 1949 Oct 1, and disagrees in minor ways +# about many of the above dates; go with Shanks. +# +# For 1894, Shanks says Jan, Whitman Apr; go with Whitman. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Copenhagen 0:50:20 - LMT 1890 + 0:50 - CMT 1894 Apr # Copenhagen Mean Time + 1:00 Denmark MET%s 1942 Nov 2 2:00s + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Denmark MET%s 1980 Apr 6 2:00 + 1:00 M-Eur MET%s +Zone Atlantic/Faeroe -0:27:04 - LMT 1908 Jan 11 # Torshavn + 0:00 - WET 1981 Mar 29 1:00 + 0:00 W-Eur WET%s +Zone America/Scoresbysund -1:29:00 - LMT 1916 Jul 28 + -2:00 - MGT 1980 Apr 6 2:00 + -2:00 M-Eur MGT%s 1981 Mar 29 + -1:00 M-Eur EGT%s +Zone America/Godthab -3:26:56 - LMT 1916 Jul 28 + -3:00 - WGT 1980 Apr 6 2:00 + -3:00 M-Eur WGT%s +Zone America/Thule -4:35:08 - LMT 1916 Jul 28 + -4:00 - AST + +# Estonia +# They switched from the Julian to the Gregorian calendar on 1918 Feb 15. +# +# From Peter Ilieve <peter@memex.co.uk> (1994-10-15): +# A relative in Tallinn confirms the accuracy of the data for 1989 onwards +# [through 1994] and gives the legal authority for it, +# a regulation of the Government of Estonia, No. 111 of 1989.... +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Tallinn 1:39:00 - LMT 1880 + 1:39 - LST 1918 Feb + 1:00 M-Eur MET%s 1919 Jul + 1:39 - LST 1921 May + 2:00 - EET 1940 Aug 6 + 3:00 - MSK 1941 Sep 15 + 1:00 M-Eur MET%s 1944 Sep 22 + 3:00 Russia MS%s 1989 Mar 26 2:00s + 2:00 1:00 "EET DST" 1989 Sep 24 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Finland +# +# From Hannu Strang <chs@apu.fi> (25 Sep 1994 06:03:37 UTC): +# Well, here in Helsinki we're just changing from summer time to regular one, +# and it's supposed to change at 4am... +# +# From Paul Eggert <eggert@twinsun.com> (25 Sep 1994): +# Shanks says Finland has switched at 02:00 standard time since 1981. +# Go with Strang instead. +# +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Finland 1921 only - May 1 0:00 0 - +Rule Finland 1942 only - Apr 3 0:00 1:00 " DST" +Rule Finland 1942 only - Oct 3 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Helsinki 1:39:52 - LMT 1878 May 31 + 1:40 - HMT 1921 May # Helsinki Mean Time + 2:00 Finland EET%s 1981 Mar 29 2:00 + 2:00 E-Eur EET%s + +# France +# Shanks seems to use `24:00' ambiguously; we resolve it with Whitman. +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule France 1911 only - Jan 1 0:00 0 - +Rule France 1916 only - Jun 14 23:00s 1:00 " DST" +Rule France 1916 1919 - Oct Sun>=1 0:00 0 - +Rule France 1917 only - Mar 24 23:00s 1:00 " DST" +Rule France 1918 only - Mar 9 23:00s 1:00 " DST" +Rule France 1919 only - Mar 1 23:00s 1:00 " DST" +Rule France 1920 only - Feb 14 23:00s 1:00 " DST" +Rule France 1920 only - Oct 23 23:00s 0 - +Rule France 1921 only - Mar 14 23:00s 1:00 " DST" +Rule France 1921 only - Oct 25 23:00s 0 - +Rule France 1922 only - Mar 25 23:00s 1:00 " DST" +Rule France 1922 1938 - Oct Sat>=1 23:00s 0 - +Rule France 1923 only - May 26 23:00s 1:00 " DST" +Rule France 1924 only - Mar 29 23:00s 1:00 " DST" +Rule France 1925 only - Apr 4 23:00s 1:00 " DST" +Rule France 1926 only - Apr 17 23:00s 1:00 " DST" +Rule France 1927 only - Apr 9 23:00s 1:00 " DST" +Rule France 1928 only - Apr 14 23:00s 1:00 " DST" +Rule France 1929 only - Apr 20 23:00s 1:00 " DST" +Rule France 1930 only - Apr 12 23:00s 1:00 " DST" +Rule France 1931 only - Apr 18 23:00s 1:00 " DST" +Rule France 1932 only - Apr 2 23:00s 1:00 " DST" +Rule France 1933 only - Mar 25 23:00s 1:00 " DST" +Rule France 1934 only - Apr 7 23:00s 1:00 " DST" +Rule France 1935 only - Mar 30 23:00s 1:00 " DST" +Rule France 1936 only - Apr 18 23:00s 1:00 " DST" +Rule France 1937 only - Apr 3 23:00s 1:00 " DST" +Rule France 1938 only - Mar 26 23:00s 1:00 " DST" +Rule France 1939 only - Apr 15 23:00s 1:00 " DST" +Rule France 1939 only - Nov 18 23:00s 0 - +Rule France 1940 only - Feb 25 2:00 1:00 " DST" +# The French rules for 1941-1944 were not used in Paris, +# but were used in other places (e.g. Monaco). +Rule France 1941 only - May 5 0:00 2:00 " DDST" +Rule France 1941 only - Oct 6 1:00 1:00 " DST" +Rule France 1942 only - Mar 8 0:00 2:00 " DDST" +Rule France 1942 only - Nov 2 3:00 1:00 " DST" +Rule France 1943 only - Mar 29 2:00 2:00 " DDST" +Rule France 1943 only - Nov 4 3:00 1:00 " DST" +Rule France 1944 only - Apr 3 2:00 2:00 " DDST" +Rule France 1944 only - Oct 8 1:00 1:00 " DST" +Rule France 1945 only - Apr 2 2:00 2:00 " DDST" +Rule France 1945 only - Sep 16 3:00 0 - +# From Paul Eggert <eggert@twinsun.com) (November 18, 1993): +# Shanks gives no times for 1975, but according to Cm722, +# France introduced summer time in 1975 from 20 March to 22 September. +Rule France 1975 only - Mar 20 2:00s 1:00 " DST" +Rule France 1975 only - Sep 22 2:00s 0 - +Rule France 1976 only - Mar 28 2:00s 1:00 " DST" +Rule France 1976 only - Sep lastSun 2:00s 0 - +# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Paris 0:09:05 - LMT 1891 Mar 15 0:01 + 0:09:05 - PMT 1911 Mar 11 # Paris Mean Time + 0:00 France WET%s 1940 Jun 14 + 1:00 M-Eur MET%s 1944 Aug 25 + 0:00 France WET%s 1945 Sep 16 3:00 + 1:00 France MET%s 1977 Apr Sun>=1 2:00 + 1:00 M-Eur MET%s + +# Germany +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Germany 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Germany 1945 only - May 24 2:00 2:00 " DDST" +Rule Germany 1945 only - Sep 24 3:00 1:00 " DST" +Rule Germany 1945 only - Nov 18 2:00s 0 - +Rule Germany 1946 only - Apr 14 2:00s 1:00 " DST" +# Whitman gives 1948 Oct 31; go with Shanks. +Rule Germany 1946 1949 - Oct Sun>=1 2:00s 0 - +Rule Germany 1947 only - Apr 6 2:00s 1:00 " DST" +Rule Germany 1947 only - May 11 2:00s 2:00 " DDST" +Rule Germany 1947 only - Jun 29 3:00 1:00 " DST" +Rule Germany 1948 only - Apr 18 2:00s 1:00 " DST" +Rule Germany 1949 only - Apr 10 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Berlin 0:53:28 - LMT 1893 Apr + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Germany MET%s 1980 Apr 6 2:00 + 1:00 M-Eur MET%s + +# Gibraltar +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Gibraltar -0:21:24 - LMT 1880 Aug 2 + 0:00 GB-Eire %s 1957 Apr 14 2:00 + 1:00 - MET 1982 Mar 28 2:00 + 1:00 M-Eur MET%s + +# Greece +# They adopted the Julian calendar in 1846. +# Part switched to the Gregorian calendar on 1916 Jul 28. +# The rest switched on 1920 Mar 18. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Greece 1916 only - July 28 0:01 0 - +# Whitman gives 1932 Jul 5 - Nov 1; go with Shanks. +Rule Greece 1932 only - Jul 7 0:00 1:00 " DST" +Rule Greece 1932 only - Sep 1 0:00 0 - +# Whitman gives 1941 Apr 25 - ?; go with Shanks. +Rule Greece 1941 only - Apr 7 0:00 1:00 " DST" +# Whitman gives 1942 Feb 2 - ?; go with Shanks. +Rule Greece 1942 only - Nov 2 3:00 0 - +Rule Greece 1943 only - Mar 30 0:00 1:00 " DST" +Rule Greece 1943 only - Oct 4 0:00 0 - +# Whitman gives 1944 Oct 3 - Oct 31; go with Shanks. +Rule Greece 1952 only - Jul 1 0:00 1:00 " DST" +Rule Greece 1952 only - Nov 2 0:00 0 - +Rule Greece 1975 only - Apr 12 0:00s 1:00 " DST" +Rule Greece 1975 only - Nov 26 0:00s 0 - +Rule Greece 1976 only - Apr 11 2:00s 1:00 " DST" +Rule Greece 1976 only - Oct 10 2:00s 0 - +Rule Greece 1977 1978 - Apr Sun>=1 2:00s 1:00 " DST" +Rule Greece 1977 only - Sep 26 2:00s 0 - +Rule Greece 1978 only - Sep 24 4:00 0 - +Rule Greece 1979 only - Apr 1 9:00 1:00 " DST" +Rule Greece 1979 only - Sep 29 2:00 0 - +Rule Greece 1980 only - Apr 1 0:00 1:00 " DST" +Rule Greece 1980 only - Sep 28 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Athens 1:34:52 - LMT 1895 Sep 14 + 1:35 - AMT 1916 Jul 28 0:01 # Athens MT + 2:00 Greece EET%s 1941 Apr 30 + 1:00 Greece MET%s 1944 Apr 4 + 2:00 Greece EET%s 1981 Mar 29 2:00 +# Greece must change by 1996 for EC compatibility. + 2:00 M-Eur EET%s 1996 # Guess the last minute. + 2:00 E-Eur EET%s + +# Hungary +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Hungary 1918 only - Sep 29 2:00s 0 - +Rule Hungary 1919 only - Apr 15 3:00 1:00 " DST" +Rule Hungary 1919 only - Sep 15 3:00 0 - +Rule Hungary 1920 only - Apr 5 3:00 1:00 " DST" +Rule Hungary 1920 only - Sep 30 3:00 0 - +Rule Hungary 1945 only - May 1 23:00 1:00 " DST" +Rule Hungary 1945 only - Nov 3 0:00 0 - +Rule Hungary 1946 only - Mar 31 2:00s 1:00 " DST" +Rule Hungary 1946 1949 - Oct Sun>=1 2:00s 0 - +Rule Hungary 1947 1949 - Apr Sun>=4 2:00s 1:00 " DST" +Rule Hungary 1950 only - Apr 17 2:00s 1:00 " DST" +Rule Hungary 1950 only - Oct 23 2:00s 0 - +Rule Hungary 1954 1955 - May 23 0:00 1:00 " DST" +Rule Hungary 1954 1955 - Oct 3 0:00 0 - +Rule Hungary 1956 only - Jun Sun>=1 0:00 1:00 " DST" +Rule Hungary 1956 only - Sep lastSun 0:00 0 - +Rule Hungary 1957 only - Jun Sun>=1 1:00 1:00 " DST" +Rule Hungary 1957 only - Sep lastSun 3:00 0 - +Rule Hungary 1980 only - Apr 6 1:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Budapest 1:16:20 - LMT 1890 Oct + 1:00 M-Eur MET%s 1918 Jul + 1:00 Hungary MET%s 1941 Apr 6 2:00 + 1:00 M-Eur MET%s 1945 May 1 23:00 + 1:00 Hungary MET%s 1980 Sep 28 2:00s + 1:00 M-Eur MET%s + +# Iceland +# +# From Adam David <adam@veda.is> (November 6, 1993): +# The name of the timezone in Iceland for system / mail / news purposes is GMT. +# +# (December 5, 1993): +# This material is paraphrased from the 1988 edition of the University of +# Iceland Almanak. +# +# From January 1st, 1908 the whole of Iceland was standardised at 1 hour +# behind GMT. Previously, local mean solar time was used in different parts +# of Iceland, the almanak had been based on Reykjavik mean solar time which +# was 1 hour and 28 minutes behind GMT. +# +# "first day of winter" referred to [below] means the first day of the 26 weeks +# of winter, according to the old icelandic calendar that dates back to the +# time the norsemen first settled Iceland. The first day of winter is always +# Saturday, but is not dependent on the Julian or Gregorian calendars. +# +# (December 10, 1993): +# I have a reference from the Oxford Icelandic-English dictionary for the +# beginning of winter, which ties it to the ecclesiastical calendar (and thus +# to the julian/gregorian calendar) over the period in question. +# the winter begins on the Saturday next before St. Luke's day +# (old style), or on St. Luke's day, if a Saturday. +# St. Luke's day ought to be traceable from ecclesiastical sources. "old style" +# might be a reference to the Julian calendar as opposed to Gregorian, or it +# might mean something else (???). The Gregorian calendar was not introduced +# in Iceland until 1700. +# +# From Paul Eggert <eggert@twinsun.com> (December 9, 1993): +# The Iceland Almanak, Shanks and Whitman disagree on many points. +# We go with the Almanak, except for one claim from Shanks, namely that +# Reykavik was -1:28 from 1837 to 1908, local mean time before that. +# +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Iceland 1908 only - Jan 1 0:00 0 S +Rule Iceland 1917 1918 - Feb 19 23:00 1:00 D +Rule Iceland 1917 only - Oct 21 1:00 0 S +Rule Iceland 1918 only - Nov 16 1:00 0 S +Rule Iceland 1939 only - Apr 29 23:00 1:00 D +Rule Iceland 1939 only - Nov 29 2:00 0 S +Rule Iceland 1940 only - Feb 25 2:00 1:00 D +Rule Iceland 1940 only - Nov 3 2:00 0 S +Rule Iceland 1941 only - Mar 2 1:00s 1:00 D +Rule Iceland 1941 only - Nov 2 1:00s 0 S +Rule Iceland 1942 only - Mar 8 1:00s 1:00 D +Rule Iceland 1942 only - Oct 25 1:00s 0 S +# 1943-1946 - first Sunday in March until first Sunday in winter +Rule Iceland 1943 1946 - Mar Sun>=1 1:00s 1:00 D +Rule Iceland 1943 1948 - Oct Sun>=22 1:00s 0 S +# 1947-1967 - first Sunday in April until first Sunday in winter +Rule Iceland 1947 1967 - Apr Sun>=1 1:00s 1:00 D +# 1949 Oct transition delayed by 1 week +Rule Iceland 1949 only - Oct 30 1:00s 0 S +Rule Iceland 1950 1966 - Oct Sun>=22 1:00s 0 S +Rule Iceland 1967 only - Oct 29 1:00s 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Reykjavik -1:27:24 - LMT 1837 + -1:28 - RMT 1908 # Reykjavik Mean Time + -1:00 Iceland I%sT 1968 Apr 7 1:00s + 0:00 - GMT + +# Italy +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Italy 1893 only - Nov 1 0:00s 0 S +# Shanks gives transition times of 1916-1920 as 24:00; go with Whitman. +Rule Italy 1916 only - Jun 3 0:00s 1:00 " DST" +Rule Italy 1916 only - Sep 30 0:00s 0 - +Rule Italy 1917 only - Mar 31 0:00s 1:00 " DST" +Rule Italy 1917 only - Sep 30 0:00s 0 - +Rule Italy 1918 only - Mar 9 0:00s 1:00 " DST" +Rule Italy 1918 1919 - Oct Sun>=1 0:00s 0 - +Rule Italy 1919 only - Mar 1 0:00s 1:00 " DST" +Rule Italy 1920 only - Mar 20 0:00s 1:00 " DST" +# Shanks gives 1920 Sep 18; go with Whitman. +Rule Italy 1920 only - Oct 1 0:00s 0 - +Rule Italy 1940 only - Jun 15 0:00 1:00 " DST" +Rule Italy 1945 only - Apr 2 2:00 1:00 " DST" +Rule Italy 1945 only - Sep 17 0:00 0 - +Rule Italy 1946 only - Mar 17 2:00s 1:00 " DST" +Rule Italy 1946 only - Oct 6 2:00s 0 - +Rule Italy 1947 only - Mar 16 0:00s 1:00 " DST" +Rule Italy 1947 only - Oct 5 0:00s 0 - +Rule Italy 1948 only - Feb 29 2:00s 1:00 " DST" +Rule Italy 1948 only - Oct 3 2:00s 0 - +Rule Italy 1966 1968 - May Sun>=22 0:00 1:00 " DST" +Rule Italy 1966 1969 - Sep Sun>=22 0:00 0 - +Rule Italy 1969 only - Jun 1 0:00 1:00 " DST" +Rule Italy 1970 only - May 31 0:00 1:00 " DST" +Rule Italy 1970 only - Sep lastSun 0:00 0 - +Rule Italy 1971 1972 - May Sun>=22 0:00 1:00 " DST" +Rule Italy 1971 only - Sep lastSun 1:00 0 - +Rule Italy 1972 only - Oct 1 0:00 0 - +Rule Italy 1973 only - Jun 3 0:00 1:00 " DST" +Rule Italy 1973 1974 - Sep lastSun 0:00 0 - +Rule Italy 1974 only - May 26 0:00 1:00 " DST" +Rule Italy 1975 only - Jun 1 0:00s 1:00 " DST" +Rule Italy 1975 1977 - Sep lastSun 0:00s 0 - +Rule Italy 1976 only - May 30 0:00s 1:00 " DST" +Rule Italy 1977 1979 - May Sun>=22 0:00s 1:00 " DST" +Rule Italy 1978 only - Oct 1 0:00s 0 - +Rule Italy 1979 only - Sep 30 0:00s 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Rome 0:49:56 - LMT 1866 Sep 22 + 0:50 - RMT 1893 Nov # Rome Mean Time + 1:00 Italy MET%s 1942 Nov 2 2:00s + 1:00 M-Eur MET%s 1945 Apr 2 2:00s + 1:00 Italy MET%s 1980 Apr 6 2:00 + 1:00 M-Eur MET%s +# Vatican is identical to Europe/Rome; San Marino is like Europe/Rome. + +# Latvia +# They switched from the Julian to the Gregorian calendar on 1918 Feb 15. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Riga 1:36:24 - LMT 1880 + 1:36 - LST 1918 Apr 15 2:00 + 1:36 M-Eur LST%s 1919 Apr 1 2:00 + 1:36 1:00 "LST DST" 1919 May 22 3:00 + 1:36 - LST 1926 May 11 + 2:00 - EET 1940 Aug 5 + 3:00 - MSK 1941 Jul + 1:00 M-Eur MET%s 1944 Aug 8 + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Liechtenstein +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Vaduz 0:38:04 - LMT 1894 Jun + 1:00 - MET 1981 Mar 29 2:00 + 1:00 M-Eur MET%s + +# Lithuania +# They switched from the Julian to the Gregorian calendar on 1918 Feb 15. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Vilnius 1:41:16 - LMT 1880 + 1:24 - LST 1917 # Kaunas + 1:36 - LST 1919 Oct 10 + 1:00 - MET 1920 Jul 12 + 2:00 - EET 1920 Oct 9 + 1:00 - MET 1940 Aug 3 + 3:00 - MSK 1941 Jun 24 + 1:00 M-Eur MET%s 1944 Aug + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Luxembourg +# Whitman disagrees with most of these dates in minor ways; go with Shanks. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Lux 1904 only - Jun 1 0:00 0 - +Rule Lux 1916 only - May 14 23:00 1:00 " DST" +Rule Lux 1916 only - Oct 1 1:00 0 - +Rule Lux 1917 only - Apr 28 23:00 1:00 " DST" +Rule Lux 1917 only - Sep 17 1:00 0 - +Rule Lux 1918 only - Apr Mon>=15 2:00s 1:00 " DST" +Rule Lux 1918 only - Sep Mon>=15 2:00s 0 - +Rule Lux 1919 only - Mar 1 23:00 1:00 " DST" +Rule Lux 1919 only - Oct 5 3:00 0 - +Rule Lux 1920 only - Feb 14 23:00 1:00 " DST" +Rule Lux 1920 only - Oct 24 2:00 0 - +Rule Lux 1921 only - Mar 14 23:00 1:00 " DST" +Rule Lux 1921 only - Oct 26 2:00 0 - +Rule Lux 1922 only - Mar 25 23:00 1:00 " DST" +Rule Lux 1922 only - Oct Sun>=2 1:00 0 - +Rule Lux 1923 only - Apr 21 23:00 1:00 " DST" +Rule Lux 1923 only - Oct Sun>=2 2:00 0 - +Rule Lux 1924 only - Mar 29 23:00 1:00 " DST" +Rule Lux 1924 1928 - Oct Sun>=2 1:00 0 - +Rule Lux 1925 only - Apr 5 23:00 1:00 " DST" +Rule Lux 1926 only - Apr 17 23:00 1:00 " DST" +Rule Lux 1927 only - Apr 9 23:00 1:00 " DST" +Rule Lux 1928 only - Apr 14 23:00 1:00 " DST" +Rule Lux 1929 only - Apr 20 23:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Luxembourg 0:24:36 - LMT 1904 Jun + 1:00 Lux MET%s 1918 Nov 25 + 0:00 Lux WET%s 1929 Oct 6 2:00s + 0:00 Belgium WET%s 1940 May 14 3:00 + 1:00 M-Eur WET%s 1944 Sep 18 3:00 + 1:00 Belgium MET%s 1979 Apr 1 2:00 + 1:00 M-Eur MET%s + +# Macedonia +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Skopje 1:25:44 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Malta +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Malta 1973 only - Mar 31 0:00s 1:00 " DST" +Rule Malta 1973 only - Sep 29 0:00s 0 - +Rule Malta 1974 only - Apr 21 0:00s 1:00 " DST" +Rule Malta 1974 only - Sep 16 0:00s 0 - +Rule Malta 1975 1979 - Apr Sun>=15 2:00 1:00 " DST" +Rule Malta 1975 1980 - Sep Sun>=15 2:00 0 - +Rule Malta 1980 only - Mar 31 2:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 # Valletta + 1:00 Italy MET%s 1942 Nov 2 2:00s + 1:00 M-Eur MET%s 1945 Apr 2 2:00s + 1:00 Italy MET%s 1973 Mar 31 + 1:00 Malta MET%s 1981 Mar 29 2:00s + 1:00 M-Eur MET%s + +# Moldova +# They switched from the Julian to the Gregorian calendar on 1919 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Chisinau 1:55:20 - LMT 1924 May 2 + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Monaco +# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15 + 0:09:05 - PMT 1911 Mar 11 # Paris Mean Time + 0:00 France WET%s 1945 Sep 16 3:00 + 1:00 France MET%s 1977 Apr Sun>=1 2:00 + 1:00 M-Eur MET%s + +# Netherlands +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Neth 1892 only - May 1 0:00 0 AMT +# Shanks gives 1916 May 1 0:00 and 1916 Oct 1 0:00; go with Whitman. +Rule Neth 1916 only - May 1 2:00s 1:00 NST +Rule Neth 1916 only - Oct 2 2:00s 0 AMT +Rule Neth 1917 only - Apr 16 2:00s 1:00 NST +Rule Neth 1917 only - Sep 17 2:00s 0 AMT +# Whitman gives 1918 Apr 14, 1918 Oct 31, and 1921 Sep 28; go with Shanks. +Rule Neth 1918 1921 - Apr Mon>=1 2:00s 1:00 NST +Rule Neth 1918 1921 - Sep Mon>=24 2:00s 0 AMT +Rule Neth 1922 only - Mar 26 2:00s 1:00 NST +# Whitman gives 1939 Oct 1; go with Shanks. +Rule Neth 1922 1939 - Oct Sun>=2 2:00s 0 AMT +Rule Neth 1923 only - Jun 1 2:00s 1:00 NST +Rule Neth 1924 only - Mar 30 2:00s 1:00 NST +# Whitman gives 1925 Apr 5; go with Shanks. +Rule Neth 1925 only - Jun 5 2:00s 1:00 NST +# For 1926 through 1930 Whitman gives Apr 15; go with Shanks. +Rule Neth 1926 1931 - May 15 2:00s 1:00 NST +Rule Neth 1932 only - May 22 2:00s 1:00 NST +Rule Neth 1933 1936 - May 15 2:00s 1:00 NST +Rule Neth 1937 only - May 22 2:00s 1:00 NST +# Whitman gives 1939 Apr 15 and 1940 Apr 19; go with Shanks. +Rule Neth 1938 1939 - May 15 2:00s 1:00 NST +Rule Neth 1945 only - Apr 2 2:00s 1:00 - +Rule Neth 1945 only - May 20 2:00s 0 " DST" +# Before 1937, Shanks says just `0:20'; we use Whitman's more precise figure. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Amsterdam 0:19:28 - LMT 1892 May + 0:19:28 Neth %s 1937 Jul + 0:20 Neth %s 1940 May 16 0:40 + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Neth MET%s 1977 Apr Sun>=1 2:00 + 1:00 M-Eur MET%s + +# Norway +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Norway 1892 only - May 1 0:00 0 - +# Whitman gives 1916 May 21 - 1916 Oct 21; go with Shanks. +Rule Norway 1916 only - May 22 1:00 1:00 " DST" +Rule Norway 1916 only - Sep 30 0:00 0 - +# Shanks omits the following transition; go with Whitman. +Rule Norway 1935 only - Aug 11 0:00 1:00 " DST" +# Whitman says DST observed until 1942 Nov 1, then 1943 Mar 29 - Oct 4, +# 1944 Apr 3 - Oct 2, and 1945 Apr 1 - Oct 1; go with Shanks after 1940. +Rule Norway 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Norway 1945 only - Oct 1 2:00s 0 - +Rule Norway 1959 1964 - Mar Sun>=15 2:00s 1:00 " DST" +Rule Norway 1959 1965 - Sep Sun>=15 2:00s 0 - +Rule Norway 1965 only - Apr 25 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Oslo 0:43:00 - LMT 1895 + 1:00 Norway MET%s 1940 Aug 10 23:00 + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Norway MET%s 1980 Apr 6 2:00 + 1:00 M-Eur MET%s +# Svalbard is like Europe/Oslo. +# +# From Whitman: +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Jan_Mayen -1:00 - EGT + +# Poland +# Austrian and German Poland switched from the Julian to the Gregorian calendar +# on 1582 Oct 15. Russian Poland switched on 1918 Jan 14. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Poland 1918 1919 - Sep 16 2:00s 0 - +Rule Poland 1919 only - Apr 15 2:00s 1:00 " DST" +# Whitman gives 1944 Nov 30; go with Shanks. +Rule Poland 1944 only - Oct 4 2:00 0 - +# For 1944-1948 Whitman gives the previous day; go with Shanks. +Rule Poland 1945 only - Apr 29 0:00 1:00 " DST" +Rule Poland 1945 only - Nov 1 0:00 0 - +Rule Poland 1946 only - Apr 14 0:00 1:00 " DST" +Rule Poland 1946 only - Sep 7 0:00 0 - +Rule Poland 1947 only - May 4 0:00 1:00 " DST" +Rule Poland 1947 1948 - Oct Sun>=1 0:00 0 - +Rule Poland 1948 only - Apr 18 0:00 1:00 " DST" +# Whitman also gives 1949 Apr 9 - 1949 Oct 1; go with Shanks. +Rule Poland 1957 only - Jun 2 1:00s 1:00 " DST" +Rule Poland 1957 1958 - Sep lastSun 1:00s 0 - +Rule Poland 1958 only - Mar 30 1:00s 1:00 " DST" +Rule Poland 1959 only - May 31 1:00s 1:00 " DST" +Rule Poland 1959 1961 - Oct Sun>=1 1:00s 0 - +Rule Poland 1960 only - Apr 3 1:00s 1:00 " DST" +Rule Poland 1961 1964 - May Sun>=25 1:00s 1:00 " DST" +Rule Poland 1962 1964 - Sep lastSun 1:00s 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Warsaw 1:24:00 - LMT 1880 + 1:24 - WMT 1915 Aug 5 # Warsaw Mean Time + 1:00 M-Eur MET%s 1918 Sep 16 3:00 + 2:00 Poland EET%s 1922 Jun + 1:00 Poland MET%s 1940 Jun 23 2:00 + 1:00 M-Eur MET%s 1944 Oct + 1:00 Poland MET%s 1977 Apr 3 1:00 + 1:00 W-Eur MET%s +# This may change to `M-Eur' soon, for EC compatibility. + +# Portugal +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Port 1911 only - May 24 0:00 0 - +Rule Port 1916 only - Jun 17 23:00 1:00 " DST" +# Whitman gives 1916 Oct 31; go with Shanks. +Rule Port 1916 only - Nov 1 1:00 0 - +Rule Port 1917 only - Feb 28 23:00s 1:00 " DST" +Rule Port 1917 1921 - Oct 14 23:00s 0 - +Rule Port 1918 only - Mar 1 23:00s 1:00 " DST" +Rule Port 1919 only - Feb 28 23:00s 1:00 " DST" +Rule Port 1920 only - Feb 29 23:00s 1:00 " DST" +Rule Port 1921 only - Feb 28 23:00s 1:00 " DST" +Rule Port 1924 only - Apr 16 23:00s 1:00 " DST" +Rule Port 1924 only - Oct 14 23:00s 0 - +Rule Port 1926 only - Apr 17 23:00s 1:00 " DST" +Rule Port 1926 1929 - Oct Sat>=1 23:00s 0 - +Rule Port 1927 only - Apr 9 23:00s 1:00 " DST" +Rule Port 1928 only - Apr 14 23:00s 1:00 " DST" +Rule Port 1929 only - Apr 20 23:00s 1:00 " DST" +Rule Port 1931 only - Apr 18 23:00s 1:00 " DST" +# Whitman gives 1931 Oct 8; go with Shanks. +Rule Port 1931 1932 - Oct Sat>=1 23:00s 0 - +Rule Port 1932 only - Apr 2 23:00s 1:00 " DST" +# Shanks gives 1934 Apr 4; go with Whitman. +Rule Port 1934 only - Apr 7 23:00s 1:00 " DST" +# Whitman gives 1934 Oct 5; go with Shanks. +Rule Port 1934 1938 - Oct Sat>=1 23:00s 0 - +# Shanks gives 1935 Apr 30; go with Whitman. +Rule Port 1935 only - Mar 30 23:00s 1:00 " DST" +Rule Port 1936 only - Apr 18 23:00s 1:00 " DST" +# Whitman gives 1937 Apr 2; go with Shanks. +Rule Port 1937 only - Apr 3 23:00s 1:00 " DST" +Rule Port 1938 only - Mar 26 23:00s 1:00 " DST" +Rule Port 1939 only - Apr 15 23:00s 1:00 " DST" +# Whitman gives 1939 Oct 7; go with Shanks. +Rule Port 1939 only - Nov 18 23:00s 0 - +Rule Port 1940 only - Feb 24 23:00s 1:00 " DST" +# Shanks gives 1940 Oct 7; go with Whitman. +Rule Port 1940 1941 - Oct 5 23:00s 0 - +Rule Port 1941 only - Apr 5 23:00s 1:00 " DST" +Rule Port 1942 1945 - Mar Sat>=8 23:00s 1:00 " DST" +Rule Port 1942 only - Apr 25 22:00s 2:00 " DDST" +Rule Port 1942 only - Aug 15 22:00s 1:00 " DST" +Rule Port 1942 1945 - Oct Sat>=24 23:00s 0 - +Rule Port 1943 only - Apr 17 22:00s 2:00 " DDST" +Rule Port 1943 1945 - Aug Sat>=25 22:00s 1:00 " DST" +Rule Port 1944 1945 - Apr Sat>=21 22:00s 2:00 " DDST" +Rule Port 1946 only - Apr Sat>=1 23:00s 1:00 " DST" +Rule Port 1946 only - Oct Sat>=1 23:00s 0 - +Rule Port 1947 1949 - Apr Sun>=1 2:00s 1:00 " DST" +Rule Port 1947 1949 - Oct Sun>=1 2:00s 0 - +# Shanks says DST was observed in 1950; go with Whitman. +# Whitman gives Oct lastSun for 1952 on; go with Shanks. +Rule Port 1951 1965 - Apr Sun>=1 2:00s 1:00 " DST" +Rule Port 1951 1965 - Oct Sun>=1 2:00s 0 - +Rule Port 1977 only - Mar 27 0:00s 1:00 " DST" +Rule Port 1977 only - Sep 25 0:00s 0 - +Rule Port 1978 1979 - Apr Sun>=1 0:00s 1:00 " DST" +Rule Port 1978 only - Oct 1 0:00s 0 - +Rule Port 1979 1982 - Sep lastSun 1:00s 0 - +Rule Port 1980 only - Mar lastSun 0:00s 1:00 " DST" +Rule Port 1981 1982 - Mar lastSun 1:00s 1:00 " DST" +Rule Port 1983 only - Mar lastSun 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Lisbon -0:36:32 - LMT 1884 + -0:37 - LMT 1911 May 24 # Lisbon Mean Time + 0:00 Port WET%s 1966 Apr 3 2:00 + 1:00 - MET 1976 Sep 26 1:00 + 0:00 Port WET%s 1983 Sep 25 1:00s + 0:00 W-Eur WET%s 1992 Sep 27 1:00s +# From Rui Pedro Salgueiro <rps@inescca.inescc.pt> (November 12, 1992): +# Portugal has recently (September, 27) changed timezone +# (from WET to MET or CET) to harmonize with EEC. + 1:00 M-Eur MET%s +# We don't know what happened to Madeira or the Azores, +# so we'll just use Shanks for now. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Azores -1:42:40 - LMT 1884 # Ponta Delgada + -1:55 - HMT 1911 May 24 # Horta Mean Time + -2:00 Port ACT%s 1966 Apr 3 2:00 + -1:00 - ACT 1977 Mar 27 + -1:00 - ACT 1983 Sep 25 1:00s + -1:00 W-Eur ACT%s +Zone Atlantic/Madeira -1:07:36 - LMT 1884 # Funchal + -1:08 - FMT 1911 May 24 # Funchal Mean Time + -1:00 Port ACT%s 1966 Apr 3 2:00 + 0:00 - WET 1977 Mar 27 + 0:00 Port WET%s 1983 Sep 25 1:00s + 0:00 W-Eur WET%s + +# Slovakia +Link Europe/Prague Europe/Bratislava + +# Romania +# Catholic Romania switched from the Julian to the Gregorian calendar on +# on 1919 Mar 18. Greek Orthodox Romania switched on 1920 Mar 18. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Romania 1931 only - Jul 24 0:00 0 - +Rule Romania 1932 only - May 21 0:00s 1:00 " DST" +Rule Romania 1932 1939 - Oct Sun>=1 0:00s 0 - +Rule Romania 1933 1939 - Apr Sun>=2 0:00s 1:00 " DST" +Rule Romania 1979 only - May 27 0:00 1:00 " DST" +Rule Romania 1979 only - Sep lastSun 0:00 0 - +Rule Romania 1980 only - Apr 5 23:00 1:00 " DST" +Rule Romania 1980 only - Sep lastSun 1:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct + 1:44 - BMT 1931 Jul 24 # Bucharest MT + 2:00 Romania EET%s 1981 Mar 29 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Russia +# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): +# Moscow and Novosibirsk time zone names, and Moscow rules after 1991, +# are from Andrew A. Chernov <ache@astral.msk.su>. +# I invented the other time zone names, and (unless otherwise specified) +# guessed what happened after 1991; the clocks were chaotic, and we know little. +# The rest is from Shanks. +# +# From Shanks (1991): +# Western Russia switched from the Julian to the Gregorian calendar +# on 1918 Jan 14. Eastern Russia switched on 1920 Mar 18. +# In 1929 the Soviet Union instituted a 5 day week; in 1932 it instituted +# a 6 day week; on 1940 Jun 27 it returned to the Gregorian week. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Moscow 2:30:20 - LMT 1880 + 2:31 Russia LST%s 1919 Jul 1 2:00 + 3:00 Russia MS%s 1922 Oct + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 - EET 1992 Jan 19 2:00s + 3:00 Russia MS%s +Zone Europe/Kuybyshev 3:20:36 - LMT 1924 May 2 + 3:00 - KSK 1957 Mar + 4:00 Russia KS%s 1991 Mar 31 2:00s + 3:00 1:00 KSD 1991 Sep 29 2:00s + 3:00 - KSK 1992 Jan 19 2:00s + 4:00 Russia KS%s +Zone Asia/Yekaterinburg 4:02:34 - LMT 1924 May 2 + 4:00 - SSK 1957 Mar + 5:00 Russia SS%s 1991 Mar 31 2:00s + 4:00 1:00 SSD 1991 Sep 29 2:00s + 4:00 - SSK 1992 Jan 19 2:00s + 5:00 Russia ES%s # name change from Sverdlovsk +Zone Asia/Omsk 4:53:36 - LMT 1924 May 2 + 5:00 - OSK 1957 Mar + 6:00 Russia OS%s 1991 Mar 31 2:00s + 5:00 1:00 OSD 1991 Sep 29 2:00s + 5:00 - OSK 1992 Jan 19 2:00s + 6:00 Russia OS%s +# From Stanislaw A. Kuzikowski <S.A.Kuz@iae.nsk.su> (June 29, 1994): +# But now it is some months since Novosibirsk is 3 hours ahead of Moscow! +# I do not know why they have decided to make this change; +# as far as I remember it was done exactly during winter->summer switching +# so we (Novosibirsk) simply did not switch. +# Tomsk is still 4 hours ahead of Moscow. +Zone Asia/Novosibirsk 5:31:40 - LMT 1924 May 2 + 6:00 - NSK 1957 Mar + 7:00 Russia NS%s 1991 Mar 31 2:00s + 6:00 1:00 NSD 1991 Sep 29 2:00s + 6:00 - NSK 1992 Jan 19 2:00s + 7:00 Russia NS%s 1994 Mar 27 2:00s + 6:00 1:00 NSD 1994 Sep 25 2:00s + 6:00 Russia NS%s +Zone Asia/Tomsk 5:39:52 - LMT 1924 May 2 + 6:00 - TSK 1957 Mar + 7:00 Russia TS%s 1991 Mar 31 2:00s + 6:00 1:00 TSD 1991 Sep 29 2:00s + 6:00 - TSK 1992 Jan 19 2:00s + 7:00 Russia TS%s +Zone Asia/Irkutsk 6:57:20 - LMT 1880 + 6:57 - LST 1924 May 2 + 7:00 - ISK 1957 Mar + 8:00 Russia IS%s 1991 Mar 31 2:00s + 7:00 1:00 ISD 1991 Sep 29 2:00s + 7:00 - ISK 1992 Jan 19 2:00s + 8:00 Russia IS%s +Zone Asia/Yakutsk 8:38:40 - LMT 1924 May 2 + 8:00 - YSK 1957 Mar + 9:00 Russia YS%s 1991 Mar 31 2:00s + 8:00 1:00 YSD 1991 Sep 29 2:00s + 8:00 - YSK 1992 Jan 19 2:00s + 9:00 Russia YS%s +Zone Asia/Vladivostok 8:47:44 - LMT 1880 + 8:48 - LST 1924 May 2 + 9:00 - VSK 1957 Mar + 10:00 Russia VS%s 1991 Mar 31 2:00s + 9:00 1:00 VSD 1991 Sep 29 2:00s + 9:00 - VSK 1992 Jan 19 2:00s + 10:00 Russia VS%s +# MSK is taken; settle for GSK. +Zone Asia/Magadan 10:03:12 - LMT 1924 May 2 + 10:00 - GSK 1957 Mar + 11:00 Russia GS%s 1991 Mar 31 2:00s + 10:00 1:00 GSD 1991 Sep 29 2:00s + 10:00 - GSK 1992 Jan 19 2:00s + 11:00 Russia GS%s +# This name should be Asia/Petropavlovsk-Kamchatski, but that's too long. +Zone Asia/Kamchatka 10:34:36 - LMT 1924 May 2 + 11:00 - PSK 1957 Mar + 12:00 Russia PS%s 1991 Mar 31 2:00s + 11:00 1:00 PSD 1991 Sep 29 2:00s + 11:00 - PSK 1992 Jan 19 2:00s + 12:00 Russia PS%s +Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2 + 12:00 - ASK 1957 Mar + 13:00 Russia AS%s 1991 Mar 31 2:00s + 12:00 1:00 ASD 1991 Sep 29 2:00s + 12:00 - ASK 1992 Jan 19 2:00s + 13:00 Russia AS%s + +# Serbia +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Belgrade 1:22:00 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Slovenia +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Ljubljana 0:58:04 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Spain +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Spain 1901 only - Jan 1 0:00 0 - +# For 1917-1919 Whitman gives Apr Sat>=1 - Oct Sat>=1; go with Shanks. +Rule Spain 1917 only - May 5 23:00s 1:00 " DST" +Rule Spain 1917 1919 - Oct 6 23:00s 0 - +Rule Spain 1918 only - Apr 15 23:00s 1:00 " DST" +Rule Spain 1919 only - Apr 5 23:00s 1:00 " DST" +# Whitman gives 1921 Feb 28 - Oct 14; go with Shanks. +Rule Spain 1924 only - Apr 16 23:00s 1:00 " DST" +# Whitman gives 1924 Oct 14; go with Shanks. +Rule Spain 1924 only - Oct 4 23:00s 0 - +Rule Spain 1926 only - Apr 17 23:00s 1:00 " DST" +# Whitman says no DST in 1929; go with Shanks. +Rule Spain 1926 1929 - Oct Sat>=1 23:00s 0 - +Rule Spain 1927 only - Apr 9 23:00s 1:00 " DST" +Rule Spain 1928 only - Apr 14 23:00s 1:00 " DST" +Rule Spain 1929 only - Apr 20 23:00s 1:00 " DST" +# Whitman gives 1937 Jun 16, 1938 Apr 16, 1940 Apr 13; go with Shanks. +Rule Spain 1937 only - May 22 23:00s 1:00 " DST" +Rule Spain 1937 1939 - Oct Sat>=1 23:00s 0 - +Rule Spain 1938 only - Mar 22 23:00s 1:00 " DST" +Rule Spain 1939 only - Apr 15 23:00s 1:00 " DST" +Rule Spain 1940 only - Mar 16 23:00s 1:00 " DST" +# Whitman says no DST 1942-1945; go with Shanks. +Rule Spain 1942 only - May 2 22:00s 2:00 " DDST" +Rule Spain 1942 only - Sep 1 22:00s 1:00 " DST" +Rule Spain 1943 1946 - Apr Sat>=13 22:00s 2:00 " DDST" +Rule Spain 1943 only - Oct 3 22:00s 1:00 " DST" +Rule Spain 1944 only - Oct 10 22:00s 1:00 " DST" +Rule Spain 1945 only - Sep 30 1:00 1:00 " DST" +Rule Spain 1949 only - Apr 30 23:00 1:00 " DST" +Rule Spain 1949 only - Sep 30 1:00 0 - +Rule Spain 1974 1975 - Apr Sat>=13 23:00 1:00 " DST" +Rule Spain 1974 1975 - Oct Sun>=1 1:00 0 - +Rule Spain 1976 only - Mar 27 23:00 1:00 " DST" +Rule Spain 1976 1977 - Sep lastSun 1:00 0 - +Rule Spain 1977 1978 - Apr 2 23:00 1:00 " DST" +Rule Spain 1978 only - Oct 1 1:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Madrid -0:14:44 - LMT 1901 + 0:00 Spain WET%s 1946 Sep 30 + 1:00 Spain MET%s 1979 Apr 1 2:00 + 1:00 M-Eur MET%s +Zone Atlantic/Canary -1:01:36 - LMT 1922 Mar # Las Palmas de Gran C. + -1:00 - ACT 1946 Sep 30 1:00 + 0:00 - WET 1980 Apr 6 0:00s + 0:00 1:00 "WET DST" 1980 Sep 28 0:00s + 0:00 W-Eur WET%s + +# Sweden +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Stockholm 1:12:12 - LMT 1878 May 31 + 1:12 - SMT 1900 Jan 1 1:00 # Stockholm MT + 1:00 - MET 1916 Apr 14 23:00s + 1:00 1:00 "MET DST" 1916 Sep 30 23:00s + 1:00 - MET 1980 Apr 6 2:00 + 1:00 M-Eur MET%s + +# Switzerland +# From Howse (1988), p 82: +# By the end of the 18th century clocks and watches became commonplace +# and their performance improved enormously. Communities began to keep +# mean time in preference to apparent time -- Geneva from 1780 .... +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Swiss 1894 only - Jun 1 0:00 0 - +# From Whitman (who writes ``Midnight?''): +Rule Swiss 1940 only - Nov 2 0:00 1:00 " DST" +Rule Swiss 1940 only - Dec 31 0:00 0 " DST" +# From Shanks (1991): +Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 " DST" +Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12 + 0:30 - SST 1894 Jun # Swiss Standard Time + 1:00 Swiss MET%s 1981 Mar 29 2:00 + 1:00 M-Eur MET%s + +# Turkey +# European Turkey switched to the Gregorian calendar in 1908. +# Asian Turkey switched in 1914. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Turkey 1910 only - Oct 1 0:00 0 - +Rule Turkey 1916 only - May 1 0:00 1:00 " DST" +Rule Turkey 1916 only - Oct 1 0:00 0 - +Rule Turkey 1920 only - Mar 28 0:00 1:00 " DST" +Rule Turkey 1920 only - Oct 25 0:00 0 - +Rule Turkey 1921 only - Apr 3 0:00 1:00 " DST" +Rule Turkey 1921 only - Oct 3 0:00 0 - +Rule Turkey 1922 only - Mar 26 0:00 1:00 " DST" +Rule Turkey 1922 only - Oct 8 0:00 0 - +# Whitman gives 1923 Apr 28 - Sep 16 and no DST in 1924-1925; go with Shanks. +Rule Turkey 1924 only - May 13 0:00 1:00 " DST" +Rule Turkey 1924 1925 - Oct 1 0:00 0 - +Rule Turkey 1925 only - May 1 0:00 1:00 " DST" +# Shanks omits the first two transitions in 1940; go with Whitman. +Rule Turkey 1940 only - Jun 30 0:00 1:00 " DST" +Rule Turkey 1940 only - Oct 5 0:00 0 - +Rule Turkey 1940 only - Dec 1 0:00 1:00 " DST" +Rule Turkey 1941 only - Sep 21 0:00 0 - +Rule Turkey 1942 only - Apr 1 0:00 1:00 " DST" +# Whitman omits the next two transition and gives 1945 Oct 1; go with Shanks. +Rule Turkey 1942 only - Nov 1 0:00 0 - +Rule Turkey 1945 only - Apr 2 0:00 1:00 " DST" +Rule Turkey 1945 only - Oct 8 0:00 0 - +Rule Turkey 1946 only - Jun 1 0:00 1:00 " DST" +Rule Turkey 1946 only - Oct 1 0:00 0 - +Rule Turkey 1947 1948 - Apr Sun>=16 0:00 1:00 " DST" +Rule Turkey 1947 1950 - Oct Sun>=2 0:00 0 - +Rule Turkey 1949 only - Apr 10 0:00 1:00 " DST" +Rule Turkey 1950 only - Apr 19 0:00 1:00 " DST" +Rule Turkey 1951 only - Apr 22 0:00 1:00 " DST" +Rule Turkey 1951 only - Oct 8 0:00 0 - +Rule Turkey 1962 only - Jul 15 0:00 1:00 " DST" +Rule Turkey 1962 only - Oct 8 0:00 0 - +Rule Turkey 1964 only - May 15 0:00 1:00 " DST" +Rule Turkey 1964 only - Oct 1 0:00 0 - +Rule Turkey 1970 1972 - May Sun>=2 0:00 1:00 " DST" +Rule Turkey 1970 1972 - Oct Sun>=2 0:00 0 - +Rule Turkey 1973 only - Jun 3 1:00 1:00 " DST" +Rule Turkey 1973 only - Nov 4 3:00 0 - +Rule Turkey 1974 only - Mar 31 2:00 1:00 " DST" +Rule Turkey 1974 only - Nov 3 5:00 0 - +Rule Turkey 1975 only - Mar 30 0:00 1:00 " DST" +Rule Turkey 1975 1976 - Oct lastSun 0:00 0 - +Rule Turkey 1976 only - Jun 1 0:00 1:00 " DST" +Rule Turkey 1977 1978 - Apr Sun>=1 0:00 1:00 " DST" +Rule Turkey 1977 only - Oct 16 0:00 0 - +Rule Turkey 1979 1980 - Apr Sun>=1 3:00 1:00 " DST" +Rule Turkey 1979 1982 - Oct Mon>=11 0:00 0 - +Rule Turkey 1981 1982 - Mar lastSun 3:00 1:00 " DST" +Rule Turkey 1983 only - Jul 31 0:00 1:00 " DST" +Rule Turkey 1983 only - Oct 2 0:00 0 - +Rule Turkey 1985 only - Apr 20 0:00 1:00 " DST" +Rule Turkey 1985 only - Sep 28 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Istanbul 1:55:52 - LMT 1880 + 1:57 - OMT 1910 Oct # Ottoman Mean Time + 2:00 Turkey EET%s 1978 Oct 15 + 3:00 Turkey TUR%s 1985 Apr 20 + 2:00 Turkey EET%s 1986 + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. +Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. + +# Ukraine +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Ukraine 1919 only - Jul 1 2:00 1:00 " DST" +Rule Ukraine 1919 only - Aug 16 0:00 0 - +Rule Ukraine 1921 only - Feb 14 23:00 1:00 " DST" +Rule Ukraine 1921 only - Mar 21 23:00 2:00 " DDST" +Rule Ukraine 1921 only - Sep 1 0:00 1:00 " DST" +Rule Ukraine 1921 only - Oct 1 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Kiev 2:02:04 - LMT 1880 + 2:02 Russia LST%s 1919 Jul 1 2:00 + 2:02 Ukraine LST%s 1924 May 2 + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1990 Jul 17 + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. +Zone Europe/Simferopol 2:16:24 - LMT 1880 + 2:08 Russia LST%s 1919 Jul 1 2:00 + 2:08 Ukraine LST%s 1924 May 2 + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s +# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): +# Today's _Economist_ (p 45) reports that Crimea switched +# from Kiev to Moscow time sometime after the January elections. +# For now, we'll guess that there was a 2-hour leap forward on March 27. + 2:00 M-Eur EET%s 1994 Mar 27 2:00s + 3:00 Russia MS%s + +############################################################################### + +# One source shows that Bulgaria, Cyprus, Finland, and Greece observe DST from +# the last Sunday in March to the last Sunday in September in 1986. +# The source shows Romania changing a day later than everybody else. +# +# According to Bernard Sieloff's source, Poland is in the MET time zone but +# uses the WE DST rules. The Western USSR uses EET+1 and ME DST rules. +# Bernard Sieloff's source claims Romania switches on the same day, but at +# 00:00 standard time (i.e., 01:00 DST). It also claims that Turkey +# switches on the same day, but switches on at 01:00 standard time +# and off at 00:00 standard time (i.e., 01:00 DST) + +# ... +# Date: Wed, 28 Jan 87 16:56:27 -0100 +# From: seismo!mcvax!cgcha!wtho (Tom Hofmann) +# Message-Id: <8701281556.AA22174@cgcha.uucp> +# ... +# +# ...the European time rules are...standardized since 1981, when +# most European coun[tr]ies started DST. Before that year, only +# a few countries (UK, France, Italy) had DST, each according +# to own national rules. In 1981, however, DST started on +# 'Apr firstSun', and not on 'Mar lastSun' as in the following +# years... +# But also since 1981 there are some more national exceptions +# than listed in 'europe': Switzerland, for example, joined DST +# one year later, Denmark ended DST on 'Oct 1' instead of 'Sep +# lastSun' in 1981---I don't know how they handle now. +# +# Finally, DST ist always from 'Apr 1' to 'Oct 1' in the +# Soviet Union (as far as I know). +# +# Tom Hofmann, Scientific Computer Center, CIBA-GEIGY AG, +# 4002 Basle, Switzerland +# UUCP: ...!mcvax!cernvax!cgcha!wtho + +# ... +# Date: Wed, 4 Feb 87 22:35:22 +0100 +# From: seismo!mcvax!cwi.nl!dik (Dik T. Winter) +# ... +# +# The information from Tom Hofmann is (as far as I know) not entirely correct. +# After a request from chongo at amdahl I tried to retrieve all information +# about DST in Europe. I was able to find all from about 1969. +# +# ...standardization on DST in Europe started in about 1977 with switches on +# first Sunday in April and last Sunday in September... +# In 1981 UK joined Europe insofar that +# the starting day for both shifted to last Sunday in March. And from 1982 +# the whole of Europe used DST, with switch dates April 1 and October 1 in +# the Sov[i]et Union. In 1985 the SU reverted to standard Europe[a]n switch +# dates... +# +# It should also be remembered that time-zones are not constants; e.g. +# Portugal switched in 1976 from MET (or CET) to WET with DST... +# Note also that though there were rules for switch dates not +# all countries abided to these dates, and many individual deviations +# occurred, though not since 1982 I believe. Another note: it is always +# assumed that DST is 1 hour ahead of normal time, this need not be the +# case; at least in the Netherlands there have been times when DST was 2 hours +# in advance of normal time. +# +# ... +# dik t. winter, cwi, amsterdam, nederland +# INTERNET : dik@cwi.nl +# BITNET/EARN: dik@mcvax + +# From Bob Devine (January 28, 1988): +# ... +# Greece: Last Sunday in April to last Sunday in September (iffy on dates). +# Since 1978. Change at midnight. +# ... +# Monaco: has same DST as France. +# ... + +# ... +# Date: Fri, 3 Sep 93 13:43:41 BST +# From: Peter Ilieve <peter@memex.co.uk> +# ... +# Turning to Europe, I now have a copy of the `Sixth Council Directive 92/20/EEC +# of 26 March 1992 on summertime arrangements'. This only covers 1993 and +# 1994, a seventh one is in the works but I doubt that the algorithm will +# change. This says summertime starts at 01:00 GMT on the last Sunday in March +# and ends at 01:00 GMT on the last Sunday in September, except for the UK +# and Eire where it ends at 01:00 GMT on the fourth Sunday in October. +# It says the arrangements for 1995 onwards will be decided by 1 January 1994, +# but as the sixth directive was supposed to appear by 1 Jan 92 and didn't +# arrive til March I wouldn't hold your breath. +# +# The first summertime directive was adopted in 1980, although the UK didn't +# seem to use it until 1981. I suspect it would be safe to move your start +# dates for the -Eur rules back to 1981. diff --git a/time/factory b/time/factory new file mode 100644 index 000000000..d95df23c1 --- /dev/null +++ b/time/factory @@ -0,0 +1,8 @@ +# @(#)factory 7.1 + +# For companies who don't want to put time zone specification in +# their installation procedures. When users run date, they'll get the message. +# Also useful for the "comp.sources" version. + +# Zone NAME GMTOFF RULES FORMAT +Zone Factory 0 - "Local time zone must be set--see zic manual page" diff --git a/time/getopt.c b/time/getopt.c new file mode 100644 index 000000000..dbe60b186 --- /dev/null +++ b/time/getopt.c @@ -0,0 +1,93 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)getopt.c 7.5"; +/* Modified from the UCB version with the SCCS ID appearing below. */ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/*LINTLIBRARY*/ + +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of California at Berkeley. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific written prior permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +#ifdef LIBC_SCCS +#ifndef lint +static char sccsid[] = "@(#)getopt.c 4.5 (Berkeley) 11/24/87"; +#endif /* !defined lint */ +#endif /* defined LIBC_SCCS */ + +#include <stdio.h> + +/* + * get option letter from argument vector + */ +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern char * optarg; /* argument associated with option */ + +#define BADCH (int)'?' +static char EMSG[1]; +#define tell(s) { \ + if (opterr) { \ + (void) fputs(*nargv, stderr); \ + (void) fputs(s, stderr); \ + (void) fputc(optopt, stderr); \ + (void) fputc((int)'\n', stderr); \ + } \ + return(BADCH); \ +} + +extern char * strchr(); + +int +getopt(nargc, nargv, ostr) + int nargc; + char **nargv, *ostr; +{ + static char *place = EMSG; /* option letter processing */ + register char *oli; /* option letter list index */ + + if (!*place) { /* update scanning pointer */ + if (optind >= nargc || *(place = nargv[optind]) != '-' || + !*++place) + return(EOF); + if (*place == '-') { /* found "--" */ + ++optind; + return(EOF); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + if (!*place) + ++optind; + tell(": illegal option -- "); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + tell(": option requires an argument -- "); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return(optopt); /* dump back option letter */ +} diff --git a/time/ialloc.c b/time/ialloc.c new file mode 100644 index 000000000..d6a1b22b0 --- /dev/null +++ b/time/ialloc.c @@ -0,0 +1,103 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)ialloc.c 8.24"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/*LINTLIBRARY*/ + +#include "private.h" + +#ifdef MAL +#define NULLMAL(x) ((x) == NULL || (x) == MAL) +#endif /* defined MAL */ +#ifndef MAL +#define NULLMAL(x) ((x) == NULL) +#endif /* !defined MAL */ + +#define nonzero(n) (((n) == 0) ? 1 : (n)) + +char * icalloc P((int nelem, int elsize)); +char * icatalloc P((char * old, const char * new)); +char * icpyalloc P((const char * string)); +char * imalloc P((int n)); +void * irealloc P((void * pointer, int size)); +void ifree P((char * pointer)); + +char * +imalloc(n) +const int n; +{ +#ifdef MAL + register char * result; + + result = malloc((alloc_size_T) nonzero(n)); + return NULLMAL(result) ? NULL : result; +#endif /* defined MAL */ +#ifndef MAL + return malloc((alloc_size_T) nonzero(n)); +#endif /* !defined MAL */ +} + +char * +icalloc(nelem, elsize) +int nelem; +int elsize; +{ + if (nelem == 0 || elsize == 0) + nelem = elsize = 1; + return calloc((alloc_size_T) nelem, (alloc_size_T) elsize); +} + +void * +irealloc(pointer, size) +void * const pointer; +const int size; +{ + if (NULLMAL(pointer)) + return imalloc(size); + return realloc((genericptr_T) pointer, (alloc_size_T) nonzero(size)); +} + +char * +icatalloc(old, new) +char * const old; +const char * const new; +{ + register char * result; + register int oldsize, newsize; + + newsize = NULLMAL(new) ? 0 : strlen(new); + if (NULLMAL(old)) + oldsize = 0; + else if (newsize == 0) + return old; + else oldsize = strlen(old); + if ((result = irealloc(old, oldsize + newsize + 1)) != NULL) + if (!NULLMAL(new)) + (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 (!NULLMAL(p)) + (void) free(p); +} + +void +icfree(p) +char * const p; +{ + if (!NULLMAL(p)) + (void) free(p); +} diff --git a/time/leapseconds b/time/leapseconds new file mode 100644 index 000000000..d610692f9 --- /dev/null +++ b/time/leapseconds @@ -0,0 +1,41 @@ +# @(#)leapseconds 7.7 + +# Allowance for leapseconds added to each timezone file. + +# The International Earth Rotation Service periodically uses leap seconds +# to keep UTC to within 0.9 s of TAI (atomic time); see +# Terry J Quinn, The BIPM and the accurate measure of time, +# Proc IEEE 79, 7 (July 1991), 894-905. +# There were no leap seconds before 1972, because the official mechanism +# accounting for the discrepancy between atomic time and the earth's rotation +# did not exist until the early 1970s. + +# The correction (+ or -) is made at the given time, so lines +# will typically look like: +# Leap YEAR MON DAY 23:59:60 + R/S +# or +# Leap YEAR MON DAY 23:59:59 - R/S + +# If the leapsecond is Rolling (R) the given time is local time +# If the leapsecond is Stationary (S) the given time is GMT + +# Leap YEAR MONTH DAY HH:MM:SS CORR R/S +Leap 1972 Jun 30 23:59:60 + S +Leap 1972 Dec 31 23:59:60 + S +Leap 1973 Dec 31 23:59:60 + S +Leap 1974 Dec 31 23:59:60 + S +Leap 1975 Dec 31 23:59:60 + S +Leap 1976 Dec 31 23:59:60 + S +Leap 1977 Dec 31 23:59:60 + S +Leap 1978 Dec 31 23:59:60 + S +Leap 1979 Dec 31 23:59:60 + S +Leap 1981 Jun 30 23:59:60 + S +Leap 1982 Jun 30 23:59:60 + S +Leap 1983 Jun 30 23:59:60 + S +Leap 1985 Jun 30 23:59:60 + S +Leap 1987 Dec 31 23:59:60 + S +Leap 1989 Dec 31 23:59:60 + S +Leap 1990 Dec 31 23:59:60 + S +Leap 1992 Jun 30 23:59:60 + S +Leap 1993 Jun 30 23:59:60 + S +Leap 1994 Jun 30 23:59:60 + S diff --git a/time/localtime.c b/time/localtime.c new file mode 100644 index 000000000..1ae36fe9f --- /dev/null +++ b/time/localtime.c @@ -0,0 +1,1569 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)localtime.c 7.26"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). +** POSIX-style TZ environment variable handling from Guy Harris +** (guy@auspex.com). +*/ + +/*LINTLIBRARY*/ + +#include "private.h" +#include "tzfile.h" +#include "fcntl.h" + +#define ACCESS_MODE O_RDONLY + +#ifdef O_BINARY +#define OPEN_MODE (O_RDONLY | O_BINARY) +#endif /* defined O_BINARY */ +#ifndef O_BINARY +#define OPEN_MODE O_RDONLY +#endif /* !defined O_BINARY */ + +#ifndef WILDABBR +/* +** Someone might make incorrect use of a time zone abbreviation: +** 1. They might reference tzname[0] before calling tzset (explicitly +** or implicitly). +** 2. They might reference tzname[1] before calling tzset (explicitly +** or implicitly). +** 3. They might reference tzname[1] after setting to a time zone +** in which Daylight Saving Time is never observed. +** 4. They might reference tzname[0] after setting to a time zone +** in which Standard Time is never observed. +** 5. They might reference tm.TM_ZONE after calling offtime. +** What's best to do in the above cases is open to debate; +** for now, we just set things up so that in any of the five cases +** WILDABBR is used. Another possibility: initialize tzname[0] to the +** string "tzname[0] used before set", and similarly for the other cases. +** And another: initialize tzname[0] to "ERA", with an explanation in the +** manual page of what this "time zone abbreviation" means (doing this so +** that tzname[0] has the "normal" length of three characters). +*/ +#define WILDABBR " " +#endif /* !defined WILDABBR */ + +static char wildabbr[] = "WILDABBR"; + +static const char gmt[] = "GMT"; + +struct ttinfo { /* time type information */ + long tt_gmtoff; /* GMT offset in seconds */ + int tt_isdst; /* used to set tm_isdst */ + int tt_abbrind; /* abbreviation list index */ + int tt_ttisstd; /* TRUE if transition is std time */ +}; + +struct lsinfo { /* leap second information */ + time_t ls_trans; /* transition time */ + long ls_corr; /* correction to apply */ +}; + +#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) + +#ifdef TZNAME_MAX +#define MY_TZNAME_MAX TZNAME_MAX +#endif /* defined TZNAME_MAX */ +#ifndef TZNAME_MAX +#define MY_TZNAME_MAX 255 +#endif /* !defined TZNAME_MAX */ + +struct state { + int leapcnt; + int timecnt; + int typecnt; + int charcnt; + time_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; + struct ttinfo ttis[TZ_MAX_TYPES]; + char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), + (2 * (MY_TZNAME_MAX + 1)))]; + struct lsinfo lsis[TZ_MAX_LEAPS]; +}; + +struct rule { + int r_type; /* type of rule--see below */ + int r_day; /* day number of rule */ + int r_week; /* week number of rule */ + int r_mon; /* month number of rule */ + long r_time; /* transition time of rule */ +}; + +#define JULIAN_DAY 0 /* Jn - Julian day */ +#define DAY_OF_YEAR 1 /* n - day of year */ +#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ + +/* +** Prototypes for static functions. +*/ + +static long detzcode P((const char * codep)); +static const char * getzname P((const char * strp)); +static const char * getnum P((const char * strp, int * nump, int min, + int max)); +static const char * getsecs P((const char * strp, long * secsp)); +static const char * getoffset P((const char * strp, long * offsetp)); +static const char * getrule P((const char * strp, struct rule * rulep)); +static void gmtload P((struct state * sp)); +static void gmtsub P((const time_t * timep, long offset, + struct tm * tmp)); +static void localsub P((const time_t * timep, long offset, + struct tm * tmp)); +static int increment_overflow P((int * number, int delta)); +static int normalize_overflow P((int * tensptr, int * unitsptr, + int base)); +static void settzname P((void)); +static time_t time1 P((struct tm * tmp, void (* funcp)(), + long offset)); +static time_t time2 P((struct tm *tmp, void (* funcp)(), + long offset, int * okayp)); +static void timesub P((const time_t * timep, long offset, + const struct state * sp, struct tm * tmp)); +static int tmcomp P((const struct tm * atmp, + const struct tm * btmp)); +static time_t transtime P((time_t janfirst, int year, + const struct rule * rulep, long offset)); +static int tzload P((const char * name, struct state * sp)); +static int tzparse P((const char * name, struct state * sp, + int lastditch)); + +#ifdef ALL_STATE +static struct state * lclptr; +static struct state * gmtptr; +#endif /* defined ALL_STATE */ + +#ifndef ALL_STATE +static struct state lclmem; +static struct state gmtmem; +#define lclptr (&lclmem) +#define gmtptr (&gmtmem) +#endif /* State Farm */ + +#ifndef TZ_STRLEN_MAX +#define TZ_STRLEN_MAX 255 +#endif + +static char lcl_TZname[TZ_STRLEN_MAX + 1]; +static int lcl_is_set; +static int gmt_is_set; + +char * tzname[2] = { + wildabbr, + wildabbr +}; + +/* +** Section 4.12.3 of X3.159-1989 requires that +** Except for the strftime function, these functions [asctime, +** ctime, gmtime, localtime] return values in one of two static +** objects: a broken-down time structure and an array of char. +** Thanks to Paul Eggert (eggert@twinsun.com) for noting this. +*/ + +static struct tm tm; + +#ifdef USG_COMPAT +time_t timezone = 0; +int daylight = 0; +#endif /* defined USG_COMPAT */ + +#ifdef ALTZONE +time_t altzone = 0; +#endif /* defined ALTZONE */ + +static long +detzcode(codep) +const char * const codep; +{ + register long result; + register int i; + + result = 0; + for (i = 0; i < 4; ++i) + result = (result << 8) | (codep[i] & 0xff); + return result; +} + +static void +settzname P((void)) +{ + register const struct state * const sp = lclptr; + register int i; + + tzname[0] = wildabbr; + tzname[1] = wildabbr; +#ifdef USG_COMPAT + daylight = 0; + timezone = 0; +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + altzone = 0; +#endif /* defined ALTZONE */ +#ifdef ALL_STATE + if (sp == NULL) { + tzname[0] = tzname[1] = gmt; + return; + } +#endif /* defined ALL_STATE */ + for (i = 0; i < sp->typecnt; ++i) { + register const struct ttinfo * const ttisp = &sp->ttis[i]; + + tzname[ttisp->tt_isdst] = + (char *) &sp->chars[ttisp->tt_abbrind]; +#ifdef USG_COMPAT + if (ttisp->tt_isdst) + daylight = 1; + if (i == 0 || !ttisp->tt_isdst) + timezone = -(ttisp->tt_gmtoff); +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + if (i == 0 || ttisp->tt_isdst) + altzone = -(ttisp->tt_gmtoff); +#endif /* defined ALTZONE */ + } + /* + ** And to get the latest zone names into tzname. . . + */ + for (i = 0; i < sp->timecnt; ++i) { + register const struct ttinfo * const ttisp = + &sp->ttis[ + sp->types[i]]; + + tzname[ttisp->tt_isdst] = + (char *) &sp->chars[ttisp->tt_abbrind]; + } +} + +static int +tzload(name, sp) +register const char * name; +register struct state * const sp; +{ + register const char * p; + register int i; + register int fid; + + if (name == NULL && (name = TZDEFAULT) == NULL) + return -1; + { + register int doaccess; + char fullname[FILENAME_MAX + 1]; + + if (name[0] == ':') + ++name; + doaccess = name[0] == '/'; + if (!doaccess) { + if ((p = TZDIR) == NULL) + return -1; + if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) + return -1; + (void) strcpy(fullname, p); + (void) strcat(fullname, "/"); + (void) strcat(fullname, name); + /* + ** Set doaccess if '.' (as in "../") shows up in name. + */ + if (strchr(name, '.') != NULL) + doaccess = TRUE; + name = fullname; + } + if (doaccess && access(name, ACCESS_MODE) != 0) + return -1; + if ((fid = open(name, OPEN_MODE)) == -1) + return -1; + } + { + register const struct tzhead * tzhp; + char buf[sizeof *sp + sizeof *tzhp]; + int ttisstdcnt; + + i = read(fid, buf, sizeof buf); + if (close(fid) != 0 || i < sizeof *tzhp) + return -1; + tzhp = (struct tzhead *) buf; + ttisstdcnt = (int) detzcode(tzhp->tzh_ttisstdcnt); + sp->leapcnt = (int) detzcode(tzhp->tzh_leapcnt); + sp->timecnt = (int) detzcode(tzhp->tzh_timecnt); + sp->typecnt = (int) detzcode(tzhp->tzh_typecnt); + sp->charcnt = (int) detzcode(tzhp->tzh_charcnt); + if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || + sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || + sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || + sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || + (ttisstdcnt != sp->typecnt && ttisstdcnt != 0)) + return -1; + if (i < sizeof *tzhp + + sp->timecnt * (4 + sizeof (char)) + + sp->typecnt * (4 + 2 * sizeof (char)) + + sp->charcnt * sizeof (char) + + sp->leapcnt * 2 * 4 + + ttisstdcnt * sizeof (char)) + return -1; + p = buf + sizeof *tzhp; + for (i = 0; i < sp->timecnt; ++i) { + sp->ats[i] = detzcode(p); + p += 4; + } + for (i = 0; i < sp->timecnt; ++i) { + sp->types[i] = (unsigned char) *p++; + if (sp->types[i] >= sp->typecnt) + return -1; + } + for (i = 0; i < sp->typecnt; ++i) { + register struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + ttisp->tt_gmtoff = detzcode(p); + p += 4; + ttisp->tt_isdst = (unsigned char) *p++; + if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) + return -1; + ttisp->tt_abbrind = (unsigned char) *p++; + if (ttisp->tt_abbrind < 0 || + ttisp->tt_abbrind > sp->charcnt) + return -1; + } + for (i = 0; i < sp->charcnt; ++i) + sp->chars[i] = *p++; + sp->chars[i] = '\0'; /* ensure '\0' at end */ + for (i = 0; i < sp->leapcnt; ++i) { + register struct lsinfo * lsisp; + + lsisp = &sp->lsis[i]; + lsisp->ls_trans = detzcode(p); + p += 4; + lsisp->ls_corr = detzcode(p); + p += 4; + } + for (i = 0; i < sp->typecnt; ++i) { + register struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisstdcnt == 0) + ttisp->tt_ttisstd = FALSE; + else { + ttisp->tt_ttisstd = *p++; + if (ttisp->tt_ttisstd != TRUE && + ttisp->tt_ttisstd != FALSE) + return -1; + } + } + } + return 0; +} + +static const int mon_lengths[2][MONSPERYEAR] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const int year_lengths[2] = { + DAYSPERNYEAR, DAYSPERLYEAR +}; + +/* +** Given a pointer into a time zone string, scan until a character that is not +** a valid character in a zone name is found. Return a pointer to that +** character. +*/ + +static const char * +getzname(strp) +register const char * strp; +{ + register char c; + + while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' && + c != '+') + ++strp; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a number from that string. +** Check that the number is within a specified range; if it is not, return +** NULL. +** Otherwise, return a pointer to the first character not part of the number. +*/ + +static const char * +getnum(strp, nump, min, max) +register const char * strp; +int * const nump; +const int min; +const int max; +{ + register char c; + register int num; + + if (strp == NULL || !isdigit(*strp)) + return NULL; + num = 0; + while ((c = *strp) != '\0' && isdigit(c)) { + num = num * 10 + (c - '0'); + if (num > max) + return NULL; /* illegal value */ + ++strp; + } + if (num < min) + return NULL; /* illegal value */ + *nump = num; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a number of seconds, +** in hh[:mm[:ss]] form, from the string. +** If any error occurs, return NULL. +** Otherwise, return a pointer to the first character not part of the number +** of seconds. +*/ + +static const char * +getsecs(strp, secsp) +register const char * strp; +long * const secsp; +{ + int num; + + /* + ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like + ** "M10.4.6/26", which does not conform to Posix, + ** but which specifies the equivalent of + ** ``02:00 on the first Sunday on or after 23 Oct''. + */ + strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); + if (strp == NULL) + return NULL; + *secsp = num * (long) SECSPERHOUR; + if (*strp == ':') { + ++strp; + strp = getnum(strp, &num, 0, MINSPERHOUR - 1); + if (strp == NULL) + return NULL; + *secsp += num * SECSPERMIN; + if (*strp == ':') { + ++strp; + /* `SECSPERMIN' allows for leap seconds. */ + strp = getnum(strp, &num, 0, SECSPERMIN); + if (strp == NULL) + return NULL; + *secsp += num; + } + } + return strp; +} + +/* +** Given a pointer into a time zone string, extract an offset, in +** [+-]hh[:mm[:ss]] form, from the string. +** If any error occurs, return NULL. +** Otherwise, return a pointer to the first character not part of the time. +*/ + +static const char * +getoffset(strp, offsetp) +register const char * strp; +long * const offsetp; +{ + register int neg; + + if (*strp == '-') { + neg = 1; + ++strp; + } else if (isdigit(*strp) || *strp++ == '+') + neg = 0; + else return NULL; /* illegal offset */ + strp = getsecs(strp, offsetp); + if (strp == NULL) + return NULL; /* illegal time */ + if (neg) + *offsetp = -*offsetp; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a rule in the form +** date[/time]. See POSIX section 8 for the format of "date" and "time". +** If a valid rule is not found, return NULL. +** Otherwise, return a pointer to the first character not part of the rule. +*/ + +static const char * +getrule(strp, rulep) +const char * strp; +register struct rule * const rulep; +{ + if (*strp == 'J') { + /* + ** Julian day. + */ + rulep->r_type = JULIAN_DAY; + ++strp; + strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); + } else if (*strp == 'M') { + /* + ** Month, week, day. + */ + rulep->r_type = MONTH_NTH_DAY_OF_WEEK; + ++strp; + strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); + if (strp == NULL) + return NULL; + if (*strp++ != '.') + return NULL; + strp = getnum(strp, &rulep->r_week, 1, 5); + if (strp == NULL) + return NULL; + if (*strp++ != '.') + return NULL; + strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); + } else if (isdigit(*strp)) { + /* + ** Day of year. + */ + rulep->r_type = DAY_OF_YEAR; + strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); + } else return NULL; /* invalid format */ + if (strp == NULL) + return NULL; + if (*strp == '/') { + /* + ** Time specified. + */ + ++strp; + strp = getsecs(strp, &rulep->r_time); + } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ + return strp; +} + +/* +** Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the +** year, a rule, and the offset from GMT at the time that rule takes effect, +** calculate the Epoch-relative time that rule takes effect. +*/ + +static time_t +transtime(janfirst, year, rulep, offset) +const time_t janfirst; +const int year; +register const struct rule * const rulep; +const long offset; +{ + register int leapyear; + register time_t value; + register int i; + int d, m1, yy0, yy1, yy2, dow; + + INITIALIZE(value); + leapyear = isleap(year); + switch (rulep->r_type) { + + case JULIAN_DAY: + /* + ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap + ** years. + ** In non-leap years, or if the day number is 59 or less, just + ** add SECSPERDAY times the day number-1 to the time of + ** January 1, midnight, to get the day. + */ + value = janfirst + (rulep->r_day - 1) * SECSPERDAY; + if (leapyear && rulep->r_day >= 60) + value += SECSPERDAY; + break; + + case DAY_OF_YEAR: + /* + ** n - day of year. + ** Just add SECSPERDAY times the day number to the time of + ** January 1, midnight, to get the day. + */ + value = janfirst + rulep->r_day * SECSPERDAY; + break; + + case MONTH_NTH_DAY_OF_WEEK: + /* + ** Mm.n.d - nth "dth day" of month m. + */ + value = janfirst; + for (i = 0; i < rulep->r_mon - 1; ++i) + value += mon_lengths[leapyear][i] * SECSPERDAY; + + /* + ** Use Zeller's Congruence to get day-of-week of first day of + ** month. + */ + m1 = (rulep->r_mon + 9) % 12 + 1; + yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; + yy1 = yy0 / 100; + yy2 = yy0 % 100; + dow = ((26 * m1 - 2) / 10 + + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; + if (dow < 0) + dow += DAYSPERWEEK; + + /* + ** "dow" is the day-of-week of the first day of the month. Get + ** the day-of-month (zero-origin) of the first "dow" day of the + ** month. + */ + d = rulep->r_day - dow; + if (d < 0) + d += DAYSPERWEEK; + for (i = 1; i < rulep->r_week; ++i) { + if (d + DAYSPERWEEK >= + mon_lengths[leapyear][rulep->r_mon - 1]) + break; + d += DAYSPERWEEK; + } + + /* + ** "d" is the day-of-month (zero-origin) of the day we want. + */ + value += d * SECSPERDAY; + break; + } + + /* + ** "value" is the Epoch-relative time of 00:00:00 GMT on the day in + ** question. To get the Epoch-relative time of the specified local + ** time on that day, add the transition time and the current offset + ** from GMT. + */ + return value + rulep->r_time + offset; +} + +/* +** Given a POSIX section 8-style TZ string, fill in the rule tables as +** appropriate. +*/ + +static int +tzparse(name, sp, lastditch) +const char * name; +register struct state * const sp; +const int lastditch; +{ + const char * stdname; + const char * dstname; + size_t stdlen; + size_t dstlen; + long stdoffset; + long dstoffset; + register time_t * atp; + register unsigned char * typep; + register char * cp; + register int load_result; + + INITIALIZE(dstname); + stdname = name; + if (lastditch) { + stdlen = strlen(name); /* length of standard zone name */ + name += stdlen; + if (stdlen >= sizeof sp->chars) + stdlen = (sizeof sp->chars) - 1; + } else { + name = getzname(name); + stdlen = name - stdname; + if (stdlen < 3) + return -1; + } + if (*name == '\0') + return -1; /* was "stdoffset = 0;" */ + else { + name = getoffset(name, &stdoffset); + if (name == NULL) + return -1; + } + load_result = tzload(TZDEFRULES, sp); + if (load_result != 0) + sp->leapcnt = 0; /* so, we're off a little */ + if (*name != '\0') { + dstname = name; + name = getzname(name); + dstlen = name - dstname; /* length of DST zone name */ + if (dstlen < 3) + return -1; + if (*name != '\0' && *name != ',' && *name != ';') { + name = getoffset(name, &dstoffset); + if (name == NULL) + return -1; + } else dstoffset = stdoffset - SECSPERHOUR; + if (*name == ',' || *name == ';') { + struct rule start; + struct rule end; + register int year; + register time_t janfirst; + time_t starttime; + time_t endtime; + + ++name; + if ((name = getrule(name, &start)) == NULL) + return -1; + if (*name++ != ',') + return -1; + if ((name = getrule(name, &end)) == NULL) + return -1; + if (*name != '\0') + return -1; + sp->typecnt = 2; /* standard time and DST */ + /* + ** Two transitions per year, from EPOCH_YEAR to 2037. + */ + sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1); + if (sp->timecnt > TZ_MAX_TIMES) + return -1; + sp->ttis[0].tt_gmtoff = -dstoffset; + sp->ttis[0].tt_isdst = 1; + sp->ttis[0].tt_abbrind = stdlen + 1; + sp->ttis[1].tt_gmtoff = -stdoffset; + sp->ttis[1].tt_isdst = 0; + sp->ttis[1].tt_abbrind = 0; + atp = sp->ats; + typep = sp->types; + janfirst = 0; + for (year = EPOCH_YEAR; year <= 2037; ++year) { + starttime = transtime(janfirst, year, &start, + stdoffset); + endtime = transtime(janfirst, year, &end, + dstoffset); + if (starttime > endtime) { + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + } else { + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + } + janfirst += year_lengths[isleap(year)] * + SECSPERDAY; + } + } else { + int sawstd; + int sawdst; + long stdfix; + long dstfix; + long oldfix; + int isdst; + register int i; + + if (*name != '\0') + return -1; + if (load_result != 0) + return -1; + /* + ** Compute the difference between the real and + ** prototype standard and summer time offsets + ** from GMT, and put the real standard and summer + ** time offsets into the rules in place of the + ** prototype offsets. + */ + sawstd = FALSE; + sawdst = FALSE; + stdfix = 0; + dstfix = 0; + for (i = 0; i < sp->typecnt; ++i) { + if (sp->ttis[i].tt_isdst) { + oldfix = dstfix; + dstfix = sp->ttis[i].tt_gmtoff + + dstoffset; + if (sawdst && (oldfix != dstfix)) + return -1; + sp->ttis[i].tt_gmtoff = -dstoffset; + sp->ttis[i].tt_abbrind = stdlen + 1; + sawdst = TRUE; + } else { + oldfix = stdfix; + stdfix = sp->ttis[i].tt_gmtoff + + stdoffset; + if (sawstd && (oldfix != stdfix)) + return -1; + sp->ttis[i].tt_gmtoff = -stdoffset; + sp->ttis[i].tt_abbrind = 0; + sawstd = TRUE; + } + } + /* + ** Make sure we have both standard and summer time. + */ + if (!sawdst || !sawstd) + return -1; + /* + ** Now correct the transition times by shifting + ** them by the difference between the real and + ** prototype offsets. Note that this difference + ** can be different in standard and summer time; + ** the prototype probably has a 1-hour difference + ** between standard and summer time, but a different + ** difference can be specified in TZ. + */ + isdst = FALSE; /* we start in standard time */ + for (i = 0; i < sp->timecnt; ++i) { + register const struct ttinfo * ttisp; + + /* + ** If summer time is in effect, and the + ** transition time was not specified as + ** standard time, add the summer time + ** offset to the transition time; + ** otherwise, add the standard time offset + ** to the transition time. + */ + ttisp = &sp->ttis[sp->types[i]]; + sp->ats[i] += + (isdst && !ttisp->tt_ttisstd) ? + dstfix : stdfix; + isdst = ttisp->tt_isdst; + } + } + } else { + dstlen = 0; + sp->typecnt = 1; /* only standard time */ + sp->timecnt = 0; + sp->ttis[0].tt_gmtoff = -stdoffset; + sp->ttis[0].tt_isdst = 0; + sp->ttis[0].tt_abbrind = 0; + } + sp->charcnt = stdlen + 1; + if (dstlen != 0) + sp->charcnt += dstlen + 1; + if (sp->charcnt > sizeof sp->chars) + return -1; + cp = sp->chars; + (void) strncpy(cp, stdname, stdlen); + cp += stdlen; + *cp++ = '\0'; + if (dstlen != 0) { + (void) strncpy(cp, dstname, dstlen); + *(cp + dstlen) = '\0'; + } + return 0; +} + +static void +gmtload(sp) +struct state * const sp; +{ + if (tzload(gmt, sp) != 0) + (void) tzparse(gmt, sp, TRUE); +} + +#ifndef STD_INSPIRED +/* +** A non-static declaration of tzsetwall in a system header file +** may cause a warning about this upcoming static declaration... +*/ +static +#endif /* !defined STD_INSPIRED */ +void +tzsetwall P((void)) +{ + if (lcl_is_set < 0) + return; + lcl_is_set = -1; + +#ifdef ALL_STATE + if (lclptr == NULL) { + lclptr = (struct state *) malloc(sizeof *lclptr); + if (lclptr == NULL) { + settzname(); /* all we can do */ + return; + } + } +#endif /* defined ALL_STATE */ + if (tzload((char *) NULL, lclptr) != 0) + gmtload(lclptr); + settzname(); +} + +void +tzset P((void)) +{ + register const char * name; + + name = getenv("TZ"); + if (name == NULL) { + tzsetwall(); + return; + } + + if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) + return; + lcl_is_set = (strlen(name) < sizeof(lcl_TZname)); + if (lcl_is_set) + (void) strcpy(lcl_TZname, name); + +#ifdef ALL_STATE + if (lclptr == NULL) { + lclptr = (struct state *) malloc(sizeof *lclptr); + if (lclptr == NULL) { + settzname(); /* all we can do */ + return; + } + } +#endif /* defined ALL_STATE */ + if (*name == '\0') { + /* + ** User wants it fast rather than right. + */ + lclptr->leapcnt = 0; /* so, we're off a little */ + lclptr->timecnt = 0; + lclptr->ttis[0].tt_gmtoff = 0; + lclptr->ttis[0].tt_abbrind = 0; + (void) strcpy(lclptr->chars, gmt); + } else if (tzload(name, lclptr) != 0) + if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) + (void) gmtload(lclptr); + settzname(); +} + +/* +** The easy way to behave "as if no library function calls" localtime +** is to not call it--so we drop its guts into "localsub", which can be +** freely called. (And no, the PANS doesn't require the above behavior-- +** but it *is* desirable.) +** +** The unused offset argument is for the benefit of mktime variants. +*/ + +/*ARGSUSED*/ +static void +localsub(timep, offset, tmp) +const time_t * const timep; +const long offset; +struct tm * const tmp; +{ + register const struct state * sp; + register const struct ttinfo * ttisp; + register int i; + const time_t t = *timep; + + sp = lclptr; +#ifdef ALL_STATE + if (sp == NULL) { + gmtsub(timep, offset, tmp); + return; + } +#endif /* defined ALL_STATE */ + if (sp->timecnt == 0 || t < sp->ats[0]) { + i = 0; + while (sp->ttis[i].tt_isdst) + if (++i >= sp->typecnt) { + i = 0; + break; + } + } else { + for (i = 1; i < sp->timecnt; ++i) + if (t < sp->ats[i]) + break; + i = sp->types[i - 1]; + } + ttisp = &sp->ttis[i]; + /* + ** To get (wrong) behavior that's compatible with System V Release 2.0 + ** you'd replace the statement below with + ** t += ttisp->tt_gmtoff; + ** timesub(&t, 0L, sp, tmp); + */ + timesub(&t, ttisp->tt_gmtoff, sp, tmp); + tmp->tm_isdst = ttisp->tt_isdst; + tzname[tmp->tm_isdst] = (char *) &sp->chars[ttisp->tt_abbrind]; +#ifdef TM_ZONE + tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; +#endif /* defined TM_ZONE */ +} + +struct tm * +localtime(timep) +const time_t * const timep; +{ + tzset(); + localsub(timep, 0L, &tm); + return &tm; +} + +/* +** gmtsub is to gmtime as localsub is to localtime. +*/ + +static void +gmtsub(timep, offset, tmp) +const time_t * const timep; +const long offset; +struct tm * const tmp; +{ + if (!gmt_is_set) { + gmt_is_set = TRUE; +#ifdef ALL_STATE + gmtptr = (struct state *) malloc(sizeof *gmtptr); + if (gmtptr != NULL) +#endif /* defined ALL_STATE */ + gmtload(gmtptr); + } + timesub(timep, offset, gmtptr, tmp); +#ifdef TM_ZONE + /* + ** Could get fancy here and deliver something such as + ** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero, + ** but this is no time for a treasure hunt. + */ + if (offset != 0) + tmp->TM_ZONE = wildabbr; + else { +#ifdef ALL_STATE + if (gmtptr == NULL) + tmp->TM_ZONE = gmt; + else tmp->TM_ZONE = gmtptr->chars; +#endif /* defined ALL_STATE */ +#ifndef ALL_STATE + tmp->TM_ZONE = gmtptr->chars; +#endif /* State Farm */ + } +#endif /* defined TM_ZONE */ +} + +struct tm * +gmtime(timep) +const time_t * const timep; +{ + gmtsub(timep, 0L, &tm); + return &tm; +} + +#ifdef STD_INSPIRED + +struct tm * +offtime(timep, offset) +const time_t * const timep; +const long offset; +{ + gmtsub(timep, offset, &tm); + return &tm; +} + +#endif /* defined STD_INSPIRED */ + +static void +timesub(timep, offset, sp, tmp) +const time_t * const timep; +const long offset; +register const struct state * const sp; +register struct tm * const tmp; +{ + register const struct lsinfo * lp; + register long days; + register long rem; + register int y; + register int yleap; + register const int * ip; + register long corr; + register int hit; + register int i; + + corr = 0; + hit = 0; +#ifdef ALL_STATE + i = (sp == NULL) ? 0 : sp->leapcnt; +#endif /* defined ALL_STATE */ +#ifndef ALL_STATE + i = sp->leapcnt; +#endif /* State Farm */ + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) { + if (*timep == lp->ls_trans) { + hit = ((i == 0 && lp->ls_corr > 0) || + lp->ls_corr > sp->lsis[i - 1].ls_corr); + if (hit) + while (i > 0 && + sp->lsis[i].ls_trans == + sp->lsis[i - 1].ls_trans + 1 && + sp->lsis[i].ls_corr == + sp->lsis[i - 1].ls_corr + 1) { + ++hit; + --i; + } + } + corr = lp->ls_corr; + break; + } + } + days = *timep / SECSPERDAY; + rem = *timep % SECSPERDAY; +#ifdef mc68k + if (*timep == 0x80000000) { + /* + ** A 3B1 muffs the division on the most negative number. + */ + days = -24855; + rem = -11648; + } +#endif /* mc68k */ + rem += (offset - corr); + while (rem < 0) { + rem += SECSPERDAY; + --days; + } + while (rem >= SECSPERDAY) { + rem -= SECSPERDAY; + ++days; + } + tmp->tm_hour = (int) (rem / SECSPERHOUR); + rem = rem % SECSPERHOUR; + tmp->tm_min = (int) (rem / SECSPERMIN); + tmp->tm_sec = (int) (rem % SECSPERMIN); + if (hit) + /* + ** A positive leap second requires a special + ** representation. This uses "... ??:59:60" et seq. + */ + tmp->tm_sec += hit; + tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); + if (tmp->tm_wday < 0) + tmp->tm_wday += DAYSPERWEEK; + y = EPOCH_YEAR; + if (days >= 0) + for ( ; ; ) { + yleap = isleap(y); + if (days < (long) year_lengths[yleap]) + break; + ++y; + days = days - (long) year_lengths[yleap]; + } + else do { + --y; + yleap = isleap(y); + days = days + (long) year_lengths[yleap]; + } while (days < 0); + tmp->tm_year = y - TM_YEAR_BASE; + tmp->tm_yday = (int) days; + ip = mon_lengths[yleap]; + for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) + days = days - (long) ip[tmp->tm_mon]; + tmp->tm_mday = (int) (days + 1); + tmp->tm_isdst = 0; +#ifdef TM_GMTOFF + tmp->TM_GMTOFF = offset; +#endif /* defined TM_GMTOFF */ +} + +char * +ctime(timep) +const time_t * const timep; +{ +/* +** Section 4.12.3.2 of X3.159-1989 requires that +** The ctime funciton converts the calendar time pointed to by timer +** to local time in the form of a string. It is equivalent to +** asctime(localtime(timer)) +*/ + return asctime(localtime(timep)); +} + +/* +** Adapted from code provided by Robert Elz, who writes: +** The "best" way to do mktime I think is based on an idea of Bob +** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now). +** It does a binary search of the time_t space. Since time_t's are +** just 32 bits, its a max of 32 iterations (even at 64 bits it +** would still be very reasonable). +*/ + +#ifndef WRONG +#define WRONG (-1) +#endif /* !defined WRONG */ + +/* +** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com). +*/ + +static int +increment_overflow(number, delta) +int * number; +int delta; +{ + int number0; + + number0 = *number; + *number += delta; + return (*number < number0) != (delta < 0); +} + +static int +normalize_overflow(tensptr, unitsptr, base) +int * const tensptr; +int * const unitsptr; +const int base; +{ + register int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return increment_overflow(tensptr, tensdelta); +} + +static int +tmcomp(atmp, btmp) +register const struct tm * const atmp; +register const struct tm * const btmp; +{ + register int result; + + if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && + (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +static time_t +time2(tmp, funcp, offset, okayp) +struct tm * const tmp; +void (* const funcp)(); +const long offset; +int * const okayp; +{ + register const struct state * sp; + register int dir; + register int bits; + register int i, j ; + register int saved_seconds; + time_t newt; + time_t t; + struct tm yourtm, mytm; + + *okayp = FALSE; + yourtm = *tmp; + if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) + return WRONG; + if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) + return WRONG; + if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR)) + return WRONG; + /* + ** Turn yourtm.tm_year into an actual year number for now. + ** It is converted back to an offset from TM_YEAR_BASE later. + */ + if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE)) + return WRONG; + while (yourtm.tm_mday <= 0) { + if (increment_overflow(&yourtm.tm_year, -1)) + return WRONG; + yourtm.tm_mday += year_lengths[isleap(yourtm.tm_year)]; + } + while (yourtm.tm_mday > DAYSPERLYEAR) { + yourtm.tm_mday -= year_lengths[isleap(yourtm.tm_year)]; + if (increment_overflow(&yourtm.tm_year, 1)) + return WRONG; + } + for ( ; ; ) { + i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon]; + if (yourtm.tm_mday <= i) + break; + yourtm.tm_mday -= i; + if (++yourtm.tm_mon >= MONSPERYEAR) { + yourtm.tm_mon = 0; + if (increment_overflow(&yourtm.tm_year, 1)) + return WRONG; + } + } + if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) + return WRONG; + if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { + /* + ** We can't set tm_sec to 0, because that might push the + ** time below the minimum representable time. + ** Set tm_sec to 59 instead. + ** This assumes that the minimum representable time is + ** not in the same minute that a leap second was deleted from, + ** which is a safer assumption than using 58 would be. + */ + if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) + return WRONG; + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = SECSPERMIN - 1; + } else { + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = 0; + } + /* + ** Calculate the number of magnitude bits in a time_t + ** (this works regardless of whether time_t is + ** signed or unsigned, though lint complains if unsigned). + */ + for (bits = 0, t = 1; t > 0; ++bits, t <<= 1) + continue; + /* + ** If time_t is signed, then 0 is the median value, + ** if time_t is unsigned, then 1 << bits is median. + */ + t = (t < 0) ? 0 : ((time_t) 1 << bits); + for ( ; ; ) { + (*funcp)(&t, offset, &mytm); + dir = tmcomp(&mytm, &yourtm); + if (dir != 0) { + if (bits-- < 0) + return WRONG; + if (bits < 0) + --t; + else if (dir > 0) + t -= (time_t) 1 << bits; + else t += (time_t) 1 << bits; + continue; + } + if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) + break; + /* + ** Right time, wrong type. + ** Hunt for right time, right type. + ** It's okay to guess wrong since the guess + ** gets checked. + */ + /* + ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. + */ + sp = (const struct state *) + (((void *) funcp == (void *) localsub) ? + lclptr : gmtptr); +#ifdef ALL_STATE + if (sp == NULL) + return WRONG; +#endif /* defined ALL_STATE */ + for (i = 0; i < sp->typecnt; ++i) { + if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) + continue; + for (j = 0; j < sp->typecnt; ++j) { + if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) + continue; + newt = t + sp->ttis[j].tt_gmtoff - + sp->ttis[i].tt_gmtoff; + (*funcp)(&newt, offset, &mytm); + if (tmcomp(&mytm, &yourtm) != 0) + continue; + if (mytm.tm_isdst != yourtm.tm_isdst) + continue; + /* + ** We have a match. + */ + t = newt; + goto label; + } + } + return WRONG; + } +label: + newt = t + saved_seconds; + if ((newt < t) != (saved_seconds < 0)) + return WRONG; + t = newt; + (*funcp)(&t, offset, tmp); + *okayp = TRUE; + return t; +} + +static time_t +time1(tmp, funcp, offset) +struct tm * const tmp; +void (* const funcp)(); +const long offset; +{ + register time_t t; + register const struct state * sp; + register int samei, otheri; + int okay; + + if (tmp->tm_isdst > 1) + tmp->tm_isdst = 1; + t = time2(tmp, funcp, offset, &okay); +#ifdef PCTS + /* + ** PCTS code courtesy Grant Sullivan (grant@osf.org). + */ + if (okay) + return t; + if (tmp->tm_isdst < 0) + tmp->tm_isdst = 0; /* reset to std and try again */ +#endif /* defined PCTS */ +#ifndef PCTS + if (okay || tmp->tm_isdst < 0) + return t; +#endif /* !defined PCTS */ + /* + ** We're supposed to assume that somebody took a time of one type + ** and did some math on it that yielded a "struct tm" that's bad. + ** We try to divine the type they started from and adjust to the + ** type they need. + */ + /* + ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. + */ + sp = (const struct state *) (((void *) funcp == (void *) localsub) ? + lclptr : gmtptr); +#ifdef ALL_STATE + if (sp == NULL) + return WRONG; +#endif /* defined ALL_STATE */ + for (samei = 0; samei < sp->typecnt; ++samei) { + if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) + continue; + for (otheri = 0; otheri < sp->typecnt; ++otheri) { + if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) + continue; + tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + t = time2(tmp, funcp, offset, &okay); + if (okay) + return t; + tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + } + } + return WRONG; +} + +time_t +mktime(tmp) +struct tm * const tmp; +{ + tzset(); + return time1(tmp, localsub, 0L); +} + +#ifdef STD_INSPIRED + +time_t +timelocal(tmp) +struct tm * const tmp; +{ + tmp->tm_isdst = -1; /* in case it wasn't initialized */ + return mktime(tmp); +} + +time_t +timegm(tmp) +struct tm * const tmp; +{ + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, 0L); +} + +time_t +timeoff(tmp, offset) +struct tm * const tmp; +const long offset; +{ + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, offset); +} + +#endif /* defined STD_INSPIRED */ + +#ifdef CMUCS + +/* +** The following is supplied for compatibility with +** previous versions of the CMUCS runtime library. +*/ + +long +gtime(tmp) +struct tm * const tmp; +{ + const time_t t = mktime(tmp); + + if (t == WRONG) + return -1; + return t; +} + +#endif /* defined CMUCS */ + +/* +** XXX--is the below the right way to conditionalize?? +*/ + +#ifdef STD_INSPIRED + +/* +** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599 +** shall correspond to "Wed Dec 31 23:59:59 GMT 1986", which +** is not the case if we are accounting for leap seconds. +** So, we provide the following conversion routines for use +** when exchanging timestamps with POSIX conforming systems. +*/ + +static long +leapcorr(timep) +time_t * timep; +{ + register struct state * sp; + register struct lsinfo * lp; + register int i; + + sp = lclptr; + i = sp->leapcnt; + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) + return lp->ls_corr; + } + return 0; +} + +time_t +time2posix(t) +time_t t; +{ + tzset(); + return t - leapcorr(&t); +} + +time_t +posix2time(t) +time_t t; +{ + time_t x; + time_t y; + + tzset(); + /* + ** For a positive leap second hit, the result + ** is not unique. For a negative leap second + ** hit, the corresponding time doesn't exist, + ** so we return an adjacent second. + */ + x = t + leapcorr(&t); + y = x - leapcorr(&x); + if (y < t) { + do { + x++; + y = x - leapcorr(&x); + } while (y < t); + if (t != y) + return x - 1; + } else if (y > t) { + do { + --x; + y = x - leapcorr(&x); + } while (y > t); + if (t != y) + return x + 1; + } + return x; +} + +#endif /* defined STD_INSPIRED */ diff --git a/time/logwtmp.c b/time/logwtmp.c new file mode 100644 index 000000000..6cf3237a6 --- /dev/null +++ b/time/logwtmp.c @@ -0,0 +1,65 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)logwtmp.c 7.4"; +/* As received from UCB, with include reordering and OLD_TIME condition. */ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANT[A]BILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +#ifdef LIBC_SCCS +static char sccsid[] = "@(#)logwtmp.c 5.2 (Berkeley) 9/20/88"; +#endif /* defined LIBC_SCCS */ +#endif /* !defined lint */ + +#include <sys/types.h> +#include <utmp.h> + +#ifndef OLD_TIME + +#include <sys/file.h> +#include <sys/time.h> +#include <sys/stat.h> + +#define WTMPFILE "/usr/adm/wtmp" + +logwtmp(line, name, host) + char *line, *name, *host; +{ + struct utmp ut; + struct stat buf; + int fd; + time_t time(); + char *strncpy(); + + if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) + return; + if (!fstat(fd, &buf)) { + (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); + (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); + (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + (void)time(&ut.ut_time); + if (write(fd, (char *)&ut, sizeof(struct utmp)) != + sizeof(struct utmp)) + (void)ftruncate(fd, buf.st_size); + } + (void)close(fd); +} + +#endif /* !defined OLD_TIME */ diff --git a/time/newctime.3 b/time/newctime.3 new file mode 100644 index 000000000..463936078 --- /dev/null +++ b/time/newctime.3 @@ -0,0 +1,220 @@ +.TH NEWCTIME 3 +.SH NAME +asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time to ASCII +.SH SYNOPSIS +.nf +.B extern char *tzname[2]; +.PP +.B void tzset() +.PP +.B #include <sys/types.h> +.PP +.B char *ctime(clock) +.B time_t *clock; +.PP +.B double difftime(time1, time0) +.B time_t time1; +.B time_t time0; +.PP +.B #include <time.h> +.PP +.B char *asctime(tm) +.B struct tm *tm; +.PP +.B struct tm *localtime(clock) +.B long *clock; +.PP +.B struct tm *gmtime(clock) +.B long *clock; +.PP +.B time_t mktime(tm) +.B struct tm *tm; +.PP +.B cc ... -lz +.fi +.SH DESCRIPTION +.I Ctime\^ +converts a long integer, pointed to by +.IR clock , +representing the time in seconds since +00:00:00 UTC, January 1, 1970, +and returns a pointer to a +26-character string +of the form +.br +.ce +.eo +Thu Nov 24 18:22:48 1986\n\0 +.ec +.br +All the fields have constant width. +.PP +.IR Localtime\^ +and +.I gmtime\^ +return pointers to ``tm'' structures, described below. +.I Localtime\^ +corrects for the time zone and any time zone adjustments +(such as Daylight Saving Time in the U.S.A.). +Before doing so, +.I localtime\^ +calls +.I tzset\^ +(if +.I tzset\^ +has not been called in the current process). +After filling in the ``tm'' structure, +.I localtime +sets the +.BR tm_isdst 'th +element of +.B tzname +to a pointer to an +ASCII string that's the time zone abbreviation to be used with +.IR localtime 's +return value. +.PP +.I Gmtime\^ +converts to Coordinated Universal Time. +.PP +.I Asctime\^ +converts a time value contained in a +``tm'' structure to a 26-character string, +as shown in the above example, +and returns a pointer +to the string. +.PP +.I Mktime\^ +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 +.I 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 +.I mktime +to presume initially that summer time (for example, Daylight Saving Time +in the U.S.A.) +respectively, +is or is not in effect for the specified time. +A negative value for +.B tm_isdst +causes the +.I mktime +function to attempt to divine whether summer time is in effect +for the specified time.) +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. +.I Mktime\^ +returns the specified calendar time; +If the calendar time cannot be represented, +it returns +.BR -1 . +.PP +.I Difftime\^ +returns the difference between two calendar times, +.RI ( time1 +- +.IR time0 ), +expressed in seconds. +.PP +Declarations of all the functions and externals, and the ``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 .5i +\w'long tm_gmtoff;\0\0'u + int tm_sec; /\(** seconds (0 - 60) \(**/ + int tm_min; /\(** minutes (0 - 59) \(**/ + int tm_hour; /\(** hours (0 - 23) \(**/ + int tm_mday; /\(** day of month (1 - 31) \(**/ + int tm_mon; /\(** month of year (0 - 11) \(**/ + int tm_year; /\(** year \- 1900 \(**/ + int tm_wday; /\(** day of week (Sunday = 0) \(**/ + int tm_yday; /\(** day of year (0 - 365) \(**/ + int tm_isdst; /\(** is summer time in effect? \(**/ + char \(**tm_zone; /\(** abbreviation of timezone name \(**/ + long tm_gmtoff; /\(** offset from UTC in seconds \(**/ +.fi +.RE +.PP +The +.I tm_zone +and +.I tm_gmtoff +fields exist, and are filled in, only if arrangements to do +so were made when the library containing these functions was +created. +There is no guarantee that these fields will continue to exist +in this form in future releases of this code. +.PP +.I Tm_isdst\^ +is non-zero if summer time is in effect. +.PP +.I Tm_gmtoff +is the offset (in seconds) of the time represented +from UTC, with positive values indicating east +of the Prime Meridian. +.SH FILES +.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u +/usr/local/etc/zoneinfo time zone information directory +.br +/usr/local/etc/zoneinfo/localtime local time zone file +.br +/usr/local/etc/zoneinfo/posixrules used with POSIX-style TZ's +.br +/usr/local/etc/zoneinfo/GMT for UTC leap seconds +.sp +If +.B /usr/local/etc/zoneinfo/GMT +is absent, +UTC leap seconds are loaded from +.BR /usr/local/etc/zoneinfo/posixrules . +.SH SEE ALSO +getenv(3), +newtzset(3), +time(2), +tzfile(5) +.SH NOTES +The return values point to static data; +the data is overwritten by each call. +The +.B tm_zone +field of a returned +.B "struct tm" +points to a static array of characters, which +will also be overwritten at the next call +(and by calls to +.IR tzset ). +.PP +Avoid using out-of-range values with +.I mktime +when setting up lunch with promptness sticklers in Riyadh. +.\" @(#)newctime.3 7.9 diff --git a/time/newtzset.3 b/time/newtzset.3 new file mode 100644 index 000000000..1ca50ca30 --- /dev/null +++ b/time/newtzset.3 @@ -0,0 +1,236 @@ +.TH NEWTZSET 3 +.SH NAME +tzset \- initialize time conversion information +.SH SYNOPSIS +.nf +.B void tzset() +.PP +.B cc ... -lz +.fi +.SH DESCRIPTION +.I Tzset +uses the value of the environment variable +.B TZ +to set time conversion information used by +.IR localtime . +If +.B TZ +does not appear in the environment, +the best available approximation to local wall clock time, as specified +by the +.IR tzfile (5)-format +file +.B localtime +in the system time conversion information directory, is used by +.IR localtime . +If +.B TZ +appears in the environment but its value is a null string, +Coordinated Universal Time (UTC) is used (without leap second +correction). If +.B TZ +appears in the environment and its value is not a null string: +.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 +.IR 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 summer +.RI ( dst ) +time zone. Only +.I std +is required; if +.I dst +is missing, then summer time does not apply in this locale. +Upper- and lowercase letters are explicitly allowed. Any characters +except a leading colon +.RB ( : ), +digits, comma +.RB ( , ), +minus +.RB ( \(mi ), +plus +.RB ( \(pl ), +and ASCII NUL are allowed. +.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 , +summer 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) \(em if present \(em between zero and 59. If preceded by a +.RB `` \(mi '', +the time zone shall be east of the Prime Meridian; otherwise it shall be +west (which may be indicated by an optional preceding +.RB `` \(pl ''). +.TP +.I rule +Indicates when to change to and back from summer 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 summer 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. +.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 \(em including leap +years \(em 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 ``the last +.I d +day in month +.IR m '' +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 no leading sign +.RB (`` \(mi '' +or +.RB `` \(pl '') +is allowed. The default, if +.I time +is not given, is +.BR 02:00:00 . +.RE +.LP +If no +.I rule +is present in +.BR TZ , +the rules specified +by the +.IR tzfile (5)-format +file +.B posixrules +in the system time conversion information directory are used, with the +standard and summer time offsets from UTC 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. +.PP +If the +.B TZ +environment variable does not specify a +.IR tzfile (5)-format +and cannot be interpreted as a direct specification, +UTC is used. +.SH FILES +.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u +/usr/local/etc/zoneinfo time zone information directory +.br +/usr/local/etc/zoneinfo/localtime local time zone file +.br +/usr/local/etc/zoneinfo/posixrules used with POSIX-style TZ's +.br +/usr/local/etc/zoneinfo/GMT for UTC leap seconds +.sp +If +.B /usr/local/etc/zoneinfo/GMT +is absent, +UTC leap seconds are loaded from +.BR /usr/local/etc/zoneinfo/posixrules . +.SH SEE ALSO +getenv(3), +newctime(3), +time(2), +tzfile(5) +.\" @(#)newtzset.3 7.3 diff --git a/time/northamerica b/time/northamerica new file mode 100644 index 000000000..40733fddc --- /dev/null +++ b/time/northamerica @@ -0,0 +1,953 @@ +# @(#)northamerica 7.12 +# also includes Central America and the Caribbean + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (August 17, 1994): +# A reliable and entertaining source about time zones is +# Derek Howse, Greenwich time and the discovery of the longitude, +# Oxford University Press (1980). + +############################################################################### + +# United States + +# From Arthur David Olson: +# US Daylight Saving Time ended on the last Sunday of *October* in 1974. +# See, for example, the front page of the Saturday, October 26, 1974 +# and Sunday, October 27, 1974 editions of the Washington Post. + +# From seismo!munnari!kre: +# I recall also being told by someone once that Canada didn't have +# the DST variations in 74/75 that the US did, but I am not nearly +# sure enough of this to add anything. + +# From Arthur David Olson: +# The above has been confirmed by Bob Devine; we'll go with it here. + +# From Arthur David Olson: +# Before the Uniform Time Act of 1966 took effect in 1967, observance of +# Daylight Saving Time in the US was by local option, except during wartime. + +# Rule NAME FROM TO TYPE 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 - Sep 30 2:00 0 S +Rule US 1967 max - 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 max - Apr Sun>=1 2:00 1:00 D + +# From Bob Devine (January 28, 1988): +# ...Alaska (and Hawaii) had the timezone names changed in 1967. +# old new +# Pacific Standard Time(PST) -same- +# Yukon Standard Time(YST) -same- +# Central Alaska S.T. (CAT) Alaska-Hawaii St[an]dard Time (AHST) +# Nome Standard Time (NT) Bering Standard Time (BST) +# +# ...Alaska's timezone lines were redrawn in 1983 to give only 2 tz. +# The YST zone now covers nearly all of the state, AHST just part +# of the Aleutian islands. No DST. + +# From U. S. Naval Observatory (January 19, 1989): +# USA EASTERN 5 H BEHIND UTC NEW YORK, WASHINGTON +# USA EASTERN 4 H BEHIND UTC APR 3 - OCT 30 +# USA CENTRAL 6 H BEHIND UTC CHICAGO, HOUSTON +# USA CENTRAL 5 H BEHIND UTC APR 3 - OCT 30 +# USA MOUNTAIN 7 H BEHIND UTC DENVER +# USA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 30 +# USA PACIFIC 8 H BEHIND UTC L.A., SAN FRANCISCO +# USA PACIFIC 7 H BEHIND UTC APR 3 - OCT 30 +# USA ALASKA STD 9 H BEHIND UTC MOST OF ALASKA (AKST) +# USA ALASKA STD 8 H BEHIND UTC APR 3 - OCT 30 (AKDT) +# USA ALEUTIAN 10 H BEHIND UTC ISLANDS WEST OF 170W +# USA - " - 9 H BEHIND UTC APR 3 - OCT 30 +# USA HAWAII 10 H BEHIND UTC +# USA BERING 11 H BEHIND UTC SAMOA, MIDWAY + +# From Arthur David Olson (January 21, 1989): +# The above dates are for 1988. +# Note the "AKST" and "AKDT" abbreviations, the claim that there's +# no DST in Samoa, and the claim that there is DST in Alaska and the +# Aleutians. + +# From Arthur David Olson (February 13, 1988): +# Legal standard time zone names, from United States Code (1982 Edition and +# Supplement III), Title 15, Chapter 6, Section 260 and forward. First, names +# up to April 1, 1967 (when most provisions of the Uniform Time Act of 1966 +# took effect), as explained in sections 263 and 261: +# (none) +# United States standard eastern time +# United States standard mountain time +# United States standard central time +# United States standard Pacific time +# (none) +# United States standard Alaska time +# (none) +# Next, names from April 1, 1967 until November 30, 1983 (the date for +# public law 98-181): +# Atlantic standard time +# eastern standard time +# central standard time +# mountain standard time +# Pacific standard time +# Yukon standard time +# Alaska-Hawaii standard time +# Bering standard time +# And after November 30, 1983: +# Atlantic standard time +# eastern standard time +# central standard time +# mountain standard time +# Pacific standard time +# Alaska standard time +# Hawaii-Aleutian standard time +# Samoa standard time +# The law doesn't give abbreviations. + +# From Paul Eggert <eggert@twinsun.com> (August 16, 1994): +# Howse writes that Alaska switched from the Julian to the Gregorian calendar, +# and from east-of-GMT to west-of-GMT days, in 1867 when the US purchased it +# from Russia. We don't have this data pinned down yet, though. + +# Easy stuff first--including Alaska, where we ignore history (since we +# can't tell if we should give Yukon time or Alaska-Hawaii time for "old" +# times). + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/New_York -5:00 US E%sT +Zone America/Chicago -6:00 US C%sT +Zone America/Denver -7:00 US M%sT +Zone America/Los_Angeles -8:00 US P%sT +Zone America/Anchorage -9:00 US AK%sT + # AK%sT is the abbreviation per USNO + +# Mainland US areas that are always Standard as of 1986. + +Zone America/Fort_Wayne -5:00 US E%sT 1946 + -5:00 - EST # Always EST as of 1986 +# From Arthur David Olson (October 28, 1991): +# An article on page A3 of the Sunday, October 27, 1991 Washington Post +# notes that Starke County switched from Central time to Eastern time as of +# October 27, 1991. +Zone America/Knox_IN -6:00 US C%sT 1991 Oct 27 2:00 + -5:00 - EST # Always EST as of 1991 +Zone America/Phoenix -7:00 US M%sT 1946 + -7:00 - MST # Always MST as of 1986 + +# From Arthur David Olson (February 13, 1988): +# However. . .a writer from the Inter Tribal Council of Arizona, Inc., +# notes in private correspondence dated 12/28/87 that "Presently, only the +# Navajo Nation participates in the Daylight Saving Time policy, due to its +# large size and location in three states." (The "only" means that other +# tribal nations don't use DST.) + +Link America/Denver Navajo + +# From Bob Devine (January 28, 1988): +# Michigan didn't observe DST from 1968 to 1973. + +Zone America/Detroit -5:00 US E%sT 1968 + -5:00 - EST 1973 + -5:00 US E%sT + +# Samoa just changes names. No DST, per Naval Observatory. +# +# Howse writes that in 1879 the King of Samoa decided to change +# ``the date in his kingdom from the Antipodean to the American system, +# ordaining -- by a masterpiece of diplomatic flattery -- that +# the Fourth of July should be celebrated twice in that year.'' + +Zone Pacific/Samoa 12:37:12 - LMT 1879 Jul 5 + -11:22:48 - LMT 1911 + -11:30 - SST 1950 + -11:00 - NST 1967 Apr # N=Nome + -11:00 - BST 1983 Nov 30 # B=Bering + -11:00 - SST # S=Samoa + +Zone Pacific/Midway -11:49:28 - LMT 1901 + -11:00 - NST 1967 Apr # N=Nome + -11:00 - BST 1983 Nov 30 # B=Bering + -11:00 - SST # S=Samoa + +# Aleutian has a name change. DST, per Naval Observatory. + +Zone America/Atka -10:00 US AH%sT 1983 Nov 30 + -10:00 US HA%sT + +# From Arthur David Olson: +# And then there's Hawaii. +# DST was observed for one day in 1933; +# Standard time was change by half an hour in 1947; +# it's always standard as of 1986. + +Zone Pacific/Honolulu -10:30 US H%sT 1933 Apr 30 2:00 + -10:30 1:00 HDT 1933 May 1 2:00 + -10:30 US H%sT 1947 Jun 8 2:00 + -10:00 - HST + +# Navassa +# no information; probably like US/Eastern + + +# Old names, for S5 users + +# Link LINK-FROM LINK-TO +Link America/New_York EST5EDT +Link America/Chicago CST6CDT +Link America/Denver MST7MDT +Link America/Los_Angeles PST8PDT +Link America/Fort_Wayne EST +Link America/Phoenix MST +Link Pacific/Honolulu HST + +################################################################################ + + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# I invented the abbreviation SPST for St Pierre Standard Time; SPDT likewise. +# Corrections are welcome! +# +# See the `europe' file for Greenland. +# +# See the `africa' file for Zone naming conventions. + + + +# Canada + +# Canada is reportedly lots easier than the US--leastways since 1951. +# I don't know what they did before then. +# 4.3BSD claims that it's perfectly regular. +# According to a posting in "comp.bugs.misc", "comp.unix.wizards", etc. +# on February 8, 1987, by Dave Sherman of the Law Society of Upper Canada, +# "...Canada (well, Ontario and at least some of the other provinces) are +# adopting the new daylight savings time rules...". We assume all of +# Canada is doing so. + +# From Bob Devine (January 28, 1988): +# All of Canada did have DST from your first rule except Saskatchewan. +# Which parts did not observe DST is hard to pinpoint but most of the +# province follows the rules. +# NOTE: those that didn't have DST for that rule, also +# probably did not have it for several years previous. + +# From U. S. Naval Observatory (January 19, 1989): +# CANADA NEW FDL 3.5H BEHIND UTC ST.JOHN'S +# CANADA NEW FDL 1.5H BEHIND UTC APR 3 - OCT 29 +# CANADA ATLANTIC 4 H BEHIND UTC HALIFAX +# CANADA ATLANTIC 3 H BEHIND UTC APR 3 - OCT 29 +# CANADA EASTERN 5 H BEHIND UTC TORONTO, MONTREAL, OTTAWA +# CANADA EASTERN 4 H BEHIND UTC APR 3 - OCT 29 +# CANADA CENTRAL 6 H BEHIND UTC REGINA, WINNIPEG +# CANADA CENTRAL 5 H BEHIND UTC APR 3 - OCT 29 +# CANADA MOUNTAIN 7 H BEHIND UTC CALGARY, EDMONTON +# CANADA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 29 +# CANADA PACIFIC 8 H BEHIND UTC VANCOUVER +# CANADA PACIFIC 7 H BEHIND UTC APR 3 - OCT 29 +# CANADA YUKON SAME AS PACIFIC DAWSON + +# From Arthur David Olson (January 21, 1989): +# April 3 fell on a Sunday in 1988; October 29 fell on a Sunday in 1989. Ahem. +# Note claim that there's double DST in Newfoundland and that Yukon should +# be same as Pacific. + +# From W. Jones (jones@skdad.usask.ca) (November 6, 1992): +# The. . .below is based on information I got from our law library, the +# provincial archives, and the provincial Community Services department. +# A precise history would require digging through newspaper archives, and +# since you didn't say what you wanted, I didn't bother. +# +# Saskatchewan is split by a time zone meridian (105W) and over the years +# the boundary became pretty ragged as communities near it reevaluated +# their affiliations in one direction or the other. In 1965 a provincial +# referendum favoured legislating common time practices. +# +# On 15 April 1966 the Time Act (c. T-14, Revised Statutes of +# Saskatchewan 1978) was proclaimed, and established that the eastern +# part of Saskatchewan would use CST year round, that districts in +# northwest Saskatchewan would by default follow CST but could opt to +# follow Mountain Time rules (thus 1 hour difference in the winter and +# zero in the summer), and that districts in southwest Saskatchewan would +# by default follow MT but could opt to follow CST. +# +# It took a few years for the dust to settle (I know one story of a town +# on one time zone having its school in another, such that a mom had to +# serve her family lunch in two shifts), but presently it seems that only +# a few towns on the border with Alberta (e.g. Lloydminster) follow MT +# rules any more; all other districts appear to have used CST year round +# since sometime in the 1960s. +# +# Here's how I would summarize things. Establish a "Saskatchewan" CST +# time zone, and note that it officially exists as of 15 April 1966. Any +# current exceptions can put themselves in the "Mountain" zone, since +# those are the rules they follow. Any past exceptions can be forgotten, +# since that's what those who live here have done. + +# From Arthur David Olson (November 21, 1992): +# East-Saskatchewan kept to avoid problems for folks using that zone by name; +# plain Saskatchewan added. + +# From Alain LaBont<e'> <ALB@immedia.ca> (1994-11-14): +# I post here the time zone abbreviations standardized in Canada +# for both English and French in the CAN/CSA-Z234.4-89 standard.... +# +# UTC Standard time Daylight savings time +# offset French English French English +# -2:30 - - HAT NDT +# -3 - - HAA ADT +# -3:30 HNT NST - - +# -4 HNA AST HAE EDT +# -5 HNE EST HAC CDT +# -6 HNC CST HAR MDT +# -7 HNR MST HAP PDT +# -8 HNP PST HAY YDT +# -9 HNY YST - - +# +# HN: Heure Normale ST: Standard Time +# HA: Heure Avanc<e'>e DT: Daylight saving Time +# +# A: de l'Atlantique Atlantic +# C: du Centre Central +# E: de l'Est Eastern +# M: Mountain +# N: Newfoundland +# P: du Pacifique Pacific +# R: des Rocheuses +# T: de Terre-Neuve +# Y: du Yukon Yukon +# +# From Paul Eggert <eggert@twinsun.com> (1994-11-22): +# Alas, this sort of thing must be handled by localization software. + + + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule StJohns 1884 only - Jan 1 0:00 0 S +Rule StJohns 1917 1918 - Apr Sun>=8 2:00 1:00 D +Rule StJohns 1917 only - Sep 17 2:00 0 S +Rule StJohns 1918 only - Oct 31 2:00 0 S +# Whitman gives 1919 Apr 5 and 1920 Apr 5; go with Shanks. +Rule StJohns 1919 only - May 5 23:00 1:00 D +Rule StJohns 1919 only - Aug 12 23:00 0 S +# For 1931-1935 Whitman gives Apr same date; go with Shanks. +Rule StJohns 1920 1935 - May Sun>=1 23:00 1:00 D +Rule StJohns 1920 1935 - Oct lastSun 23:00 0 S +# For 1936-1941 Shanks gives May Mon>=9 and Oct Mon>=2; go with Whitman. +Rule StJohns 1936 1941 - May Sun>=8 0:00 1:00 D +Rule StJohns 1936 1941 - Oct Sun>=1 0:00 0 S +# Shanks gives 1942 May 11 - 1945 Sep 30; go with Whitman. +Rule StJohns 1942 only - Mar 1 0:00 1:00 D +Rule StJohns 1942 only - Dec 31 0:00 0 S +Rule StJohns 1943 only - May 30 0:00 1:00 D +Rule StJohns 1943 only - Sep 5 0:00 0 S +Rule StJohns 1944 only - Jul 10 0:00 1:00 D +Rule StJohns 1944 only - Sep 2 0:00 0 S +Rule StJohns 1945 only - Jan 1 0:00 1:00 D +Rule StJohns 1945 only - Oct 7 2:00 0 S +# For 1946-9 Whitman gives May 5,4,9,1 - Oct 1,5,3,2, and for 1950 he gives +# Apr 30 - Sep 24; go with Shanks. +Rule StJohns 1946 1950 - May Sun>=8 2:00 1:00 D +Rule StJohns 1946 1950 - Oct Sun>=2 2:00 0 S +Rule StJohns 1951 1986 - Apr lastSun 2:00 1:00 D +Rule StJohns 1951 1959 - Sep lastSun 2:00 0 S +Rule StJohns 1960 max - Oct lastSun 2:00 0 S +Rule StJohns 1987 only - Apr Sun>=1 2:00 1:00 D +Rule StJohns 1988 only - Apr Sun>=1 2:00 2:00 D +Rule StJohns 1989 max - Apr Sun>=1 2:00 1:00 D +# St John's has an apostrophe, but Posix file names can't have apostrophes. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/St_Johns -3:30:52 - LMT 1884 + -3:31 StJohns N%sT 1935 Mar 30 + -3:30 StJohns N%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Halifax 1902 only - Jun 15 0:00 0 S +Rule Halifax 1916 only - Apr 1 0:00 1:00 D +Rule Halifax 1916 only - Oct 1 0:00 0 S +Rule Halifax 1918 only - Apr 14 2:00 1:00 D +Rule Halifax 1918 only - Oct 31 2:00 0 S +Rule Halifax 1920 only - May 9 0:00 1:00 D +Rule Halifax 1920 only - Aug 29 0:00 0 S +Rule Halifax 1921 only - May 6 0:00 1:00 D +Rule Halifax 1921 1922 - Sep 5 0:00 0 S +Rule Halifax 1922 only - Apr 30 0:00 1:00 D +Rule Halifax 1923 1925 - May Sun>=1 0:00 1:00 D +Rule Halifax 1923 only - Sep 4 0:00 0 S +Rule Halifax 1924 only - Sep 15 0:00 0 S +Rule Halifax 1925 only - Sep 28 0:00 0 S +Rule Halifax 1926 only - May 16 0:00 1:00 D +Rule Halifax 1926 only - Sep 13 0:00 0 S +Rule Halifax 1927 only - May 1 0:00 1:00 D +Rule Halifax 1927 only - Sep 26 0:00 0 S +Rule Halifax 1928 1931 - May Sun>=8 0:00 1:00 D +Rule Halifax 1928 only - Sep 9 0:00 0 S +Rule Halifax 1929 only - Sep 3 0:00 0 S +Rule Halifax 1930 only - Sep 15 0:00 0 S +Rule Halifax 1931 1932 - Sep Mon>=24 0:00 0 S +Rule Halifax 1933 only - Apr 30 0:00 1:00 D +Rule Halifax 1933 only - Oct 2 0:00 0 S +Rule Halifax 1934 only - May 20 0:00 1:00 D +Rule Halifax 1934 only - Sep 16 0:00 0 S +Rule Halifax 1935 only - Jun 2 0:00 1:00 D +Rule Halifax 1935 only - Sep 30 0:00 0 S +Rule Halifax 1936 only - Jun 1 0:00 1:00 D +Rule Halifax 1936 only - Sep 14 0:00 0 S +Rule Halifax 1937 1938 - May Sun>=1 0:00 1:00 D +Rule Halifax 1937 1941 - Sep Mon>=24 0:00 0 S +Rule Halifax 1939 only - May 28 0:00 1:00 D +Rule Halifax 1940 1941 - May Sun>=1 0:00 1:00 D +Rule Halifax 1942 only - Feb 9 2:00 1:00 D +Rule Halifax 1945 1959 - Sep lastSun 2:00 0 S +Rule Halifax 1946 1959 - Apr lastSun 2:00 1:00 D +Rule Halifax 1962 1986 - Apr lastSun 2:00 1:00 D +Rule Halifax 1962 max - Oct lastSun 2:00 0 S +Rule Halifax 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Halifax -4:14:24 - LMT 1902 Jun 15 + -4:00 Halifax A%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Mont 1884 only - Jan 1 0:00 0 S +Rule Mont 1917 only - Mar 25 2:00 1:00 D +Rule Mont 1917 only - Apr 24 0:00 0 S +Rule Mont 1918 only - Apr 14 2:00 1:00 D +Rule Mont 1918 only - Oct 31 2:00 0 S +Rule Mont 1919 only - Mar 31 2:30 1:00 D +Rule Mont 1919 only - Oct 25 2:30 0 S +Rule Mont 1920 only - May 2 2:30 1:00 D +Rule Mont 1920 only - Oct 3 2:30 0 S +Rule Mont 1921 only - May 1 2:00 1:00 D +Rule Mont 1921 only - Oct 2 2:30 0 S +Rule Mont 1922 only - Apr 30 2:00 1:00 D +Rule Mont 1922 only - Oct 1 2:30 0 S +Rule Mont 1924 only - May 17 2:00 1:00 D +Rule Mont 1924 1926 - Sep lastSun 2:30 0 S +Rule Mont 1925 1926 - May Sun>=1 2:00 1:00 D +Rule Mont 1927 only - May 1 0:00 1:00 D +Rule Mont 1927 1932 - Sep Sun>=25 0:00 0 S +Rule Mont 1928 1931 - Apr Sun>=25 0:00 1:00 D +Rule Mont 1932 only - May 1 0:00 1:00 D +Rule Mont 1933 1940 - Apr Sun>=24 0:00 1:00 D +Rule Mont 1933 only - Oct 1 0:00 0 S +Rule Mont 1934 1939 - Sep Sun>=24 0:00 0 S +Rule Mont 1945 1948 - Sep lastSun 2:00 0 S +Rule Mont 1946 1986 - Apr lastSun 2:00 1:00 D +Rule Mont 1949 1950 - Oct lastSun 2:00 0 S +Rule Mont 1951 1956 - Sep lastSun 2:00 0 S +Rule Mont 1957 max - Oct lastSun 2:00 0 S +Rule Mont 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Montreal -4:54:16 - LMT 1884 + -5:00 Mont E%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Winn 1887 only - Jul 16 0:00 0 S +Rule Winn 1916 only - Apr 23 0:00 1:00 D +Rule Winn 1916 only - Sep 17 0:00 0 S +Rule Winn 1918 only - Apr 14 2:00 1:00 D +Rule Winn 1918 only - Oct 31 2:00 0 S +Rule Winn 1937 only - May 16 2:00 1:00 D +Rule Winn 1937 only - Sep 23 2:00 0 S +Rule Winn 1942 only - Feb 9 2:00 1:00 D +Rule Winn 1945 only - Sep lastSun 2:00 0 S +Rule Winn 1946 only - May 12 2:00 1:00 D +Rule Winn 1946 only - Oct 13 2:00 0 S +Rule Winn 1947 1949 - Apr lastSun 2:00 1:00 D +Rule Winn 1947 1958 - Sep lastSun 2:00 0 S +Rule Winn 1948 only - May 1 2:00 1:00 D +Rule Winn 1948 1960 - Apr lastSun 2:00 1:00 D +Rule Winn 1959 only - Oct lastSun 2:00 0 S +Rule Winn 1960 only - Sep lastSun 2:00 0 S +Rule Winn 1963 only - Apr lastSun 2:00 1:00 D +Rule Winn 1963 only - Sep lastSun 2:00 0 S +Rule Winn 1966 1986 - Apr lastSun 2:00 1:00 D +Rule Winn 1966 max - Sep lastSun 2:00 0 S +Rule Winn 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Winnipeg -6:28:36 - LMT 1887 Jul 16 + -6:00 Winn C%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Regina 1905 only - Sep 1 0:00 0 S +Rule Regina 1918 only - Apr 14 2:00 1:00 D +Rule Regina 1918 only - Oct 31 2:00 0 S +Rule Regina 1930 1934 - May Sun>=1 0:00 1:00 D +Rule Regina 1930 1934 - Oct Sun>=1 0:00 0 S +Rule Regina 1937 1941 - Apr Sun>=8 0:00 1:00 D +Rule Regina 1937 only - Oct Sun>=8 0:00 0 S +Rule Regina 1938 only - Oct Sun>=1 0:00 0 S +Rule Regina 1939 1941 - Oct Sun>=8 0:00 0 S +Rule Regina 1942 only - Feb 9 2:00 1:00 D +Rule Regina 1945 only - Sep lastSun 2:00 0 S +Rule Regina 1946 only - Apr 14 2:00 1:00 D +Rule Regina 1946 only - Oct 13 2:00 0 S +Rule Regina 1947 1960 - Apr lastSun 2:00 1:00 D +Rule Regina 1947 1959 - Sep lastSun 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Regina -6:58:36 - LMT 1905 Sep + -7:00 Regina M%sT 1966 Apr 15 + -6:00 - CST + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Edm 1906 only - Sep 1 0:00 0 S +Rule Edm 1918 1919 - Apr Sun>=8 2:00 1:00 D +Rule Edm 1918 only - Oct 31 2:00 0 S +Rule Edm 1919 only - May 27 2:00 0 S +Rule Edm 1920 1923 - Apr lastSun 2:00 1:00 D +Rule Edm 1920 only - Oct lastSun 2:00 0 S +Rule Edm 1921 1923 - Sep lastSun 2:00 0 S +Rule Edm 1942 only - Feb 9 2:00 1:00 D +Rule Edm 1945 only - Sep lastSun 2:00 0 S +Rule Edm 1947 only - Apr lastSun 2:00 1:00 D +Rule Edm 1947 only - Sep lastSun 2:00 0 S +Rule Edm 1967 only - Apr lastSun 2:00 1:00 D +Rule Edm 1967 only - Oct lastSun 2:00 0 S +Rule Edm 1969 only - Apr lastSun 2:00 1:00 D +Rule Edm 1969 only - Oct lastSun 2:00 0 S +Rule Edm 1972 1986 - Apr lastSun 2:00 1:00 D +Rule Edm 1972 max - Oct lastSun 2:00 0 S +Rule Edm 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Edmonton -7:33:52 - LMT 1906 Sep + -7:00 Edm M%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Vanc 1884 only - Jan 1 0:00 0 S +Rule Vanc 1918 only - Apr 14 2:00 1:00 D +Rule Vanc 1918 only - Oct 31 2:00 0 S +Rule Vanc 1942 only - Feb 9 2:00 1:00 D +Rule Vanc 1945 only - Sep 30 2:00 0 S +Rule Vanc 1946 1986 - Apr lastSun 2:00 1:00 D +Rule Vanc 1946 only - Oct 13 2:00 0 S +Rule Vanc 1947 1961 - Sep lastSun 2:00 0 S +Rule Vanc 1962 max - Oct lastSun 2:00 0 S +Rule Vanc 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Vancouver -8:12:28 - LMT 1884 + -8:00 Vanc P%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Yukon 1900 only - Jan 1 0:00 0 S +Rule Yukon 1918 only - Apr 14 2:00 1:00 D +Rule Yukon 1918 only - Oct 27 2:00 0 S +Rule Yukon 1919 only - May 25 2:00 1:00 D +Rule Yukon 1919 only - Nov 1 0:00 0 S +Rule Yukon 1942 only - Feb 9 2:00 1:00 D +Rule Yukon 1965 only - Apr 25 0:00 1:00 D +Rule Yukon 1965 only - Oct 31 2:00 0 S +Rule Yukon 1980 1986 - Apr lastSun 2:00 1:00 D +Rule Yukon 1980 max - Oct lastSun 2:00 0 S +Rule Yukon 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Whitehorse -9:00:12 - LMT 1900 Aug 20 + -9:00 Yukon Y%sT 1966 Jul + -8:00 Yukon P%sT +# Parts of Yukon (e.g. Dawson) didn't switch to -8:00 until 1973 Oct 28. + +############################################################################### + +# Mexico + +# From Guy Harris: +# Rules are from the Official Airline Guide, Worldwide Edition, for 1987. +# Rules prior to 1987 are unknown. +# The comments in the OAG say "Only Ensenada, Mexicale, San Felipe and Tijuana +# observe DST." This is presumably Baja California Norte, above 28th parallel, +# as listed there; Mexico/BajaSur is for "Baja California Sur and N. Pacific +# Coast (States of Sinaloa and Sonora)." + +# From Bob Devine (January 28, 1988): +# The Federal District (where Mexico City is) has observed [DST] several +# times but not recently. +# +# I don't where to drawn the line in the North Baja area. 28th latitude +# sounds good -- but it may be higher (how far [d]o radio stations from +# San Diego affect culture?). +# +# The dates of DST probably go back to 1981. The rules are the same as +# US's. This is going to be a headache for US presidential electi[o]n years! + +# From Arthur David Olson (February 13, 1988) +# Since the 1981 starting date is only "probable," we'll keep the 1987 +# starting date below. + +# From U. S. Naval Observatory (January 19, 1989): +# MEXICO BAJA CAL N 7 H BEHIND UTC BAJA CALIFORNIA SUR AND +# MEXICO BAJA CAL N N. PACIFIC COAST (STATES +# MEXICO BAJA CAL N OF SINALOA AND SONORA) +# MEXICO BAJA CAL N 8 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +# MEXICO BAJA CAL N - OCT 29 +# MEXICO BAJA CAL N 7 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +# MEXICO BAJA CAL N - 0CT 29 +# MEXICO 6 H BEHIND UTC STATES OF DURANGO, +# MEXICO COAHUILA, NUEVO LEON, +# MEXICO TAMAULIPAS +# MEXICO 5 H BEHIND UTC STATES OF DURANGO, +# MEXICO COAHUILA, NUEVO LEON, +# MEXICO TAMAULIPAS APR 3 - OCT 29 +# MEXICO 6 H BEHIND UTC GENERAL MEXICO, STATES OF +# MEXICO CAMPECHE, QUINTANA ROO AND +# MEXICO YUCATAN + +# From Arthur David Olson (January 21, 1989): +# April 3 fell on a Sunday in 1988; October 29 fell on a Sunday in 1989. Ahem. +# USNO claims there should be four Mexican zones rather than three: +# a zone that's GMT-8 with DST; a zone that's always GMT-7; +# a zone that's GMT-6 with DST; and a zone that's always GMT-6. + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks also says there are four zones, but disagrees about the fourth. +# Instead of GMT-6 with DST, he says there's GMT-8 without DST. + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Mexico 1922 only - Jan 1 0:00 0 S +Rule Mexico 1939 only - Feb 5 0:00 1:00 D +Rule Mexico 1939 only - Jun 25 0:00 0 S +Rule Mexico 1940 only - Dec 9 0:00 1:00 D +Rule Mexico 1941 only - Apr 1 0:00 0 S +Rule Mexico 1943 only - Dec 16 0:00 1:00 D +Rule Mexico 1944 only - May 1 0:00 0 S +Rule Mexico 1950 only - Feb 12 0:00 1:00 D +Rule Mexico 1950 only - Jul 30 0:00 0 S +Rule BajaN 1950 1966 - Apr lastSun 2:00 1:00 D +Rule BajaN 1950 1961 - Sep lastSun 2:00 0 S +Rule BajaN 1961 1966 - Oct lastSun 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24 + -7:00 - MST 1927 Jun 10 23:00 + -6:00 - CST 1930 Nov 15 + -7:00 - MST 1931 May 1 23:00 + -6:00 - CST 1931 Oct + -7:00 - MST 1932 Mar 30 23:00 + -6:00 Mexico C%sT +Zone America/Mazatlan -7:05:40 - LMT 1921 Dec 31 23:54:20 + -7:00 - MST 1927 Jun 10 23:00 + -6:00 - CST 1930 Nov 15 + -7:00 - MST 1931 May 1 23:00 + -6:00 - CST 1931 Oct + -7:00 - MST 1932 Mar 30 23:00 + -6:00 - CST 1942 Apr + -7:00 - MST 1949 Jan 14 + -8:00 - PST 1970 + -7:00 - MST +Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56 + -8:00 - PST 1927 Jun 10 23:00 + -7:00 - MST 1930 Nov 16 + -8:00 - PST 1942 Apr + -7:00 - MST 1949 Jan 14 + -8:00 BajaN P%sT 1967 Apr lastSun 2:00 + -8:00 US P%sT +Zone America/Ensenada -7:46:28 - LMT 1922 Jan 1 0:13:32 + -8:00 - PST 1927 Jun 10 23:00 + -7:00 - MST 1930 Nov 16 + -8:00 - PST 1942 Apr + -7:00 - MST 1949 Jan 14 + -8:00 - PST +# +# Revillagigedo Is +# no information + +############################################################################### + +# Anguilla +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Anguilla -4:12:16 - LMT 1912 Mar 2 + -4:00 - AST + +# Antigua and Barbuda +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Antigua -4:07:12 - LMT 1912 Mar 2 + -5:00 - EST 1951 + -4:00 - AST + +# Bahamas +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Bahamas 1912 only - Mar 2 0:00 0 S +Rule Bahamas 1964 max - Oct lastSun 2:00 0 S +Rule Bahamas 1964 1986 - Apr lastSun 2:00 1:00 D +Rule Bahamas 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Nassau -5:09:24 - LMT 1912 Mar 2 + -5:00 Bahamas E%sT + +# Barbados +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Barb 1932 only - Jan 1 0:00 0 S +Rule Barb 1977 only - Jun 12 2:00 1:00 D +Rule Barb 1977 1978 - Oct Sun>=1 2:00 0 S +Rule Barb 1978 1980 - Apr Sun>=15 2:00 1:00 D +Rule Barb 1979 only - Sep 30 2:00 0 S +Rule Barb 1980 only - Sep 25 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Barbados -3:58:28 - LMT 1924 # Bridgetown + -3:58 - BMT 1932 # Bridgetown Mean Time + -4:00 Barb A%sT + +# Belize +# Whitman entirely disagrees with Shanks; go with Shanks. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Belize 1912 only - Apr 1 0:00 0 S +Rule Belize 1918 1942 - Oct Sun>=2 0:00 0:30 HD +Rule Belize 1919 1943 - Feb Sun>=9 0:00 0 S +Rule Belize 1973 only - Dec 5 0:00 1:00 D +Rule Belize 1974 only - Feb 9 0:00 0 S +Rule Belize 1982 only - Dec 18 0:00 1:00 D +Rule Belize 1983 only - Feb 12 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Belize -5:52:48 - LMT 1912 Apr + -6:00 Belize C%sT + +# Bermuda +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Bermuda -4:19:04 - LMT 1930 Jan 1 2:00 # Hamilton + -4:00 - AST 1974 Apr 28 2:00 + -4:00 Bahamas A%sT + +# Cayman Is +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Cayman -5:25:32 - LMT 1890 # Georgetown + -5:07 - KMT 1912 Feb # Kingston Mean Time + -5:00 - EST + +# Clipperton +# no information + +# Costa Rica +# Shanks gives some very odd dates for 1991, and stops there. +# For now, we won't guess further. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule CR 1921 only - Jan 15 0:00 0 S +Rule CR 1979 1980 - Feb lastSun 0:00 1:00 D +Rule CR 1979 1980 - Jun Sun>=1 0:00 0 S +Rule CR 1991 only - Jan 19 0:00 1:00 D +Rule CR 1991 only - Jul 1 0:00 0 S +# There are too many San Joses elsewhere, so we'll use `Costa Rica'. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Costa_Rica -5:36:20 - LMT 1890 # San Jose + -5:36 - SJMT 1921 Jan 15 # San Jose Mean Time + -6:00 CR C%sT +# Coco +# no information; probably like America/Costa_Rica + +# Cuba + +# From Bob Devine (January 28, 1988): +# . . .DST is from 2nd Sunday in May to 2nd Sunday in October since 1981. +# Change at midnight. In 1979 & 1980, started at 3rd Sunday in March +# (I think). + +# From U. S. Naval Observatory (January 19, 1989): +# CUBA 5 H BEHIND UTC +# CUBA 4 H BEHIND UTC MAR 20 - OCT 8 + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Cuba 1925 only - Jul 19 12:00 0 S +Rule Cuba 1928 only - Jun 10 0:00 1:00 D +Rule Cuba 1928 only - Oct 10 0:00 0 S +Rule Cuba 1940 1942 - Jun Sun>=1 0:00 1:00 D +Rule Cuba 1940 1942 - Sep Sun>=1 0:00 0 S +Rule Cuba 1945 1946 - Jun Sun>=1 0:00 1:00 D +Rule Cuba 1945 1946 - Sep Sun>=1 0:00 0 S +Rule Cuba 1965 only - Jun 1 0:00 1:00 D +Rule Cuba 1965 only - Sep 30 0:00 0 S +Rule Cuba 1966 only - May 29 0:00 1:00 D +Rule Cuba 1966 only - Oct 2 0:00 0 S +Rule Cuba 1967 only - Apr 8 0:00 1:00 D +Rule Cuba 1967 1968 - Sep Sun>=8 0:00 0 S +Rule Cuba 1968 only - Apr 14 0:00 1:00 D +Rule Cuba 1969 1977 - Apr lastSun 0:00 1:00 D +Rule Cuba 1969 1971 - Oct lastSun 0:00 0 S +Rule Cuba 1972 1974 - Oct 8 0:00 0 S +Rule Cuba 1975 1977 - Oct lastSun 0:00 0 S +Rule Cuba 1978 only - May 7 0:00 1:00 D +Rule Cuba 1978 1980 - Oct Sun>=8 0:00 0 S +Rule Cuba 1979 1980 - Mar Sun>=15 0:00 1:00 D +Rule Cuba 1981 1985 - May Sun>=5 0:00 1:00 D +Rule Cuba 1981 max - Oct Sun>=8 0:00 0 S +Rule Cuba 1986 1989 - Mar Sun>=14 0:00 1:00 D +Rule Cuba 1990 only - Apr 1 0:00 1:00 D +Rule Cuba 1991 max - Mar Sun>=14 0:00 1:00 D + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Havana -5:29:28 - LMT 1890 + -5:30 - HMT 1925 Jul 19 12:00 # Havana MT + -5:00 Cuba C%sT + +# Dominica +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Dominica -4:05:36 - LMT 1911 Jul 1 0:01 # Roseau + -4:00 - AST + +# Dominican Republic +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule DR 1933 only - Apr 1 12:00 0 S +Rule DR 1966 only - Oct 30 0:00 1:00 D +Rule DR 1967 only - Feb 28 0:00 0 S +Rule DR 1969 1973 - Oct lastSun 0:00 0:30 HD +Rule DR 1970 only - Feb 21 0:00 0 S +Rule DR 1971 only - Jan 20 0:00 0 S +Rule DR 1972 1974 - Jan 21 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Santo_Domingo -4:39:36 - LMT 1890 + -4:40 - SDMT 1933 Apr 1 12:00 # S. Dom. MT + -5:00 DR E%sT 1974 Oct 27 + -4:00 - AST + +# El Salvador +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Salv 1921 only - Jan 1 0:00 0 S +Rule Salv 1987 1988 - May Sun>=1 0:00 1:00 D +Rule Salv 1987 1988 - Sep lastSun 0:00 0 S +# There are too many San Salvadors elsewhere, so we'll use `El Salvador'. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/El_Salvador -5:56:48 - LMT 1921 # San Salvador + -6:00 Salv C%sT + +# Grenada +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Grenada -4:07:00 - LMT 1911 Jul + -4:00 - AST + +# Guadeloupe +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Guadeloupe -4:06:08 - LMT 1911 Jun 8 # Pointe a Pitre + -4:00 - AST + +# Guatemala +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Guat 1918 only - Oct 5 0:00 0 S +Rule Guat 1973 only - Nov 25 0:00 1:00 D +Rule Guat 1974 only - Feb 24 0:00 0 S +Rule Guat 1983 only - May 21 0:00 1:00 D +Rule Guat 1983 only - Sep 22 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Guatemala -6:02:04 - LMT 1918 Oct 5 + -6:00 Guat C%sT + +# Haiti +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Haiti 1917 only - Jan 24 12:00 0 S +Rule Haiti 1983 only - May 8 0:00 1:00 D +Rule Haiti 1984 1987 - Apr lastSun 0:00 1:00 D +Rule Haiti 1983 1987 - Oct lastSun 0:00 0 S +Rule Haiti 1988 max - Apr Sun>=1 2:00 1:00 D +Rule Haiti 1988 max - Oct lastSun 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Port-au-Prince -4:49:20 - LMT 1890 + -4:49 - PPMT 1917 Jan 24 12:00 # P-a-P MT + -5:00 Haiti E%sT + +# Honduras +# Shanks says 1921 Jan 1; go with Whitman's more precise Apr 1. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Tegucigalpa -5:48:52 - LMT 1921 Apr + -6:00 Salv C%sT + +# Jamaica + +# From Bob Devine (January 28, 1988): +# Follows US rules. + +# From U. S. Naval Observatory (January 19, 1989): +# JAMAICA 5 H BEHIND UTC + +# From Shanks (1991): +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Jamaica -5:07:12 - LMT 1890 # Kingston + -5:07 - KMT 1912 Feb # Kingston Mean Time + -5:00 - EST 1974 Jan 6 2:00 + -5:00 US E%sT + +# Martinique +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Martinique -4:04:20 - LMT 1890 # Fort-de-France + -4:04 - FFMT 1911 May # Fort-de-France MT + -4:00 - AST 1980 Apr 6 + -4:00 1:00 ADT 1980 Sep 28 + -4:00 - AST + +# Montserrat +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Montserrat -4:08:52 - LMT 1911 Jul 1 0:01 # Plymouth + -4:00 - AST + +# Nicaragua +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Nic 1975 only - Feb 16 0:00 0 S +Rule Nic 1979 1980 - Mar Sun>=16 0:00 1:00 D +Rule Nic 1979 1980 - Jun Mon>=23 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Managua -5:45:08 - LMT 1890 + -5:45 - MMT 1934 Jun 23 # Managua Mean Time + -6:00 - CST 1973 May + -5:00 - EST 1975 Feb 16 + -6:00 Nic C%sT + +# Panama +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Panama -5:18:08 - LMT 1890 + -5:20 - PMT 1908 Apr 22 # Panama Mean Time + -5:00 - EST + +# Puerto Rico +# There are too many San Juans elsewhere, so we'll use `Puerto_Rico'. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Puerto_Rico -4:24:28 - LMT 1899 Mar 28 12:00 # San Juan + -4:00 - AST 1942 May 3 + -4:00 1:00 ADT 1945 Sep 30 2:00 + -4:00 - AST + +# St Kitts-Nevis +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/St_Kitts -4:10:52 - LMT 1912 Mar 2 # Basseterre + -4:00 - AST + +# St Lucia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/St_Lucia -4:04:00 - LMT 1890 # Castries + -4:04 - CMT 1912 # Castries Mean Time + -4:00 - AST + +# St Pierre and Miquelon +# There are too many St Pierres elsewhere, so we'll use `Miquelon'. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre + -4:00 - AST 1980 May + -3:00 Mont SP%sT + +# St Vincent and the Grenadines +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/St_Vincent -4:04:56 - LMT 1890 # Kingstown + -4:05 - KMT 1912 # Kingstown Mean Time + -4:00 - AST + +# Turks and Caicos +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Grand_Turk -4:44:32 - LMT 1890 + -5:07 - KMT 1912 Feb # Kingston Mean Time + -5:00 - EST 1979 Apr 29 2:00 + -5:00 US E%sT + +# Virgin Is (British and US) +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Virgin -4:19:44 - LMT 1911 Jul # Charlotte Amalie + -4:00 - AST diff --git a/time/optind.c b/time/optind.c new file mode 100644 index 000000000..70c1db23e --- /dev/null +++ b/time/optind.c @@ -0,0 +1,10 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)optind.c 7.3"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +int opterr = 1, /* if error message should be printed */ + optind = 1; /* index into parent argv vector */ +char *optarg; /* argument associated with option */ +int optopt; diff --git a/time/pacificnew b/time/pacificnew new file mode 100644 index 000000000..cd1477cc7 --- /dev/null +++ b/time/pacificnew @@ -0,0 +1,26 @@ +# @(#)pacificnew 7.6 + +# From Arthur David Olson (April 5, 1989): +# On April 5, 1989, the U. S. House of Representatives passed (238-154) a bill +# establishing "Pacific Presidential Election Time"; it was not acted on +# by the Senate or signed into law by the President. +# You might want to change the "PE" (Presidential Election) below to +# "Q" (Quadrennial) to maintain three-character zone abbreviations. +# If you're really conservative, you might want to change it to "D". +# Avoid "L" (Leap Year), which won't be true in 2100. + +# If Presidential Election Time is ever established, replace "XXXX" below +# with the year the law takes effect and uncomment the "##" lines. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +## Rule Twilite XXXX max - Apr Sun>=1 2:00 1:00 D +## Rule Twilite XXXX max uspres Oct lastSun 2:00 1:00 PE +## Rule Twilite XXXX max uspres Nov Sun>=7 2:00 0 S +## Rule Twilite XXXX max nonpres Oct lastSun 2:00 0 S + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +## Zone US/Pacific-PET -8:00 US P%sT XXXX +## -8:00 Twilite P%sT + +# For now... +Link America/Los_Angeles US/Pacific-New ## diff --git a/time/private.h b/time/private.h new file mode 100644 index 000000000..8852b8337 --- /dev/null +++ b/time/private.h @@ -0,0 +1,210 @@ +#ifndef PRIVATE_H + +#define PRIVATE_H + +/* +** 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 7.10"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** const +*/ + +#ifndef const +#ifndef __STDC__ +#define const +#endif /* !defined __STDC__ */ +#endif /* !defined const */ + +/* +** void +*/ + +#ifndef void +#ifndef __STDC__ +#ifndef vax +#ifndef sun +#define void char +#endif /* !defined sun */ +#endif /* !defined vax */ +#endif /* !defined __STDC__ */ +#endif /* !defined void */ + +/* +** INITIALIZE +*/ + +#ifndef GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#endif /* defined lint */ +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#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 */ + +/* +** P((args)) +*/ + +#ifndef P +#ifdef __STDC__ +#define P(x) x +#endif /* defined __STDC__ */ +#ifndef __STDC__ +#define P(x) () +#endif /* !defined __STDC__ */ +#endif /* !defined P */ + +/* +** genericptr_T +*/ + +#ifdef __STDC__ +typedef void * genericptr_T; +#endif /* defined __STDC__ */ +#ifndef __STDC__ +typedef char * genericptr_T; +#endif /* !defined __STDC__ */ + +#include "sys/types.h" /* for time_t */ +#include "stdio.h" +#include "ctype.h" +#include "errno.h" +#include "string.h" +#include "limits.h" /* for CHAR_BIT */ +#ifndef _TIME_ +#include "time.h" +#endif /* !defined _TIME_ */ + +#ifndef remove +extern int unlink P((const char * filename)); +#define remove unlink +#endif /* !defined remove */ + +#ifndef FILENAME_MAX + +#ifndef MAXPATHLEN +#ifdef unix +#include "sys/param.h" +#endif /* defined unix */ +#endif /* !defined MAXPATHLEN */ + +#ifdef MAXPATHLEN +#define FILENAME_MAX MAXPATHLEN +#endif /* defined MAXPATHLEN */ +#ifndef MAXPATHLEN +#define FILENAME_MAX 1024 /* Pure guesswork */ +#endif /* !defined MAXPATHLEN */ + +#endif /* !defined FILENAME_MAX */ + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif /* !defined EXIT_SUCCESS */ + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif /* !defined EXIT_FAILURE */ + +#ifdef __STDC__ + +#define alloc_size_T size_t +#define qsort_size_T size_t +#define fwrite_size_T size_t + +#endif /* defined __STDC__ */ +#ifndef __STDC__ + +#ifndef alloc_size_T +#define alloc_size_T unsigned +#endif /* !defined alloc_size_T */ + +#ifndef qsort_size_T +#ifdef USG +#define qsort_size_T unsigned +#endif /* defined USG */ +#ifndef USG +#define qsort_size_T int +#endif /* !defined USG */ +#endif /* !defined qsort_size_T */ + +#ifndef fwrite_size_T +#define fwrite_size_T int +#endif /* !defined fwrite_size_T */ + +#ifndef USG +extern char * sprintf P((char * buf, const char * format, ...)); +#endif /* !defined USG */ + +#endif /* !defined __STDC__ */ + +/* +** Ensure that these are declared--redundantly declaring them shouldn't hurt. +*/ + +extern char * getenv P((const char * name)); +extern genericptr_T malloc P((alloc_size_T size)); +extern genericptr_T calloc P((alloc_size_T nelem, alloc_size_T elsize)); +extern genericptr_T realloc P((genericptr_T oldptr, alloc_size_T newsize)); + +#ifdef USG +extern void exit P((int s)); +extern void qsort P((genericptr_T base, qsort_size_T nelem, + qsort_size_T elsize, int (*comp)())); +extern void perror P((const char * string)); +extern void free P((char * buf)); +#endif /* defined USG */ + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* !defined FALSE */ + +#ifndef INT_STRLEN_MAXIMUM +/* +** 302 / 1000 is log10(2.0) rounded up. +** Subtract one for the sign bit; +** add one for integer division truncation; +** add one more for a minus sign. +*/ +#define INT_STRLEN_MAXIMUM(type) \ + ((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2) +#endif /* !defined INT_STRLEN_MAXIMUM */ + +#ifndef LOCALE_HOME +#define LOCALE_HOME "/usr/lib/locale" +#endif /* !defined LOCALE_HOME */ + +/* +** UNIX was a registered trademark of UNIX System Laboratories in 1993. +** VAX is a trademark of Digital Equipment Corporation. +*/ + +#endif /* !defined PRIVATE_H */ diff --git a/time/scheck.c b/time/scheck.c new file mode 100644 index 000000000..404c6b211 --- /dev/null +++ b/time/scheck.c @@ -0,0 +1,62 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)scheck.c 8.12"; +#endif /* !defined lint */ +#endif /* !defined NOID */ + +/*LINTLIBRARY*/ + +#include "private.h" + +extern char * imalloc P((int n)); +extern void ifree P((char * p)); + +char * +scheck(string, format) +const char * const string; +char * const format; +{ + register char * fbuf; + register const char * fp; + register char * tp; + register int c; + register char * result; + char dummy; + static char nada; + + result = &nada; + 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 (isascii(*fp) && isdigit(*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; +} diff --git a/time/solar87 b/time/solar87 new file mode 100644 index 000000000..a4e2f39df --- /dev/null +++ b/time/solar87 @@ -0,0 +1,386 @@ +# @(#)solar87 7.2 + +# So much for footnotes about Saudi Arabia. +# Apparent noon times below are for Riyadh; your mileage will vary. +# Times were computed using formulas in the U.S. Naval Observatory's +# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of +# [plus or minus two] seconds during the current year." +# +# Rounding to the nearest five seconds results in fewer than +# 256 different "time types"--a limit that's faced because time types are +# stored on disk as unsigned chars. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule sol87 1987 only - Jan 1 12:03:20s -0:03:20 - +Rule sol87 1987 only - Jan 2 12:03:50s -0:03:50 - +Rule sol87 1987 only - Jan 3 12:04:15s -0:04:15 - +Rule sol87 1987 only - Jan 4 12:04:45s -0:04:45 - +Rule sol87 1987 only - Jan 5 12:05:10s -0:05:10 - +Rule sol87 1987 only - Jan 6 12:05:40s -0:05:40 - +Rule sol87 1987 only - Jan 7 12:06:05s -0:06:05 - +Rule sol87 1987 only - Jan 8 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jan 9 12:06:55s -0:06:55 - +Rule sol87 1987 only - Jan 10 12:07:20s -0:07:20 - +Rule sol87 1987 only - Jan 11 12:07:45s -0:07:45 - +Rule sol87 1987 only - Jan 12 12:08:10s -0:08:10 - +Rule sol87 1987 only - Jan 13 12:08:30s -0:08:30 - +Rule sol87 1987 only - Jan 14 12:08:55s -0:08:55 - +Rule sol87 1987 only - Jan 15 12:09:15s -0:09:15 - +Rule sol87 1987 only - Jan 16 12:09:35s -0:09:35 - +Rule sol87 1987 only - Jan 17 12:09:55s -0:09:55 - +Rule sol87 1987 only - Jan 18 12:10:15s -0:10:15 - +Rule sol87 1987 only - Jan 19 12:10:35s -0:10:35 - +Rule sol87 1987 only - Jan 20 12:10:55s -0:10:55 - +Rule sol87 1987 only - Jan 21 12:11:10s -0:11:10 - +Rule sol87 1987 only - Jan 22 12:11:30s -0:11:30 - +Rule sol87 1987 only - Jan 23 12:11:45s -0:11:45 - +Rule sol87 1987 only - Jan 24 12:12:00s -0:12:00 - +Rule sol87 1987 only - Jan 25 12:12:15s -0:12:15 - +Rule sol87 1987 only - Jan 26 12:12:30s -0:12:30 - +Rule sol87 1987 only - Jan 27 12:12:40s -0:12:40 - +Rule sol87 1987 only - Jan 28 12:12:55s -0:12:55 - +Rule sol87 1987 only - Jan 29 12:13:05s -0:13:05 - +Rule sol87 1987 only - Jan 30 12:13:15s -0:13:15 - +Rule sol87 1987 only - Jan 31 12:13:25s -0:13:25 - +Rule sol87 1987 only - Feb 1 12:13:35s -0:13:35 - +Rule sol87 1987 only - Feb 2 12:13:40s -0:13:40 - +Rule sol87 1987 only - Feb 3 12:13:50s -0:13:50 - +Rule sol87 1987 only - Feb 4 12:13:55s -0:13:55 - +Rule sol87 1987 only - Feb 5 12:14:00s -0:14:00 - +Rule sol87 1987 only - Feb 6 12:14:05s -0:14:05 - +Rule sol87 1987 only - Feb 7 12:14:10s -0:14:10 - +Rule sol87 1987 only - Feb 8 12:14:10s -0:14:10 - +Rule sol87 1987 only - Feb 9 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 10 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 11 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 12 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 13 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 14 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 15 12:14:10s -0:14:10 - +Rule sol87 1987 only - Feb 16 12:14:10s -0:14:10 - +Rule sol87 1987 only - Feb 17 12:14:05s -0:14:05 - +Rule sol87 1987 only - Feb 18 12:14:00s -0:14:00 - +Rule sol87 1987 only - Feb 19 12:13:55s -0:13:55 - +Rule sol87 1987 only - Feb 20 12:13:50s -0:13:50 - +Rule sol87 1987 only - Feb 21 12:13:45s -0:13:45 - +Rule sol87 1987 only - Feb 22 12:13:35s -0:13:35 - +Rule sol87 1987 only - Feb 23 12:13:30s -0:13:30 - +Rule sol87 1987 only - Feb 24 12:13:20s -0:13:20 - +Rule sol87 1987 only - Feb 25 12:13:10s -0:13:10 - +Rule sol87 1987 only - Feb 26 12:13:00s -0:13:00 - +Rule sol87 1987 only - Feb 27 12:12:50s -0:12:50 - +Rule sol87 1987 only - Feb 28 12:12:40s -0:12:40 - +Rule sol87 1987 only - Mar 1 12:12:30s -0:12:30 - +Rule sol87 1987 only - Mar 2 12:12:20s -0:12:20 - +Rule sol87 1987 only - Mar 3 12:12:05s -0:12:05 - +Rule sol87 1987 only - Mar 4 12:11:55s -0:11:55 - +Rule sol87 1987 only - Mar 5 12:11:40s -0:11:40 - +Rule sol87 1987 only - Mar 6 12:11:25s -0:11:25 - +Rule sol87 1987 only - Mar 7 12:11:15s -0:11:15 - +Rule sol87 1987 only - Mar 8 12:11:00s -0:11:00 - +Rule sol87 1987 only - Mar 9 12:10:45s -0:10:45 - +Rule sol87 1987 only - Mar 10 12:10:30s -0:10:30 - +Rule sol87 1987 only - Mar 11 12:10:15s -0:10:15 - +Rule sol87 1987 only - Mar 12 12:09:55s -0:09:55 - +Rule sol87 1987 only - Mar 13 12:09:40s -0:09:40 - +Rule sol87 1987 only - Mar 14 12:09:25s -0:09:25 - +Rule sol87 1987 only - Mar 15 12:09:10s -0:09:10 - +Rule sol87 1987 only - Mar 16 12:08:50s -0:08:50 - +Rule sol87 1987 only - Mar 17 12:08:35s -0:08:35 - +Rule sol87 1987 only - Mar 18 12:08:15s -0:08:15 - +Rule sol87 1987 only - Mar 19 12:08:00s -0:08:00 - +Rule sol87 1987 only - Mar 20 12:07:40s -0:07:40 - +Rule sol87 1987 only - Mar 21 12:07:25s -0:07:25 - +Rule sol87 1987 only - Mar 22 12:07:05s -0:07:05 - +Rule sol87 1987 only - Mar 23 12:06:50s -0:06:50 - +Rule sol87 1987 only - Mar 24 12:06:30s -0:06:30 - +Rule sol87 1987 only - Mar 25 12:06:10s -0:06:10 - +Rule sol87 1987 only - Mar 26 12:05:55s -0:05:55 - +Rule sol87 1987 only - Mar 27 12:05:35s -0:05:35 - +Rule sol87 1987 only - Mar 28 12:05:15s -0:05:15 - +Rule sol87 1987 only - Mar 29 12:05:00s -0:05:00 - +Rule sol87 1987 only - Mar 30 12:04:40s -0:04:40 - +Rule sol87 1987 only - Mar 31 12:04:25s -0:04:25 - +Rule sol87 1987 only - Apr 1 12:04:05s -0:04:05 - +Rule sol87 1987 only - Apr 2 12:03:45s -0:03:45 - +Rule sol87 1987 only - Apr 3 12:03:30s -0:03:30 - +Rule sol87 1987 only - Apr 4 12:03:10s -0:03:10 - +Rule sol87 1987 only - Apr 5 12:02:55s -0:02:55 - +Rule sol87 1987 only - Apr 6 12:02:35s -0:02:35 - +Rule sol87 1987 only - Apr 7 12:02:20s -0:02:20 - +Rule sol87 1987 only - Apr 8 12:02:05s -0:02:05 - +Rule sol87 1987 only - Apr 9 12:01:45s -0:01:45 - +Rule sol87 1987 only - Apr 10 12:01:30s -0:01:30 - +Rule sol87 1987 only - Apr 11 12:01:15s -0:01:15 - +Rule sol87 1987 only - Apr 12 12:00:55s -0:00:55 - +Rule sol87 1987 only - Apr 13 12:00:40s -0:00:40 - +Rule sol87 1987 only - Apr 14 12:00:25s -0:00:25 - +Rule sol87 1987 only - Apr 15 12:00:10s -0:00:10 - +Rule sol87 1987 only - Apr 16 11:59:55s 0:00:05 - +Rule sol87 1987 only - Apr 17 11:59:45s 0:00:15 - +Rule sol87 1987 only - Apr 18 11:59:30s 0:00:30 - +Rule sol87 1987 only - Apr 19 11:59:15s 0:00:45 - +Rule sol87 1987 only - Apr 20 11:59:05s 0:00:55 - +Rule sol87 1987 only - Apr 21 11:58:50s 0:01:10 - +Rule sol87 1987 only - Apr 22 11:58:40s 0:01:20 - +Rule sol87 1987 only - Apr 23 11:58:25s 0:01:35 - +Rule sol87 1987 only - Apr 24 11:58:15s 0:01:45 - +Rule sol87 1987 only - Apr 25 11:58:05s 0:01:55 - +Rule sol87 1987 only - Apr 26 11:57:55s 0:02:05 - +Rule sol87 1987 only - Apr 27 11:57:45s 0:02:15 - +Rule sol87 1987 only - Apr 28 11:57:35s 0:02:25 - +Rule sol87 1987 only - Apr 29 11:57:25s 0:02:35 - +Rule sol87 1987 only - Apr 30 11:57:15s 0:02:45 - +Rule sol87 1987 only - May 1 11:57:10s 0:02:50 - +Rule sol87 1987 only - May 2 11:57:00s 0:03:00 - +Rule sol87 1987 only - May 3 11:56:55s 0:03:05 - +Rule sol87 1987 only - May 4 11:56:50s 0:03:10 - +Rule sol87 1987 only - May 5 11:56:45s 0:03:15 - +Rule sol87 1987 only - May 6 11:56:40s 0:03:20 - +Rule sol87 1987 only - May 7 11:56:35s 0:03:25 - +Rule sol87 1987 only - May 8 11:56:30s 0:03:30 - +Rule sol87 1987 only - May 9 11:56:25s 0:03:35 - +Rule sol87 1987 only - May 10 11:56:25s 0:03:35 - +Rule sol87 1987 only - May 11 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 12 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 13 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 14 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 15 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 16 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 17 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 18 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 19 11:56:25s 0:03:35 - +Rule sol87 1987 only - May 20 11:56:25s 0:03:35 - +Rule sol87 1987 only - May 21 11:56:30s 0:03:30 - +Rule sol87 1987 only - May 22 11:56:35s 0:03:25 - +Rule sol87 1987 only - May 23 11:56:40s 0:03:20 - +Rule sol87 1987 only - May 24 11:56:45s 0:03:15 - +Rule sol87 1987 only - May 25 11:56:50s 0:03:10 - +Rule sol87 1987 only - May 26 11:56:55s 0:03:05 - +Rule sol87 1987 only - May 27 11:57:00s 0:03:00 - +Rule sol87 1987 only - May 28 11:57:10s 0:02:50 - +Rule sol87 1987 only - May 29 11:57:15s 0:02:45 - +Rule sol87 1987 only - May 30 11:57:25s 0:02:35 - +Rule sol87 1987 only - May 31 11:57:30s 0:02:30 - +Rule sol87 1987 only - Jun 1 11:57:40s 0:02:20 - +Rule sol87 1987 only - Jun 2 11:57:50s 0:02:10 - +Rule sol87 1987 only - Jun 3 11:58:00s 0:02:00 - +Rule sol87 1987 only - Jun 4 11:58:10s 0:01:50 - +Rule sol87 1987 only - Jun 5 11:58:20s 0:01:40 - +Rule sol87 1987 only - Jun 6 11:58:30s 0:01:30 - +Rule sol87 1987 only - Jun 7 11:58:40s 0:01:20 - +Rule sol87 1987 only - Jun 8 11:58:50s 0:01:10 - +Rule sol87 1987 only - Jun 9 11:59:05s 0:00:55 - +Rule sol87 1987 only - Jun 10 11:59:15s 0:00:45 - +Rule sol87 1987 only - Jun 11 11:59:30s 0:00:30 - +Rule sol87 1987 only - Jun 12 11:59:40s 0:00:20 - +Rule sol87 1987 only - Jun 13 11:59:50s 0:00:10 - +Rule sol87 1987 only - Jun 14 12:00:05s -0:00:05 - +Rule sol87 1987 only - Jun 15 12:00:15s -0:00:15 - +Rule sol87 1987 only - Jun 16 12:00:30s -0:00:30 - +Rule sol87 1987 only - Jun 17 12:00:45s -0:00:45 - +Rule sol87 1987 only - Jun 18 12:00:55s -0:00:55 - +Rule sol87 1987 only - Jun 19 12:01:10s -0:01:10 - +Rule sol87 1987 only - Jun 20 12:01:20s -0:01:20 - +Rule sol87 1987 only - Jun 21 12:01:35s -0:01:35 - +Rule sol87 1987 only - Jun 22 12:01:50s -0:01:50 - +Rule sol87 1987 only - Jun 23 12:02:00s -0:02:00 - +Rule sol87 1987 only - Jun 24 12:02:15s -0:02:15 - +Rule sol87 1987 only - Jun 25 12:02:25s -0:02:25 - +Rule sol87 1987 only - Jun 26 12:02:40s -0:02:40 - +Rule sol87 1987 only - Jun 27 12:02:50s -0:02:50 - +Rule sol87 1987 only - Jun 28 12:03:05s -0:03:05 - +Rule sol87 1987 only - Jun 29 12:03:15s -0:03:15 - +Rule sol87 1987 only - Jun 30 12:03:30s -0:03:30 - +Rule sol87 1987 only - Jul 1 12:03:40s -0:03:40 - +Rule sol87 1987 only - Jul 2 12:03:50s -0:03:50 - +Rule sol87 1987 only - Jul 3 12:04:05s -0:04:05 - +Rule sol87 1987 only - Jul 4 12:04:15s -0:04:15 - +Rule sol87 1987 only - Jul 5 12:04:25s -0:04:25 - +Rule sol87 1987 only - Jul 6 12:04:35s -0:04:35 - +Rule sol87 1987 only - Jul 7 12:04:45s -0:04:45 - +Rule sol87 1987 only - Jul 8 12:04:55s -0:04:55 - +Rule sol87 1987 only - Jul 9 12:05:05s -0:05:05 - +Rule sol87 1987 only - Jul 10 12:05:15s -0:05:15 - +Rule sol87 1987 only - Jul 11 12:05:20s -0:05:20 - +Rule sol87 1987 only - Jul 12 12:05:30s -0:05:30 - +Rule sol87 1987 only - Jul 13 12:05:40s -0:05:40 - +Rule sol87 1987 only - Jul 14 12:05:45s -0:05:45 - +Rule sol87 1987 only - Jul 15 12:05:50s -0:05:50 - +Rule sol87 1987 only - Jul 16 12:06:00s -0:06:00 - +Rule sol87 1987 only - Jul 17 12:06:05s -0:06:05 - +Rule sol87 1987 only - Jul 18 12:06:10s -0:06:10 - +Rule sol87 1987 only - Jul 19 12:06:15s -0:06:15 - +Rule sol87 1987 only - Jul 20 12:06:15s -0:06:15 - +Rule sol87 1987 only - Jul 21 12:06:20s -0:06:20 - +Rule sol87 1987 only - Jul 22 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 23 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 24 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 25 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jul 26 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jul 27 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jul 28 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jul 29 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 30 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 31 12:06:25s -0:06:25 - +Rule sol87 1987 only - Aug 1 12:06:20s -0:06:20 - +Rule sol87 1987 only - Aug 2 12:06:15s -0:06:15 - +Rule sol87 1987 only - Aug 3 12:06:10s -0:06:10 - +Rule sol87 1987 only - Aug 4 12:06:05s -0:06:05 - +Rule sol87 1987 only - Aug 5 12:06:00s -0:06:00 - +Rule sol87 1987 only - Aug 6 12:05:55s -0:05:55 - +Rule sol87 1987 only - Aug 7 12:05:50s -0:05:50 - +Rule sol87 1987 only - Aug 8 12:05:40s -0:05:40 - +Rule sol87 1987 only - Aug 9 12:05:35s -0:05:35 - +Rule sol87 1987 only - Aug 10 12:05:25s -0:05:25 - +Rule sol87 1987 only - Aug 11 12:05:15s -0:05:15 - +Rule sol87 1987 only - Aug 12 12:05:05s -0:05:05 - +Rule sol87 1987 only - Aug 13 12:04:55s -0:04:55 - +Rule sol87 1987 only - Aug 14 12:04:45s -0:04:45 - +Rule sol87 1987 only - Aug 15 12:04:35s -0:04:35 - +Rule sol87 1987 only - Aug 16 12:04:25s -0:04:25 - +Rule sol87 1987 only - Aug 17 12:04:10s -0:04:10 - +Rule sol87 1987 only - Aug 18 12:04:00s -0:04:00 - +Rule sol87 1987 only - Aug 19 12:03:45s -0:03:45 - +Rule sol87 1987 only - Aug 20 12:03:30s -0:03:30 - +Rule sol87 1987 only - Aug 21 12:03:15s -0:03:15 - +Rule sol87 1987 only - Aug 22 12:03:00s -0:03:00 - +Rule sol87 1987 only - Aug 23 12:02:45s -0:02:45 - +Rule sol87 1987 only - Aug 24 12:02:30s -0:02:30 - +Rule sol87 1987 only - Aug 25 12:02:15s -0:02:15 - +Rule sol87 1987 only - Aug 26 12:02:00s -0:02:00 - +Rule sol87 1987 only - Aug 27 12:01:40s -0:01:40 - +Rule sol87 1987 only - Aug 28 12:01:25s -0:01:25 - +Rule sol87 1987 only - Aug 29 12:01:05s -0:01:05 - +Rule sol87 1987 only - Aug 30 12:00:50s -0:00:50 - +Rule sol87 1987 only - Aug 31 12:00:30s -0:00:30 - +Rule sol87 1987 only - Sep 1 12:00:10s -0:00:10 - +Rule sol87 1987 only - Sep 2 11:59:50s 0:00:10 - +Rule sol87 1987 only - Sep 3 11:59:35s 0:00:25 - +Rule sol87 1987 only - Sep 4 11:59:15s 0:00:45 - +Rule sol87 1987 only - Sep 5 11:58:55s 0:01:05 - +Rule sol87 1987 only - Sep 6 11:58:35s 0:01:25 - +Rule sol87 1987 only - Sep 7 11:58:15s 0:01:45 - +Rule sol87 1987 only - Sep 8 11:57:55s 0:02:05 - +Rule sol87 1987 only - Sep 9 11:57:30s 0:02:30 - +Rule sol87 1987 only - Sep 10 11:57:10s 0:02:50 - +Rule sol87 1987 only - Sep 11 11:56:50s 0:03:10 - +Rule sol87 1987 only - Sep 12 11:56:30s 0:03:30 - +Rule sol87 1987 only - Sep 13 11:56:10s 0:03:50 - +Rule sol87 1987 only - Sep 14 11:55:45s 0:04:15 - +Rule sol87 1987 only - Sep 15 11:55:25s 0:04:35 - +Rule sol87 1987 only - Sep 16 11:55:05s 0:04:55 - +Rule sol87 1987 only - Sep 17 11:54:45s 0:05:15 - +Rule sol87 1987 only - Sep 18 11:54:20s 0:05:40 - +Rule sol87 1987 only - Sep 19 11:54:00s 0:06:00 - +Rule sol87 1987 only - Sep 20 11:53:40s 0:06:20 - +Rule sol87 1987 only - Sep 21 11:53:15s 0:06:45 - +Rule sol87 1987 only - Sep 22 11:52:55s 0:07:05 - +Rule sol87 1987 only - Sep 23 11:52:35s 0:07:25 - +Rule sol87 1987 only - Sep 24 11:52:15s 0:07:45 - +Rule sol87 1987 only - Sep 25 11:51:55s 0:08:05 - +Rule sol87 1987 only - Sep 26 11:51:35s 0:08:25 - +Rule sol87 1987 only - Sep 27 11:51:10s 0:08:50 - +Rule sol87 1987 only - Sep 28 11:50:50s 0:09:10 - +Rule sol87 1987 only - Sep 29 11:50:30s 0:09:30 - +Rule sol87 1987 only - Sep 30 11:50:10s 0:09:50 - +Rule sol87 1987 only - Oct 1 11:49:50s 0:10:10 - +Rule sol87 1987 only - Oct 2 11:49:35s 0:10:25 - +Rule sol87 1987 only - Oct 3 11:49:15s 0:10:45 - +Rule sol87 1987 only - Oct 4 11:48:55s 0:11:05 - +Rule sol87 1987 only - Oct 5 11:48:35s 0:11:25 - +Rule sol87 1987 only - Oct 6 11:48:20s 0:11:40 - +Rule sol87 1987 only - Oct 7 11:48:00s 0:12:00 - +Rule sol87 1987 only - Oct 8 11:47:45s 0:12:15 - +Rule sol87 1987 only - Oct 9 11:47:25s 0:12:35 - +Rule sol87 1987 only - Oct 10 11:47:10s 0:12:50 - +Rule sol87 1987 only - Oct 11 11:46:55s 0:13:05 - +Rule sol87 1987 only - Oct 12 11:46:40s 0:13:20 - +Rule sol87 1987 only - Oct 13 11:46:25s 0:13:35 - +Rule sol87 1987 only - Oct 14 11:46:10s 0:13:50 - +Rule sol87 1987 only - Oct 15 11:45:55s 0:14:05 - +Rule sol87 1987 only - Oct 16 11:45:45s 0:14:15 - +Rule sol87 1987 only - Oct 17 11:45:30s 0:14:30 - +Rule sol87 1987 only - Oct 18 11:45:20s 0:14:40 - +Rule sol87 1987 only - Oct 19 11:45:05s 0:14:55 - +Rule sol87 1987 only - Oct 20 11:44:55s 0:15:05 - +Rule sol87 1987 only - Oct 21 11:44:45s 0:15:15 - +Rule sol87 1987 only - Oct 22 11:44:35s 0:15:25 - +Rule sol87 1987 only - Oct 23 11:44:25s 0:15:35 - +Rule sol87 1987 only - Oct 24 11:44:20s 0:15:40 - +Rule sol87 1987 only - Oct 25 11:44:10s 0:15:50 - +Rule sol87 1987 only - Oct 26 11:44:05s 0:15:55 - +Rule sol87 1987 only - Oct 27 11:43:55s 0:16:05 - +Rule sol87 1987 only - Oct 28 11:43:50s 0:16:10 - +Rule sol87 1987 only - Oct 29 11:43:45s 0:16:15 - +Rule sol87 1987 only - Oct 30 11:43:45s 0:16:15 - +Rule sol87 1987 only - Oct 31 11:43:40s 0:16:20 - +Rule sol87 1987 only - Nov 1 11:43:40s 0:16:20 - +Rule sol87 1987 only - Nov 2 11:43:35s 0:16:25 - +Rule sol87 1987 only - Nov 3 11:43:35s 0:16:25 - +Rule sol87 1987 only - Nov 4 11:43:35s 0:16:25 - +Rule sol87 1987 only - Nov 5 11:43:35s 0:16:25 - +Rule sol87 1987 only - Nov 6 11:43:40s 0:16:20 - +Rule sol87 1987 only - Nov 7 11:43:40s 0:16:20 - +Rule sol87 1987 only - Nov 8 11:43:45s 0:16:15 - +Rule sol87 1987 only - Nov 9 11:43:50s 0:16:10 - +Rule sol87 1987 only - Nov 10 11:43:55s 0:16:05 - +Rule sol87 1987 only - Nov 11 11:44:00s 0:16:00 - +Rule sol87 1987 only - Nov 12 11:44:05s 0:15:55 - +Rule sol87 1987 only - Nov 13 11:44:15s 0:15:45 - +Rule sol87 1987 only - Nov 14 11:44:20s 0:15:40 - +Rule sol87 1987 only - Nov 15 11:44:30s 0:15:30 - +Rule sol87 1987 only - Nov 16 11:44:40s 0:15:20 - +Rule sol87 1987 only - Nov 17 11:44:50s 0:15:10 - +Rule sol87 1987 only - Nov 18 11:45:05s 0:14:55 - +Rule sol87 1987 only - Nov 19 11:45:15s 0:14:45 - +Rule sol87 1987 only - Nov 20 11:45:30s 0:14:30 - +Rule sol87 1987 only - Nov 21 11:45:45s 0:14:15 - +Rule sol87 1987 only - Nov 22 11:46:00s 0:14:00 - +Rule sol87 1987 only - Nov 23 11:46:15s 0:13:45 - +Rule sol87 1987 only - Nov 24 11:46:30s 0:13:30 - +Rule sol87 1987 only - Nov 25 11:46:50s 0:13:10 - +Rule sol87 1987 only - Nov 26 11:47:10s 0:12:50 - +Rule sol87 1987 only - Nov 27 11:47:25s 0:12:35 - +Rule sol87 1987 only - Nov 28 11:47:45s 0:12:15 - +Rule sol87 1987 only - Nov 29 11:48:05s 0:11:55 - +Rule sol87 1987 only - Nov 30 11:48:30s 0:11:30 - +Rule sol87 1987 only - Dec 1 11:48:50s 0:11:10 - +Rule sol87 1987 only - Dec 2 11:49:10s 0:10:50 - +Rule sol87 1987 only - Dec 3 11:49:35s 0:10:25 - +Rule sol87 1987 only - Dec 4 11:50:00s 0:10:00 - +Rule sol87 1987 only - Dec 5 11:50:25s 0:09:35 - +Rule sol87 1987 only - Dec 6 11:50:50s 0:09:10 - +Rule sol87 1987 only - Dec 7 11:51:15s 0:08:45 - +Rule sol87 1987 only - Dec 8 11:51:40s 0:08:20 - +Rule sol87 1987 only - Dec 9 11:52:05s 0:07:55 - +Rule sol87 1987 only - Dec 10 11:52:30s 0:07:30 - +Rule sol87 1987 only - Dec 11 11:53:00s 0:07:00 - +Rule sol87 1987 only - Dec 12 11:53:25s 0:06:35 - +Rule sol87 1987 only - Dec 13 11:53:55s 0:06:05 - +Rule sol87 1987 only - Dec 14 11:54:25s 0:05:35 - +Rule sol87 1987 only - Dec 15 11:54:50s 0:05:10 - +Rule sol87 1987 only - Dec 16 11:55:20s 0:04:40 - +Rule sol87 1987 only - Dec 17 11:55:50s 0:04:10 - +Rule sol87 1987 only - Dec 18 11:56:20s 0:03:40 - +Rule sol87 1987 only - Dec 19 11:56:50s 0:03:10 - +Rule sol87 1987 only - Dec 20 11:57:20s 0:02:40 - +Rule sol87 1987 only - Dec 21 11:57:50s 0:02:10 - +Rule sol87 1987 only - Dec 22 11:58:20s 0:01:40 - +Rule sol87 1987 only - Dec 23 11:58:50s 0:01:10 - +Rule sol87 1987 only - Dec 24 11:59:20s 0:00:40 - +Rule sol87 1987 only - Dec 25 11:59:50s 0:00:10 - +Rule sol87 1987 only - Dec 26 12:00:20s -0:00:20 - +Rule sol87 1987 only - Dec 27 12:00:45s -0:00:45 - +Rule sol87 1987 only - Dec 28 12:01:15s -0:01:15 - +Rule sol87 1987 only - Dec 29 12:01:45s -0:01:45 - +Rule sol87 1987 only - Dec 30 12:02:15s -0:02:15 - +Rule sol87 1987 only - Dec 31 12:02:45s -0:02:45 - + +# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs +# Before and after 1987, we'll operate on local mean solar time. + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone Mideast/Riyadh87 3:07:04 - ?? 1987 + 3:07:04 sol87 ?? 1988 + 3:07:04 - ?? diff --git a/time/solar88 b/time/solar88 new file mode 100644 index 000000000..0384b17a0 --- /dev/null +++ b/time/solar88 @@ -0,0 +1,386 @@ +# @(#)solar88 7.2 + +# Apparent noon times below are for Riyadh; they're a bit off for other places. +# Times were computed using formulas in the U.S. Naval Observatory's +# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of +# [plus or minus two] seconds during the current year." +# +# Rounding to the nearest five seconds results in fewer than +# 256 different "time types"--a limit that's faced because time types are +# stored on disk as unsigned chars. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule sol88 1988 only - Jan 1 12:03:15s -0:03:15 - +Rule sol88 1988 only - Jan 2 12:03:40s -0:03:40 - +Rule sol88 1988 only - Jan 3 12:04:10s -0:04:10 - +Rule sol88 1988 only - Jan 4 12:04:40s -0:04:40 - +Rule sol88 1988 only - Jan 5 12:05:05s -0:05:05 - +Rule sol88 1988 only - Jan 6 12:05:30s -0:05:30 - +Rule sol88 1988 only - Jan 7 12:06:00s -0:06:00 - +Rule sol88 1988 only - Jan 8 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jan 9 12:06:50s -0:06:50 - +Rule sol88 1988 only - Jan 10 12:07:15s -0:07:15 - +Rule sol88 1988 only - Jan 11 12:07:40s -0:07:40 - +Rule sol88 1988 only - Jan 12 12:08:05s -0:08:05 - +Rule sol88 1988 only - Jan 13 12:08:25s -0:08:25 - +Rule sol88 1988 only - Jan 14 12:08:50s -0:08:50 - +Rule sol88 1988 only - Jan 15 12:09:10s -0:09:10 - +Rule sol88 1988 only - Jan 16 12:09:30s -0:09:30 - +Rule sol88 1988 only - Jan 17 12:09:50s -0:09:50 - +Rule sol88 1988 only - Jan 18 12:10:10s -0:10:10 - +Rule sol88 1988 only - Jan 19 12:10:30s -0:10:30 - +Rule sol88 1988 only - Jan 20 12:10:50s -0:10:50 - +Rule sol88 1988 only - Jan 21 12:11:05s -0:11:05 - +Rule sol88 1988 only - Jan 22 12:11:25s -0:11:25 - +Rule sol88 1988 only - Jan 23 12:11:40s -0:11:40 - +Rule sol88 1988 only - Jan 24 12:11:55s -0:11:55 - +Rule sol88 1988 only - Jan 25 12:12:10s -0:12:10 - +Rule sol88 1988 only - Jan 26 12:12:25s -0:12:25 - +Rule sol88 1988 only - Jan 27 12:12:40s -0:12:40 - +Rule sol88 1988 only - Jan 28 12:12:50s -0:12:50 - +Rule sol88 1988 only - Jan 29 12:13:00s -0:13:00 - +Rule sol88 1988 only - Jan 30 12:13:10s -0:13:10 - +Rule sol88 1988 only - Jan 31 12:13:20s -0:13:20 - +Rule sol88 1988 only - Feb 1 12:13:30s -0:13:30 - +Rule sol88 1988 only - Feb 2 12:13:40s -0:13:40 - +Rule sol88 1988 only - Feb 3 12:13:45s -0:13:45 - +Rule sol88 1988 only - Feb 4 12:13:55s -0:13:55 - +Rule sol88 1988 only - Feb 5 12:14:00s -0:14:00 - +Rule sol88 1988 only - Feb 6 12:14:05s -0:14:05 - +Rule sol88 1988 only - Feb 7 12:14:10s -0:14:10 - +Rule sol88 1988 only - Feb 8 12:14:10s -0:14:10 - +Rule sol88 1988 only - Feb 9 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 10 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 11 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 12 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 13 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 14 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 15 12:14:10s -0:14:10 - +Rule sol88 1988 only - Feb 16 12:14:10s -0:14:10 - +Rule sol88 1988 only - Feb 17 12:14:05s -0:14:05 - +Rule sol88 1988 only - Feb 18 12:14:00s -0:14:00 - +Rule sol88 1988 only - Feb 19 12:13:55s -0:13:55 - +Rule sol88 1988 only - Feb 20 12:13:50s -0:13:50 - +Rule sol88 1988 only - Feb 21 12:13:45s -0:13:45 - +Rule sol88 1988 only - Feb 22 12:13:40s -0:13:40 - +Rule sol88 1988 only - Feb 23 12:13:30s -0:13:30 - +Rule sol88 1988 only - Feb 24 12:13:20s -0:13:20 - +Rule sol88 1988 only - Feb 25 12:13:15s -0:13:15 - +Rule sol88 1988 only - Feb 26 12:13:05s -0:13:05 - +Rule sol88 1988 only - Feb 27 12:12:55s -0:12:55 - +Rule sol88 1988 only - Feb 28 12:12:45s -0:12:45 - +Rule sol88 1988 only - Feb 29 12:12:30s -0:12:30 - +Rule sol88 1988 only - Mar 1 12:12:20s -0:12:20 - +Rule sol88 1988 only - Mar 2 12:12:10s -0:12:10 - +Rule sol88 1988 only - Mar 3 12:11:55s -0:11:55 - +Rule sol88 1988 only - Mar 4 12:11:45s -0:11:45 - +Rule sol88 1988 only - Mar 5 12:11:30s -0:11:30 - +Rule sol88 1988 only - Mar 6 12:11:15s -0:11:15 - +Rule sol88 1988 only - Mar 7 12:11:00s -0:11:00 - +Rule sol88 1988 only - Mar 8 12:10:45s -0:10:45 - +Rule sol88 1988 only - Mar 9 12:10:30s -0:10:30 - +Rule sol88 1988 only - Mar 10 12:10:15s -0:10:15 - +Rule sol88 1988 only - Mar 11 12:10:00s -0:10:00 - +Rule sol88 1988 only - Mar 12 12:09:45s -0:09:45 - +Rule sol88 1988 only - Mar 13 12:09:30s -0:09:30 - +Rule sol88 1988 only - Mar 14 12:09:10s -0:09:10 - +Rule sol88 1988 only - Mar 15 12:08:55s -0:08:55 - +Rule sol88 1988 only - Mar 16 12:08:40s -0:08:40 - +Rule sol88 1988 only - Mar 17 12:08:20s -0:08:20 - +Rule sol88 1988 only - Mar 18 12:08:05s -0:08:05 - +Rule sol88 1988 only - Mar 19 12:07:45s -0:07:45 - +Rule sol88 1988 only - Mar 20 12:07:30s -0:07:30 - +Rule sol88 1988 only - Mar 21 12:07:10s -0:07:10 - +Rule sol88 1988 only - Mar 22 12:06:50s -0:06:50 - +Rule sol88 1988 only - Mar 23 12:06:35s -0:06:35 - +Rule sol88 1988 only - Mar 24 12:06:15s -0:06:15 - +Rule sol88 1988 only - Mar 25 12:06:00s -0:06:00 - +Rule sol88 1988 only - Mar 26 12:05:40s -0:05:40 - +Rule sol88 1988 only - Mar 27 12:05:20s -0:05:20 - +Rule sol88 1988 only - Mar 28 12:05:05s -0:05:05 - +Rule sol88 1988 only - Mar 29 12:04:45s -0:04:45 - +Rule sol88 1988 only - Mar 30 12:04:25s -0:04:25 - +Rule sol88 1988 only - Mar 31 12:04:10s -0:04:10 - +Rule sol88 1988 only - Apr 1 12:03:50s -0:03:50 - +Rule sol88 1988 only - Apr 2 12:03:35s -0:03:35 - +Rule sol88 1988 only - Apr 3 12:03:15s -0:03:15 - +Rule sol88 1988 only - Apr 4 12:03:00s -0:03:00 - +Rule sol88 1988 only - Apr 5 12:02:40s -0:02:40 - +Rule sol88 1988 only - Apr 6 12:02:25s -0:02:25 - +Rule sol88 1988 only - Apr 7 12:02:05s -0:02:05 - +Rule sol88 1988 only - Apr 8 12:01:50s -0:01:50 - +Rule sol88 1988 only - Apr 9 12:01:35s -0:01:35 - +Rule sol88 1988 only - Apr 10 12:01:15s -0:01:15 - +Rule sol88 1988 only - Apr 11 12:01:00s -0:01:00 - +Rule sol88 1988 only - Apr 12 12:00:45s -0:00:45 - +Rule sol88 1988 only - Apr 13 12:00:30s -0:00:30 - +Rule sol88 1988 only - Apr 14 12:00:15s -0:00:15 - +Rule sol88 1988 only - Apr 15 12:00:00s 0:00:00 - +Rule sol88 1988 only - Apr 16 11:59:45s 0:00:15 - +Rule sol88 1988 only - Apr 17 11:59:30s 0:00:30 - +Rule sol88 1988 only - Apr 18 11:59:20s 0:00:40 - +Rule sol88 1988 only - Apr 19 11:59:05s 0:00:55 - +Rule sol88 1988 only - Apr 20 11:58:55s 0:01:05 - +Rule sol88 1988 only - Apr 21 11:58:40s 0:01:20 - +Rule sol88 1988 only - Apr 22 11:58:30s 0:01:30 - +Rule sol88 1988 only - Apr 23 11:58:15s 0:01:45 - +Rule sol88 1988 only - Apr 24 11:58:05s 0:01:55 - +Rule sol88 1988 only - Apr 25 11:57:55s 0:02:05 - +Rule sol88 1988 only - Apr 26 11:57:45s 0:02:15 - +Rule sol88 1988 only - Apr 27 11:57:35s 0:02:25 - +Rule sol88 1988 only - Apr 28 11:57:30s 0:02:30 - +Rule sol88 1988 only - Apr 29 11:57:20s 0:02:40 - +Rule sol88 1988 only - Apr 30 11:57:10s 0:02:50 - +Rule sol88 1988 only - May 1 11:57:05s 0:02:55 - +Rule sol88 1988 only - May 2 11:56:55s 0:03:05 - +Rule sol88 1988 only - May 3 11:56:50s 0:03:10 - +Rule sol88 1988 only - May 4 11:56:45s 0:03:15 - +Rule sol88 1988 only - May 5 11:56:40s 0:03:20 - +Rule sol88 1988 only - May 6 11:56:35s 0:03:25 - +Rule sol88 1988 only - May 7 11:56:30s 0:03:30 - +Rule sol88 1988 only - May 8 11:56:25s 0:03:35 - +Rule sol88 1988 only - May 9 11:56:25s 0:03:35 - +Rule sol88 1988 only - May 10 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 11 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 12 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 13 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 14 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 15 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 16 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 17 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 18 11:56:25s 0:03:35 - +Rule sol88 1988 only - May 19 11:56:25s 0:03:35 - +Rule sol88 1988 only - May 20 11:56:30s 0:03:30 - +Rule sol88 1988 only - May 21 11:56:35s 0:03:25 - +Rule sol88 1988 only - May 22 11:56:40s 0:03:20 - +Rule sol88 1988 only - May 23 11:56:45s 0:03:15 - +Rule sol88 1988 only - May 24 11:56:50s 0:03:10 - +Rule sol88 1988 only - May 25 11:56:55s 0:03:05 - +Rule sol88 1988 only - May 26 11:57:00s 0:03:00 - +Rule sol88 1988 only - May 27 11:57:05s 0:02:55 - +Rule sol88 1988 only - May 28 11:57:15s 0:02:45 - +Rule sol88 1988 only - May 29 11:57:20s 0:02:40 - +Rule sol88 1988 only - May 30 11:57:30s 0:02:30 - +Rule sol88 1988 only - May 31 11:57:40s 0:02:20 - +Rule sol88 1988 only - Jun 1 11:57:50s 0:02:10 - +Rule sol88 1988 only - Jun 2 11:57:55s 0:02:05 - +Rule sol88 1988 only - Jun 3 11:58:05s 0:01:55 - +Rule sol88 1988 only - Jun 4 11:58:15s 0:01:45 - +Rule sol88 1988 only - Jun 5 11:58:30s 0:01:30 - +Rule sol88 1988 only - Jun 6 11:58:40s 0:01:20 - +Rule sol88 1988 only - Jun 7 11:58:50s 0:01:10 - +Rule sol88 1988 only - Jun 8 11:59:00s 0:01:00 - +Rule sol88 1988 only - Jun 9 11:59:15s 0:00:45 - +Rule sol88 1988 only - Jun 10 11:59:25s 0:00:35 - +Rule sol88 1988 only - Jun 11 11:59:35s 0:00:25 - +Rule sol88 1988 only - Jun 12 11:59:50s 0:00:10 - +Rule sol88 1988 only - Jun 13 12:00:00s 0:00:00 - +Rule sol88 1988 only - Jun 14 12:00:15s -0:00:15 - +Rule sol88 1988 only - Jun 15 12:00:25s -0:00:25 - +Rule sol88 1988 only - Jun 16 12:00:40s -0:00:40 - +Rule sol88 1988 only - Jun 17 12:00:55s -0:00:55 - +Rule sol88 1988 only - Jun 18 12:01:05s -0:01:05 - +Rule sol88 1988 only - Jun 19 12:01:20s -0:01:20 - +Rule sol88 1988 only - Jun 20 12:01:30s -0:01:30 - +Rule sol88 1988 only - Jun 21 12:01:45s -0:01:45 - +Rule sol88 1988 only - Jun 22 12:02:00s -0:02:00 - +Rule sol88 1988 only - Jun 23 12:02:10s -0:02:10 - +Rule sol88 1988 only - Jun 24 12:02:25s -0:02:25 - +Rule sol88 1988 only - Jun 25 12:02:35s -0:02:35 - +Rule sol88 1988 only - Jun 26 12:02:50s -0:02:50 - +Rule sol88 1988 only - Jun 27 12:03:00s -0:03:00 - +Rule sol88 1988 only - Jun 28 12:03:15s -0:03:15 - +Rule sol88 1988 only - Jun 29 12:03:25s -0:03:25 - +Rule sol88 1988 only - Jun 30 12:03:40s -0:03:40 - +Rule sol88 1988 only - Jul 1 12:03:50s -0:03:50 - +Rule sol88 1988 only - Jul 2 12:04:00s -0:04:00 - +Rule sol88 1988 only - Jul 3 12:04:10s -0:04:10 - +Rule sol88 1988 only - Jul 4 12:04:25s -0:04:25 - +Rule sol88 1988 only - Jul 5 12:04:35s -0:04:35 - +Rule sol88 1988 only - Jul 6 12:04:45s -0:04:45 - +Rule sol88 1988 only - Jul 7 12:04:55s -0:04:55 - +Rule sol88 1988 only - Jul 8 12:05:05s -0:05:05 - +Rule sol88 1988 only - Jul 9 12:05:10s -0:05:10 - +Rule sol88 1988 only - Jul 10 12:05:20s -0:05:20 - +Rule sol88 1988 only - Jul 11 12:05:30s -0:05:30 - +Rule sol88 1988 only - Jul 12 12:05:35s -0:05:35 - +Rule sol88 1988 only - Jul 13 12:05:45s -0:05:45 - +Rule sol88 1988 only - Jul 14 12:05:50s -0:05:50 - +Rule sol88 1988 only - Jul 15 12:05:55s -0:05:55 - +Rule sol88 1988 only - Jul 16 12:06:00s -0:06:00 - +Rule sol88 1988 only - Jul 17 12:06:05s -0:06:05 - +Rule sol88 1988 only - Jul 18 12:06:10s -0:06:10 - +Rule sol88 1988 only - Jul 19 12:06:15s -0:06:15 - +Rule sol88 1988 only - Jul 20 12:06:20s -0:06:20 - +Rule sol88 1988 only - Jul 21 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 22 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 23 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 24 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 25 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 26 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 27 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 28 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 29 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 30 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 31 12:06:20s -0:06:20 - +Rule sol88 1988 only - Aug 1 12:06:15s -0:06:15 - +Rule sol88 1988 only - Aug 2 12:06:15s -0:06:15 - +Rule sol88 1988 only - Aug 3 12:06:10s -0:06:10 - +Rule sol88 1988 only - Aug 4 12:06:05s -0:06:05 - +Rule sol88 1988 only - Aug 5 12:05:55s -0:05:55 - +Rule sol88 1988 only - Aug 6 12:05:50s -0:05:50 - +Rule sol88 1988 only - Aug 7 12:05:45s -0:05:45 - +Rule sol88 1988 only - Aug 8 12:05:35s -0:05:35 - +Rule sol88 1988 only - Aug 9 12:05:25s -0:05:25 - +Rule sol88 1988 only - Aug 10 12:05:20s -0:05:20 - +Rule sol88 1988 only - Aug 11 12:05:10s -0:05:10 - +Rule sol88 1988 only - Aug 12 12:05:00s -0:05:00 - +Rule sol88 1988 only - Aug 13 12:04:50s -0:04:50 - +Rule sol88 1988 only - Aug 14 12:04:35s -0:04:35 - +Rule sol88 1988 only - Aug 15 12:04:25s -0:04:25 - +Rule sol88 1988 only - Aug 16 12:04:15s -0:04:15 - +Rule sol88 1988 only - Aug 17 12:04:00s -0:04:00 - +Rule sol88 1988 only - Aug 18 12:03:50s -0:03:50 - +Rule sol88 1988 only - Aug 19 12:03:35s -0:03:35 - +Rule sol88 1988 only - Aug 20 12:03:20s -0:03:20 - +Rule sol88 1988 only - Aug 21 12:03:05s -0:03:05 - +Rule sol88 1988 only - Aug 22 12:02:50s -0:02:50 - +Rule sol88 1988 only - Aug 23 12:02:35s -0:02:35 - +Rule sol88 1988 only - Aug 24 12:02:20s -0:02:20 - +Rule sol88 1988 only - Aug 25 12:02:00s -0:02:00 - +Rule sol88 1988 only - Aug 26 12:01:45s -0:01:45 - +Rule sol88 1988 only - Aug 27 12:01:30s -0:01:30 - +Rule sol88 1988 only - Aug 28 12:01:10s -0:01:10 - +Rule sol88 1988 only - Aug 29 12:00:50s -0:00:50 - +Rule sol88 1988 only - Aug 30 12:00:35s -0:00:35 - +Rule sol88 1988 only - Aug 31 12:00:15s -0:00:15 - +Rule sol88 1988 only - Sep 1 11:59:55s 0:00:05 - +Rule sol88 1988 only - Sep 2 11:59:35s 0:00:25 - +Rule sol88 1988 only - Sep 3 11:59:20s 0:00:40 - +Rule sol88 1988 only - Sep 4 11:59:00s 0:01:00 - +Rule sol88 1988 only - Sep 5 11:58:40s 0:01:20 - +Rule sol88 1988 only - Sep 6 11:58:20s 0:01:40 - +Rule sol88 1988 only - Sep 7 11:58:00s 0:02:00 - +Rule sol88 1988 only - Sep 8 11:57:35s 0:02:25 - +Rule sol88 1988 only - Sep 9 11:57:15s 0:02:45 - +Rule sol88 1988 only - Sep 10 11:56:55s 0:03:05 - +Rule sol88 1988 only - Sep 11 11:56:35s 0:03:25 - +Rule sol88 1988 only - Sep 12 11:56:15s 0:03:45 - +Rule sol88 1988 only - Sep 13 11:55:50s 0:04:10 - +Rule sol88 1988 only - Sep 14 11:55:30s 0:04:30 - +Rule sol88 1988 only - Sep 15 11:55:10s 0:04:50 - +Rule sol88 1988 only - Sep 16 11:54:50s 0:05:10 - +Rule sol88 1988 only - Sep 17 11:54:25s 0:05:35 - +Rule sol88 1988 only - Sep 18 11:54:05s 0:05:55 - +Rule sol88 1988 only - Sep 19 11:53:45s 0:06:15 - +Rule sol88 1988 only - Sep 20 11:53:25s 0:06:35 - +Rule sol88 1988 only - Sep 21 11:53:00s 0:07:00 - +Rule sol88 1988 only - Sep 22 11:52:40s 0:07:20 - +Rule sol88 1988 only - Sep 23 11:52:20s 0:07:40 - +Rule sol88 1988 only - Sep 24 11:52:00s 0:08:00 - +Rule sol88 1988 only - Sep 25 11:51:40s 0:08:20 - +Rule sol88 1988 only - Sep 26 11:51:15s 0:08:45 - +Rule sol88 1988 only - Sep 27 11:50:55s 0:09:05 - +Rule sol88 1988 only - Sep 28 11:50:35s 0:09:25 - +Rule sol88 1988 only - Sep 29 11:50:15s 0:09:45 - +Rule sol88 1988 only - Sep 30 11:49:55s 0:10:05 - +Rule sol88 1988 only - Oct 1 11:49:35s 0:10:25 - +Rule sol88 1988 only - Oct 2 11:49:20s 0:10:40 - +Rule sol88 1988 only - Oct 3 11:49:00s 0:11:00 - +Rule sol88 1988 only - Oct 4 11:48:40s 0:11:20 - +Rule sol88 1988 only - Oct 5 11:48:25s 0:11:35 - +Rule sol88 1988 only - Oct 6 11:48:05s 0:11:55 - +Rule sol88 1988 only - Oct 7 11:47:50s 0:12:10 - +Rule sol88 1988 only - Oct 8 11:47:30s 0:12:30 - +Rule sol88 1988 only - Oct 9 11:47:15s 0:12:45 - +Rule sol88 1988 only - Oct 10 11:47:00s 0:13:00 - +Rule sol88 1988 only - Oct 11 11:46:45s 0:13:15 - +Rule sol88 1988 only - Oct 12 11:46:30s 0:13:30 - +Rule sol88 1988 only - Oct 13 11:46:15s 0:13:45 - +Rule sol88 1988 only - Oct 14 11:46:00s 0:14:00 - +Rule sol88 1988 only - Oct 15 11:45:45s 0:14:15 - +Rule sol88 1988 only - Oct 16 11:45:35s 0:14:25 - +Rule sol88 1988 only - Oct 17 11:45:20s 0:14:40 - +Rule sol88 1988 only - Oct 18 11:45:10s 0:14:50 - +Rule sol88 1988 only - Oct 19 11:45:00s 0:15:00 - +Rule sol88 1988 only - Oct 20 11:44:45s 0:15:15 - +Rule sol88 1988 only - Oct 21 11:44:40s 0:15:20 - +Rule sol88 1988 only - Oct 22 11:44:30s 0:15:30 - +Rule sol88 1988 only - Oct 23 11:44:20s 0:15:40 - +Rule sol88 1988 only - Oct 24 11:44:10s 0:15:50 - +Rule sol88 1988 only - Oct 25 11:44:05s 0:15:55 - +Rule sol88 1988 only - Oct 26 11:44:00s 0:16:00 - +Rule sol88 1988 only - Oct 27 11:43:55s 0:16:05 - +Rule sol88 1988 only - Oct 28 11:43:50s 0:16:10 - +Rule sol88 1988 only - Oct 29 11:43:45s 0:16:15 - +Rule sol88 1988 only - Oct 30 11:43:40s 0:16:20 - +Rule sol88 1988 only - Oct 31 11:43:40s 0:16:20 - +Rule sol88 1988 only - Nov 1 11:43:35s 0:16:25 - +Rule sol88 1988 only - Nov 2 11:43:35s 0:16:25 - +Rule sol88 1988 only - Nov 3 11:43:35s 0:16:25 - +Rule sol88 1988 only - Nov 4 11:43:35s 0:16:25 - +Rule sol88 1988 only - Nov 5 11:43:40s 0:16:20 - +Rule sol88 1988 only - Nov 6 11:43:40s 0:16:20 - +Rule sol88 1988 only - Nov 7 11:43:45s 0:16:15 - +Rule sol88 1988 only - Nov 8 11:43:45s 0:16:15 - +Rule sol88 1988 only - Nov 9 11:43:50s 0:16:10 - +Rule sol88 1988 only - Nov 10 11:44:00s 0:16:00 - +Rule sol88 1988 only - Nov 11 11:44:05s 0:15:55 - +Rule sol88 1988 only - Nov 12 11:44:10s 0:15:50 - +Rule sol88 1988 only - Nov 13 11:44:20s 0:15:40 - +Rule sol88 1988 only - Nov 14 11:44:30s 0:15:30 - +Rule sol88 1988 only - Nov 15 11:44:40s 0:15:20 - +Rule sol88 1988 only - Nov 16 11:44:50s 0:15:10 - +Rule sol88 1988 only - Nov 17 11:45:00s 0:15:00 - +Rule sol88 1988 only - Nov 18 11:45:15s 0:14:45 - +Rule sol88 1988 only - Nov 19 11:45:25s 0:14:35 - +Rule sol88 1988 only - Nov 20 11:45:40s 0:14:20 - +Rule sol88 1988 only - Nov 21 11:45:55s 0:14:05 - +Rule sol88 1988 only - Nov 22 11:46:10s 0:13:50 - +Rule sol88 1988 only - Nov 23 11:46:30s 0:13:30 - +Rule sol88 1988 only - Nov 24 11:46:45s 0:13:15 - +Rule sol88 1988 only - Nov 25 11:47:05s 0:12:55 - +Rule sol88 1988 only - Nov 26 11:47:20s 0:12:40 - +Rule sol88 1988 only - Nov 27 11:47:40s 0:12:20 - +Rule sol88 1988 only - Nov 28 11:48:00s 0:12:00 - +Rule sol88 1988 only - Nov 29 11:48:25s 0:11:35 - +Rule sol88 1988 only - Nov 30 11:48:45s 0:11:15 - +Rule sol88 1988 only - Dec 1 11:49:05s 0:10:55 - +Rule sol88 1988 only - Dec 2 11:49:30s 0:10:30 - +Rule sol88 1988 only - Dec 3 11:49:55s 0:10:05 - +Rule sol88 1988 only - Dec 4 11:50:15s 0:09:45 - +Rule sol88 1988 only - Dec 5 11:50:40s 0:09:20 - +Rule sol88 1988 only - Dec 6 11:51:05s 0:08:55 - +Rule sol88 1988 only - Dec 7 11:51:35s 0:08:25 - +Rule sol88 1988 only - Dec 8 11:52:00s 0:08:00 - +Rule sol88 1988 only - Dec 9 11:52:25s 0:07:35 - +Rule sol88 1988 only - Dec 10 11:52:55s 0:07:05 - +Rule sol88 1988 only - Dec 11 11:53:20s 0:06:40 - +Rule sol88 1988 only - Dec 12 11:53:50s 0:06:10 - +Rule sol88 1988 only - Dec 13 11:54:15s 0:05:45 - +Rule sol88 1988 only - Dec 14 11:54:45s 0:05:15 - +Rule sol88 1988 only - Dec 15 11:55:15s 0:04:45 - +Rule sol88 1988 only - Dec 16 11:55:45s 0:04:15 - +Rule sol88 1988 only - Dec 17 11:56:15s 0:03:45 - +Rule sol88 1988 only - Dec 18 11:56:40s 0:03:20 - +Rule sol88 1988 only - Dec 19 11:57:10s 0:02:50 - +Rule sol88 1988 only - Dec 20 11:57:40s 0:02:20 - +Rule sol88 1988 only - Dec 21 11:58:10s 0:01:50 - +Rule sol88 1988 only - Dec 22 11:58:40s 0:01:20 - +Rule sol88 1988 only - Dec 23 11:59:10s 0:00:50 - +Rule sol88 1988 only - Dec 24 11:59:40s 0:00:20 - +Rule sol88 1988 only - Dec 25 12:00:10s -0:00:10 - +Rule sol88 1988 only - Dec 26 12:00:40s -0:00:40 - +Rule sol88 1988 only - Dec 27 12:01:10s -0:01:10 - +Rule sol88 1988 only - Dec 28 12:01:40s -0:01:40 - +Rule sol88 1988 only - Dec 29 12:02:10s -0:02:10 - +Rule sol88 1988 only - Dec 30 12:02:35s -0:02:35 - +Rule sol88 1988 only - Dec 31 12:03:05s -0:03:05 - + +# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs +# Before and after 1988, we'll operate on local mean solar time. + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone Mideast/Riyadh88 3:07:04 - ?? 1988 + 3:07:04 sol88 ?? 1989 + 3:07:04 - ?? diff --git a/time/solar89 b/time/solar89 new file mode 100644 index 000000000..3221f976c --- /dev/null +++ b/time/solar89 @@ -0,0 +1,391 @@ +# @(#)solar89 7.2 + +# Apparent noon times below are for Riyadh; they're a bit off for other places. +# Times were computed using a formula provided by the U. S. Naval Observatory: +# eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l) +# -12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l) +# + 19.3 * cos(3 * l); +# where l is the "mean longitude of the Sun" given by +# l = 279.642 degrees + 0.985647 * d +# and d is the interval in days from January 0, 0 hours Universal Time +# (equaling the day of the year plus the fraction of a day from zero hours). +# The accuracy of the formula is plus or minus three seconds. +# +# Rounding to the nearest five seconds results in fewer than +# 256 different "time types"--a limit that's faced because time types are +# stored on disk as unsigned chars. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule sol89 1989 only - Jan 1 12:03:35s -0:03:35 - +Rule sol89 1989 only - Jan 2 12:04:05s -0:04:05 - +Rule sol89 1989 only - Jan 3 12:04:30s -0:04:30 - +Rule sol89 1989 only - Jan 4 12:05:00s -0:05:00 - +Rule sol89 1989 only - Jan 5 12:05:25s -0:05:25 - +Rule sol89 1989 only - Jan 6 12:05:50s -0:05:50 - +Rule sol89 1989 only - Jan 7 12:06:15s -0:06:15 - +Rule sol89 1989 only - Jan 8 12:06:45s -0:06:45 - +Rule sol89 1989 only - Jan 9 12:07:10s -0:07:10 - +Rule sol89 1989 only - Jan 10 12:07:35s -0:07:35 - +Rule sol89 1989 only - Jan 11 12:07:55s -0:07:55 - +Rule sol89 1989 only - Jan 12 12:08:20s -0:08:20 - +Rule sol89 1989 only - Jan 13 12:08:45s -0:08:45 - +Rule sol89 1989 only - Jan 14 12:09:05s -0:09:05 - +Rule sol89 1989 only - Jan 15 12:09:25s -0:09:25 - +Rule sol89 1989 only - Jan 16 12:09:45s -0:09:45 - +Rule sol89 1989 only - Jan 17 12:10:05s -0:10:05 - +Rule sol89 1989 only - Jan 18 12:10:25s -0:10:25 - +Rule sol89 1989 only - Jan 19 12:10:45s -0:10:45 - +Rule sol89 1989 only - Jan 20 12:11:05s -0:11:05 - +Rule sol89 1989 only - Jan 21 12:11:20s -0:11:20 - +Rule sol89 1989 only - Jan 22 12:11:35s -0:11:35 - +Rule sol89 1989 only - Jan 23 12:11:55s -0:11:55 - +Rule sol89 1989 only - Jan 24 12:12:10s -0:12:10 - +Rule sol89 1989 only - Jan 25 12:12:20s -0:12:20 - +Rule sol89 1989 only - Jan 26 12:12:35s -0:12:35 - +Rule sol89 1989 only - Jan 27 12:12:50s -0:12:50 - +Rule sol89 1989 only - Jan 28 12:13:00s -0:13:00 - +Rule sol89 1989 only - Jan 29 12:13:10s -0:13:10 - +Rule sol89 1989 only - Jan 30 12:13:20s -0:13:20 - +Rule sol89 1989 only - Jan 31 12:13:30s -0:13:30 - +Rule sol89 1989 only - Feb 1 12:13:40s -0:13:40 - +Rule sol89 1989 only - Feb 2 12:13:45s -0:13:45 - +Rule sol89 1989 only - Feb 3 12:13:55s -0:13:55 - +Rule sol89 1989 only - Feb 4 12:14:00s -0:14:00 - +Rule sol89 1989 only - Feb 5 12:14:05s -0:14:05 - +Rule sol89 1989 only - Feb 6 12:14:10s -0:14:10 - +Rule sol89 1989 only - Feb 7 12:14:10s -0:14:10 - +Rule sol89 1989 only - Feb 8 12:14:15s -0:14:15 - +Rule sol89 1989 only - Feb 9 12:14:15s -0:14:15 - +Rule sol89 1989 only - Feb 10 12:14:20s -0:14:20 - +Rule sol89 1989 only - Feb 11 12:14:20s -0:14:20 - +Rule sol89 1989 only - Feb 12 12:14:20s -0:14:20 - +Rule sol89 1989 only - Feb 13 12:14:15s -0:14:15 - +Rule sol89 1989 only - Feb 14 12:14:15s -0:14:15 - +Rule sol89 1989 only - Feb 15 12:14:10s -0:14:10 - +Rule sol89 1989 only - Feb 16 12:14:10s -0:14:10 - +Rule sol89 1989 only - Feb 17 12:14:05s -0:14:05 - +Rule sol89 1989 only - Feb 18 12:14:00s -0:14:00 - +Rule sol89 1989 only - Feb 19 12:13:55s -0:13:55 - +Rule sol89 1989 only - Feb 20 12:13:50s -0:13:50 - +Rule sol89 1989 only - Feb 21 12:13:40s -0:13:40 - +Rule sol89 1989 only - Feb 22 12:13:35s -0:13:35 - +Rule sol89 1989 only - Feb 23 12:13:25s -0:13:25 - +Rule sol89 1989 only - Feb 24 12:13:15s -0:13:15 - +Rule sol89 1989 only - Feb 25 12:13:05s -0:13:05 - +Rule sol89 1989 only - Feb 26 12:12:55s -0:12:55 - +Rule sol89 1989 only - Feb 27 12:12:45s -0:12:45 - +Rule sol89 1989 only - Feb 28 12:12:35s -0:12:35 - +Rule sol89 1989 only - Mar 1 12:12:25s -0:12:25 - +Rule sol89 1989 only - Mar 2 12:12:10s -0:12:10 - +Rule sol89 1989 only - Mar 3 12:12:00s -0:12:00 - +Rule sol89 1989 only - Mar 4 12:11:45s -0:11:45 - +Rule sol89 1989 only - Mar 5 12:11:35s -0:11:35 - +Rule sol89 1989 only - Mar 6 12:11:20s -0:11:20 - +Rule sol89 1989 only - Mar 7 12:11:05s -0:11:05 - +Rule sol89 1989 only - Mar 8 12:10:50s -0:10:50 - +Rule sol89 1989 only - Mar 9 12:10:35s -0:10:35 - +Rule sol89 1989 only - Mar 10 12:10:20s -0:10:20 - +Rule sol89 1989 only - Mar 11 12:10:05s -0:10:05 - +Rule sol89 1989 only - Mar 12 12:09:50s -0:09:50 - +Rule sol89 1989 only - Mar 13 12:09:30s -0:09:30 - +Rule sol89 1989 only - Mar 14 12:09:15s -0:09:15 - +Rule sol89 1989 only - Mar 15 12:09:00s -0:09:00 - +Rule sol89 1989 only - Mar 16 12:08:40s -0:08:40 - +Rule sol89 1989 only - Mar 17 12:08:25s -0:08:25 - +Rule sol89 1989 only - Mar 18 12:08:05s -0:08:05 - +Rule sol89 1989 only - Mar 19 12:07:50s -0:07:50 - +Rule sol89 1989 only - Mar 20 12:07:30s -0:07:30 - +Rule sol89 1989 only - Mar 21 12:07:15s -0:07:15 - +Rule sol89 1989 only - Mar 22 12:06:55s -0:06:55 - +Rule sol89 1989 only - Mar 23 12:06:35s -0:06:35 - +Rule sol89 1989 only - Mar 24 12:06:20s -0:06:20 - +Rule sol89 1989 only - Mar 25 12:06:00s -0:06:00 - +Rule sol89 1989 only - Mar 26 12:05:40s -0:05:40 - +Rule sol89 1989 only - Mar 27 12:05:25s -0:05:25 - +Rule sol89 1989 only - Mar 28 12:05:05s -0:05:05 - +Rule sol89 1989 only - Mar 29 12:04:50s -0:04:50 - +Rule sol89 1989 only - Mar 30 12:04:30s -0:04:30 - +Rule sol89 1989 only - Mar 31 12:04:10s -0:04:10 - +Rule sol89 1989 only - Apr 1 12:03:55s -0:03:55 - +Rule sol89 1989 only - Apr 2 12:03:35s -0:03:35 - +Rule sol89 1989 only - Apr 3 12:03:20s -0:03:20 - +Rule sol89 1989 only - Apr 4 12:03:00s -0:03:00 - +Rule sol89 1989 only - Apr 5 12:02:45s -0:02:45 - +Rule sol89 1989 only - Apr 6 12:02:25s -0:02:25 - +Rule sol89 1989 only - Apr 7 12:02:10s -0:02:10 - +Rule sol89 1989 only - Apr 8 12:01:50s -0:01:50 - +Rule sol89 1989 only - Apr 9 12:01:35s -0:01:35 - +Rule sol89 1989 only - Apr 10 12:01:20s -0:01:20 - +Rule sol89 1989 only - Apr 11 12:01:05s -0:01:05 - +Rule sol89 1989 only - Apr 12 12:00:50s -0:00:50 - +Rule sol89 1989 only - Apr 13 12:00:35s -0:00:35 - +Rule sol89 1989 only - Apr 14 12:00:20s -0:00:20 - +Rule sol89 1989 only - Apr 15 12:00:05s -0:00:05 - +Rule sol89 1989 only - Apr 16 11:59:50s 0:00:10 - +Rule sol89 1989 only - Apr 17 11:59:35s 0:00:25 - +Rule sol89 1989 only - Apr 18 11:59:20s 0:00:40 - +Rule sol89 1989 only - Apr 19 11:59:10s 0:00:50 - +Rule sol89 1989 only - Apr 20 11:58:55s 0:01:05 - +Rule sol89 1989 only - Apr 21 11:58:45s 0:01:15 - +Rule sol89 1989 only - Apr 22 11:58:30s 0:01:30 - +Rule sol89 1989 only - Apr 23 11:58:20s 0:01:40 - +Rule sol89 1989 only - Apr 24 11:58:10s 0:01:50 - +Rule sol89 1989 only - Apr 25 11:58:00s 0:02:00 - +Rule sol89 1989 only - Apr 26 11:57:50s 0:02:10 - +Rule sol89 1989 only - Apr 27 11:57:40s 0:02:20 - +Rule sol89 1989 only - Apr 28 11:57:30s 0:02:30 - +Rule sol89 1989 only - Apr 29 11:57:20s 0:02:40 - +Rule sol89 1989 only - Apr 30 11:57:15s 0:02:45 - +Rule sol89 1989 only - May 1 11:57:05s 0:02:55 - +Rule sol89 1989 only - May 2 11:57:00s 0:03:00 - +Rule sol89 1989 only - May 3 11:56:50s 0:03:10 - +Rule sol89 1989 only - May 4 11:56:45s 0:03:15 - +Rule sol89 1989 only - May 5 11:56:40s 0:03:20 - +Rule sol89 1989 only - May 6 11:56:35s 0:03:25 - +Rule sol89 1989 only - May 7 11:56:30s 0:03:30 - +Rule sol89 1989 only - May 8 11:56:30s 0:03:30 - +Rule sol89 1989 only - May 9 11:56:25s 0:03:35 - +Rule sol89 1989 only - May 10 11:56:25s 0:03:35 - +Rule sol89 1989 only - May 11 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 12 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 13 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 14 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 15 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 16 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 17 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 18 11:56:25s 0:03:35 - +Rule sol89 1989 only - May 19 11:56:25s 0:03:35 - +Rule sol89 1989 only - May 20 11:56:30s 0:03:30 - +Rule sol89 1989 only - May 21 11:56:35s 0:03:25 - +Rule sol89 1989 only - May 22 11:56:35s 0:03:25 - +Rule sol89 1989 only - May 23 11:56:40s 0:03:20 - +Rule sol89 1989 only - May 24 11:56:45s 0:03:15 - +Rule sol89 1989 only - May 25 11:56:55s 0:03:05 - +Rule sol89 1989 only - May 26 11:57:00s 0:03:00 - +Rule sol89 1989 only - May 27 11:57:05s 0:02:55 - +Rule sol89 1989 only - May 28 11:57:15s 0:02:45 - +Rule sol89 1989 only - May 29 11:57:20s 0:02:40 - +Rule sol89 1989 only - May 30 11:57:30s 0:02:30 - +Rule sol89 1989 only - May 31 11:57:35s 0:02:25 - +Rule sol89 1989 only - Jun 1 11:57:45s 0:02:15 - +Rule sol89 1989 only - Jun 2 11:57:55s 0:02:05 - +Rule sol89 1989 only - Jun 3 11:58:05s 0:01:55 - +Rule sol89 1989 only - Jun 4 11:58:15s 0:01:45 - +Rule sol89 1989 only - Jun 5 11:58:25s 0:01:35 - +Rule sol89 1989 only - Jun 6 11:58:35s 0:01:25 - +Rule sol89 1989 only - Jun 7 11:58:45s 0:01:15 - +Rule sol89 1989 only - Jun 8 11:59:00s 0:01:00 - +Rule sol89 1989 only - Jun 9 11:59:10s 0:00:50 - +Rule sol89 1989 only - Jun 10 11:59:20s 0:00:40 - +Rule sol89 1989 only - Jun 11 11:59:35s 0:00:25 - +Rule sol89 1989 only - Jun 12 11:59:45s 0:00:15 - +Rule sol89 1989 only - Jun 13 12:00:00s 0:00:00 - +Rule sol89 1989 only - Jun 14 12:00:10s -0:00:10 - +Rule sol89 1989 only - Jun 15 12:00:25s -0:00:25 - +Rule sol89 1989 only - Jun 16 12:00:35s -0:00:35 - +Rule sol89 1989 only - Jun 17 12:00:50s -0:00:50 - +Rule sol89 1989 only - Jun 18 12:01:05s -0:01:05 - +Rule sol89 1989 only - Jun 19 12:01:15s -0:01:15 - +Rule sol89 1989 only - Jun 20 12:01:30s -0:01:30 - +Rule sol89 1989 only - Jun 21 12:01:40s -0:01:40 - +Rule sol89 1989 only - Jun 22 12:01:55s -0:01:55 - +Rule sol89 1989 only - Jun 23 12:02:10s -0:02:10 - +Rule sol89 1989 only - Jun 24 12:02:20s -0:02:20 - +Rule sol89 1989 only - Jun 25 12:02:35s -0:02:35 - +Rule sol89 1989 only - Jun 26 12:02:45s -0:02:45 - +Rule sol89 1989 only - Jun 27 12:03:00s -0:03:00 - +Rule sol89 1989 only - Jun 28 12:03:10s -0:03:10 - +Rule sol89 1989 only - Jun 29 12:03:25s -0:03:25 - +Rule sol89 1989 only - Jun 30 12:03:35s -0:03:35 - +Rule sol89 1989 only - Jul 1 12:03:45s -0:03:45 - +Rule sol89 1989 only - Jul 2 12:04:00s -0:04:00 - +Rule sol89 1989 only - Jul 3 12:04:10s -0:04:10 - +Rule sol89 1989 only - Jul 4 12:04:20s -0:04:20 - +Rule sol89 1989 only - Jul 5 12:04:30s -0:04:30 - +Rule sol89 1989 only - Jul 6 12:04:40s -0:04:40 - +Rule sol89 1989 only - Jul 7 12:04:50s -0:04:50 - +Rule sol89 1989 only - Jul 8 12:05:00s -0:05:00 - +Rule sol89 1989 only - Jul 9 12:05:10s -0:05:10 - +Rule sol89 1989 only - Jul 10 12:05:20s -0:05:20 - +Rule sol89 1989 only - Jul 11 12:05:25s -0:05:25 - +Rule sol89 1989 only - Jul 12 12:05:35s -0:05:35 - +Rule sol89 1989 only - Jul 13 12:05:40s -0:05:40 - +Rule sol89 1989 only - Jul 14 12:05:50s -0:05:50 - +Rule sol89 1989 only - Jul 15 12:05:55s -0:05:55 - +Rule sol89 1989 only - Jul 16 12:06:00s -0:06:00 - +Rule sol89 1989 only - Jul 17 12:06:05s -0:06:05 - +Rule sol89 1989 only - Jul 18 12:06:10s -0:06:10 - +Rule sol89 1989 only - Jul 19 12:06:15s -0:06:15 - +Rule sol89 1989 only - Jul 20 12:06:20s -0:06:20 - +Rule sol89 1989 only - Jul 21 12:06:20s -0:06:20 - +Rule sol89 1989 only - Jul 22 12:06:25s -0:06:25 - +Rule sol89 1989 only - Jul 23 12:06:25s -0:06:25 - +Rule sol89 1989 only - Jul 24 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 25 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 26 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 27 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 28 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 29 12:06:25s -0:06:25 - +Rule sol89 1989 only - Jul 30 12:06:25s -0:06:25 - +Rule sol89 1989 only - Jul 31 12:06:20s -0:06:20 - +Rule sol89 1989 only - Aug 1 12:06:20s -0:06:20 - +Rule sol89 1989 only - Aug 2 12:06:15s -0:06:15 - +Rule sol89 1989 only - Aug 3 12:06:10s -0:06:10 - +Rule sol89 1989 only - Aug 4 12:06:05s -0:06:05 - +Rule sol89 1989 only - Aug 5 12:06:00s -0:06:00 - +Rule sol89 1989 only - Aug 6 12:05:50s -0:05:50 - +Rule sol89 1989 only - Aug 7 12:05:45s -0:05:45 - +Rule sol89 1989 only - Aug 8 12:05:35s -0:05:35 - +Rule sol89 1989 only - Aug 9 12:05:30s -0:05:30 - +Rule sol89 1989 only - Aug 10 12:05:20s -0:05:20 - +Rule sol89 1989 only - Aug 11 12:05:10s -0:05:10 - +Rule sol89 1989 only - Aug 12 12:05:00s -0:05:00 - +Rule sol89 1989 only - Aug 13 12:04:50s -0:04:50 - +Rule sol89 1989 only - Aug 14 12:04:40s -0:04:40 - +Rule sol89 1989 only - Aug 15 12:04:30s -0:04:30 - +Rule sol89 1989 only - Aug 16 12:04:15s -0:04:15 - +Rule sol89 1989 only - Aug 17 12:04:05s -0:04:05 - +Rule sol89 1989 only - Aug 18 12:03:50s -0:03:50 - +Rule sol89 1989 only - Aug 19 12:03:35s -0:03:35 - +Rule sol89 1989 only - Aug 20 12:03:25s -0:03:25 - +Rule sol89 1989 only - Aug 21 12:03:10s -0:03:10 - +Rule sol89 1989 only - Aug 22 12:02:55s -0:02:55 - +Rule sol89 1989 only - Aug 23 12:02:40s -0:02:40 - +Rule sol89 1989 only - Aug 24 12:02:20s -0:02:20 - +Rule sol89 1989 only - Aug 25 12:02:05s -0:02:05 - +Rule sol89 1989 only - Aug 26 12:01:50s -0:01:50 - +Rule sol89 1989 only - Aug 27 12:01:30s -0:01:30 - +Rule sol89 1989 only - Aug 28 12:01:15s -0:01:15 - +Rule sol89 1989 only - Aug 29 12:00:55s -0:00:55 - +Rule sol89 1989 only - Aug 30 12:00:40s -0:00:40 - +Rule sol89 1989 only - Aug 31 12:00:20s -0:00:20 - +Rule sol89 1989 only - Sep 1 12:00:00s 0:00:00 - +Rule sol89 1989 only - Sep 2 11:59:45s 0:00:15 - +Rule sol89 1989 only - Sep 3 11:59:25s 0:00:35 - +Rule sol89 1989 only - Sep 4 11:59:05s 0:00:55 - +Rule sol89 1989 only - Sep 5 11:58:45s 0:01:15 - +Rule sol89 1989 only - Sep 6 11:58:25s 0:01:35 - +Rule sol89 1989 only - Sep 7 11:58:05s 0:01:55 - +Rule sol89 1989 only - Sep 8 11:57:45s 0:02:15 - +Rule sol89 1989 only - Sep 9 11:57:20s 0:02:40 - +Rule sol89 1989 only - Sep 10 11:57:00s 0:03:00 - +Rule sol89 1989 only - Sep 11 11:56:40s 0:03:20 - +Rule sol89 1989 only - Sep 12 11:56:20s 0:03:40 - +Rule sol89 1989 only - Sep 13 11:56:00s 0:04:00 - +Rule sol89 1989 only - Sep 14 11:55:35s 0:04:25 - +Rule sol89 1989 only - Sep 15 11:55:15s 0:04:45 - +Rule sol89 1989 only - Sep 16 11:54:55s 0:05:05 - +Rule sol89 1989 only - Sep 17 11:54:35s 0:05:25 - +Rule sol89 1989 only - Sep 18 11:54:10s 0:05:50 - +Rule sol89 1989 only - Sep 19 11:53:50s 0:06:10 - +Rule sol89 1989 only - Sep 20 11:53:30s 0:06:30 - +Rule sol89 1989 only - Sep 21 11:53:10s 0:06:50 - +Rule sol89 1989 only - Sep 22 11:52:45s 0:07:15 - +Rule sol89 1989 only - Sep 23 11:52:25s 0:07:35 - +Rule sol89 1989 only - Sep 24 11:52:05s 0:07:55 - +Rule sol89 1989 only - Sep 25 11:51:45s 0:08:15 - +Rule sol89 1989 only - Sep 26 11:51:25s 0:08:35 - +Rule sol89 1989 only - Sep 27 11:51:05s 0:08:55 - +Rule sol89 1989 only - Sep 28 11:50:40s 0:09:20 - +Rule sol89 1989 only - Sep 29 11:50:20s 0:09:40 - +Rule sol89 1989 only - Sep 30 11:50:00s 0:10:00 - +Rule sol89 1989 only - Oct 1 11:49:45s 0:10:15 - +Rule sol89 1989 only - Oct 2 11:49:25s 0:10:35 - +Rule sol89 1989 only - Oct 3 11:49:05s 0:10:55 - +Rule sol89 1989 only - Oct 4 11:48:45s 0:11:15 - +Rule sol89 1989 only - Oct 5 11:48:30s 0:11:30 - +Rule sol89 1989 only - Oct 6 11:48:10s 0:11:50 - +Rule sol89 1989 only - Oct 7 11:47:50s 0:12:10 - +Rule sol89 1989 only - Oct 8 11:47:35s 0:12:25 - +Rule sol89 1989 only - Oct 9 11:47:20s 0:12:40 - +Rule sol89 1989 only - Oct 10 11:47:00s 0:13:00 - +Rule sol89 1989 only - Oct 11 11:46:45s 0:13:15 - +Rule sol89 1989 only - Oct 12 11:46:30s 0:13:30 - +Rule sol89 1989 only - Oct 13 11:46:15s 0:13:45 - +Rule sol89 1989 only - Oct 14 11:46:00s 0:14:00 - +Rule sol89 1989 only - Oct 15 11:45:50s 0:14:10 - +Rule sol89 1989 only - Oct 16 11:45:35s 0:14:25 - +Rule sol89 1989 only - Oct 17 11:45:20s 0:14:40 - +Rule sol89 1989 only - Oct 18 11:45:10s 0:14:50 - +Rule sol89 1989 only - Oct 19 11:45:00s 0:15:00 - +Rule sol89 1989 only - Oct 20 11:44:50s 0:15:10 - +Rule sol89 1989 only - Oct 21 11:44:40s 0:15:20 - +Rule sol89 1989 only - Oct 22 11:44:30s 0:15:30 - +Rule sol89 1989 only - Oct 23 11:44:20s 0:15:40 - +Rule sol89 1989 only - Oct 24 11:44:10s 0:15:50 - +Rule sol89 1989 only - Oct 25 11:44:05s 0:15:55 - +Rule sol89 1989 only - Oct 26 11:44:00s 0:16:00 - +Rule sol89 1989 only - Oct 27 11:43:50s 0:16:10 - +Rule sol89 1989 only - Oct 28 11:43:45s 0:16:15 - +Rule sol89 1989 only - Oct 29 11:43:40s 0:16:20 - +Rule sol89 1989 only - Oct 30 11:43:40s 0:16:20 - +Rule sol89 1989 only - Oct 31 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 1 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 2 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 3 11:43:30s 0:16:30 - +Rule sol89 1989 only - Nov 4 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 5 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 6 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 7 11:43:40s 0:16:20 - +Rule sol89 1989 only - Nov 8 11:43:45s 0:16:15 - +Rule sol89 1989 only - Nov 9 11:43:50s 0:16:10 - +Rule sol89 1989 only - Nov 10 11:43:55s 0:16:05 - +Rule sol89 1989 only - Nov 11 11:44:00s 0:16:00 - +Rule sol89 1989 only - Nov 12 11:44:05s 0:15:55 - +Rule sol89 1989 only - Nov 13 11:44:15s 0:15:45 - +Rule sol89 1989 only - Nov 14 11:44:25s 0:15:35 - +Rule sol89 1989 only - Nov 15 11:44:35s 0:15:25 - +Rule sol89 1989 only - Nov 16 11:44:45s 0:15:15 - +Rule sol89 1989 only - Nov 17 11:44:55s 0:15:05 - +Rule sol89 1989 only - Nov 18 11:45:10s 0:14:50 - +Rule sol89 1989 only - Nov 19 11:45:20s 0:14:40 - +Rule sol89 1989 only - Nov 20 11:45:35s 0:14:25 - +Rule sol89 1989 only - Nov 21 11:45:50s 0:14:10 - +Rule sol89 1989 only - Nov 22 11:46:05s 0:13:55 - +Rule sol89 1989 only - Nov 23 11:46:25s 0:13:35 - +Rule sol89 1989 only - Nov 24 11:46:40s 0:13:20 - +Rule sol89 1989 only - Nov 25 11:47:00s 0:13:00 - +Rule sol89 1989 only - Nov 26 11:47:20s 0:12:40 - +Rule sol89 1989 only - Nov 27 11:47:35s 0:12:25 - +Rule sol89 1989 only - Nov 28 11:47:55s 0:12:05 - +Rule sol89 1989 only - Nov 29 11:48:20s 0:11:40 - +Rule sol89 1989 only - Nov 30 11:48:40s 0:11:20 - +Rule sol89 1989 only - Dec 1 11:49:00s 0:11:00 - +Rule sol89 1989 only - Dec 2 11:49:25s 0:10:35 - +Rule sol89 1989 only - Dec 3 11:49:50s 0:10:10 - +Rule sol89 1989 only - Dec 4 11:50:15s 0:09:45 - +Rule sol89 1989 only - Dec 5 11:50:35s 0:09:25 - +Rule sol89 1989 only - Dec 6 11:51:00s 0:09:00 - +Rule sol89 1989 only - Dec 7 11:51:30s 0:08:30 - +Rule sol89 1989 only - Dec 8 11:51:55s 0:08:05 - +Rule sol89 1989 only - Dec 9 11:52:20s 0:07:40 - +Rule sol89 1989 only - Dec 10 11:52:50s 0:07:10 - +Rule sol89 1989 only - Dec 11 11:53:15s 0:06:45 - +Rule sol89 1989 only - Dec 12 11:53:45s 0:06:15 - +Rule sol89 1989 only - Dec 13 11:54:10s 0:05:50 - +Rule sol89 1989 only - Dec 14 11:54:40s 0:05:20 - +Rule sol89 1989 only - Dec 15 11:55:10s 0:04:50 - +Rule sol89 1989 only - Dec 16 11:55:40s 0:04:20 - +Rule sol89 1989 only - Dec 17 11:56:05s 0:03:55 - +Rule sol89 1989 only - Dec 18 11:56:35s 0:03:25 - +Rule sol89 1989 only - Dec 19 11:57:05s 0:02:55 - +Rule sol89 1989 only - Dec 20 11:57:35s 0:02:25 - +Rule sol89 1989 only - Dec 21 11:58:05s 0:01:55 - +Rule sol89 1989 only - Dec 22 11:58:35s 0:01:25 - +Rule sol89 1989 only - Dec 23 11:59:05s 0:00:55 - +Rule sol89 1989 only - Dec 24 11:59:35s 0:00:25 - +Rule sol89 1989 only - Dec 25 12:00:05s -0:00:05 - +Rule sol89 1989 only - Dec 26 12:00:35s -0:00:35 - +Rule sol89 1989 only - Dec 27 12:01:05s -0:01:05 - +Rule sol89 1989 only - Dec 28 12:01:35s -0:01:35 - +Rule sol89 1989 only - Dec 29 12:02:00s -0:02:00 - +Rule sol89 1989 only - Dec 30 12:02:30s -0:02:30 - +Rule sol89 1989 only - Dec 31 12:03:00s -0:03:00 - + +# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs +# Before and after 1989, we'll operate on local mean solar time. + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone Mideast/Riyadh89 3:07:04 - ?? 1989 + 3:07:04 sol89 ?? 1990 + 3:07:04 - ?? diff --git a/time/southamerica b/time/southamerica new file mode 100644 index 000000000..b40ce559a --- /dev/null +++ b/time/southamerica @@ -0,0 +1,397 @@ +# @(#)southamerica 7.6 + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# I invented the abbreviations marked `*' in the following table; +# the rest are from earlier versions of this file, or from other sources. +# Some of these are just plausible excuses for common English abbreviations. +# Corrections are welcome! +# std dst +# LMT Local Mean Time +# -2:00 FST FDT Fernando de Noronha +# -3:00 EST EDT Eastern South America (conflicts with -5:00) +# -4:00 AST ADT Andes*, Antilles*, Asuncion*, Atlantic +# -4:00 CST CDT Chile (conflicts with -6:00) +# -4:00 WST WDT Western Brazil +# -5:00 AST ADT Acre (conflicts with -4:00) +# -5:00 EST EDT Eastern, Ecuador* +# -6:00 CST CDT Archipelago of Columbus*, Central +# -7:00 MST MDT Mataveri*, Mountain +# +# See the `africa' file for Zone naming conventions. + +# From Guy Harris: +# From Official Airline Guide - Worldwide Edition (1987). Countries not +# listed here do not observe DST, according to the OAG. Time zone names +# are pure inventions, and none are supplied for countries not observing +# DST; updates from natives would be appreciated. The times that DST +# starts and ends are based on the assumption that they switch a 2AM just +# as everybody else does. + +############################################################################### + +############################################################################### + +# Argentina + +# From Bob Devine (January 28, 1988): +# Argentina: first Sunday in October to first Sunday in April since 1976. +# Double Summer time from 1969 to 1974. Switches at midnight. + +# From U. S. Naval Observatory (January 19, 19889): +# ARGENTINA 3 H BEHIND UTC + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Arg 1930 only - Dec 1 0:00 1:00 D +Rule Arg 1931 only - Apr 1 0:00 0 S +Rule Arg 1931 only - Oct 15 0:00 1:00 D +Rule Arg 1932 1940 - Mar 1 0:00 0 S +Rule Arg 1932 1939 - Nov 1 0:00 1:00 D +Rule Arg 1940 only - Jul 1 0:00 1:00 D +Rule Arg 1941 only - Jun 15 0:00 0 S +Rule Arg 1941 only - Oct 15 0:00 1:00 D +Rule Arg 1943 only - Aug 1 0:00 0 S +Rule Arg 1943 only - Oct 15 0:00 1:00 D +Rule Arg 1946 only - Mar 1 0:00 0 S +Rule Arg 1946 only - Oct 1 0:00 1:00 D +Rule Arg 1963 only - Oct 1 0:00 0 S +Rule Arg 1963 only - Dec 15 0:00 1:00 D +Rule Arg 1964 1966 - Mar 1 0:00 0 S +Rule Arg 1964 1966 - Oct 15 0:00 1:00 D +Rule Arg 1967 only - Apr 1 0:00 0 S +Rule Arg 1967 1968 - Oct Sun<=7 0:00 1:00 D +Rule Arg 1968 1969 - Apr Sun<=7 0:00 0 S +Rule Arg 1974 only - Jan 23 0:00 1:00 D +Rule Arg 1974 only - May 1 0:00 0 S +Rule Arg 1974 1976 - Oct Sun<=7 0:00 1:00 D +Rule Arg 1975 1977 - Apr Sun<=7 0:00 0 S +Rule Arg 1985 only - Nov 2 0:00 1:00 D +Rule Arg 1986 only - Mar 14 0:00 0 S +Rule Arg 1986 1987 - Oct 25 0:00 1:00 D +Rule Arg 1987 only - Feb 13 0:00 0 S +Rule Arg 1988 only - Feb 7 0:00 0 S +Rule Arg 1988 only - Dec 1 0:00 1:00 D +Rule Arg 1989 only - Mar 16 0:00 0 S +Rule Arg 1989 only - Oct 15 0:00 1:00 D +Rule Arg 1990 only - Mar 4 0:00 0 S +# _The Economist_ (8 Jan 1994, p 42) reports that Argentina +# had DST in 1991-2 and 1992-3, but not in 1990-1 or in 1993-4. +# It has something to do with electricity companies meeting demand in summer. +# We don't know the 1991-3 transition times, unfortunately. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Buenos_Aires -3:53:48 - LMT 1894 Nov + -4:17 - CMT 1920 May # Cordoba Mean Time + -4:00 - AST 1930 Dec + -4:00 Arg A%sT 1969 Oct 5 + -3:00 Arg E%sT + +# Bolivia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/La_Paz -4:32:36 - LMT 1890 + -4:33 - LPMT 1931 Oct 15 # La Paz Mean Time + -4:33 1:00 LPDT 1932 Mar 21 + -4:00 - AST + +# Brazil + +# From Guy Harris: +# The OAG lists October 25, 1987 and February 12, 1988 as the starting and +# ending dates, giving them as "estimated date(s) based on previous year". We +# infer a rule here from one example, always a dangerous practice.... Yes, +# they really do switch on Saturday, according to the OAG. +# "Brazil/Acre" is for the Territory of Acre; "Brazil/DeNoronha" is for +# Fernando De Noronha. + +# From Bob Devine (January 28, 1988): +# The only information I found is that there was no DST up to 1985. +# But there was some before 1952! + +# From U. S. Naval Observatory (January 16, 1989): +# BRAZIL WEST 5 H BEHIND UTC TERRITORY OF ACRE +# BRAZIL WEST 4 H BEHIND UTC ACRE OCT 23, '88-FEB 11, +# BRAZIL '89 (ESTIMATED) +# BRAZIL CENTRAL 4 H BEHIND UTC MANAUS +# BRAZIL CENTRAL 3 H BEHIND UTC MANAUS OCT 23, '88-FEB 11, +# BRAZIL CENTRAL '89 (ESTIMATED) +# BRAZIL EAST 3 H BEHIND UTC COASTAL STATES, RIO, SAO +# BRAZIL EAST PAULO, BRASILIA +# BRAZIL EAST 2 H BEHIND UTC COASTAL STATES, RIO, SAO +# BRAZIL PAULO, BRASILIA OCT 23, +# BRAZIL '88-FEB 11, '89 +# BRAZIL (ESTIMATED) +# BRAZIL 2 H BEHIND UTC ATLANTIC ISLANDS, FERNANDO +# BRAZIL DE NORONHA +# BRAZIL 1 H BEHIND UTC OCT 23, '88-FEB 11, '89 +# BRAZIL (ESTIMATED) +# BRAZIL 3 H BEHIND UTC FOR MOST MAJOR AIRPORTS. + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# The mayor of Rio recently attempted to change the time zone rules +# just in his city, in order to leave more summer time for the tourist trade. +# The rule change lasted only part of the day; +# the federal government refused to follow the city's rules, and business +# was in a chaos, so the mayor backed down that afternoon. +# Shanks claims Acre stopped observing DST after 1988 Feb 7, but it +# could just be that his table ran out of room. We're extrapolating +# about time zone changes after 1990 Feb 11. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Brazil 1914 only - Jan 1 0:00 0 S +Rule Brazil 1931 only - Oct 3 11:00 1 D +Rule Brazil 1932 1933 - Apr 1 0:00 0 S +Rule Brazil 1932 only - Oct 3 0:00 1 D +Rule Brazil 1949 1952 - Dec 1 0:00 1 D +Rule Brazil 1950 only - Apr 16 0:00 0 S +Rule Brazil 1951 1953 - Apr 1 0:00 0 S +Rule Brazil 1963 only - Dec 9 0:00 1 D +Rule Brazil 1964 only - Mar 1 0:00 0 S +Rule Brazil 1965 only - Jan 31 0:00 1 D +Rule Brazil 1965 only - Apr 1 0:00 0 S +Rule Brazil 1965 only - Dec 1 0:00 1 D +Rule Brazil 1966 1968 - Mar 1 0:00 0 S +Rule Brazil 1966 1967 - Nov 1 0:00 1 D +Rule Brazil 1985 only - Nov 2 0:00 1 D +Rule Brazil 1986 only - Mar 15 0:00 0 S +Rule Brazil 1986 1987 - Oct Sat<=28 0:00 1 D +Rule Brazil 1987 only - Feb 14 0:00 0 S +Rule Brazil 1988 only - Feb 7 0:00 0 S +Rule Brazil 1989 only - Jan 22 0:00 0 S +Rule Brazil 1988 max - Oct Sun>=15 0:00 1 D +Rule Brazil 1990 max - Feb Sun>=8 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Noronha -2:09:40 - LMT 1914 + -2:00 - FST 1963 Dec 9 + -2:00 Brazil F%sT +Zone America/Sao_Paulo -3:06:28 - LMT 1914 + -3:00 Brazil E%sT +Zone America/Manaus -4:00:04 - LMT 1914 + -4:00 - WST 1963 Dec 9 + -4:00 Brazil W%sT +# Rio_Branco is too ambiguous, since there's a Rio Branco in Uruguay too. +Zone America/Porto_Acre -4:31:12 - LMT 1914 + -5:00 - AST 1963 Dec 9 + -5:00 Brazil A%sT +# +# Martin Vaz and Trinidade are like America/Noronha. + + +# Chile + +# From Guy Harris: +# The OAG lists October 11, 1987 and March 12, 1988 as the starting and +# ending dates, giving them as "estimated date(s) based on previous year." + +# From Bob Devine (January 28, 1988): +# Chile has had 2nd Sunday in October to 2nd Sunday in March DST since 1977. +# Switch is at midnight. OAG is right. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Chile 1918 only - Sep 1 0:00 1:00 D +Rule Chile 1919 only - Jul 2 0:00 0 S +Rule Chile 1927 1931 - Sep 1 0:00 1:00 D +Rule Chile 1928 1932 - Apr 1 0:00 0 S +Rule Chile 1969 max - Oct Sun>=8 0:00 1:00 D +Rule Chile 1970 max - Mar Sun>=8 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Santiago -4:42:40 - LMT 1890 + -4:43 - SMT 1910 # Santiago Mean Time + -5:00 Chile C%sT 1932 Sep + -4:00 Chile C%sT +Zone Pacific/Easter -7:17:28 - LMT 1890 # Mataveri + -7:17 - MMT 1932 Sep # Mataveri Mean Time + -7:00 Chile M%sT 1982 Mar 14 + -6:00 Chile C%sT +# +# Whitman says Juan Fernandez Is are like America/Santiago. +# San Ambrosio, San Felix +# no information; probably like America/Santiago + + +# Colombia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Bogota -4:56:20 - LMT 1884 Mar 13 + -4:56 - BMT 1914 Nov 23 # Bogota Mean Time + -5:00 - EST +# Malpelo, Providencia, San Andres +# no information; probably like America/Bogota + +# Curacao +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Curacao -4:35:44 - LMT 1912 Feb 12 # Willemstad + -4:30 - NAST 1965 # Netherlands Antilles + -4:00 - AST + +# Ecuador +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Guayaquil -5:19:20 - LMT 1890 + -5:14 - QMT 1931 # Quito Mean Time + -5:00 - EST +Zone Pacific/Galapagos -5:58:24 - LMT 1931 # Puerto Baquerizo Moreno + -5:00 - EST 1986 + -6:00 - CST + +# Falklands +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Falk 1912 only - Mar 12 0:00 0 S +Rule Falk 1937 1938 - Sep lastSun 0:00 1:00 D +Rule Falk 1938 1942 - Mar Sun>=19 0:00 0 S +Rule Falk 1939 only - Oct 1 0:00 1:00 D +Rule Falk 1940 1942 - Sep lastSun 0:00 1:00 D +Rule Falk 1943 only - Jan 1 0:00 0 S +Rule Falk 1983 only - Sep lastSun 0:00 1:00 D +Rule Falk 1984 1985 - Apr lastSun 0:00 0 S +Rule Falk 1984 only - Sep 16 0:00 1:00 D +Rule Falk 1985 max - Sep Sun>=9 0:00 1:00 D +Rule Falk 1986 max - Apr Sun>=16 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Stanley -3:51:24 - LMT 1890 + -3:51 - SMT 1912 Mar 12 # Stanley Mean Time + -4:00 Falk A%sT 1983 May + -3:00 Falk E%sT 1985 Sep 15 + -4:00 Falk A%sT + +# French Guiana +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Cayenne -3:29:20 - LMT 1911 Jul + -4:00 - AST 1967 Oct + -3:00 - EST + +# Guyana +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Guyana -3:52:40 - LMT 1915 Mar # Georgetown + -3:45 - BGST 1975 Jul 31 # British Guiana ST + -3:00 - EST + + +# Paraguay + +# From Bob Devine (January 28, 1988): +# Paraguay: First day in October to last in March. Midnight switch?? +# Since 1980. + +# From U. S. Naval Observatory (January 19, 1989): +# PARAGUAY 4 H BEHIND UTC +# PARAGUAY 3 H BEHIND UTC OCT 1, '88-MAR 31, '89 + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Para 1974 only - Apr 1 0:00 0 S +Rule Para 1975 1978 - Oct 1 0:00 1:00 D +Rule Para 1975 1978 - Mar 1 0:00 0 S +# Shanks says 1979 was all DST. +Rule Para 1980 max - Apr 1 0:00 0 S +Rule Para 1980 1988 - Oct 1 0:00 1:00 D +Rule Para 1989 only - Oct 22 0:00 1:00 D +Rule Para 1990 max - Oct 1 0:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Asuncion -3:50:40 - LMT 1890 + -3:51 - AMT 1931 Oct 10 # Asuncion Mean Time + -4:00 - AST 1972 Oct + -3:00 - EST 1974 Apr + -4:00 Para A%sT + +# Peru +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Peru 1908 only - Jul 28 0:00 0 S +Rule Peru 1938 only - Jan 1 0:00 1:00 D +Rule Peru 1938 only - Apr 1 0:00 0 S +Rule Peru 1938 1939 - Sep lastSun 0:00 1:00 D +Rule Peru 1939 1940 - Mar Sun>=24 0:00 0 S +Rule Peru 1987 only - Jan 1 0:00 1:00 D +Rule Peru 1987 only - Apr 1 0:00 0 S +Rule Peru 1990 only - Jan 1 0:00 1:00 D +Rule Peru 1990 only - Apr 1 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Lima -5:08:12 - LMT 1890 + -5:09 - LMT 1908 Jul 28 + -5:00 Peru E%sT + +# South Georgia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/South_Georgia -2:26:08 - LMT 1890 # Grytviken + -2:00 - FST + +# South Sandwich Is +# no information + +# Suriname +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Paramaribo -3:40:40 - LMT 1911 + -3:40:52 - PMT 1935 # Paramaribo Mean Time + -3:40:36 - PMT 1945 Oct # The capital moved? + -3:30 - DGST 1984 Oct # Dutch Guiana Std Time + -3:00 - EST + +# Trinidad and Tobago +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Port_of_Spain -4:06:04 - LMT 1912 Mar 2 + -4:00 - AST + +# Uruguay +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Uruguay wins the prize for the strangest peacetime manipulation of the rules. +# Your guess is as good as mine for what happened after 1989. +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Uruguay 1920 only - May 1 0:00 0 S +# Whitman gives 1923 Oct 1; go with Shanks. +Rule Uruguay 1923 only - Oct 2 0:00 0:30 HD +Rule Uruguay 1924 1926 - Apr 1 0:00 0 S +Rule Uruguay 1924 1925 - Oct 1 0:00 0:30 HD +Rule Uruguay 1933 1935 - Oct lastSun 0:00 0:30 HD +# Shanks gives 1935 Apr 1 0:00 and 1936 Mar 30 0:00; go with Whitman. +Rule Uruguay 1934 1936 - Mar Sat>=25 23:30s 0 S +Rule Uruguay 1936 only - Nov 1 0:00 0:30 HD +Rule Uruguay 1937 1941 - Mar lastSun 0:00 0 S +# Whitman gives 1937 Oct 3; go with Shanks. +Rule Uruguay 1937 1940 - Oct lastSun 0:00 0:30 HD +# Whitman gives 1941 Oct 24 - 1942 Mar 27, 1942 Dec 14 - 1943 Apr 13, +# and 1943 Apr 13 ``to present time''; go with Shanks. +Rule Uruguay 1941 only - Aug 1 0:00 0 S +Rule Uruguay 1942 only - Jan 1 0:00 0:30 HD +Rule Uruguay 1942 only - Dec 14 0:00 1:00 D +Rule Uruguay 1943 only - Mar 14 0:00 0 S +Rule Uruguay 1959 only - May 24 0:00 1:00 D +Rule Uruguay 1959 only - Nov 15 0:00 0 S +Rule Uruguay 1960 only - Jan 17 0:00 1:00 D +Rule Uruguay 1960 only - Mar 6 0:00 0 S +Rule Uruguay 1965 1967 - Apr Sun>=1 0:00 1:00 D +Rule Uruguay 1965 only - Sep 26 0:00 0 S +Rule Uruguay 1966 1967 - Oct 31 0:00 0 S +Rule Uruguay 1968 1970 - May 27 0:00 0:30 HD +Rule Uruguay 1968 1970 - Dec 2 0:00 0 S +Rule Uruguay 1972 only - Apr 24 0:00 1:00 D +Rule Uruguay 1972 only - Aug 15 0:00 0 S +Rule Uruguay 1974 only - Mar 10 0:00 0:30 HD +Rule Uruguay 1974 only - Dec 22 0:00 1:00 D +Rule Uruguay 1976 only - Oct 1 0:00 0 S +Rule Uruguay 1977 only - Dec 4 0:00 1:00 D +Rule Uruguay 1978 only - Apr 1 0:00 0 S +Rule Uruguay 1979 only - Oct 1 0:00 1:00 D +Rule Uruguay 1980 only - May 1 0:00 0 S +Rule Uruguay 1987 only - Dec 14 0:00 1:00 D +Rule Uruguay 1988 only - Mar 14 0:00 0 S +Rule Uruguay 1988 only - Dec 11 0:00 1:00 D +Rule Uruguay 1989 only - Mar 12 0:00 0 S +Rule Uruguay 1989 only - Oct 29 0:00 1:00 D +Rule Uruguay 1990 only - Mar 4 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 + -3:45 - MMT 1920 May 1 # Montevideo MT + -3:30 Uruguay U%sT 1942 Dec 14 # Uruguay ST + -3:00 Uruguay E%sT + +# Venezuela +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Caracas -4:27:44 - LMT 1890 + -4:28 - CMT 1912 Feb 12 # Caracas Mean Time + -4:30 - VZT 1965 # Venezuela Time + -4:00 - AST diff --git a/time/strftime.c b/time/strftime.c new file mode 100644 index 000000000..39f1aabd9 --- /dev/null +++ b/time/strftime.c @@ -0,0 +1,576 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)strftime.c 7.33"; +/* +** Based on the UCB version with the ID appearing below. +** This is ANSIish only when "multibyte character == plain character". +*/ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#include "private.h" + +/* +** Copyright (c) 1989 The Regents of the University of California. +** All rights reserved. +** +** Redistribution and use in source and binary forms are permitted +** provided that the above copyright notice and this paragraph are +** duplicated in all such forms and that any documentation, +** advertising materials, and other materials related to such +** distribution and use acknowledge that the software was developed +** by the University of California, Berkeley. The name of the +** University may not be used to endorse or promote products derived +** from this software without specific prior written permission. +** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#ifndef LIBC_SCCS +#ifndef lint +static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; +#endif /* !defined lint */ +#endif /* !defined LIBC_SCCS */ + +#include "tzfile.h" +#include "fcntl.h" +#if HAVE_SETLOCALE - 0 +#include "locale.h" +#endif /* HAVE_SETLOCALE - 0 */ + +struct lc_time_T { + const char * mon[12]; + const char * month[12]; + const char * wday[7]; + const char * weekday[7]; + const char * X_fmt; + const char * x_fmt; + const char * c_fmt; + const char * am; + const char * pm; + const char * date_fmt; +}; + +#ifdef LOCALE_HOME +static struct lc_time_T localebuf; +static struct lc_time_T * _loc P((void)); +#define Locale _loc() +#endif /* defined LOCALE_HOME */ +#ifndef LOCALE_HOME +#define Locale (&C_time_locale) +#endif /* !defined LOCALE_HOME */ + +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 + ** Since the C language standard calls for + ** "date, using locale's date format," anything goes. + ** Using just numbers (as here) makes Quakers happier; + ** it's also compatible with SVR4. + */ + "%m/%d/%y", + + /* + ** c_fmt + ** Note that + ** "%a %b %d %H:%M:%S %Y" + ** is used by Solaris 2.3. + */ + "%D %X", /* %m/%d/%y %H:%M:%S */ + + /* am */ + "AM", + + /* pm */ + "PM", + + /* date_fmt */ + "%a %b %e %H:%M:%S %Z %Y" +}; + +static char * _add P((const char *, char *, const char *)); +static char * _conv P((int, const char *, char *, const char *)); +static char *_fmt P((const char *, const struct tm *, char *, const char *)); + +size_t strftime P((char *, size_t, const char *, const struct tm *)); + +extern char * tzname[]; + +size_t +strftime(s, maxsize, format, t) +char * const s; +const size_t maxsize; +const char * const format; +const struct tm * const t; +{ + char * p; + + tzset(); +#ifdef LOCALE_HOME + localebuf.mon[0] = 0; +#endif /* defined LOCALE_HOME */ + p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize); + if (p == s + maxsize) + return 0; + *p = '\0'; + return p - s; +} + +static char * +_fmt(format, t, pt, ptlim) +const char * format; +const struct tm * const t; +char * pt; +const char * const ptlim; +{ + for ( ; *format; ++format) { + if (*format == '%') { +label: + switch (*++format) { + case '\0': + --format; + break; + case 'A': + pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? + "?" : Locale->weekday[t->tm_wday], + pt, ptlim); + continue; + case 'a': + pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? + "?" : Locale->wday[t->tm_wday], + pt, ptlim); + continue; + case 'B': + pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? + "?" : Locale->month[t->tm_mon], + pt, ptlim); + continue; + case 'b': + case 'h': + pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? + "?" : 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, 5/24/93) + */ + pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, + "%02d", pt, ptlim); + continue; + case 'c': + pt = _fmt(Locale->c_fmt, t, pt, ptlim); + continue; + case 'D': + pt = _fmt("%m/%d/%y", t, pt, ptlim); + continue; + case 'd': + pt = _conv(t->tm_mday, "%02d", pt, ptlim); + continue; + case 'E': + case 'O': + /* + ** POSIX locale extensions, a la + ** Arnold Robbins' strftime version 3.0. + ** The sequences + ** %Ec %EC %Ex %Ey %EY + ** %Od %oe %OH %OI %Om %OM + ** %OS %Ou %OU %OV %Ow %OW %Oy + ** are supposed to provide alternate + ** representations. + ** (ado, 5/24/93) + */ + goto label; + case 'e': + pt = _conv(t->tm_mday, "%2d", pt, ptlim); + 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, 5/24/93) + */ + 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, 5/24/93) + */ + 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 >= 12) ? + Locale->pm : + Locale->am, + pt, ptlim); + continue; + case 'R': + pt = _fmt("%H:%M", t, pt, ptlim); + continue; + case 'r': + pt = _fmt("%I:%M:%S %p", t, pt, ptlim); + continue; + case 'S': + pt = _conv(t->tm_sec, "%02d", pt, ptlim); + continue; + case 'T': + pt = _fmt("%H:%M:%S", t, pt, ptlim); + continue; + case 't': + pt = _add("\t", pt, ptlim); + continue; + case 'U': + pt = _conv((t->tm_yday + 7 - t->tm_wday) / 7, + "%02d", pt, ptlim); + continue; + case 'u': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "ISO 8601: Weekday as a decimal number + ** [1 (Monday) - 7]" + ** (ado, 5/24/93) + */ + pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday, + "%d", pt, ptlim); + continue; + case 'V': + /* + ** 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). The method for + ** determining the week number is as specified + ** by ISO 8601 (to wit: 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)." + ** (ado, 5/24/93) + */ + /* + ** XXX--If January 1 falls on a Friday, + ** January 1-3 are part of week 53 of the + ** previous year. By analogy, if January + ** 1 falls on a Thursday, are December 29-31 + ** of the PREVIOUS year part of week 1??? + ** (ado 5/24/93) + */ + /* + ** You are understood not to expect this. + */ + { + int i; + + i = (t->tm_yday + 10 - (t->tm_wday ? + (t->tm_wday - 1) : 6)) / 7; + if (i == 0) { + /* + ** What day of the week does + ** January 1 fall on? + */ + i = t->tm_wday - + (t->tm_yday - 1); + /* + ** Fri Jan 1: 53 + ** Sun Jan 1: 52 + ** Sat Jan 1: 53 if previous + ** year a leap + ** year, else 52 + */ + if (i == TM_FRIDAY) + i = 53; + else if (i == TM_SUNDAY) + i = 52; + else i = isleap(t->tm_year + + TM_YEAR_BASE) ? + 53 : 52; +#ifdef XPG4_1994_04_09 + /* + ** As of 4/9/94, though, + ** XPG4 calls for 53 + ** unconditionally. + */ + i = 53; +#endif /* defined XPG4_1994_04_09 */ + } + pt = _conv(i, "%02d", pt, ptlim); + } + continue; + case 'v': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "date as dd-bbb-YYYY" + ** (ado, 5/24/93) + */ + pt = _fmt("%e-%b-%Y", t, pt, ptlim); + continue; + case 'W': + pt = _conv((t->tm_yday + 7 - + (t->tm_wday ? + (t->tm_wday - 1) : 6)) / 7, + "%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); + continue; + case 'x': + pt = _fmt(Locale->x_fmt, t, pt, ptlim); + continue; + case 'y': + pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, + "%02d", pt, ptlim); + continue; + case 'Y': + pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", + pt, ptlim); + continue; + case 'Z': +#ifdef TM_ZONE + if (t->TM_ZONE != NULL) + pt = _add(t->TM_ZONE, pt, ptlim); + else +#endif /* defined TM_ZONE */ + if (t->tm_isdst == 0 || t->tm_isdst == 1) { + pt = _add(tzname[t->tm_isdst], + pt, ptlim); + } else pt = _add("?", pt, ptlim); + continue; + case '+': + pt = _fmt(Locale->date_fmt, t, pt, ptlim); + 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(n, format, pt, ptlim) +const int n; +const char * const format; +char * const pt; +const char * const ptlim; +{ + char buf[INT_STRLEN_MAXIMUM(int) + 1]; + + (void) sprintf(buf, format, n); + return _add(buf, pt, ptlim); +} + +static char * +_add(str, pt, ptlim) +const char * str; +char * pt; +const char * const ptlim; +{ + while (pt < ptlim && (*pt = *str++) != '\0') + ++pt; + return pt; +} + +#ifdef LOCALE_HOME +static struct lc_time_T * +_loc P((void)) +{ + static const char locale_home[] = LOCALE_HOME; + static const char lc_time[] = "LC_TIME"; + static char * locale_buf; + static char locale_buf_C[] = "C"; + + int fd; + int oldsun; /* "...ain't got nothin' to do..." */ + char * lbuf; + char * name; + char * p; + const char ** ap; + const char * plim; + char filename[FILENAME_MAX]; + struct stat st; + size_t namesize; + size_t bufsize; + + /* + ** Use localebuf.mon[0] to signal whether locale is already set up. + */ + if (localebuf.mon[0]) + return &localebuf; +#if HAVE_SETLOCALE - 0 + name = setlocale(LC_TIME, (char *) NULL); +#endif /* HAVE_SETLOCALE - 0 */ +#if !(HAVE_SETLOCALE - 0) + if ((name = getenv("LC_ALL")) == NULL || *name == '\0') + if ((name = getenv(lc_time)) == NULL || *name == '\0') + name = getenv("LANG"); +#endif /* !(HAVE_SETLOCALE - 0) */ + if (name == NULL || *name == '\0') + goto no_locale; + /* + ** If the locale name is the same as our cache, use the cache. + */ + lbuf = locale_buf; + if (lbuf != NULL && strcmp(name, lbuf) == 0) { + p = lbuf; + for (ap = (const char **) &localebuf; + ap < (const char **) (&localebuf + 1); + ++ap) + *ap = p += strlen(p) + 1; + return &localebuf; + } + /* + ** Slurp the locale file into the cache. + */ + namesize = strlen(name) + 1; + if (sizeof(filename) < + sizeof(locale_home) + namesize + sizeof(lc_time)) + goto no_locale; + oldsun = 0; + (void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time); + fd = open(filename, O_RDONLY); + if (fd < 0) { + /* + ** Old Sun systems have a different naming and data convention. + */ + oldsun = 1; + (void) sprintf(filename, "%s/%s/%s", locale_home, + lc_time, name); + fd = open(filename, O_RDONLY); + if (fd < 0) + goto no_locale; + } + if (fstat(fd, &st) != 0) + goto bad_locale; + if (st.st_size <= 0) + goto bad_locale; + bufsize = namesize + st.st_size; + locale_buf = NULL; + lbuf = (lbuf == NULL || lbuf == locale_buf_C) ? + malloc(bufsize) : realloc(lbuf, bufsize); + if (lbuf == NULL) + goto bad_locale; + (void) strcpy(lbuf, name); + p = lbuf + namesize; + plim = p + st.st_size; + if (read(fd, p, (size_t) st.st_size) != st.st_size) + goto bad_lbuf; + if (close(fd) != 0) + goto bad_lbuf; + /* + ** Parse the locale file into localebuf. + */ + if (plim[-1] != '\n') + goto bad_lbuf; + for (ap = (const char **) &localebuf; + ap < (const char **) (&localebuf + 1); + ++ap) { + if (p == plim) + goto bad_lbuf; + *ap = p; + while (*p != '\n') + ++p; + *p++ = '\0'; + } + if (oldsun) { + /* + ** SunOS 4 used an obsolescent format; see localdtconv(3). + ** c_fmt had the ``short format for dates and times together'' + ** (SunOS 4 date, "%a %b %e %T %Z %Y" in the C locale); + ** date_fmt had the ``long format for dates'' + ** (SunOS 4 strftime %C, "%A, %B %e, %Y" in the C locale). + ** Discard the latter in favor of the former. + */ + localebuf.date_fmt = localebuf.c_fmt; + } + /* + ** Record the successful parse in the cache. + */ + locale_buf = lbuf; + + return &localebuf; + +bad_lbuf: + free(lbuf); +bad_locale: + (void) close(fd); +no_locale: + localebuf = C_time_locale; + locale_buf = locale_buf_C; + return &localebuf; +} +#endif /* defined LOCALE_HOME */ diff --git a/time/systemv b/time/systemv new file mode 100644 index 000000000..a6f79d231 --- /dev/null +++ b/time/systemv @@ -0,0 +1,35 @@ +# @(#)systemv 7.2 + +# Old rules, should the need arise. +# No attempt is made to handle Newfoundland, since it cannot be expressed +# using the System V "TZ" scheme (half-hour offset), or anything outside +# North America (no support for non-standard DST start/end dates), nor +# the change in the DST rules in the US in 1987 (can't split between +# Canada, with no changes, and the US) +# +# Be sure to compile this *without* leap second correction for true conformance. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule SystemV min 1973 - Apr lastSun 2:00 1:00 D +Rule SystemV min 1973 - Oct lastSun 2:00 0 S +Rule SystemV 1974 only - Jan 6 2:00 1:00 D +Rule SystemV 1974 only - Nov lastSun 2:00 0 S +Rule SystemV 1975 only - Feb 23 2:00 1:00 D +Rule SystemV 1975 only - Oct lastSun 2:00 0 S +Rule SystemV 1976 max - Apr lastSun 2:00 1:00 D +Rule SystemV 1976 max - Oct lastSun 2:00 0 S + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone SystemV/AST4ADT -4:00 SystemV A%sT +Zone SystemV/EST5EDT -5:00 SystemV E%sT +Zone SystemV/CST6CDT -6:00 SystemV C%sT +Zone SystemV/MST7MDT -7:00 SystemV M%sT +Zone SystemV/PST8PDT -8:00 SystemV P%sT +Zone SystemV/YST9YDT -9:00 SystemV Y%sT +Zone SystemV/AST4 -4:00 - AST +Zone SystemV/EST5 -5:00 - EST +Zone SystemV/CST6 -6:00 - CST +Zone SystemV/MST7 -7:00 - MST +Zone SystemV/PST8 -8:00 - PST +Zone SystemV/YST9 -9:00 - YST +Zone SystemV/HST10 -10:00 - HST diff --git a/time/time2posix.3 b/time/time2posix.3 new file mode 100644 index 000000000..846a52ed1 --- /dev/null +++ b/time/time2posix.3 @@ -0,0 +1,119 @@ +.TH TIME2POSIX 3 +.SH NAME +time2posix, posix2time \- convert seconds since the Epoch +.SH SYNOPSIS +.nf +.B #include <sys/types.h> +.B #include <time.h> +.PP +.B time_t time2posix(t) +.B time_t t +.PP +.B time_t posix2time(t) +.B time_t t +.PP +.B cc ... -lz +.fi +.SH DESCRIPTION +IEEE Standard 1003.1 +(POSIX) +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 +seconds and, +therefore, +that the system time must be adjusted as each leap occurs. +.PP +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). +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 +to be +(mostly) +opaque\(emtime_t values should only be obtained-from and +passed-to functions such as +.IR time(2) , +.IR localtime(3) , +.IR mktime(3) , +and +.IR difftime(3) . +However, +POSIX gives an arithmetic +expression for directly computing a 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 +using such a relationship will typically not handle intervals +over leap seconds correctly. +.PP +The +.I time2posix +and +.I posix2time +functions are provided to address this time_t mismatch by converting +between local 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. +These converted values can then be used in lieu of correcting the older +applications, +or when communicating with POSIX-compliant systems. +.PP +.I Time2posix +is single-valued. +That is, +every local time_t +corresponds to a single POSIX time_t. +.I Posix2time +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 doesn't 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 a time +T and it's conversion to, +and back from, +the POSIX representation over the leap second inserted at the end of June, +1993. +.nf +.ta \w'93/06/30 'u +\w'23:59:59 'u +\w'A+0 'u +\w'X=time2posix(T) 'u +DATE TIME T X=time2posix(T) posix2time(X) +93/06/30 23:59:59 A+0 B+0 A+0 +93/06/30 23:59:60 A+1 B+1 A+1 or A+2 +93/07/01 00:00:00 A+2 B+1 A+1 or A+2 +93/07/01 00:00:01 A+3 B+2 A+3 + +A leap second deletion would look like... + +DATE TIME T X=time2posix(T) posix2time(X) +??/06/30 23:59:58 A+0 B+0 A+0 +??/07/01 00:00:00 A+1 B+2 A+1 +??/07/01 00:00:01 A+2 B+3 A+2 +.sp +.ce + [Note: posix2time(B+1) => A+0 or A+1] +.fi +.PP +If leap-second support is not enabled, +local time_t's and +POSIX time_t's are equivalent, +and both +.I time2posix +and +.I posix2time +degenerate to the identity function. +.SH SEE ALSO +difftime(3), +localtime(3), +mktime(3), +time(2) +.\" @(#)time2posix.3 7.3 diff --git a/time/tzfile.5 b/time/tzfile.5 new file mode 100644 index 000000000..1d4703384 --- /dev/null +++ b/time/tzfile.5 @@ -0,0 +1,123 @@ +.TH TZFILE 5 +.SH NAME +tzfile \- time zone information +.SH SYNOPSIS +.B +#include <tzfile.h> +.SH DESCRIPTION +The time zone information files used by +.IR tzset (3) +begin with bytes reserved for future use, +followed by four four-byte values of type +.BR long , +written in a ``standard'' byte order +(the high-order byte of the value is written first). +These values are, +in order: +.TP +.I tzh_ttisstdcnt +The number of standard/wall indicators stored in the file. +.TP +.I tzh_leapcnt +The number of leap seconds for which data is stored in the file. +.TP +.I tzh_timecnt +The number of "transition times" for which data is stored +in the file. +.TP +.I tzh_typecnt +The number of "local time types" for which data is stored +in the file (must not be zero). +.TP +.I tzh_charcnt +The number of characters of "time zone abbreviation strings" +stored in the file. +.PP +The above header is followed by +.I tzh_timecnt +four-byte values of type +.BR long , +sorted in ascending order. +These values are written in ``standard'' byte order. +Each is used as a transition time (as returned by +.IR time (2)) +at which the rules for computing local time change. +Next come +.I tzh_timecnt +one-byte values of type +.BR "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 +.I ttinfo +structures that appears next in the file; +these structures are defined as follows: +.in +.5i +.sp +.nf +.ta .5i +\w'unsigned int\0\0'u +struct ttinfo { + long tt_gmtoff; + int tt_isdst; + unsigned int tt_abbrind; +}; +.in -.5i +.fi +.sp +Each structure is written as a four-byte value for +.I tt_gmtoff +of type +.BR long , +in a standard byte order, followed by a one-byte value for +.I tt_isdst +and a one-byte value for +.IR tt_abbrind . +In each structure, +.I tt_gmtoff +gives the number of seconds to be added to GMT, +.I tt_isdst +tells whether +.I tm_isdst +should be set by +.I localtime (3) +and +.I tt_abbrind +serves as an index into the array of time zone abbreviation characters +that follow the +.I ttinfo +structure(s) in the file. +.PP +Then there are +.I tzh_leapcnt +pairs of four-byte values, written in standard byte order; +the first value of each pair gives the time +(as returned by +.IR time(2)) +at which a leap second occurs; +the second gives the +.I total +number of leap seconds to be applied after the given time. +The pairs of values are sorted in ascending order by time. +.PP +Finally there are +.I 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 +.I Localtime +uses the first standard-time +.I ttinfo +structure in the file +(or simply the first +.I ttinfo +structure in the absence of a standard-time structure) +if either +.I tzh_timecnt +is zero or the time argument is less than the first transition time recorded +in the file. +.SH SEE ALSO +newctime(3) +.\" @(#)tzfile.5 7.2 diff --git a/time/tzfile.h b/time/tzfile.h new file mode 100644 index 000000000..45b4d7d60 --- /dev/null +++ b/time/tzfile.h @@ -0,0 +1,170 @@ +#ifndef TZFILE_H + +#define TZFILE_H + +/* +** 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 7.4"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** Information about time zone files. +*/ + +#ifndef TZDIR +#define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */ +#endif /* !defined TZDIR */ + +#ifndef TZDEFAULT +#define TZDEFAULT "localtime" +#endif /* !defined TZDEFAULT */ + +#ifndef TZDEFRULES +#define TZDEFRULES "posixrules" +#endif /* !defined TZDEFRULES */ + +/* +** Each file begins with. . . +*/ + +struct tzhead { + char tzh_reserved[24]; /* reserved for future use */ + 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 GMT 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 +*/ + +/* +** In the current implementation, "tzset()" refuses to deal with files that +** exceed any of the limits below. +*/ + +#ifndef TZ_MAX_TIMES +/* +** The TZ_MAX_TIMES value below is enough to handle a bit more than a +** year's worth of solar time (corrected daily to the nearest second) or +** 138 years of Pacific Presidential Election time +** (where there are three time zone transitions every fourth year). +*/ +#define TZ_MAX_TIMES 370 +#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 +#define TZ_MAX_TYPES 10 /* 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 + +/* +** Accurate only for the past couple of centuries; +** that will probably do. +*/ + +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) + +#ifndef USG + +/* +** Use of the underscored variants may cause problems if you move your code to +** certain System-V-based systems; for maximum portability, use the +** underscore-free variants. The underscored variants are provided for +** backward compatibility only; they may disappear from future versions of +** this file. +*/ + +#define SECS_PER_MIN SECSPERMIN +#define MINS_PER_HOUR MINSPERHOUR +#define HOURS_PER_DAY HOURSPERDAY +#define DAYS_PER_WEEK DAYSPERWEEK +#define DAYS_PER_NYEAR DAYSPERNYEAR +#define DAYS_PER_LYEAR DAYSPERLYEAR +#define SECS_PER_HOUR SECSPERHOUR +#define SECS_PER_DAY SECSPERDAY +#define MONS_PER_YEAR MONSPERYEAR + +#endif /* !defined USG */ + +#endif /* !defined TZFILE_H */ diff --git a/time/usno1988 b/time/usno1988 new file mode 100644 index 000000000..dcb72834e --- /dev/null +++ b/time/usno1988 @@ -0,0 +1,111 @@ +# @(#)usno1988 7.1 +# +# From Arthur David Olson (January 19, 1989): +# +# Here's some United States Naval Observatory time zone data from +# February 1988. It's here mostly to convince you that the USNO has indeed +# been updating its files (see its 1989 data elsewhere). +# +ANDORRA 1 H AHEAD OF UTC +ARGENTINA 3 H BEHIND UTC +BRASIL WEST 5 H BEHIND UTC (CRUZEIRO DO SUL) +BRASIL CENTRAL 4 H BEHIND UTC (MANAUS) +BRASIL EAST 3 H BEHIND UTC COASTAL STATES, RIO, SP, BRASILIA +BRASIL 2 H BEHIND UTC ATLANTIC ISLANDS +BRAZIL 5 H BEHIND UTC WEST (CRUZEIRO DO SUL) +BRAZIL 4 H BEHIND UTC CENTRAL (MANAUS) +BRAZIL 3 H BEHIND UTC COASTAL STATES, RIO, SP, BRASILIA +BRAZIL 3 H BEHIND UTC FOR MOST MAJOR AIRPORTS. +BRAZIL 2 H BEHIND UTC ATLANTIC ISLANDS +BULGARIA 2 H AHEAD OF UTC WINTER +BULGARIA 3 H AHEAD OF UTC SUMMER MAR31 - SEP 85, 0100 LOCAL +CHINA 8 H AHEAD OF UTC; ALL OF CHINA, INCL TAIWAN +CUBA 5 H BEHIND UTC IN WINTER +CUBA 4 H BEHIND UTC MAY 8 - OCT 8 +CYPRUS 2 H AHEAD UTC IN WINTER +CYPRUS 3 H AHEAD UTC MAR 25 - SEP 30 +DENMARK 1 H AHEAD UTC IN WINTER +DENMARK 2 H AHEAD UTC MAR 31 - SEP 30 , 0200 LOCAL +DENMK. FAEROE IS 1 H AHEAD UTC MAR 31 - SEP 30 , 0200 LOCAL +EGYPT 2 H AHEAD UTC +EGYPT 3 H AHEAD UTC SUMMER (AFTER RAMADAN) +ENGLAND ON UTC IN WINTER; WALES, SCOTLAND, N.I., CH.IS. +ENGLAND 1 H AHEAD OF UTC; SUMMER TIL 28 OCT 0200 LOCAL +FINLAND 2 H AHEAD OF UTC IN WINTER +FINLAND 3 H AHEAD OF UTC MAR 25 - SEP 30 +FRANCE 1 H AHEAD OF UTC IN WINTER +FRANCE 2 H AHEAD OF UTC MAR 31 - SEP 30 , 0100 LOCAL +GREECE 2 H AHEAD OF UTC IN WINTER +GREECE 3 H AHEAD OF UTC IN SUMMER EFF. 31MAR85 02/03 LOCAL +GREECE 3 H AHEAD OF UTC MAR 25 - SEP 30 +GREENLAND 4 H BEHIND UTC IN THULE AIRBASE YEAR ROUND +GREENLAND 3 H BEHIND UTC IN WINTER AT SONDRESTROM +GREENLAND 2 H BEHIND UTC 30 MAR - 30 SEP 2200 LOCAL AT -"- +GREENLAND 2 H BEHIND UTC AROUND SCORESBY SUND +ICELAND ON UTC +IRAN 3.5H AHEAD OF UTC +IRELAND ON UTC IN WINTER +IRELAND 1 H AHEAD OF UTC MAR 31 - OCT 23 0200 LOCAL +ITALY 1 H AHEAD OF UTC IN WINTER +ITALY 2 H AHEAD OF UTC MAR 31 - SEP 30, 0030 LOCAL +JAMAICA 5 H BEHIND UTC IN WINTER +JAMAICA 4 H BEHIND UTC APR 29 - OCT 29 +LIBYA 2 H AHEAD OF UTC +MEXICO BAJA CAL N 8 H BEHIND UTC IN WINTER; NORTH BAJA CAL, TIJUANA +MEXICO BAJA CAL N 7 H BEHIND UTC APR 29 - OCT 29 +MEXICO BAJA CAL S 7 H BEHIND UTC ALL YEAR; MAZATLAN +MEXICO CENTRAL 6 H BEHIND UTC ALL YEAR; MEXICO CITY +MONACO 1 H AHEAD UTC IN WINTER +MONACO 2 H AHEAD UTC MAR 25 - SEP30 +PARAGUAY 4 H BEHIND UTC IN WINTER +PARAGUAY 3 H BEHIND UTC SEP 30 - MAR 30 +POLAND 1 H AHEAD OF UTC IN WINTER +POLAND 2 H AHEAD OF UTC MAR 24 - SEP 0200 LOCAL +PORTUGAL ON UTC IN WINTER +PORTUGAL 1 H AHEAD OF UTC IN SUMMER MAR 31 - SEP 29 0100 LOCAL +PORTUGAL AZORES 1 H BEHIND UTC IN WINTER +PORTUGAL AZORES ON UTC IN SUMMER MAR 31 - SEP 29 +PORTUGAL MADEIRA ON UTC ALL YEAR; +ROMANIA 2 H AHEAD OF UTC IN WINTER +ROMANIA 3 H AHEAD OF UTC APR 3 - SEP 24 +SCOTLAND SEE ENGLAND +SWITZERLAND 1 H AHEAD OF UTC IN WINTER +SWITZERLAND 2 H AHEAD OF UTC MAR 31 - SEP 30 0200 LOCAL +TURKEY 3 H AHEAD OF UTC +USA EASTERN 5 H BEHIND UTC IN WINTER; NEW YORK, WASHINGTON +USA EASTERN 4 H BEHIND UTC APR 29 - OCT 29 +USA CENTRAL 6 H BEHIND UTC IN WINTER; CHICAGO, HOUSTON +USA CENTRAL 5 H BEHIND UTC APR 29 - OCT 29 +USA MOUNTAIN 7 H BEHIND UTC IN WINTER; DENVER +USA MOUNTAIN 6 H BEHIND UTC APR 29 - OCT 29 +USA PACIFIC 8 H BEHIND UTC IN WINTER; L.A., SAN FRANCISCO +USA PACIFIC 7 H BEHIND UTC APR 29 - OCT 29 +USA ALASKA STD 9 H BEHIND UTC IN WINTER; MOST OF ALASKA (AKST) +USA ALASKA STD 8 H BEHIND UTC APR 29 - OCT 29 (AKDT) +USA ALEUTIAN 10 H BEHIND UTC IN WINTER; ISLANDS WEST OF 170W +USA - " - 9 H BEHIND UTC APR 29 - OCT 29 +USA HAWAII 10 H BEHIND UTC ALL YEAR; +USA BERING 11 H BEHIND UTC ALL YEAR; SAMOA, MIDWAY +USSR WEST EUROP 3 H AHEAD OF UTC IN WINTER; LENINGRAD, MOSCOW +USSR WEST EUROP 4 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL EUR 4 H AHEAD OF UTC IN WINTER; ROSTOV, BAKU +USSR CENTRAL EUR 5 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST EUROP 5 H AHEAD OF UTC IN WINTER; SVERDLOVSK +USSR EAST EUROP 6 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST SIBERIAN 6 H AHEAD OF UTC IN WINTER; TASHKENT, ALMA ATA +USSR WEST SIBERIAN 7 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 7 H AHEAD OF UTC IN WINTER; NOVOSIBIRSK +USSR WEST-CENTRAL 8 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 8 H AHEAD OF UTC IN WINTER; IRKUTSK +USSR WEST-CENTRAL 9 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 9 H AHEAD OF UTC IN WINTER; YAKUTSK +USSR CENTRAL SIB 10 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 10 H AHEAD OF UTC IN WINTER; VLADIVOSTOK +USSR CENTRAL SIB 11 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 11 H AHEAD OF UTC IN WINTER; MAGADAN +USSR EAST SIBERIA 12 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 12 H AHEAD OF UTC IN WINTER; PETROPAVLOVSK +USSR EAST SIBERIA 13 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 13 H AHEAD OF UTC IN WINTER; UELEN +USSR EAST SIBERIA 14 H AHEAD OF UTC APR 1 - SEP 30 +WALES SEE ENGLAND diff --git a/time/usno1989 b/time/usno1989 new file mode 100644 index 000000000..91a69c6fd --- /dev/null +++ b/time/usno1989 @@ -0,0 +1,452 @@ +# @(#)usno1989 7.1 +# +# From Arthur David Olson (January 19, 1989): +# +# Here's time zone information from the United States Naval Observatory; +# no corrections have been made, and there are some obvious challenges. +# The USNO warns: +# DUE TO FREQUENT CHANGES IN THE LOCAL LAWS GOVERNING DAYLIGHT +# SAVING TIME, WE CANNOT GUARANTEE THE ACCURACY OF THIS +# INFORMATION. PLEASE ALERT US TO ANY DISCREPANCY YOU MAY +# DISCOVER. +# +AFGHANISTAN 4.5H AHEAD OF UTC +ALBANIA 1 H AHEAD OF UTC +ALBANIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ALBANIA (ESTIMATED) +ALGERIA 1 H AHEAD OF UTC +AMERICAN SAMOA 11 H BEHIND UTC +ANDORRA 1 H AHEAD OF UTC +ANDORRA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ANDORRA (ESTIMATED) +ANGOLA 1 H AHEAD OF UTC +ARGENTINA 3 H BEHIND UTC +ARUBA 4 H BEHIND UTC ALSO BONAIRE, CURACAO, +ARUBA ST.MAARTEN +AUSTRALIA WEST 8 H AHEAD OF UTC PERTH, EXMOUTH +AUSTRALIA N.T. 9.5H AHEAD OF UTC DARWIN NO ADVANCED TIME +AUSTRALIA N.T. IN SUMMER +AUSTRALIA SOUTH 9.5H AHEAD OF UTC ADELAIDE +AUSTRALIA INCLUDING BROKEN HILL, NSW +AUSTRALIA SOUTH 10.5H AHEAD OF UTC ADELAIDE OCT 30, '88-MAR +AUSTRALIA SOUTH 18, '89 INCLUDING BROKEN +AUSTRIALIA SOUTH HILL, NSW +AUSTRALIA QUEENL 10 H AHEAD OF UTC +AUSTRALIA NSW 10 H AHEAD OF UTC SYDNEY +AUSTRALIA NSW 11 H AHEAD OF UTC SYDNEY OCT 30, '88-MAR 18, +AUSTRALIA NSW '89 +AUSTRALIA TASM. 10 H AHEAD OF UTC HOBART +AUSTRALIA TASM. 11 H AHEAD OF UTC HOBART OCT 30, '88-MAR 18, +AUSTRALIA TASM. '89 +AUSTRIA 1 H AHEAD OF UTC +AUSTRIA 2 H AHEAD OF UTC MAR 27 - SEPT 24 +AZORES SEE PORTUGAL +BAHAMAS 5 H BEHIND UTC EXCLUDING TURKS AND CAICOS +BAHAMAS ISLANDS) +BAHAMAS 4 H BEHIND UTC APR 3 - OCT 29 (SAME +BAHAMAS EXCLUSION) +BAHRAIN 3 H AHEAD OF UTC +BANGLADESH 6 H AHEAD OF UTC +BARBADOS 4 H BEHIND UTC +BELGIUM 1 H AHEAD OF UTC +BELGIUM 2 H AHEAD OF UTC MAR 27 - SEP 24 +BELIZE 6 H BEHIND UTC +BENIN PEOPLES REP 1 H AHEAD OF UTC DAHOMEY +BERMUDA 4 H BEHIND UTC +BERMUDA 3 H BEHIND UTC APR 3 - OCT 29 +BHUTAN 6 H AHEAD OF UTC +BOLIVIA 4 H BEHIND UTC +BONAIRE 4 H BEHIND UTC ALSO ARUBA,CURACAO, +BONAIRE ST.MAARTEN, SABA +BOTSWANA 2 H AHEAD OF UTC +BRAZIL WEST 5 H BEHIND UTC TERRITORY OF ACRE +BRAZIL WEST 4 H BEHIND UTC ACRE OCT 23, '88-FEB 11, +BRAZIL '89 (ESTIMATED) +BRAZIL CENTRAL 4 H BEHIND UTC MANAUS +BRAZIL CENTRAL 3 H BEHIND UTC MANAUS OCT 23, '88-FEB 11, +BRAZIL CENTRAL '89 (ESTIMATED) +BRAZIL EAST 3 H BEHIND UTC COASTAL STATES, RIO, SAO +BRAZIL EAST PAULO, BRASILIA +BRAZIL EAST 2 H BEHIND UTC COASTAL STATES, RIO, SAO +BRAZIL PAULO, BRASILIA OCT 23, +BRAZIL '88-FEB 11, '89 +BRAZIL (ESTIMATED) +BRAZIL 2 H BEHIND UTC ATLANTIC ISLANDS, FERNANDO +BRAZIL DE NORONHA +BRAZIL 1 H BEHIND UTC OCT 23, '88-FEB 11, '89 +BRAZIL (ESTIMATED) +BRAZIL 3 H BEHIND UTC FOR MOST MAJOR AIRPORTS. +BRITISH VIRGIN I. 4 H BEHIND UTC +BRUNEI 8 H AHEAD OF UTC +BULGARIA 2 H AHEAD OF UTC +BULGARIA 3 H AHEAD OF UTC MAR 27 - SEP 24 +BURKINA FASO ON UTC +BURMA 6.5H AHEAD OF UTC +BURUNDI 2 H AHEAD OF UTC +CAMBODIA SEE KAMPUCHEA +CAMEROON 1 H AHEAD OF UTC +CANADA NEW FDL 3.5H BEHIND UTC ST.JOHN'S +CANADA NEW FDL 1.5H BEHIND UTC APR 3 - OCT 29 +CANADA ATLANTIC 4 H BEHIND UTC HALIFAX +CANADA ATLANTIC 3 H BEHIND UTC APR 3 - OCT 29 +CANADA EASTERN 5 H BEHIND UTC TORONTO, MONTREAL, OTTAWA +CANADA EASTERN 4 H BEHIND UTC APR 3 - OCT 29 +CANADA CENTRAL 6 H BEHIND UTC REGINA, WINNIPEG +CANADA CENTRAL 5 H BEHIND UTC APR 3 - OCT 29 +CANADA MOUNTAIN 7 H BEHIND UTC CALGARY, EDMONTON +CANADA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 29 +CANADA PACIFIC 8 H BEHIND UTC VANCOUVER +CANADA PACIFIC 7 H BEHIND UTC APR 3 - OCT 29 +CANADA YUKON SAME AS PACIFIC DAWSON +CAPE VERDE 1 H BEHIND UTC +CAYMAN ISLANDS 5 H BEHIND UTC +CAROLINE ISLAND 10 H AHEAD OF UTC EXCLUDING PONAPE IS., +CAROLINE ISLAND KUSAIE, AND PINGELAP +CENTRAL AFRICA 1 H AHEAD OF UTC +CEYLON 5.5H AHEAD OF UTC, SEE SRI LANKA +CHAD 1 H AHEAD OF UTC +CHANNEL ISLANDS SEE ENGLAND +CHILE 4 H BEHIND UTC CONTINENTAL +CHILE 3 H BEHIND UTC OCT 9, '88-MAR 11, '89 +CHILE 6 H BEHIND UTC EASTER ISLAND +CHILE 5 H BEHIND UTC OCT 9, '88-MAR 11, '89 +CHINA 8 H AHEAD OF UTC ALL OF CHINA, INCL TAIWAN +CHINA 9 H AHEAD OF UTC APR 17 - SEP 10 +COCOS (Keeling) I. 6.5H AHEAD OF UTC +COLOMBIA 5 H BEHIND UTC +COMOROS 3 H AHEAD OF UTC +CONGO 1 H AHEAD OF UTC +COOK ISLANDS 10 H BEHIND UTC +COOK ISLANDS 9.5H BEHIND UTC OCT 30, '88-MAR 24, '89 +COOK ISLANDS (ESTIMATED) +COSTA RICA 6 H BEHIND UTC +COTE D'IVOIRE ON UTC +CUBA 5 H BEHIND UTC +CUBA 4 H BEHIND UTC MAR 20 - OCT 8 +CURACAO 4 H BEHIND UTC ALSO BONAIRE, ARUBA, +CURACAO ST.MAARTEN +CYPRUS 2 H AHEAD OF UTC +CYPRUS 3 H AHEAD OF UTC MAR 27 - SEP 24 +CZECHOSLOVAKIA 1 H AHEAD OF UTC +CZECHOSLOVAKIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +DENMARK 1 H AHEAD OF UTC +DENMARK 2 H AHEAD OF UTC MAR 27 - SEP 24 +DENMK. FAEROE IS 1 H AHEAD OF UTC MAR 27 - SEP 24 +DJIBOUTI 3 H AHEAD OF UTC +DOMINICA 4 H BEHIND UTC +DOMINICAN REP 4 H BEHIND UTC +ECUADOR 5 H BEHIND UTC CONTINENTAL +ECUADOR 6 H BEHIND UTC GALAPAGOS ISLANDS +EGYPT 2 H AHEAD OF UTC +EGYPT 3 H AHEAD OF UTC MAY 17 - SEP 30 (AFTER +EGYPT RAMADAN) +EL SALVADOR 6 H BEHIND UTC +ENGLAND ON UTC (WALES, SCOTLAND, N.I., +ENGLAND CH. IS.) +ENGLAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +ENEZUELA 4 H BEHIND UTC +EQUITORIAL GUINEA 1 H AHEAD OF UTC +ETHIOPIA 3 H AHEAD OF UTC +FALKLAND ISLANDS 4 H BEHIND UTC +FALKLAND ISLANDS 3 H BEHIND UTC SEP 11, '88-APR 15, '89 +FALKLAND ISLANDS (ESTIMATED) +FAROE ISLAND ON UTC +FAROE ISLAND 1 H AHEAD OF UTC MAR 27 - SEP 24 +FIJI 12 H AHEAD OF UTC +FINLAND 2 H AHEAD OF UTC +FINLAND 3 H AHEAD OF UTC MAR 27 - SEP 24 +FRANCE 1 H AHEAD OF UTC +FRANCE 2 H AHEAD OF UTC MAR 27 - SEP 24 +FRENCH GUIANA 3 H BEHIND UTC +FRENCH POLYNESIA 9 H BEHIND UTC GAMBIER ISLAND +FRENCH POLYNESIA 9.5H BEHIND UTC MARQUESAS ISLANDS +FRENCH POLYNESIA 10 H BEHIND UTC SOCIETY ISLANDS, TUBUAI +FRENCH POLYNESIA ISLANDS, TUAMOTU ISLAND, +FRENCH POLYNESIA TAHITI +GABON 1 H AHEAD OF UTC +GAMBIA ON UTC +GERMANY ALL 1 H AHEAD OF UTC +GERMANY ALL 2 H AHEAD OF UTC MAR 27 - SEP 24 +GHANA ON UTC +GIBRALTAR 1 H AHEAD OF UTC +GIBRALTAR 2 H AHEAD OF UTC MAR 27 - SEP 24 +GREECE 2 H AHEAD OF UTC +GREECE 3 H AHEAD OF UTC MAR 27 - SEP 24 +GREENLAND 4 H BEHIND UTC THULE AIRBASE YEAR ROUND +GREENLAND 3 H BEHIND UTC ANGMAGSSALIK AND W. COAST +GREENLAND 2 H BEHIND UTC MAR 27 - SEP 24 +GREENLAND 1 H BEHIND UTC SCORESBYSUND +GREENLAND ON UTC MAR 27 - SEP 24 +GRENADA 4 H BEHIND UTC +GUADELOUPE 4 H BEHIND UTC ST. BARTHELEMY, NORTHERN +GUADELOUPE ST. MARTIN MARTINIQUE +GUAM 10 H AHEAD OF UTC +GUATEMALA 6 H BEHIND UTC +GUINEA ON UTC +GUINEA BISSAU ON UTC +GUINEA REPUBLIC ON UTC +GUINEA EQUATORIAL 1 H AHEAD OF UTC +GUYANA 3 H BEHIND UTC +HAITI 5 H BEHIND UTC +HAITI 4 H BEHIND UTC APR 3 - OCT 29 +HOLLAND SEE NETHERLANDS +HONDURAS 6 H BEHIND UTC +HONG KONG 8 H AHEAD OF UTC +HUNGARY 1 H AHEAD OF UTC +HUNGARY 2 H AHEAD OF UTC MAR 27 - SEP 24 +ICELAND ON UTC +INDIA 5.5H AHEAD OF UTC INCLUDING ANDAMAN ISLANDS +INDONESIA WEST 7 H AHEAD OF UTC SUMATRA, JAVA, BALI, +INDONESIA WEST JAKARTA +INDONESIA CENTRAL 8 H AHEAD OF UTC KALIMANTAN, SULAWESI +INDONESIA EAST 9 H AHEAD OF UTC IRIAN, BARAT +IRAN 3.5H AHEAD OF UTC +IRAQ 3 H AHEAD OF UTC +IRAQ 4 H AHEAD OF UTC APR 1 - SEP 30 +IRELAND ON UTC +IRELAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +ISRAEL 2 H AHEAD OF UTC +ISRAEL 3 H AHEAD OF UTC APR 10 - SEP 3 +ITALY 1 H AHEAD OF UTC +ITALY 2 H AHEAD OF UTC MAR 27 - SEP 24 +IVORY COAST ON UTC +IWAN 8 H AHEAD OF UTC +JAMAICA 5 H BEHIND UTC +JAPAN 9 H AHEAD OF UTC +JOHNSTON ISLAND 10 H BEHIND UTC +JORDAN 2 H AHEAD OF UTC +JORDAN 3 H AHEAD OF UTC APR 1 - OCT 6 +KAMPUCHEA 7 H AHEAD OF UTC +KENYA 3 H AHEAD OF UTC +KIRIBATI, REP OF 12 H AHEAD OF UTC CANTON, ENDERBURY ISLANDS +KIRIBATI, REP OF 11 H AHEAD OF UTC CHRISTMAS ISLAND +KOREA 9 H AHEAD OF UTC +KOREA, REP OF 9 H AHEAD OF UTC +KOREA, REP OF 10 H AHEAD OF UTC MAY 8 - OCT 8 +KUWAIT 3 H AHEAD OF UTC +KUSAIE, PINGELAP 12 H AHEAD OF UTC INCLUDING MARSHALL IS., +KUSAIE, PINGELAP EXCLUDING KWAJALEIN) +KWAJALEIN 12 H BEHIND UTC +LAOS 7 H AHEAD OF UTC +LEBANON 2 H AHEAD OF UTC +LEBANON 3 H AHEAD OF UTC JUN 1 - OCT 31 +LEEWARD ISLANDS 4 H BEHIND UTC ANTIGUA, DOMINICA, +LEEWARD ISLANDS MONTSERRAT, ST. +LEEWARD ISLAANDS CHRISTOPHER, ST. KITTS, +LEEWARD ISLANDS NEVIS, ANGUILLA +LESOTHO 2 H AHEAD OF UTC +LIBERIA ON UTC +LIBYAN ARAB 1 H AHEAD OF UTC JAMAHIRIYA/LIBYA +LIBYAN ARAB 2 H AHEAD OF UTC APR 1 - SEP 30 JAMAHIRIYA/LIBYA +LIECHTENSTEIN 1 H AHEAD OF UTC +LIECHTENSTEIN 2 H AHEAD OF UTC MAR 27 - SEP 24 +LUXEMBOURG 1 H AHEAD OF UTC +LUXEMBOURG 2 H AHEAD OF UTC MAR 27 - SEP 24 +MACAO 8 H AHEAD OF UTC +MADAGASCAR 3 H AHEAD OF UTC +MADEIRA SEE PORTUGAL +MALAWI 2 H AHEAD OF UTC +MALAYSIA 8 H AHEAD OF UTC +MALDIVES 5 H AHEAD OF UTC +MALI ON UTC +MALTA 1 H AHEAD OF UTC +MALTA 2 H AHEAD OF UTC MAR 27 - SEP 24 +MARTINIQUE 4 H BEHIND UTC +MAURITANIA ON UTC +MAURITIUS 4 H AHEAD OF UTC +MARIANA ISLAND 10 H AHEAD OF UTC EXCLUDING GUAM +MEXICO BAJA CAL N 7 H BEHIND UTC BAJA CALIFORNIA SUR AND +MEXICO BAJA CAL N N. PACIFIC COAST (STATES +MEXICO BAJA CAL N OF SINALOA AND SONORA) +MEXICO BAJA CAL N 8 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +MEXICO BAJA CAL N - OCT 29 +MEXICO BAJA CAL N 7 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +MEXICO BAJA CAL N - 0CT 29 +MEXICO 6 H BEHIND UTC STATES OF DURANGO, +MEXICO COAHUILA, NUEVO LEON, +MEXICO TAMAULIPAS +MEXICO 5 H BEHIND UTC STATES OF DURANGO, +MEXICO COAHUILA, NUEVO LEON, +MEXICO TAMAULIPAS APR 3 - OCT 29 +MEXICO 6 H BEHIND UTC GENERAL MEXICO, STATES OF +MEXICO CAMPECHE, QUINTANA ROO AND +MEXICO YUCATAN +MIDWAY ISLAND 11 H BEHIND UTC +MONACO 1 H AHEAD OF UTC +MONACO 2 H AHEAD OF UTC MAR 27 - SEP 24 +MONGOLIA 8 H AHEAD OF UTC +MONGOLIA 9 H AHEAD OF UTC MAR 27 - SEP 24 +MONTSERRAT 4 H BEHIND UTC +MOROCCO ON UTC +MOZAMBIQUE 2 H AHEAD OF UTC +NAMIBIA 2 H AHEAD OF UTC +NAURU, REP OF 12 H AHEAD OF UTC +NEPAL 5H45M AHEAD OF UTC +NETHERLANDS 1 H AHEAD OF UTC +NETHERLANDS 2 H AHEAD OF UTC MAR 27 - SEP 24 +NETHERLANDS 4 H BEHIND UTC ANTILLES AND SOUTHERN ST. +NETHERLANDS MAARTEN +NEW CALEDONIA 11 H AHEAD OF UTC +NEW HEBRIDES SEE VANUATU +NEW ZEALAND 12 H AHEAD OF UTC (EXCLUDING CHATHAM ISLAND) +NEW ZEALAND 13 H AHEAD OF UTC OCT 30, '88-MAR 4, '89 +NEW ZEALAND 12H45M AHEAD OF UTC CHATHAM ISLAND +NICARAGUA 6 H BEHIND UTC +NIGER 1 H AHEAD OF UTC +NIGERIA 1 H AHEAD OF UTC +NIUE ISLAND 11 H BEHIND UTC +NORFOLK ISLAND 11H30M AHEAD OF UTC +NORTHERN IRELAND ON UTC WALES, SCOTLAND, N.I., +NORTHERN IRELAND CH.IS. +NORTHERN IRELAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +NORWAY 1 H AHEAD OF UTC +NORWAY 2 H AHEAD OF UTC MAR 27 - SEP 24 +OGO ON UTC +OMAN 4 H AHEAD OF UTC +PACIFIC ISLAND T.T. +PALAU ISLAND 9 H AHEAD OF UTC +PAKISTAN 5 H AHEAD OF UTC +PANAMA 5 H BEHIND UTC +PAPUA NEW GUINEA 10 H AHEAD OF UTC INCLUDING BOUGAINVILLE +PAPUA NEW GUINEA ISLAND +PARAGUAY 4 H BEHIND UTC +PARAGUAY 3 H BEHIND UTC OCT 1, '88-MAR 31, '89 +PERU 5 H BEHIND UTC +PHILIPPINES 8 H AHEAD OF UTC +PONAPE ISLAND 11 H AHEAD OF UTC +POLAND 1 H AHEAD OF UTC +POLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +PORTUGAL MAINLAND ON UTC +PORTUGAL MAINLAND 1 H AHEAD OF UTC MAR 27 - SEP 24 +PORTUGAL AZORES 1 H BEHIND UTC +PORTUGAL AZORES ON UTC MAR 27 - SEP 24 +PORTUGAL MADEIRA ON UTC +PORTUGAL MADEIRA 1 H AHEAD OF UTC MAR 27 - SEP 24 +PUERTO RICO 4 H BEHIND UTC +QATAR 3 H AHEAD OF UTC +ROMANIA 2 H AHEAD OF UTC +ROMANIA 3 H AHEAD OF UTC MAR 27 - SEP 24 +RUSSIA SEE USSR +RWANDA 2 H AHEAD OF UTC +SABA 4 H BEHIND UTC ALSO BONAIRE, CURACAO, +SAMOA 11 H BEHIND UTC +SAN MARINO 1 H AHEAD OF UTC +SAN MARINO 2 H AHEAD OF UTC MAR 27 - SEP 24 +SAN SALVADOR 6 H BEHIND UTC +SAO TOME ISLAND ON UTC AND PRINCIPE ISLAND +SAUDI ARABIA 3 H AHEAD OF UTC +SCOTLAND SEE ENGLAND +SENEGAL ON UTC +SEYCHELLES 4 H AHEAD OF UTC +SIERRA LEONE ON UTC +SINGAPORE 8 H AHEAD OF UTC +SOLOMON ISLANDS 11 H AHEAD OF UTC EXCLUDING BOUGAINVILLE +SOLOMON ISLANDS ISLAND +SOMALI 3 H AHEAD OF UTC +SOUTH AFRICA 2 H AHEAD OF UTC +SPAIN CANARY IS ON UTC +SPAIN CANARY IS 1 H AHEAD OF UTC MAR 27 - SEP 24 +SPAIN 1 H AHEAD OF UTC CONTINENTAL, BALEARIC AND +SPAIN MALLORCA ISLANDS +SPAIN 2 H AHEAD OF UTC CONTINENTAL, BALEARIC AND +SPAIN MALLORCA ISLANDS MAR 27 - +SPAIN SEP 24 +SPAIN MAINLAND 1 H AHEAD OF UTC MELILLA +SPAIN MAINLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +SRI LANKA 5H30M AHEAD OF UTC +ST.MAARTEN +ST.KITTS-NEVIS 4 H BEHIND UTC +ST.LUCIA 4 H BEHIND UTC +ST.PIERRE 3 H BEHIND UTC INCLUDING MIQUELON +ST.PIERRE 2 H BEHIND UTC INLCUDING MIQUELON APR 3 +ST.PIERRE - OCT 29 +ST.VINCENT 4 H BEHIND UTC INCLUDING THE GRENADINES +ST. HELENA ON UTC +SURINAME 3 H BEHIND UTC +SWAZILAND 2 H AHEAD OF UTC +SWEDEN 1 H AHEAD OF UTC +SWEDEN 2 H AHEAD OF UTC MAR 27 - SEP 24 +SWITZERLAND 1 H AHEAD OF UTC +SWITZERLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +SYRIA 2 H AHEAD OF UTC +SYRIA 3 H AHEAD OF UTC MAR 15 - OCT 30 +TAHITI 10 H BEHIND UTC +TANZANIA 3 H AHEAD OF UTC +THAILAND 7 H AHEAD OF UTC +TRINIDAD / TOBAGO 4 H BEHIND UTC +TUNISIA 1 H AHEAD OF UTC +TUNISIA 2 H AHEAD OF UTC APR 10 - SEP 24 +TURKEY 2 H AHEAD OF UTC +TURKEY 3 H AHEAD OF UTC MAR 27 - SEP 24 +TURKS AND CAICOS 5 H BEHIND UTC +TURKS AND CAICOS 4 H BEHIND UTC APR 3 - OCT 29 +TUVALU 12 H AHEAD OF UTC +UDAN 2 H AHEAD OF UTC +UGANDA 3 H AHEAD OF UTC +UNITED ARAB EMIR. 4 H AHEAD OF UTC ABU DHABI, DUBAI, SHARJAH, +UNITED ARAB EMIR RAS AL KHAIMAH +UNITED KINGDOM ON UTC WALES, SCOTLAND, N.I., CH. +UNITED KINGDOM IS. +UNITED KINGDOM 1 H AHEAD OF UTC MAR 27 - OCT 22 +UNITED STATES SEE USA +UPPER VOLTA ON UTC +URUGUAY 3 H BEHIND UTC +URUGUAY 2 H BEHIND UTC DEC 11, '88-FEB 25, '89 +URAGUAY (ESTIMATED) +USA EASTERN 5 H BEHIND UTC NEW YORK, WASHINGTON +USA EASTERN 4 H BEHIND UTC APR 3 - OCT 30 +USA CENTRAL 6 H BEHIND UTC CHICAGO, HOUSTON +USA CENTRAL 5 H BEHIND UTC APR 3 - OCT 30 +USA MOUNTAIN 7 H BEHIND UTC DENVER +USA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 30 +USA PACIFIC 8 H BEHIND UTC L.A., SAN FRANCISCO +USA PACIFIC 7 H BEHIND UTC APR 3 - OCT 30 +USA ALASKA STD 9 H BEHIND UTC MOST OF ALASKA (AKST) +USA ALASKA STD 8 H BEHIND UTC APR 3 - OCT 30 (AKDT) +USA ALEUTIAN 10 H BEHIND UTC ISLANDS WEST OF 170W +USA - " - 9 H BEHIND UTC APR 3 - OCT 30 +USA HAWAII 10 H BEHIND UTC +USA BERING 11 H BEHIND UTC SAMOA, MIDWAY +USA FOR SPECIFIC INFO ON USA ZONES/TIMES CALL DOT 202-426-4520 +USSR WEST EUROP 3 H AHEAD OF UTC LENINGRAD, MOSCOW +USSR WEST EUROP 4 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL EUR 4 H AHEAD OF UTC ROSTOV, BAKU +USSR CENTRAL EUR 5 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST EUROP 5 H AHEAD OF UTC SVERDLOVSK +USSR EAST EUROP 6 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST SIBERIAN 6 H AHEAD OF UTC TASHKENT, ALMA ATA +USSR WEST SIBERIAN 7 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 7 H AHEAD OF UTC NOVOSIBIRSK +USSR WEST-CENTRAL 8 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 8 H AHEAD OF UTC IRKUTSK +USSR WEST-CENTRAL 9 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 9 H AHEAD OF UTC YAKUTSK +USSR CENTRAL SIB 10 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 10 H AHEAD OF UTC VLADIVOSTOK +USSR CENTRAL SIB 11 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 11 H AHEAD OF UTC MAGADAN +USSR EAST SIBERIA 12 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 12 H AHEAD OF UTC PETROPAVLOVSK +USSR EAST SIBERIA 13 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 13 H AHEAD OF UTC UELEN +USSR EAST SIBERIA 14 H AHEAD OF UTC APR 1 - SEP 30 +VANUATU 11 H AHEAD OF UTC (NEW HEBRIDES) +VANUATU 12 H AHEAD OF UTC SEP 25, '88-MAR 25, '89 +VANUATU (ESTIMATED) +VATICAN 1 H AHEAD OF UTC +VATICAN 2 H AHEAD OF UTC MAR 27 - SEP 24 +VIETNAM 7 H AHEAD OF UTC +VIRGIN ISLANDS 4 H BEHIND UTC ST.CROIX, ST.THOMAS, +VIRGIN ISLANDS ST.JOHN +WAKE ISLAND 12 H AHEAD OF UTC +WALES SEE ENGLAND +WALLIS/FUTUNA IS. 12 H AHEAD OF UTC +WINDWARD ISLANDS 4 H BEHIND UTC GRENADA, ST. LUCIA +YEMEN 3 H AHEAD OF UTC BOTH REPUBLICS +YUGOSLAVIA 1 H AHEAD OF UTC +YUGOSLAVIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ZAIRE EAST 1 H AHEAD OF UTC KINSHASA MBANDAKA +ZAIRE WEST 2 H AHEAD OF UTC LUBUMBASHI, KASAI, KIVU, +ZAIRE WEST HAUT-ZAIRE, SHABA +ZAMBIA 2 H AHEAD OF UTC +ZIMBABWE 2 H AHEAD OF UTC diff --git a/time/usno1989a b/time/usno1989a new file mode 100644 index 000000000..42cd9b338 --- /dev/null +++ b/time/usno1989a @@ -0,0 +1,452 @@ +# @(#)usno1989a 7.2 +# +# From Arthur David Olson (February 7, 1994): +# +# Here's time zone information from the United States Naval Observatory, +# with corrections from Paul Eggert (eggert@twinsun.com). +# The USNO warns: +# DUE TO FREQUENT CHANGES IN THE LOCAL LAWS GOVERNING DAYLIGHT +# SAVING TIME, WE CANNOT GUARANTEE THE ACCURACY OF THIS +# INFORMATION. PLEASE ALERT US TO ANY DISCREPANCY YOU MAY +# DISCOVER. +# +AFGHANISTAN 4.5H AHEAD OF UTC +ALBANIA 1 H AHEAD OF UTC +ALBANIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ALBANIA (ESTIMATED) +ALGERIA 1 H AHEAD OF UTC +AMERICAN SAMOA 11 H BEHIND UTC +ANDORRA 1 H AHEAD OF UTC +ANDORRA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ANDORRA (ESTIMATED) +ANGOLA 1 H AHEAD OF UTC +ARGENTINA 3 H BEHIND UTC +ARUBA 4 H BEHIND UTC ALSO BONAIRE, CURACAO, +ARUBA ST.MAARTEN +AUSTRALIA WEST 8 H AHEAD OF UTC PERTH, EXMOUTH +AUSTRALIA N.T. 9.5H AHEAD OF UTC DARWIN NO ADVANCED TIME +AUSTRALIA N.T. IN SUMMER +AUSTRALIA SOUTH 9.5H AHEAD OF UTC ADELAIDE +AUSTRALIA INCLUDING BROKEN HILL, NSW +AUSTRALIA SOUTH 10.5H AHEAD OF UTC ADELAIDE OCT 30, '88-MAR +AUSTRALIA SOUTH 18, '89 INCLUDING BROKEN +AUSTRIALIA SOUTH HILL, NSW +AUSTRALIA QUEENL 10 H AHEAD OF UTC +AUSTRALIA NSW 10 H AHEAD OF UTC SYDNEY +AUSTRALIA NSW 11 H AHEAD OF UTC SYDNEY OCT 30, '88-MAR 18, +AUSTRALIA NSW '89 +AUSTRALIA TASM. 10 H AHEAD OF UTC HOBART +AUSTRALIA TASM. 11 H AHEAD OF UTC HOBART OCT 30, '88-MAR 18, +AUSTRALIA TASM. '89 +AUSTRIA 1 H AHEAD OF UTC +AUSTRIA 2 H AHEAD OF UTC MAR 27 - SEPT 24 +AZORES SEE PORTUGAL +BAHAMAS 5 H BEHIND UTC EXCLUDING TURKS AND CAICOS +BAHAMAS ISLANDS) +BAHAMAS 4 H BEHIND UTC APR 3 - OCT 29 (SAME +BAHAMAS EXCLUSION) +BAHRAIN 3 H AHEAD OF UTC +BANGLADESH 6 H AHEAD OF UTC +BARBADOS 4 H BEHIND UTC +BELGIUM 1 H AHEAD OF UTC +BELGIUM 2 H AHEAD OF UTC MAR 27 - SEP 24 +BELIZE 6 H BEHIND UTC +BENIN PEOPLES REP 1 H AHEAD OF UTC DAHOMEY +BERMUDA 4 H BEHIND UTC +BERMUDA 3 H BEHIND UTC APR 3 - OCT 29 +BHUTAN 6 H AHEAD OF UTC +BOLIVIA 4 H BEHIND UTC +BONAIRE 4 H BEHIND UTC ALSO ARUBA,CURACAO, +BONAIRE ST.MAARTEN, SABA +BOTSWANA 2 H AHEAD OF UTC +BRAZIL WEST 5 H BEHIND UTC TERRITORY OF ACRE +BRAZIL WEST 4 H BEHIND UTC ACRE OCT 23, '88-FEB 11, +BRAZIL '89 (ESTIMATED) +BRAZIL CENTRAL 4 H BEHIND UTC MANAUS +BRAZIL CENTRAL 3 H BEHIND UTC MANAUS OCT 23, '88-FEB 11, +BRAZIL CENTRAL '89 (ESTIMATED) +BRAZIL EAST 3 H BEHIND UTC COASTAL STATES, RIO, SAO +BRAZIL EAST PAULO, BRASILIA +BRAZIL EAST 2 H BEHIND UTC COASTAL STATES, RIO, SAO +BRAZIL PAULO, BRASILIA OCT 23, +BRAZIL '88-FEB 11, '89 +BRAZIL (ESTIMATED) +BRAZIL 2 H BEHIND UTC ATLANTIC ISLANDS, FERNANDO +BRAZIL DE NORONHA +BRAZIL 1 H BEHIND UTC OCT 23, '88-FEB 11, '89 +BRAZIL (ESTIMATED) +BRAZIL 3 H BEHIND UTC FOR MOST MAJOR AIRPORTS. +BRITISH VIRGIN I. 4 H BEHIND UTC +BRUNEI 8 H AHEAD OF UTC +BULGARIA 2 H AHEAD OF UTC +BULGARIA 3 H AHEAD OF UTC MAR 27 - SEP 24 +BURKINA FASO ON UTC +BURMA 6.5H AHEAD OF UTC +BURUNDI 2 H AHEAD OF UTC +CAMBODIA SEE KAMPUCHEA +CAMEROON 1 H AHEAD OF UTC +CANADA NEW FDL 3.5H BEHIND UTC ST.JOHN'S +CANADA NEW FDL 1.5H BEHIND UTC APR 3 - OCT 29 +CANADA ATLANTIC 4 H BEHIND UTC HALIFAX +CANADA ATLANTIC 3 H BEHIND UTC APR 3 - OCT 29 +CANADA EASTERN 5 H BEHIND UTC TORONTO, MONTREAL, OTTAWA +CANADA EASTERN 4 H BEHIND UTC APR 3 - OCT 29 +CANADA CENTRAL 6 H BEHIND UTC REGINA, WINNIPEG +CANADA CENTRAL 5 H BEHIND UTC APR 3 - OCT 29 +CANADA MOUNTAIN 7 H BEHIND UTC CALGARY, EDMONTON +CANADA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 29 +CANADA PACIFIC 8 H BEHIND UTC VANCOUVER +CANADA PACIFIC 7 H BEHIND UTC APR 3 - OCT 29 +CANADA YUKON SAME AS PACIFIC DAWSON +CAPE VERDE 1 H BEHIND UTC +CAYMAN ISLANDS 5 H BEHIND UTC +CAROLINE ISLAND 10 H AHEAD OF UTC EXCLUDING PONAPE IS., +CAROLINE ISLAND KUSAIE, AND PINGELAP +CENTRAL AFRICA 1 H AHEAD OF UTC +CEYLON 5.5H AHEAD OF UTC, SEE SRI LANKA +CHAD 1 H AHEAD OF UTC +CHANNEL ISLANDS SEE ENGLAND +CHILE 4 H BEHIND UTC CONTINENTAL +CHILE 3 H BEHIND UTC OCT 9, '88-MAR 11, '89 +CHILE 6 H BEHIND UTC EASTER ISLAND +CHILE 5 H BEHIND UTC OCT 9, '88-MAR 11, '89 +CHINA 8 H AHEAD OF UTC ALL OF CHINA, INCL TAIWAN +CHINA 9 H AHEAD OF UTC APR 17 - SEP 10 +COCOS (Keeling) I. 6.5H AHEAD OF UTC +COLOMBIA 5 H BEHIND UTC +COMOROS 3 H AHEAD OF UTC +CONGO 1 H AHEAD OF UTC +COOK ISLANDS 10 H BEHIND UTC +COOK ISLANDS 9.5H BEHIND UTC OCT 30, '88-MAR 24, '89 +COOK ISLANDS (ESTIMATED) +COSTA RICA 6 H BEHIND UTC +COTE D'IVOIRE ON UTC +CUBA 5 H BEHIND UTC +CUBA 4 H BEHIND UTC MAR 20 - OCT 8 +CURACAO 4 H BEHIND UTC ALSO BONAIRE, ARUBA, +CURACAO ST.MAARTEN +CYPRUS 2 H AHEAD OF UTC +CYPRUS 3 H AHEAD OF UTC MAR 27 - SEP 24 +CZECHOSLOVAKIA 1 H AHEAD OF UTC +CZECHOSLOVAKIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +DENMARK 1 H AHEAD OF UTC +DENMARK 2 H AHEAD OF UTC MAR 27 - SEP 24 +DENMK. FAEROE IS 1 H AHEAD OF UTC MAR 27 - SEP 24 +DJIBOUTI 3 H AHEAD OF UTC +DOMINICA 4 H BEHIND UTC +DOMINICAN REP 4 H BEHIND UTC +ECUADOR 5 H BEHIND UTC CONTINENTAL +ECUADOR 6 H BEHIND UTC GALAPAGOS ISLANDS +EGYPT 2 H AHEAD OF UTC +EGYPT 3 H AHEAD OF UTC MAY 17 - SEP 30 (AFTER +EGYPT RAMADAN) +EL SALVADOR 6 H BEHIND UTC +ENGLAND ON UTC (WALES, SCOTLAND, N.I., +ENGLAND CH. IS.) +ENGLAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +EQUATORIAL GUINEA 1 H AHEAD OF UTC +ETHIOPIA 3 H AHEAD OF UTC +FALKLAND ISLANDS 4 H BEHIND UTC +FALKLAND ISLANDS 3 H BEHIND UTC SEP 11, '88-APR 15, '89 +FALKLAND ISLANDS (ESTIMATED) +FAROE ISLAND ON UTC +FAROE ISLAND 1 H AHEAD OF UTC MAR 27 - SEP 24 +FIJI 12 H AHEAD OF UTC +FINLAND 2 H AHEAD OF UTC +FINLAND 3 H AHEAD OF UTC MAR 27 - SEP 24 +FRANCE 1 H AHEAD OF UTC +FRANCE 2 H AHEAD OF UTC MAR 27 - SEP 24 +FRENCH GUIANA 3 H BEHIND UTC +FRENCH POLYNESIA 9 H BEHIND UTC GAMBIER ISLAND +FRENCH POLYNESIA 9.5H BEHIND UTC MARQUESAS ISLANDS +FRENCH POLYNESIA 10 H BEHIND UTC SOCIETY ISLANDS, TUBUAI +FRENCH POLYNESIA ISLANDS, TUAMOTU ISLAND, +FRENCH POLYNESIA TAHITI +GABON 1 H AHEAD OF UTC +GAMBIA ON UTC +GERMANY ALL 1 H AHEAD OF UTC +GERMANY ALL 2 H AHEAD OF UTC MAR 27 - SEP 24 +GHANA ON UTC +GIBRALTAR 1 H AHEAD OF UTC +GIBRALTAR 2 H AHEAD OF UTC MAR 27 - SEP 24 +GREECE 2 H AHEAD OF UTC +GREECE 3 H AHEAD OF UTC MAR 27 - SEP 24 +GREENLAND 4 H BEHIND UTC THULE AIRBASE YEAR ROUND +GREENLAND 3 H BEHIND UTC ANGMAGSSALIK AND W. COAST +GREENLAND 2 H BEHIND UTC MAR 27 - SEP 24 +GREENLAND 1 H BEHIND UTC SCORESBYSUND +GREENLAND ON UTC MAR 27 - SEP 24 +GRENADA 4 H BEHIND UTC +GUADELOUPE 4 H BEHIND UTC ST. BARTHELEMY, NORTHERN +GUADELOUPE ST. MARTIN MARTINIQUE +GUAM 10 H AHEAD OF UTC +GUATEMALA 6 H BEHIND UTC +GUINEA ON UTC +GUINEA BISSAU ON UTC +GUINEA REPUBLIC ON UTC +GUINEA EQUATORIAL 1 H AHEAD OF UTC +GUYANA 3 H BEHIND UTC +HAITI 5 H BEHIND UTC +HAITI 4 H BEHIND UTC APR 3 - OCT 29 +HOLLAND SEE NETHERLANDS +HONDURAS 6 H BEHIND UTC +HONG KONG 8 H AHEAD OF UTC +HUNGARY 1 H AHEAD OF UTC +HUNGARY 2 H AHEAD OF UTC MAR 27 - SEP 24 +ICELAND ON UTC +INDIA 5.5H AHEAD OF UTC INCLUDING ANDAMAN ISLANDS +INDONESIA WEST 7 H AHEAD OF UTC SUMATRA, JAVA, BALI, +INDONESIA WEST JAKARTA +INDONESIA CENTRAL 8 H AHEAD OF UTC KALIMANTAN, SULAWESI +INDONESIA EAST 9 H AHEAD OF UTC IRIAN, BARAT +IRAN 3.5H AHEAD OF UTC +IRAQ 3 H AHEAD OF UTC +IRAQ 4 H AHEAD OF UTC APR 1 - SEP 30 +IRELAND ON UTC +IRELAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +ISRAEL 2 H AHEAD OF UTC +ISRAEL 3 H AHEAD OF UTC APR 10 - SEP 3 +ITALY 1 H AHEAD OF UTC +ITALY 2 H AHEAD OF UTC MAR 27 - SEP 24 +IVORY COAST ON UTC +JAMAICA 5 H BEHIND UTC +JAPAN 9 H AHEAD OF UTC +JOHNSTON ISLAND 10 H BEHIND UTC +JORDAN 2 H AHEAD OF UTC +JORDAN 3 H AHEAD OF UTC APR 1 - OCT 6 +KAMPUCHEA 7 H AHEAD OF UTC +KENYA 3 H AHEAD OF UTC +KIRIBATI, REP OF 12 H AHEAD OF UTC CANTON, ENDERBURY ISLANDS +KIRIBATI, REP OF 11 H AHEAD OF UTC CHRISTMAS ISLAND +KOREA 9 H AHEAD OF UTC +KOREA, REP OF 9 H AHEAD OF UTC +KOREA, REP OF 10 H AHEAD OF UTC MAY 8 - OCT 8 +KUWAIT 3 H AHEAD OF UTC +KUSAIE, PINGELAP 12 H AHEAD OF UTC INCLUDING MARSHALL IS., +KUSAIE, PINGELAP EXCLUDING KWAJALEIN) +KWAJALEIN 12 H BEHIND UTC +LAOS 7 H AHEAD OF UTC +LEBANON 2 H AHEAD OF UTC +LEBANON 3 H AHEAD OF UTC JUN 1 - OCT 31 +LEEWARD ISLANDS 4 H BEHIND UTC ANTIGUA, DOMINICA, +LEEWARD ISLANDS MONTSERRAT, ST. +LEEWARD ISLAANDS CHRISTOPHER, ST. KITTS, +LEEWARD ISLANDS NEVIS, ANGUILLA +LESOTHO 2 H AHEAD OF UTC +LIBERIA ON UTC +LIBYAN ARAB 1 H AHEAD OF UTC JAMAHIRIYA/LIBYA +LIBYAN ARAB 2 H AHEAD OF UTC APR 1 - SEP 30 JAMAHIRIYA/LIBYA +LIECHTENSTEIN 1 H AHEAD OF UTC +LIECHTENSTEIN 2 H AHEAD OF UTC MAR 27 - SEP 24 +LUXEMBOURG 1 H AHEAD OF UTC +LUXEMBOURG 2 H AHEAD OF UTC MAR 27 - SEP 24 +MACAO 8 H AHEAD OF UTC +MADAGASCAR 3 H AHEAD OF UTC +MADEIRA SEE PORTUGAL +MALAWI 2 H AHEAD OF UTC +MALAYSIA 8 H AHEAD OF UTC +MALDIVES 5 H AHEAD OF UTC +MALI ON UTC +MALTA 1 H AHEAD OF UTC +MALTA 2 H AHEAD OF UTC MAR 27 - SEP 24 +MARTINIQUE 4 H BEHIND UTC +MAURITANIA ON UTC +MAURITIUS 4 H AHEAD OF UTC +MARIANA ISLANDS 10 H AHEAD OF UTC EXCLUDING GUAM +MEXICO BAJA CAL N 7 H BEHIND UTC BAJA CALIFORNIA SUR AND +MEXICO BAJA CAL N N. PACIFIC COAST (STATES +MEXICO BAJA CAL N OF SINALOA AND SONORA) +MEXICO BAJA CAL N 8 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +MEXICO BAJA CAL N - OCT 29 +MEXICO BAJA CAL N 7 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +MEXICO BAJA CAL N - 0CT 29 +MEXICO 6 H BEHIND UTC STATES OF DURANGO, +MEXICO COAHUILA, NUEVO LEON, +MEXICO TAMAULIPAS +MEXICO 5 H BEHIND UTC STATES OF DURANGO, +MEXICO COAHUILA, NUEVO LEON, +MEXICO TAMAULIPAS APR 3 - OCT 29 +MEXICO 6 H BEHIND UTC GENERAL MEXICO, STATES OF +MEXICO CAMPECHE, QUINTANA ROO AND +MEXICO YUCATAN +MIDWAY ISLAND 11 H BEHIND UTC +MONACO 1 H AHEAD OF UTC +MONACO 2 H AHEAD OF UTC MAR 27 - SEP 24 +MONGOLIA 8 H AHEAD OF UTC +MONGOLIA 9 H AHEAD OF UTC MAR 27 - SEP 24 +MONTSERRAT 4 H BEHIND UTC +MOROCCO ON UTC +MOZAMBIQUE 2 H AHEAD OF UTC +NAMIBIA 2 H AHEAD OF UTC +NAURU, REP OF 12 H AHEAD OF UTC +NEPAL 5H45M AHEAD OF UTC +NETHERLANDS 1 H AHEAD OF UTC +NETHERLANDS 2 H AHEAD OF UTC MAR 27 - SEP 24 +NETHERLANDS 4 H BEHIND UTC ANTILLES AND SOUTHERN ST. +NETHERLANDS MAARTEN +NEW CALEDONIA 11 H AHEAD OF UTC +NEW HEBRIDES SEE VANUATU +NEW ZEALAND 12 H AHEAD OF UTC (EXCLUDING CHATHAM ISLAND) +NEW ZEALAND 13 H AHEAD OF UTC OCT 30, '88-MAR 4, '89 +NEW ZEALAND 12H45M AHEAD OF UTC CHATHAM ISLAND +NICARAGUA 6 H BEHIND UTC +NIGER 1 H AHEAD OF UTC +NIGERIA 1 H AHEAD OF UTC +NIUE ISLAND 11 H BEHIND UTC +NORFOLK ISLAND 11H30M AHEAD OF UTC +NORTHERN IRELAND ON UTC WALES, SCOTLAND, N.I., +NORTHERN IRELAND CH.IS. +NORTHERN IRELAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +NORWAY 1 H AHEAD OF UTC +NORWAY 2 H AHEAD OF UTC MAR 27 - SEP 24 +OMAN 4 H AHEAD OF UTC +PACIFIC ISLAND T.T. +PALAU ISLANDS 9 H AHEAD OF UTC +PAKISTAN 5 H AHEAD OF UTC +PANAMA 5 H BEHIND UTC +PAPUA NEW GUINEA 10 H AHEAD OF UTC INCLUDING BOUGAINVILLE +PAPUA NEW GUINEA ISLAND +PARAGUAY 4 H BEHIND UTC +PARAGUAY 3 H BEHIND UTC OCT 1, '88-MAR 31, '89 +PERU 5 H BEHIND UTC +PHILIPPINES 8 H AHEAD OF UTC +PONAPE ISLAND 11 H AHEAD OF UTC +POLAND 1 H AHEAD OF UTC +POLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +PORTUGAL MAINLAND ON UTC +PORTUGAL MAINLAND 1 H AHEAD OF UTC MAR 27 - SEP 24 +PORTUGAL AZORES 1 H BEHIND UTC +PORTUGAL AZORES ON UTC MAR 27 - SEP 24 +PORTUGAL MADEIRA ON UTC +PORTUGAL MADEIRA 1 H AHEAD OF UTC MAR 27 - SEP 24 +PUERTO RICO 4 H BEHIND UTC +QATAR 3 H AHEAD OF UTC +ROMANIA 2 H AHEAD OF UTC +ROMANIA 3 H AHEAD OF UTC MAR 27 - SEP 24 +RUSSIA SEE USSR +RWANDA 2 H AHEAD OF UTC +SABA 4 H BEHIND UTC ALSO BONAIRE, CURACAO, +SAMOA 11 H BEHIND UTC +SAN MARINO 1 H AHEAD OF UTC +SAN MARINO 2 H AHEAD OF UTC MAR 27 - SEP 24 +SAN SALVADOR 6 H BEHIND UTC +SAO TOME ISLAND ON UTC AND PRINCIPE ISLAND +SAUDI ARABIA 3 H AHEAD OF UTC +SCOTLAND SEE ENGLAND +SENEGAL ON UTC +SEYCHELLES 4 H AHEAD OF UTC +SIERRA LEONE ON UTC +SINGAPORE 8 H AHEAD OF UTC +SOLOMON ISLANDS 11 H AHEAD OF UTC EXCLUDING BOUGAINVILLE +SOLOMON ISLANDS ISLAND +SOMALI 3 H AHEAD OF UTC +SOUTH AFRICA 2 H AHEAD OF UTC +SPAIN CANARY IS ON UTC +SPAIN CANARY IS 1 H AHEAD OF UTC MAR 27 - SEP 24 +SPAIN 1 H AHEAD OF UTC CONTINENTAL, BALEARIC AND +SPAIN MALLORCA ISLANDS +SPAIN 2 H AHEAD OF UTC CONTINENTAL, BALEARIC AND +SPAIN MALLORCA ISLANDS MAR 27 - +SPAIN SEP 24 +SPAIN MAINLAND 1 H AHEAD OF UTC MELILLA +SPAIN MAINLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +SRI LANKA 5H30M AHEAD OF UTC +ST. MAARTEN +ST. KITTS-NEVIS 4 H BEHIND UTC +ST. LUCIA 4 H BEHIND UTC +ST. PIERRE 3 H BEHIND UTC INCLUDING MIQUELON +ST. PIERRE 2 H BEHIND UTC INLCUDING MIQUELON APR 3 +ST. PIERRE - OCT 29 +ST. VINCENT 4 H BEHIND UTC INCLUDING THE GRENADINES +ST. HELENA ON UTC +SUDAN 2 H AHEAD OF UTC +SURINAME 3 H BEHIND UTC +SWAZILAND 2 H AHEAD OF UTC +SWEDEN 1 H AHEAD OF UTC +SWEDEN 2 H AHEAD OF UTC MAR 27 - SEP 24 +SWITZERLAND 1 H AHEAD OF UTC +SWITZERLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +SYRIA 2 H AHEAD OF UTC +SYRIA 3 H AHEAD OF UTC MAR 15 - OCT 30 +TAHITI 10 H BEHIND UTC +TAIWAN 8 H AHEAD OF UTC +TANZANIA 3 H AHEAD OF UTC +THAILAND 7 H AHEAD OF UTC +TOGO ON UTC +TRINIDAD / TOBAGO 4 H BEHIND UTC +TUNISIA 1 H AHEAD OF UTC +TUNISIA 2 H AHEAD OF UTC APR 10 - SEP 24 +TURKEY 2 H AHEAD OF UTC +TURKEY 3 H AHEAD OF UTC MAR 27 - SEP 24 +TURKS AND CAICOS 5 H BEHIND UTC +TURKS AND CAICOS 4 H BEHIND UTC APR 3 - OCT 29 +TUVALU 12 H AHEAD OF UTC +UGANDA 3 H AHEAD OF UTC +UNITED ARAB EMIR. 4 H AHEAD OF UTC ABU DHABI, DUBAI, SHARJAH, +UNITED ARAB EMIR RAS AL KHAIMAH +UNITED KINGDOM ON UTC WALES, SCOTLAND, N.I., CH. +UNITED KINGDOM IS. +UNITED KINGDOM 1 H AHEAD OF UTC MAR 27 - OCT 22 +UNITED STATES SEE USA +UPPER VOLTA ON UTC +URUGUAY 3 H BEHIND UTC +URUGUAY 2 H BEHIND UTC DEC 11, '88-FEB 25, '89 +URAGUAY (ESTIMATED) +USA EASTERN 5 H BEHIND UTC NEW YORK, WASHINGTON +USA EASTERN 4 H BEHIND UTC APR 3 - OCT 30 +USA CENTRAL 6 H BEHIND UTC CHICAGO, HOUSTON +USA CENTRAL 5 H BEHIND UTC APR 3 - OCT 30 +USA MOUNTAIN 7 H BEHIND UTC DENVER +USA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 30 +USA PACIFIC 8 H BEHIND UTC L.A., SAN FRANCISCO +USA PACIFIC 7 H BEHIND UTC APR 3 - OCT 30 +USA ALASKA STD 9 H BEHIND UTC MOST OF ALASKA (AKST) +USA ALASKA STD 8 H BEHIND UTC APR 3 - OCT 30 (AKDT) +USA ALEUTIAN 10 H BEHIND UTC ISLANDS WEST OF 170W +USA - " - 9 H BEHIND UTC APR 3 - OCT 30 +USA HAWAII 10 H BEHIND UTC +USA BERING 11 H BEHIND UTC SAMOA, MIDWAY +USA FOR SPECIFIC INFO ON USA ZONES/TIMES CALL DOT 202-426-4520 +USSR WEST EUROP 3 H AHEAD OF UTC LENINGRAD, MOSCOW +USSR WEST EUROP 4 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL EUR 4 H AHEAD OF UTC ROSTOV, BAKU +USSR CENTRAL EUR 5 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST EUROP 5 H AHEAD OF UTC SVERDLOVSK +USSR EAST EUROP 6 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST SIBERIAN 6 H AHEAD OF UTC TASHKENT, ALMA ATA +USSR WEST SIBERIAN 7 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 7 H AHEAD OF UTC NOVOSIBIRSK +USSR WEST-CENTRAL 8 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 8 H AHEAD OF UTC IRKUTSK +USSR WEST-CENTRAL 9 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 9 H AHEAD OF UTC YAKUTSK +USSR CENTRAL SIB 10 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 10 H AHEAD OF UTC VLADIVOSTOK +USSR CENTRAL SIB 11 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 11 H AHEAD OF UTC MAGADAN +USSR EAST SIBERIA 12 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 12 H AHEAD OF UTC PETROPAVLOVSK +USSR EAST SIBERIA 13 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 13 H AHEAD OF UTC UELEN +USSR EAST SIBERIA 14 H AHEAD OF UTC APR 1 - SEP 30 +VANUATU 11 H AHEAD OF UTC (NEW HEBRIDES) +VANUATU 12 H AHEAD OF UTC SEP 25, '88-MAR 25, '89 +VANUATU (ESTIMATED) +VATICAN 1 H AHEAD OF UTC +VATICAN 2 H AHEAD OF UTC MAR 27 - SEP 24 +VENEZUELA 4 H BEHIND UTC +VIETNAM 7 H AHEAD OF UTC +VIRGIN ISLANDS 4 H BEHIND UTC ST.CROIX, ST.THOMAS, +VIRGIN ISLANDS ST.JOHN +WAKE ISLAND 12 H AHEAD OF UTC +WALES SEE ENGLAND +WALLIS/FUTUNA IS. 12 H AHEAD OF UTC +WINDWARD ISLANDS 4 H BEHIND UTC GRENADA, ST. LUCIA +YEMEN 3 H AHEAD OF UTC BOTH REPUBLICS +YUGOSLAVIA 1 H AHEAD OF UTC +YUGOSLAVIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ZAIRE EAST 1 H AHEAD OF UTC KINSHASA MBANDAKA +ZAIRE WEST 2 H AHEAD OF UTC LUBUMBASHI, KASAI, KIVU, +ZAIRE WEST HAUT-ZAIRE, SHABA +ZAMBIA 2 H AHEAD OF UTC +ZIMBABWE 2 H AHEAD OF UTC diff --git a/time/yearistype.sh b/time/yearistype.sh new file mode 100644 index 000000000..c7a886c25 --- /dev/null +++ b/time/yearistype.sh @@ -0,0 +1,26 @@ +#! /bin/sh + +: '@(#)yearistype.sh 7.3' + +case $#-$2 in + 2-even) case $1 in + *[24680]) exit 0 ;; + *) exit 1 ;; + esac ;; + 2-nonpres) case $1 in + *[02468][048]|*[13567][26]) exit 1 ;; + *) exit 0 ;; + esac ;; + 2-odd) case $1 in + *[13579]) exit 0 ;; + *) exit 1 ;; + esac ;; + 2-uspres) case $1 in + *[02468][048]|*[13567][26]) exit 0 ;; + *) exit 1 ;; + esac ;; + 2-*) echo "$0: wild type - $2" >&2 + exit 1 ;; + *) echo "$0: usage is $0 year type" >&2 + exit 1 ;; +esac diff --git a/time/zdump.8 b/time/zdump.8 new file mode 100644 index 000000000..23f49461c --- /dev/null +++ b/time/zdump.8 @@ -0,0 +1,40 @@ +.TH ZDUMP 8 +.SH NAME +zdump \- time zone dumper +.SH SYNOPSIS +.B zdump +[ +.B \-v +] [ +.B \-c +cutoffyear ] [ zonename ... ] +.SH DESCRIPTION +.I Zdump +prints the current time in each +.I zonename +named on the command line. +.PP +These options are available: +.TP +.B \-v +For each +.I zonename +on the command line, +print the current time, +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 +.B isdst=1 +if the given time is Daylight Saving Time or +.B isdst=0 +otherwise. +.TP +.BI "\-c " cutoffyear +Cut off the verbose output near the start of the given year. +.SH "SEE ALSO" +newctime(3), tzfile(5), zic(8) +.\" @(#)zdump.8 7.2 diff --git a/time/zdump.c b/time/zdump.c new file mode 100644 index 000000000..d35df3307 --- /dev/null +++ b/time/zdump.c @@ -0,0 +1,331 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)zdump.c 7.12"; +#endif /* !defined NOID */ +#endif /* !defined 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 "stdio.h" /* for stdout, stderr */ +#include "string.h" /* for strcpy */ +#include "sys/types.h" /* for time_t */ +#include "time.h" /* for struct tm */ + +#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 GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#endif /* defined lint */ +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#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 */ + +extern char ** environ; +extern int getopt(); +extern char * optarg; +extern int optind; +extern time_t time(); +extern char * tzname[2]; + +#ifdef USG +extern void exit(); +extern void perror(); +#endif /* defined USG */ + +static char * abbr(); +static long delta(); +static time_t hunt(); +static int longest; +static char * progname; +static void show(); + +int +main(argc, argv) +int argc; +char * argv[]; +{ + register int i, c; + register int vflag; + register char * cutoff; + register int cutyear; + register long cuttime; + char ** fakeenv; + time_t now; + time_t t, newt; + time_t hibit; + struct tm tm, newtm; + + INITIALIZE(cuttime); + progname = argv[0]; + vflag = 0; + cutoff = NULL; + while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v') + if (c == 'v') + vflag = 1; + else cutoff = optarg; + if (c != EOF || + (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) { + (void) fprintf(stderr, +"%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n", + argv[0], argv[0]); + (void) exit(EXIT_FAILURE); + } + if (cutoff != NULL) { + int y; + + cutyear = atoi(cutoff); + cuttime = 0; + for (y = EPOCH_YEAR; y < cutyear; ++y) + cuttime += DAYSPERNYEAR + isleap(y); + cuttime *= SECSPERHOUR * HOURSPERDAY; + } + (void) time(&now); + longest = 0; + for (i = optind; i < argc; ++i) + if (strlen(argv[i]) > longest) + longest = strlen(argv[i]); + for (hibit = 1; (hibit << 1) != 0; hibit <<= 1) + continue; + { + register int from, to; + + for (i = 0; environ[i] != NULL; ++i) + continue; + fakeenv = (char **) malloc((i + 2) * sizeof *fakeenv); + if (fakeenv == NULL || + (fakeenv[0] = (char *) malloc(longest + 4)) == NULL) { + (void) perror(progname); + (void) exit(EXIT_FAILURE); + } + 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]); + show(argv[i], now, FALSE); + if (!vflag) + continue; + /* + ** Get lowest value of t. + */ + t = hibit; + if (t > 0) /* time_t is unsigned */ + t = 0; + show(argv[i], t, TRUE); + t += SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + tm = *localtime(&t); + (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + for ( ; ; ) { + if (cutoff != NULL && t >= cuttime) + break; + newt = t + SECSPERHOUR * 12; + if (cutoff != NULL && newt >= cuttime) + break; + if (newt <= t) + break; + newtm = *localtime(&newt); + if (delta(&newtm, &tm) != (newt - t) || + newtm.tm_isdst != tm.tm_isdst || + strcmp(abbr(&newtm), buf) != 0) { + newt = hunt(argv[i], t, newt); + newtm = *localtime(&newt); + (void) strncpy(buf, abbr(&newtm), + (sizeof buf) - 1); + } + t = newt; + tm = newtm; + } + /* + ** Get highest value of t. + */ + t = ~((time_t) 0); + if (t < 0) /* time_t is signed */ + t &= ~hibit; + t -= SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + t += SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + } + if (fflush(stdout) || ferror(stdout)) { + (void) fprintf(stderr, "%s: Error writing standard output ", + argv[0]); + (void) perror("standard output"); + (void) exit(EXIT_FAILURE); + } + exit(EXIT_SUCCESS); + + /* gcc -Wall pacifier */ + for ( ; ; ) + continue; +} + +static time_t +hunt(name, lot, hit) +char * name; +time_t lot; +time_t hit; +{ + time_t t; + struct tm lotm; + struct tm tm; + static char loab[MAX_STRING_LENGTH]; + + lotm = *localtime(&lot); + (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); + while ((hit - lot) >= 2) { + t = lot / 2 + hit / 2; + if (t <= lot) + ++t; + else if (t >= hit) + --t; + tm = *localtime(&t); + if (delta(&tm, &lotm) == (t - lot) && + tm.tm_isdst == lotm.tm_isdst && + strcmp(abbr(&tm), loab) == 0) { + lot = t; + lotm = tm; + } else hit = t; + } + show(name, lot, TRUE); + show(name, hit, TRUE); + return hit; +} + +/* +** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta. +*/ + +static long +delta(newp, oldp) +struct tm * newp; +struct tm * oldp; +{ + long result; + int tmy; + + if (newp->tm_year < oldp->tm_year) + return -delta(oldp, newp); + result = 0; + for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy) + result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE); + result += 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; +} + +extern struct tm * localtime(); + +static void +show(zone, t, v) +char * zone; +time_t t; +int v; +{ + struct tm * tmp; + + (void) printf("%-*s ", longest, zone); + if (v) + (void) printf("%.24s GMT = ", asctime(gmtime(&t))); + tmp = localtime(&t); + (void) printf("%.24s", asctime(tmp)); + if (*abbr(tmp) != '\0') + (void) printf(" %s", abbr(tmp)); + if (v) { + (void) printf(" isdst=%d", tmp->tm_isdst); +#ifdef TM_GMTOFF + (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); +#endif /* defined TM_GMTOFF */ + } + (void) printf("\n"); +} + +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; +} diff --git a/time/zic.8 b/time/zic.8 new file mode 100644 index 000000000..b3623aa26 --- /dev/null +++ b/time/zic.8 @@ -0,0 +1,406 @@ +.TH ZIC 8 +.SH NAME +zic \- time zone compiler +.SH SYNOPSIS +.B zic +[ +.B \-v +] [ +.B \-d +.I directory +] [ +.B \-l +.I localtime +] [ +.B \-p +.I posixrules +] [ +.B \-L +.I leapsecondfilename +] [ +.B \-s +] [ +.B \-y +.I command +] [ +.I filename +\&... ] +.SH DESCRIPTION +.if t .ds lq `` +.if t .ds rq '' +.if n .ds lq \&"\" +.if n .ds rq \&"\" +.de q +\\$3\*(lq\\$1\*(rq\\$2 +.. +.I Zic +reads text from the file(s) named on the command line +and creates the time conversion information files specified in this input. +If a +.I filename +is +.BR \- , +the standard input is read. +.PP +These options are available: +.TP +.BI "\-d " directory +Create time conversion information files in the named directory rather than +in the standard directory named below. +.TP +.BI "\-l " timezone +Use the given time zone as local time. +.I Zic +will act as if the input contained a link line of the form +.sp +.ti +.5i +Link \fItimezone\fP localtime +.TP +.BI "\-p " timezone +Use the given time zone's rules when handling POSIX-format +time zone environment variables. +.I Zic +will act as if the input contained a link line of the form +.sp +.ti +.5i +Link \fItimezone\fP posixrules +.TP +.BI "\-L " 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. +.TP +.B \-v +Complain if a year that appears in a data file is outside the range +of years representable by +.IR time (2) +values. +.TP +.B \-s +Limit time values stored in output files to values that are the same +whether they're taken to be signed or unsigned. +You can use this option to generate SVVS-compatible files. +.TP +.BI "\-y " command +Use the given +.I command +rather than +.B yearistype +when checking year types (see below). +.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're 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 +A rule line has the form +.nf +.ti +.5i +.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 +.sp +For example: +.ti +.5i +.sp +Rule US 1967 1973 \- Apr lastSun 2:00 1:00 D +.sp +.fi +The fields that make up a rule line are: +.TP "\w'LETTER/S'u" +.B NAME +Gives the (arbitrary) name of the set of rules this rule is part of. +.TP +.B FROM +Gives the first year in which the rule applies. +Any integer year can be supplied; the Gregorian calendar is assumed. +The word +.B minimum +(or an abbreviation) means the minimum year representable as an integer. +The word +.B 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. +.TP +.B TO +Gives the final year in which the rule applies. +In addition to +.B minimum +and +.B maximum +(as above), +the word +.B only +(or an abbreviation) +may be used to repeat the value of the +.B FROM +field. +.TP +.B TYPE +Gives the type of year in which the rule applies. +If +.B TYPE +is +.B \- +then the rule applies in all years between +.B FROM +and +.B TO +inclusive. +If +.B TYPE +is something else, then +.I zic +executes the command +.ti +.5i +\fByearistype\fP \fIyear\fP \fItype\fP +.br +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. +.TP +.B IN +Names the month in which the rule takes effect. +Month names may be abbreviated. +.TP +.B ON +Gives the day on which the rule takes effect. +Recognized forms include: +.nf +.in +.5i +.sp +.ta \w'Sun<=25\0\0'u +5 the fifth of the month +lastSun the last Sunday in the month +lastMon the last Monday in the month +Sun>=8 first Sunday on or after the eighth +Sun<=25 last Sunday on or before the 25th +.fi +.in -.5i +.sp +Names of days of the week may be abbreviated or spelled out in full. +Note that there must be no spaces within the +.B ON +field. +.TP +.B AT +Gives the time of day at which the rule takes effect. +Recognized forms include: +.nf +.in +.5i +.sp +.ta \w'1:28:13\0\0'u +2 time in hours +2:00 time in hours and minutes +15:00 24-hour format time (for times after noon) +1:28:14 time in hours, minutes, and seconds +.fi +.in -.5i +.sp +Any of these forms may be followed by the letter +.B w +if the given time is local +.q "wall clock" +time, +.B s +if the given time is local +.q standard +time, or +.B u +(or +.B g +or +.BR z ) +if the given time is universal time; +in the absence of an indicator, +wall clock time is assumed. +.TP +.B SAVE +Gives 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 +.B AT +field +(although, of course, the +.B w +and +.B s +suffixes are not used). +.TP +.B LETTER/S +Gives the +.q "variable part" +(for example, the +.q S +or +.q D +in +.q EST +or +.q EDT ) +of time zone abbreviations to be used when this rule is in effect. +If this field is +.BR \- , +the variable part is null. +.PP +A zone line has the form +.sp +.nf +.ti +.5i +.ta \w'Zone\0\0'u +\w'Australia/Adelaide\0\0'u +\w'GMTOFF\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u +Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +.sp +For example: +.sp +.ti +.5i +Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00 +.sp +.fi +The fields that make up a zone line are: +.TP "\w'GMTOFF'u" +.B NAME +The name of the time zone. +This is the name used in creating the time conversion information file for the +zone. +.TP +.B GMTOFF +The amount of time to add to GMT to get standard time in this zone. +This field has the same format as the +.B AT +and +.B SAVE +fields of rule lines; +begin the field with a minus sign if time must be subtracted from GMT. +.TP +.B 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 +.B \- +then standard time always applies in the time zone. +.TP +.B FORMAT +The format for time zone abbreviations in this time zone. +The pair of characters +.B %s +is used to show where the +.q "variable part" +of the time zone abbreviation goes. +.TP +.B UNTIL +The time at which the GMT 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 GMT offset +and rule change until the time specified. +.IP +The next line must be a +.q continuation +line; this has the same form as a zone line except that the +string +.q Zone +and the name are omitted, as the continuation line will +place information starting at the time specified as the +.B UNTIL +field in the previous line in the file used by the previous line. +Continuation lines may contain an +.B UNTIL +field, just as zone lines do, indicating that the next line is a further +continuation. +.PP +A link line has the form +.sp +.nf +.ti +.5i +.if t .ta \w'Link\0\0'u +\w'LINK-FROM\0\0'u +.if n .ta \w'Link\0\0'u +\w'US/Eastern\0\0'u +Link LINK-FROM LINK-TO +.sp +For example: +.sp +.ti +.5i +Link US/Eastern EST5EDT +.sp +.fi +The +.B LINK-FROM +field should appear as the +.B NAME +field in some zone line; +the +.B 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: +.nf +.ti +.5i +.ta \w'Leap\0\0'u +\w'YEAR\0\0'u +\w'MONTH\0\0'u +\w'DAY\0\0'u +\w'HH:MM:SS\0\0'u +\w'CORR\0\0'u +.sp +Leap YEAR MONTH DAY HH:MM:SS CORR R/S +.sp +For example: +.ti +.5i +.sp +Leap 1974 Dec 31 23:59:60 + S +.sp +.fi +The +.BR YEAR , +.BR MONTH , +.BR DAY , +and +.B HH:MM:SS +fields tell when the leap second happened. +The +.B CORR +field +should be +.q + +if a second was added +or +.q - +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 +.B R/S +field +should be (an abbreviation of) +.q Stationary +if the leap second time given by the other fields should be interpreted as GMT +or +(an abbreviation of) +.q Rolling +if the leap second time given by the other fields should be interpreted as +local wall clock time. +.SH NOTE +For areas with more than two types of local time, +you may need to use local standard time in the +.B AT +field of the earliest transition time's rule to ensure that +the earliest transition time recorded in the compiled file is correct. +.SH FILE +/usr/local/etc/zoneinfo standard directory used for created files +.SH "SEE ALSO" +newctime(3), tzfile(5), zdump(8) +.\" @(#)zic.8 7.10 diff --git a/time/zic.c b/time/zic.c new file mode 100644 index 000000000..73ea46821 --- /dev/null +++ b/time/zic.c @@ -0,0 +1,1956 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)zic.c 7.28"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#include "private.h" +#include "tzfile.h" + +struct rule { + const char * r_filename; + int r_linenum; + const char * r_name; + + int r_loyear; /* for example, 1986 */ + int r_hiyear; /* for example, 1986 */ + const char * r_yrtype; + + int r_month; /* 0..11 */ + + int r_dycode; /* see below */ + int r_dayofmonth; + int r_wday; + + long r_tod; /* time from midnight */ + int r_todisstd; /* above is standard time if TRUE */ + /* or wall clock time if FALSE */ + int r_todisuniv; /* above is universal time if TRUE */ + /* or local time if FALSE */ + long r_stdoff; /* offset from standard time */ + const char * r_abbrvar; /* variable part of abbreviation */ + + int r_todo; /* a rule to do (used in outzone) */ + time_t r_temp; /* used in outzone */ +}; + +/* +** r_dycode r_dayofmonth r_wday +*/ + +#define DC_DOM 0 /* 1..31 */ /* unused */ +#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */ +#define DC_DOWLEQ 2 /* 1..31 */ /* 0..6 (Sun..Sat) */ + +struct zone { + const char * z_filename; + int z_linenum; + + const char * z_name; + long z_gmtoff; + const char * z_rule; + const char * z_format; + + long z_stdoff; + + struct rule * z_rules; + int z_nrules; + + struct rule z_untilrule; + time_t z_untiltime; +}; + +extern int emkdir P((const char * name, int mode)); +extern int getopt P((int argc, char * argv[], const char * options)); +extern char * icatalloc P((char * old, const char * new)); +extern char * icpyalloc P((const char * string)); +extern void ifree P((char * p)); +extern char * imalloc P((int n)); +extern void * irealloc P((void * old, int n)); +extern int link P((const char * fromname, const char * toname)); +extern char * optarg; +extern int optind; +extern char * scheck P((const char * string, const char * format)); + +static void addtt P((time_t starttime, int type)); +static int addtype P((long gmtoff, const char * abbr, int isdst, + int ttisstd)); +static void leapadd P((time_t t, int positive, int rolling, int count)); +static void adjleap P((void)); +static void associate P((void)); +static int ciequal P((const char * ap, const char * bp)); +static void convert P((long val, char * buf)); +static void dolink P((const char * fromfile, const char * tofile)); +static void eat P((const char * name, int num)); +static void eats P((const char * name, int num, + const char * rname, int rnum)); +static long eitol P((int i)); +static void error P((const char * message)); +static char ** getfields P((char * buf)); +static long gethms P((const char * string, const char * errstrng, + int signable)); +static void infile P((const char * filename)); +static void inleap P((char ** fields, int nfields)); +static void inlink P((char ** fields, int nfields)); +static void inrule P((char ** fields, int nfields)); +static int inzcont P((char ** fields, int nfields)); +static int inzone P((char ** fields, int nfields)); +static int inzsub P((char ** fields, int nfields, int iscont)); +static int itsabbr P((const char * abbr, const char * word)); +static int itsdir P((const char * name)); +static int lowerit P((int c)); +static char * memcheck P((char * tocheck)); +static int mkdirs P((char * filename)); +static void newabbr P((const char * abbr)); +static long oadd P((long t1, long t2)); +static void outzone P((const struct zone * zp, int ntzones)); +static void puttzcode P((long code, FILE * fp)); +static int rcomp P((const genericptr_T leftp, const genericptr_T rightp)); +static time_t rpytime P((const struct rule * rp, int wantedy)); +static void rulesub P((struct rule * rp, + const char * loyearp, const char * hiyearp, + const char * typep, const char * monthp, + const char * dayp, const char * timep)); +static void setboundaries P((void)); +static time_t tadd P((time_t t1, long t2)); +static void usage P((void)); +static void writezone P((const char * name)); +static int yearistype P((int year, const char * type)); + +static int charcnt; +static int errors; +static const char * filename; +static int leapcnt; +static int linenum; +static int max_int; +static time_t max_time; +static int max_year; +static int min_int; +static time_t min_time; +static int min_year; +static int noise; +static const char * rfilename; +static int rlinenum; +static const char * progname; +static int timecnt; +static int typecnt; +static int tt_signed; + +/* +** Line codes. +*/ + +#define LC_RULE 0 +#define LC_ZONE 1 +#define LC_LINK 2 +#define LC_LEAP 3 + +/* +** Which fields are which on a Zone line. +*/ + +#define ZF_NAME 1 +#define ZF_GMTOFF 2 +#define ZF_RULE 3 +#define ZF_FORMAT 4 +#define ZF_TILYEAR 5 +#define ZF_TILMONTH 6 +#define ZF_TILDAY 7 +#define ZF_TILTIME 8 +#define ZONE_MINFIELDS 5 +#define ZONE_MAXFIELDS 9 + +/* +** Which fields are which on a Zone continuation line. +*/ + +#define ZFC_GMTOFF 0 +#define ZFC_RULE 1 +#define ZFC_FORMAT 2 +#define ZFC_TILYEAR 3 +#define ZFC_TILMONTH 4 +#define ZFC_TILDAY 5 +#define ZFC_TILTIME 6 +#define ZONEC_MINFIELDS 3 +#define ZONEC_MAXFIELDS 7 + +/* +** Which files are which on a Rule line. +*/ + +#define RF_NAME 1 +#define RF_LOYEAR 2 +#define RF_HIYEAR 3 +#define RF_COMMAND 4 +#define RF_MONTH 5 +#define RF_DAY 6 +#define RF_TOD 7 +#define RF_STDOFF 8 +#define RF_ABBRVAR 9 +#define RULE_FIELDS 10 + +/* +** Which fields are which on a Link line. +*/ + +#define LF_FROM 1 +#define LF_TO 2 +#define LINK_FIELDS 3 + +/* +** Which fields are which on a Leap line. +*/ + +#define LP_YEAR 1 +#define LP_MONTH 2 +#define LP_DAY 3 +#define LP_TIME 4 +#define LP_CORR 5 +#define LP_ROLL 6 +#define LEAP_FIELDS 7 + +/* +** Year synonyms. +*/ + +#define YR_MINIMUM 0 +#define YR_MAXIMUM 1 +#define YR_ONLY 2 + +static struct rule * rules; +static int nrules; /* number of rules */ + +static struct zone * zones; +static int nzones; /* number of zones */ + +struct link { + const char * l_filename; + int l_linenum; + const char * l_from; + const char * l_to; +}; + +static struct link * links; +static int nlinks; + +struct lookup { + const char * l_word; + const int l_value; +}; + +static struct lookup const * byword P((const char * string, + const struct lookup * lp)); + +static struct lookup const line_codes[] = { + { "Rule", LC_RULE }, + { "Zone", LC_ZONE }, + { "Link", LC_LINK }, + { "Leap", LC_LEAP }, + { NULL, 0} +}; + +static struct lookup const mon_names[] = { + { "January", TM_JANUARY }, + { "February", TM_FEBRUARY }, + { "March", TM_MARCH }, + { "April", TM_APRIL }, + { "May", TM_MAY }, + { "June", TM_JUNE }, + { "July", TM_JULY }, + { "August", TM_AUGUST }, + { "September", TM_SEPTEMBER }, + { "October", TM_OCTOBER }, + { "November", TM_NOVEMBER }, + { "December", TM_DECEMBER }, + { NULL, 0 } +}; + +static struct lookup const wday_names[] = { + { "Sunday", TM_SUNDAY }, + { "Monday", TM_MONDAY }, + { "Tuesday", TM_TUESDAY }, + { "Wednesday", TM_WEDNESDAY }, + { "Thursday", TM_THURSDAY }, + { "Friday", TM_FRIDAY }, + { "Saturday", TM_SATURDAY }, + { NULL, 0 } +}; + +static struct lookup const lasts[] = { + { "last-Sunday", TM_SUNDAY }, + { "last-Monday", TM_MONDAY }, + { "last-Tuesday", TM_TUESDAY }, + { "last-Wednesday", TM_WEDNESDAY }, + { "last-Thursday", TM_THURSDAY }, + { "last-Friday", TM_FRIDAY }, + { "last-Saturday", TM_SATURDAY }, + { NULL, 0 } +}; + +static struct lookup const begin_years[] = { + { "minimum", YR_MINIMUM }, + { "maximum", YR_MAXIMUM }, + { NULL, 0 } +}; + +static struct lookup const end_years[] = { + { "minimum", YR_MINIMUM }, + { "maximum", YR_MAXIMUM }, + { "only", YR_ONLY }, + { NULL, 0 } +}; + +static struct lookup const leap_types[] = { + { "Rolling", TRUE }, + { "Stationary", FALSE }, + { NULL, 0 } +}; + +static const int len_months[2][MONSPERYEAR] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const int len_years[2] = { + DAYSPERNYEAR, DAYSPERLYEAR +}; + +static time_t ats[TZ_MAX_TIMES]; +static unsigned char types[TZ_MAX_TIMES]; +static long gmtoffs[TZ_MAX_TYPES]; +static char isdsts[TZ_MAX_TYPES]; +static unsigned char abbrinds[TZ_MAX_TYPES]; +static char ttisstds[TZ_MAX_TYPES]; +static char chars[TZ_MAX_CHARS]; +static time_t trans[TZ_MAX_LEAPS]; +static long corr[TZ_MAX_LEAPS]; +static char roll[TZ_MAX_LEAPS]; + +/* +** Memory allocation. +*/ + +static char * +memcheck(ptr) +char * const ptr; +{ + if (ptr == NULL) { + (void) perror(progname); + (void) exit(EXIT_FAILURE); + } + return ptr; +} + +#define emalloc(size) memcheck(imalloc(size)) +#define erealloc(ptr, size) memcheck(irealloc((ptr), (size))) +#define ecpyalloc(ptr) memcheck(icpyalloc(ptr)) +#define ecatalloc(oldp, newp) memcheck(icatalloc((oldp), (newp))) + +/* +** Error handling. +*/ + +static void +eats(name, num, rname, rnum) +const char * const name; +const int num; +const char * const rname; +const int rnum; +{ + filename = name; + linenum = num; + rfilename = rname; + rlinenum = rnum; +} + +static void +eat(name, num) +const char * const name; +const int num; +{ + eats(name, num, (char *) NULL, -1); +} + +static void +error(string) +const char * const string; +{ + /* + ** Match the format of "cc" to allow sh users to + ** zic ... 2>&1 | error -t "*" -v + ** on BSD systems. + */ + (void) fprintf(stderr, "\"%s\", line %d: %s", + filename, linenum, string); + if (rfilename != NULL) + (void) fprintf(stderr, " (rule from \"%s\", line %d)", + rfilename, rlinenum); + (void) fprintf(stderr, "\n"); + ++errors; +} + +static void +usage P((void)) +{ + (void) fprintf(stderr, +"%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ] \n\ +\t[ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n", + progname, progname); + (void) exit(EXIT_FAILURE); +} + +static const char * psxrules; +static const char * lcltime; +static const char * directory; +static const char * leapsec; +static const char * yitcommand; +static int sflag = FALSE; + +int +main(argc, argv) +int argc; +char * argv[]; +{ + register int i, j; + register int c; + +#ifdef unix + (void) umask(umask(022) | 022); +#endif /* defined unix */ + progname = argv[0]; + while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF) + switch (c) { + default: + usage(); + case 'd': + if (directory == NULL) + directory = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -d option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'l': + if (lcltime == NULL) + lcltime = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -l option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'p': + if (psxrules == NULL) + psxrules = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -p option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'y': + if (yitcommand == NULL) + yitcommand = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -y option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'L': + if (leapsec == NULL) + leapsec = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -L option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'v': + noise = TRUE; + break; + case 's': + sflag = TRUE; + break; + } + if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) + usage(); /* usage message by request */ + if (directory == NULL) + directory = TZDIR; + if (yitcommand == NULL) + yitcommand = "yearistype"; + + setboundaries(); + + if (optind < argc && leapsec != NULL) { + infile(leapsec); + adjleap(); + } + + for (i = optind; i < argc; ++i) + infile(argv[i]); + if (errors) + (void) exit(EXIT_FAILURE); + associate(); + for (i = 0; i < nzones; i = j) { + /* + ** Find the next non-continuation zone entry. + */ + for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j) + continue; + outzone(&zones[i], j - i); + } + /* + ** Make links. + */ + for (i = 0; i < nlinks; ++i) + dolink(links[i].l_from, links[i].l_to); + if (lcltime != NULL) + dolink(lcltime, TZDEFAULT); + if (psxrules != NULL) + dolink(psxrules, TZDEFRULES); + return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +static void +dolink(fromfile, tofile) +const char * const fromfile; +const char * const tofile; +{ + register char * fromname; + register char * toname; + + if (fromfile[0] == '/') + fromname = ecpyalloc(fromfile); + else { + fromname = ecpyalloc(directory); + fromname = ecatalloc(fromname, "/"); + fromname = ecatalloc(fromname, fromfile); + } + if (tofile[0] == '/') + toname = ecpyalloc(tofile); + else { + toname = ecpyalloc(directory); + toname = ecatalloc(toname, "/"); + toname = ecatalloc(toname, tofile); + } + /* + ** We get to be careful here since + ** there's a fair chance of root running us. + */ + if (!itsdir(toname)) + (void) remove(toname); + if (link(fromname, toname) != 0) { + if (mkdirs(toname) != 0) + (void) exit(EXIT_FAILURE); + if (link(fromname, toname) != 0) { + (void) fprintf(stderr, "%s: Can't link from %s to ", + progname, fromname); + (void) perror(toname); + (void) exit(EXIT_FAILURE); + } + } + ifree(fromname); + ifree(toname); +} + +static void +setboundaries P((void)) +{ + register time_t bit; + register int bii; + + for (bit = 1; bit > 0; bit <<= 1) + continue; + if (bit == 0) { /* time_t is an unsigned type */ + tt_signed = FALSE; + min_time = 0; + max_time = ~(time_t) 0; + if (sflag) + max_time >>= 1; + } else { + tt_signed = TRUE; + min_time = bit; + max_time = bit; + ++max_time; + max_time = -max_time; + if (sflag) + min_time = 0; + } + min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year; + max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year; + + for (bii = 1; bii > 0; bii <<= 1) + continue; + min_int = bii; + max_int = -1 - bii; +} + +static int +itsdir(name) +const char * const name; +{ + register char * myname; + register int accres; + + myname = ecpyalloc(name); + myname = ecatalloc(myname, "/."); + accres = access(myname, 0); + ifree(myname); + return accres == 0; +} + +/* +** Associate sets of rules with zones. +*/ + +/* +** Sort by rule name. +*/ + +static int +rcomp(cp1, cp2) +const genericptr_T cp1; +const genericptr_T cp2; +{ + return strcmp(((struct rule *) cp1)->r_name, + ((struct rule *) cp2)->r_name); +} + +static void +associate P((void)) +{ + register struct zone * zp; + register struct rule * rp; + register int base, out; + register int i; + + if (nrules != 0) + (void) qsort((genericptr_T) rules, + (qsort_size_T) nrules, + (qsort_size_T) sizeof *rules, rcomp); + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + zp->z_rules = NULL; + zp->z_nrules = 0; + } + for (base = 0; base < nrules; base = out) { + rp = &rules[base]; + for (out = base + 1; out < nrules; ++out) + if (strcmp(rp->r_name, rules[out].r_name) != 0) + break; + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + if (strcmp(zp->z_rule, rp->r_name) != 0) + continue; + zp->z_rules = rp; + zp->z_nrules = out - base; + } + } + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + if (zp->z_nrules == 0) { + /* + ** Maybe we have a local standard time offset. + */ + eat(zp->z_filename, zp->z_linenum); + zp->z_stdoff = gethms(zp->z_rule, "unruly zone", TRUE); + /* + ** Note, though, that if there's no rule, + ** a '%s' in the format is a bad thing. + */ + if (strchr(zp->z_format, '%') != 0) + error("%s in ruleless zone"); + } + } + if (errors) + (void) exit(EXIT_FAILURE); +} + +static void +infile(name) +const char * name; +{ + register FILE * fp; + register char ** fields; + register char * cp; + register const struct lookup * lp; + register int nfields; + register int wantcont; + register int num; + char buf[BUFSIZ]; + + if (strcmp(name, "-") == 0) { + name = "standard input"; + fp = stdin; + } else if ((fp = fopen(name, "r")) == NULL) { + (void) fprintf(stderr, "%s: Can't open ", progname); + (void) perror(name); + (void) exit(EXIT_FAILURE); + } + wantcont = FALSE; + for (num = 1; ; ++num) { + eat(name, num); + if (fgets(buf, (int) sizeof buf, fp) != buf) + break; + cp = strchr(buf, '\n'); + if (cp == NULL) { + error("line too long"); + (void) exit(EXIT_FAILURE); + } + *cp = '\0'; + fields = getfields(buf); + nfields = 0; + while (fields[nfields] != NULL) { + static char nada; + + if (ciequal(fields[nfields], "-")) + fields[nfields] = &nada; + ++nfields; + } + if (nfields == 0) { + /* nothing to do */ + } else if (wantcont) { + wantcont = inzcont(fields, nfields); + } else { + lp = byword(fields[0], line_codes); + if (lp == NULL) + error("input line of unknown type"); + else switch ((int) (lp->l_value)) { + case LC_RULE: + inrule(fields, nfields); + wantcont = FALSE; + break; + case LC_ZONE: + wantcont = inzone(fields, nfields); + break; + case LC_LINK: + inlink(fields, nfields); + wantcont = FALSE; + break; + case LC_LEAP: + if (name != leapsec) + (void) fprintf(stderr, +"%s: Leap line in non leap seconds file %s\n", + progname, name); + else inleap(fields, nfields); + wantcont = FALSE; + break; + default: /* "cannot happen" */ + (void) fprintf(stderr, +"%s: panic: Invalid l_value %d\n", + progname, lp->l_value); + (void) exit(EXIT_FAILURE); + } + } + ifree((char *) fields); + } + if (ferror(fp)) { + (void) fprintf(stderr, "%s: Error reading ", progname); + (void) perror(filename); + (void) exit(EXIT_FAILURE); + } + if (fp != stdin && fclose(fp)) { + (void) fprintf(stderr, "%s: Error closing ", progname); + (void) perror(filename); + (void) exit(EXIT_FAILURE); + } + if (wantcont) + error("expected continuation line not found"); +} + +/* +** Convert a string of one of the forms +** h -h hh:mm -hh:mm hh:mm:ss -hh:mm:ss +** into a number of seconds. +** A null string maps to zero. +** Call error with errstring and return zero on errors. +*/ + +static long +gethms(string, errstring, signable) +const char * string; +const char * const errstring; +const int signable; +{ + int hh, mm, ss, sign; + + if (string == NULL || *string == '\0') + return 0; + if (!signable) + sign = 1; + else if (*string == '-') { + sign = -1; + ++string; + } else sign = 1; + if (sscanf(string, scheck(string, "%d"), &hh) == 1) + mm = ss = 0; + else if (sscanf(string, scheck(string, "%d:%d"), &hh, &mm) == 2) + ss = 0; + else if (sscanf(string, scheck(string, "%d:%d:%d"), + &hh, &mm, &ss) != 3) { + error(errstring); + return 0; + } + if (hh < 0 || hh >= HOURSPERDAY || + mm < 0 || mm >= MINSPERHOUR || + ss < 0 || ss > SECSPERMIN) { + error(errstring); + return 0; + } + return eitol(sign) * + (eitol(hh * MINSPERHOUR + mm) * + eitol(SECSPERMIN) + eitol(ss)); +} + +static void +inrule(fields, nfields) +register char ** const fields; +const int nfields; +{ + static struct rule r; + + if (nfields != RULE_FIELDS) { + error("wrong number of fields on Rule line"); + return; + } + if (*fields[RF_NAME] == '\0') { + error("nameless rule"); + return; + } + r.r_filename = filename; + r.r_linenum = linenum; + r.r_stdoff = gethms(fields[RF_STDOFF], "invalid saved time", TRUE); + rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND], + fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); + r.r_name = ecpyalloc(fields[RF_NAME]); + r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]); + rules = (struct rule *) (void *) erealloc((char *) rules, + (int) ((nrules + 1) * sizeof *rules)); + rules[nrules++] = r; +} + +static int +inzone(fields, nfields) +register char ** const fields; +const int nfields; +{ + register int i; + static char * buf; + + if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) { + error("wrong number of fields on Zone line"); + return FALSE; + } + if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) { + buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT))); + (void) sprintf(buf, +"\"Zone %s\" line and -l option are mutually exclusive", + TZDEFAULT); + error(buf); + return FALSE; + } + if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) { + buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES))); + (void) sprintf(buf, +"\"Zone %s\" line and -p option are mutually exclusive", + TZDEFRULES); + error(buf); + return FALSE; + } + for (i = 0; i < nzones; ++i) + if (zones[i].z_name != NULL && + strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) { + buf = erealloc(buf, (int) (132 + + strlen(fields[ZF_NAME]) + + strlen(zones[i].z_filename))); + (void) sprintf(buf, +"duplicate zone name %s (file \"%s\", line %d)", + fields[ZF_NAME], + zones[i].z_filename, + zones[i].z_linenum); + error(buf); + return FALSE; + } + return inzsub(fields, nfields, FALSE); +} + +static int +inzcont(fields, nfields) +register char ** const fields; +const int nfields; +{ + if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) { + error("wrong number of fields on Zone continuation line"); + return FALSE; + } + return inzsub(fields, nfields, TRUE); +} + +static int +inzsub(fields, nfields, iscont) +register char ** const fields; +const int nfields; +const int iscont; +{ + register char * cp; + static struct zone z; + register int i_gmtoff, i_rule, i_format; + register int i_untilyear, i_untilmonth; + register int i_untilday, i_untiltime; + register int hasuntil; + + if (iscont) { + i_gmtoff = ZFC_GMTOFF; + i_rule = ZFC_RULE; + i_format = ZFC_FORMAT; + i_untilyear = ZFC_TILYEAR; + i_untilmonth = ZFC_TILMONTH; + i_untilday = ZFC_TILDAY; + i_untiltime = ZFC_TILTIME; + z.z_name = NULL; + } else { + i_gmtoff = ZF_GMTOFF; + i_rule = ZF_RULE; + i_format = ZF_FORMAT; + i_untilyear = ZF_TILYEAR; + i_untilmonth = ZF_TILMONTH; + i_untilday = ZF_TILDAY; + i_untiltime = ZF_TILTIME; + z.z_name = ecpyalloc(fields[ZF_NAME]); + } + z.z_filename = filename; + z.z_linenum = linenum; + z.z_gmtoff = gethms(fields[i_gmtoff], "invalid GMT offset", TRUE); + if ((cp = strchr(fields[i_format], '%')) != 0) { + if (*++cp != 's' || strchr(cp, '%') != 0) { + error("invalid abbreviation format"); + return FALSE; + } + } + z.z_rule = ecpyalloc(fields[i_rule]); + z.z_format = ecpyalloc(fields[i_format]); + hasuntil = nfields > i_untilyear; + if (hasuntil) { + z.z_untilrule.r_filename = filename; + z.z_untilrule.r_linenum = linenum; + rulesub(&z.z_untilrule, + fields[i_untilyear], + "only", + "", + (nfields > i_untilmonth) ? + fields[i_untilmonth] : "Jan", + (nfields > i_untilday) ? fields[i_untilday] : "1", + (nfields > i_untiltime) ? fields[i_untiltime] : "0"); + z.z_untiltime = rpytime(&z.z_untilrule, + z.z_untilrule.r_loyear); + if (iscont && nzones > 0 && + z.z_untiltime > min_time && + z.z_untiltime < max_time && + zones[nzones - 1].z_untiltime > min_time && + zones[nzones - 1].z_untiltime < max_time && + zones[nzones - 1].z_untiltime >= z.z_untiltime) { +error("Zone continuation line end time is not after end time of previous line"); + return FALSE; + } + } + zones = (struct zone *) (void *) erealloc((char *) zones, + (int) ((nzones + 1) * sizeof *zones)); + zones[nzones++] = z; + /* + ** If there was an UNTIL field on this line, + ** there's more information about the zone on the next line. + */ + return hasuntil; +} + +static void +inleap(fields, nfields) +register char ** const fields; +const int nfields; +{ + register const char * cp; + register const struct lookup * lp; + register int i, j; + int year, month, day; + long dayoff, tod; + time_t t; + + if (nfields != LEAP_FIELDS) { + error("wrong number of fields on Leap line"); + return; + } + dayoff = 0; + cp = fields[LP_YEAR]; + if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { + /* + * Leapin' Lizards! + */ + error("invalid leaping year"); + return; + } + j = EPOCH_YEAR; + while (j != year) { + if (year > j) { + i = len_years[isleap(j)]; + ++j; + } else { + --j; + i = -len_years[isleap(j)]; + } + dayoff = oadd(dayoff, eitol(i)); + } + if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) { + error("invalid month name"); + return; + } + month = lp->l_value; + j = TM_JANUARY; + while (j != month) { + i = len_months[isleap(year)][j]; + dayoff = oadd(dayoff, eitol(i)); + ++j; + } + cp = fields[LP_DAY]; + if (sscanf(cp, scheck(cp, "%d"), &day) != 1 || + day <= 0 || day > len_months[isleap(year)][month]) { + error("invalid day of month"); + return; + } + dayoff = oadd(dayoff, eitol(day - 1)); + if (dayoff < 0 && !tt_signed) { + error("time before zero"); + return; + } + t = (time_t) dayoff * SECSPERDAY; + /* + ** Cheap overflow check. + */ + if (t / SECSPERDAY != dayoff) { + error("time overflow"); + return; + } + tod = gethms(fields[LP_TIME], "invalid time of day", FALSE); + cp = fields[LP_CORR]; + { + register int positive; + int count; + + if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */ + positive = FALSE; + count = 1; + } else if (strcmp(cp, "--") == 0) { + positive = FALSE; + count = 2; + } else if (strcmp(cp, "+") == 0) { + positive = TRUE; + count = 1; + } else if (strcmp(cp, "++") == 0) { + positive = TRUE; + count = 2; + } else { + error("illegal CORRECTION field on Leap line"); + return; + } + if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { + error("illegal Rolling/Stationary field on Leap line"); + return; + } + leapadd(tadd(t, tod), positive, lp->l_value, count); + } +} + +static void +inlink(fields, nfields) +register char ** const fields; +const int nfields; +{ + struct link l; + + if (nfields != LINK_FIELDS) { + error("wrong number of fields on Link line"); + return; + } + if (*fields[LF_FROM] == '\0') { + error("blank FROM field on Link line"); + return; + } + if (*fields[LF_TO] == '\0') { + error("blank TO field on Link line"); + return; + } + l.l_filename = filename; + l.l_linenum = linenum; + l.l_from = ecpyalloc(fields[LF_FROM]); + l.l_to = ecpyalloc(fields[LF_TO]); + links = (struct link *) (void *) erealloc((char *) links, + (int) ((nlinks + 1) * sizeof *links)); + links[nlinks++] = l; +} + +static void +rulesub(rp, loyearp, hiyearp, typep, monthp, dayp, timep) +register struct rule * const rp; +const char * const loyearp; +const char * const hiyearp; +const char * const typep; +const char * const monthp; +const char * const dayp; +const char * const timep; +{ + register const struct lookup * lp; + register const char * cp; + register char * dp; + register char * ep; + + if ((lp = byword(monthp, mon_names)) == NULL) { + error("invalid month name"); + return; + } + rp->r_month = lp->l_value; + rp->r_todisstd = FALSE; + rp->r_todisuniv = FALSE; + dp = ecpyalloc(timep); + if (*dp != '\0') { + ep = dp + strlen(dp) - 1; + switch (lowerit(*ep)) { + case 's': /* Standard */ + rp->r_todisstd = TRUE; + rp->r_todisuniv = FALSE; + *ep = '\0'; + break; + case 'w': /* Wall */ + rp->r_todisstd = FALSE; + rp->r_todisuniv = FALSE; + *ep = '\0'; + case 'g': /* Greenwich */ + case 'u': /* Universal */ + case 'z': /* Zulu */ + rp->r_todisstd = TRUE; + rp->r_todisuniv = TRUE; + *ep = '\0'; + break; + } + } + rp->r_tod = gethms(dp, "invalid time of day", FALSE); + ifree(dp); + /* + ** Year work. + */ + cp = loyearp; + if ((lp = byword(cp, begin_years)) != NULL) switch ((int) lp->l_value) { + case YR_MINIMUM: + rp->r_loyear = min_int; + break; + case YR_MAXIMUM: + rp->r_loyear = max_int; + break; + default: /* "cannot happen" */ + (void) fprintf(stderr, + "%s: panic: Invalid l_value %d\n", + progname, lp->l_value); + (void) exit(EXIT_FAILURE); + } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { + error("invalid starting year"); + return; + } + cp = hiyearp; + if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) { + case YR_MINIMUM: + rp->r_hiyear = min_int; + break; + case YR_MAXIMUM: + rp->r_hiyear = max_int; + break; + case YR_ONLY: + rp->r_hiyear = rp->r_loyear; + break; + default: /* "cannot happen" */ + (void) fprintf(stderr, + "%s: panic: Invalid l_value %d\n", + progname, lp->l_value); + (void) exit(EXIT_FAILURE); + } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { + error("invalid ending year"); + return; + } + if (rp->r_loyear > rp->r_hiyear) { + error("starting year greater than ending year"); + return; + } + if (*typep == '\0') + rp->r_yrtype = NULL; + else { + if (rp->r_loyear == rp->r_hiyear) { + error("typed single year"); + return; + } + rp->r_yrtype = ecpyalloc(typep); + } + /* + ** Day work. + ** Accept things such as: + ** 1 + ** last-Sunday + ** Sun<=20 + ** Sun>=7 + */ + dp = ecpyalloc(dayp); + if ((lp = byword(dp, lasts)) != NULL) { + rp->r_dycode = DC_DOWLEQ; + rp->r_wday = lp->l_value; + rp->r_dayofmonth = len_months[1][rp->r_month]; + } else { + if ((ep = strchr(dp, '<')) != 0) + rp->r_dycode = DC_DOWLEQ; + else if ((ep = strchr(dp, '>')) != 0) + rp->r_dycode = DC_DOWGEQ; + else { + ep = dp; + rp->r_dycode = DC_DOM; + } + if (rp->r_dycode != DC_DOM) { + *ep++ = 0; + if (*ep++ != '=') { + error("invalid day of month"); + ifree(dp); + return; + } + if ((lp = byword(dp, wday_names)) == NULL) { + error("invalid weekday name"); + ifree(dp); + return; + } + rp->r_wday = lp->l_value; + } + if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 || + rp->r_dayofmonth <= 0 || + (rp->r_dayofmonth > len_months[1][rp->r_month])) { + error("invalid day of month"); + ifree(dp); + return; + } + } + ifree(dp); +} + +static void +convert(val, buf) +const long val; +char * const buf; +{ + register int i; + register long shift; + + for (i = 0, shift = 24; i < 4; ++i, shift -= 8) + buf[i] = val >> shift; +} + +static void +puttzcode(val, fp) +const long val; +FILE * const fp; +{ + char buf[4]; + + convert(val, buf); + (void) fwrite((genericptr_T) buf, + (fwrite_size_T) sizeof buf, + (fwrite_size_T) 1, fp); +} + +static void +writezone(name) +const char * const name; +{ + register FILE * fp; + register int i, j; + static char * fullname; + static struct tzhead tzh; + + fullname = erealloc(fullname, + (int) (strlen(directory) + 1 + strlen(name) + 1)); + (void) sprintf(fullname, "%s/%s", directory, name); + if ((fp = fopen(fullname, "wb")) == NULL) { + if (mkdirs(fullname) != 0) + (void) exit(EXIT_FAILURE); + if ((fp = fopen(fullname, "wb")) == NULL) { + (void) fprintf(stderr, "%s: Can't create ", progname); + (void) perror(fullname); + (void) exit(EXIT_FAILURE); + } + } + convert(eitol(typecnt), tzh.tzh_ttisstdcnt); + convert(eitol(leapcnt), tzh.tzh_leapcnt); + convert(eitol(timecnt), tzh.tzh_timecnt); + convert(eitol(typecnt), tzh.tzh_typecnt); + convert(eitol(charcnt), tzh.tzh_charcnt); + (void) fwrite((genericptr_T) &tzh, + (fwrite_size_T) sizeof tzh, + (fwrite_size_T) 1, fp); + for (i = 0; i < timecnt; ++i) { + j = leapcnt; + while (--j >= 0) + if (ats[i] >= trans[j]) { + ats[i] = tadd(ats[i], corr[j]); + break; + } + puttzcode((long) ats[i], fp); + } + if (timecnt > 0) + (void) fwrite((genericptr_T) types, + (fwrite_size_T) sizeof types[0], + (fwrite_size_T) timecnt, fp); + for (i = 0; i < typecnt; ++i) { + puttzcode((long) gmtoffs[i], fp); + (void) putc(isdsts[i], fp); + (void) putc(abbrinds[i], fp); + } + if (charcnt != 0) + (void) fwrite((genericptr_T) chars, + (fwrite_size_T) sizeof chars[0], + (fwrite_size_T) charcnt, fp); + for (i = 0; i < leapcnt; ++i) { + if (roll[i]) { + if (timecnt == 0 || trans[i] < ats[0]) { + j = 0; + while (isdsts[j]) + if (++j >= typecnt) { + j = 0; + break; + } + } else { + j = 1; + while (j < timecnt && trans[i] >= ats[j]) + ++j; + j = types[j - 1]; + } + puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp); + } else puttzcode((long) trans[i], fp); + puttzcode((long) corr[i], fp); + } + for (i = 0; i < typecnt; ++i) + (void) putc(ttisstds[i], fp); + if (ferror(fp) || fclose(fp)) { + (void) fprintf(stderr, "%s: Write error on ", progname); + (void) perror(fullname); + (void) exit(EXIT_FAILURE); + } +} + +static void +outzone(zpfirst, zonecount) +const struct zone * const zpfirst; +const int zonecount; +{ + register const struct zone * zp; + register struct rule * rp; + register int i, j; + register int usestart, useuntil; + register time_t starttime, untiltime; + register long gmtoff; + register long stdoff; + register int year; + register long startoff; + register int startisdst; + register int startttisstd; + register int type; + char startbuf[BUFSIZ]; + + INITIALIZE(untiltime); + INITIALIZE(starttime); + INITIALIZE(startoff); + /* + ** Now. . .finally. . .generate some useful data! + */ + timecnt = 0; + typecnt = 0; + charcnt = 0; + /* + ** A guess that may well be corrected later. + */ + stdoff = 0; + /* + ** Thanks to Earl Chew (earl@dnd.icp.nec.com.au) + ** for noting the need to unconditionally initialize startttisstd. + */ + startttisstd = FALSE; +#ifdef lint + starttime = 0; +#endif /* defined lint */ + for (i = 0; i < zonecount; ++i) { + zp = &zpfirst[i]; + usestart = i > 0 && (zp - 1)->z_untiltime > min_time; + useuntil = i < (zonecount - 1); + if (useuntil && zp->z_untiltime <= min_time) + continue; + gmtoff = zp->z_gmtoff; + eat(zp->z_filename, zp->z_linenum); + startisdst = -1; + if (zp->z_nrules == 0) { + stdoff = zp->z_stdoff; + (void) strcpy(startbuf, zp->z_format); + type = addtype(oadd(zp->z_gmtoff, stdoff), + startbuf, stdoff != 0, startttisstd); + if (usestart) + addtt(starttime, type); + else if (stdoff != 0) + addtt(min_time, type); + } else for (year = min_year; year <= max_year; ++year) { + if (useuntil && year > zp->z_untilrule.r_hiyear) + break; + /* + ** Mark which rules to do in the current year. + ** For those to do, calculate rpytime(rp, year); + */ + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + rp->r_todo = year >= rp->r_loyear && + year <= rp->r_hiyear && + yearistype(year, rp->r_yrtype); + if (rp->r_todo) + rp->r_temp = rpytime(rp, year); + } + for ( ; ; ) { + register int k; + register time_t jtime, ktime; + register long offset; + char buf[BUFSIZ]; + + INITIALIZE(ktime); + if (useuntil) { + /* + ** Turn untiltime into GMT + ** assuming the current gmtoff and + ** stdoff values. + */ + untiltime = zp->z_untiltime; + if (!zp->z_untilrule.r_todisuniv) + untiltime = tadd(untiltime, + -gmtoff); + if (!zp->z_untilrule.r_todisstd) + untiltime = tadd(untiltime, + -stdoff); + } + /* + ** Find the rule (of those to do, if any) + ** that takes effect earliest in the year. + */ + k = -1; +#ifdef lint + ktime = 0; +#endif /* defined lint */ + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + if (!rp->r_todo) + continue; + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + offset = rp->r_todisuniv ? 0 : gmtoff; + if (!rp->r_todisstd) + offset = oadd(offset, stdoff); + jtime = rp->r_temp; + if (jtime == min_time || + jtime == max_time) + continue; + jtime = tadd(jtime, -offset); + if (k < 0 || jtime < ktime) { + k = j; + ktime = jtime; + } + } + if (k < 0) + break; /* go on to next year */ + rp = &zp->z_rules[k]; + rp->r_todo = FALSE; + if (useuntil && ktime >= untiltime) + break; + if (usestart) { + if (ktime < starttime) { + stdoff = rp->r_stdoff; + startoff = oadd(zp->z_gmtoff, + rp->r_stdoff); + (void) sprintf(startbuf, zp->z_format, + rp->r_abbrvar); + startisdst = rp->r_stdoff != 0; + continue; + } + usestart = FALSE; + if (ktime != starttime) { + if (startisdst < 0 && + zp->z_gmtoff != + (zp - 1)->z_gmtoff) { + type = (timecnt == 0) ? 0 : + types[timecnt - 1]; + startoff = oadd(gmtoffs[type], + -(zp - 1)->z_gmtoff); + startisdst = startoff != 0; + startoff = oadd(startoff, + zp->z_gmtoff); + (void) strcpy(startbuf, + &chars[abbrinds[type]]); + } + if (startisdst >= 0) +addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd)); + } + } + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + (void) sprintf(buf, zp->z_format, + rp->r_abbrvar); + offset = oadd(zp->z_gmtoff, rp->r_stdoff); + type = addtype(offset, buf, rp->r_stdoff != 0, + rp->r_todisstd); + addtt(ktime, type); + stdoff = rp->r_stdoff; + } + } + /* + ** Now we may get to set starttime for the next zone line. + */ + if (useuntil) { + starttime = tadd(zp->z_untiltime, -gmtoff); + startttisstd = zp->z_untilrule.r_todisstd; + if (!startttisstd) + starttime = tadd(starttime, -stdoff); + } + } + writezone(zpfirst->z_name); +} + +static void +addtt(starttime, type) +const time_t starttime; +const int type; +{ + if (timecnt != 0 && type == types[timecnt - 1]) + return; /* easy enough! */ + if (timecnt == 0 && type == 0 && isdsts[0] == 0) + return; /* handled by default rule */ + if (timecnt >= TZ_MAX_TIMES) { + error("too many transitions?!"); + (void) exit(EXIT_FAILURE); + } + ats[timecnt] = starttime; + types[timecnt] = type; + ++timecnt; +} + +static int +addtype(gmtoff, abbr, isdst, ttisstd) +const long gmtoff; +const char * const abbr; +const int isdst; +const int ttisstd; +{ + register int i, j; + + /* + ** See if there's already an entry for this zone type. + ** If so, just return its index. + */ + for (i = 0; i < typecnt; ++i) { + if (gmtoff == gmtoffs[i] && isdst == isdsts[i] && + strcmp(abbr, &chars[abbrinds[i]]) == 0 && + ttisstd == ttisstds[i]) + return i; + } + /* + ** There isn't one; add a new one, unless there are already too + ** many. + */ + if (typecnt >= TZ_MAX_TYPES) { + error("too many local time types"); + (void) exit(EXIT_FAILURE); + } + gmtoffs[i] = gmtoff; + isdsts[i] = isdst; + ttisstds[i] = ttisstd; + + for (j = 0; j < charcnt; ++j) + if (strcmp(&chars[j], abbr) == 0) + break; + if (j == charcnt) + newabbr(abbr); + abbrinds[i] = j; + ++typecnt; + return i; +} + +static void +leapadd(t, positive, rolling, count) +const time_t t; +const int positive; +const int rolling; +int count; +{ + register int i, j; + + if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { + error("too many leap seconds"); + (void) exit(EXIT_FAILURE); + } + for (i = 0; i < leapcnt; ++i) + if (t <= trans[i]) { + if (t == trans[i]) { + error("repeated leap second moment"); + (void) exit(EXIT_FAILURE); + } + break; + } + do { + for (j = leapcnt; j > i; --j) { + trans[j] = trans[j - 1]; + corr[j] = corr[j - 1]; + roll[j] = roll[j - 1]; + } + trans[i] = t; + corr[i] = positive ? 1L : eitol(-count); + roll[i] = rolling; + ++leapcnt; + } while (positive && --count != 0); +} + +static void +adjleap P((void)) +{ + register int i; + register long last = 0; + + /* + ** propagate leap seconds forward + */ + for (i = 0; i < leapcnt; ++i) { + trans[i] = tadd(trans[i], last); + last = corr[i] += last; + } +} + +static int +yearistype(year, type) +const int year; +const char * const type; +{ + static char * buf; + int result; + + if (type == NULL || *type == '\0') + return TRUE; + buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type))); + (void) sprintf(buf, "%s %d %s", yitcommand, year, type); + result = system(buf); + if (result == 0) + return TRUE; + if (result == (1 << 8)) + return FALSE; + error("Wild result from command execution"); + (void) fprintf(stderr, "%s: command was '%s', result was %d\n", + progname, buf, result); + for ( ; ; ) + (void) exit(EXIT_FAILURE); +} + +static int +lowerit(a) +const int a; +{ + return (isascii(a) && isupper(a)) ? tolower(a) : a; +} + +static int +ciequal(ap, bp) /* case-insensitive equality */ +register const char * ap; +register const char * bp; +{ + while (lowerit(*ap) == lowerit(*bp++)) + if (*ap++ == '\0') + return TRUE; + return FALSE; +} + +static int +itsabbr(abbr, word) +register const char * abbr; +register const char * word; +{ + if (lowerit(*abbr) != lowerit(*word)) + return FALSE; + ++word; + while (*++abbr != '\0') + do if (*word == '\0') + return FALSE; + while (lowerit(*word++) != lowerit(*abbr)); + return TRUE; +} + +static const struct lookup * +byword(word, table) +register const char * const word; +register const struct lookup * const table; +{ + register const struct lookup * foundlp; + register const struct lookup * lp; + + if (word == NULL || table == NULL) + return NULL; + /* + ** Look for exact match. + */ + for (lp = table; lp->l_word != NULL; ++lp) + if (ciequal(word, lp->l_word)) + return lp; + /* + ** Look for inexact match. + */ + foundlp = NULL; + for (lp = table; lp->l_word != NULL; ++lp) + if (itsabbr(word, lp->l_word)) + if (foundlp == NULL) + foundlp = lp; + else return NULL; /* multiple inexact matches */ + return foundlp; +} + +static char ** +getfields(cp) +register char * cp; +{ + register char * dp; + register char ** array; + register int nsubs; + + if (cp == NULL) + return NULL; + array = (char **) (void *) + emalloc((int) ((strlen(cp) + 1) * sizeof *array)); + nsubs = 0; + for ( ; ; ) { + while (isascii(*cp) && isspace(*cp)) + ++cp; + if (*cp == '\0' || *cp == '#') + break; + array[nsubs++] = dp = cp; + do { + if ((*dp = *cp++) != '"') + ++dp; + else while ((*dp = *cp++) != '"') + if (*dp != '\0') + ++dp; + else error("Odd number of quotation marks"); + } while (*cp != '\0' && *cp != '#' && + (!isascii(*cp) || !isspace(*cp))); + if (isascii(*cp) && isspace(*cp)) + ++cp; + *dp = '\0'; + } + array[nsubs] = NULL; + return array; +} + +static long +oadd(t1, t2) +const long t1; +const long t2; +{ + register long t; + + t = t1 + t2; + if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { + error("time overflow"); + (void) exit(EXIT_FAILURE); + } + return t; +} + +static time_t +tadd(t1, t2) +const time_t t1; +const long t2; +{ + register time_t t; + + if (t1 == max_time && t2 > 0) + return max_time; + if (t1 == min_time && t2 < 0) + return min_time; + t = t1 + t2; + if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { + error("time overflow"); + (void) exit(EXIT_FAILURE); + } + return t; +} + +/* +** Given a rule, and a year, compute the date - in seconds since January 1, +** 1970, 00:00 LOCAL time - in that year that the rule refers to. +*/ + +static time_t +rpytime(rp, wantedy) +register const struct rule * const rp; +register const int wantedy; +{ + register int y, m, i; + register long dayoff; /* with a nod to Margaret O. */ + register time_t t; + + if (wantedy == min_int) + return min_time; + if (wantedy == max_int) + return max_time; + dayoff = 0; + m = TM_JANUARY; + y = EPOCH_YEAR; + while (wantedy != y) { + if (wantedy > y) { + i = len_years[isleap(y)]; + ++y; + } else { + --y; + i = -len_years[isleap(y)]; + } + dayoff = oadd(dayoff, eitol(i)); + } + while (m != rp->r_month) { + i = len_months[isleap(y)][m]; + dayoff = oadd(dayoff, eitol(i)); + ++m; + } + i = rp->r_dayofmonth; + if (m == TM_FEBRUARY && i == 29 && !isleap(y)) { + if (rp->r_dycode == DC_DOWLEQ) + --i; + else { + error("use of 2/29 in non leap-year"); + (void) exit(EXIT_FAILURE); + } + } + --i; + dayoff = oadd(dayoff, eitol(i)); + if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) { + register long wday; + +#define LDAYSPERWEEK ((long) DAYSPERWEEK) + wday = eitol(EPOCH_WDAY); + /* + ** Don't trust mod of negative numbers. + */ + if (dayoff >= 0) + wday = (wday + dayoff) % LDAYSPERWEEK; + else { + wday -= ((-dayoff) % LDAYSPERWEEK); + if (wday < 0) + wday += LDAYSPERWEEK; + } + while (wday != eitol(rp->r_wday)) + if (rp->r_dycode == DC_DOWGEQ) { + dayoff = oadd(dayoff, (long) 1); + if (++wday >= LDAYSPERWEEK) + wday = 0; + ++i; + } else { + dayoff = oadd(dayoff, (long) -1); + if (--wday < 0) + wday = LDAYSPERWEEK - 1; + --i; + } + if (i < 0 || i >= len_months[isleap(y)][m]) { + error("no day in month matches rule"); + (void) exit(EXIT_FAILURE); + } + } + if (dayoff < 0 && !tt_signed) + return min_time; + t = (time_t) dayoff * SECSPERDAY; + /* + ** Cheap overflow check. + */ + if (t / SECSPERDAY != dayoff) + return (dayoff > 0) ? max_time : min_time; + return tadd(t, rp->r_tod); +} + +static void +newabbr(string) +const char * const string; +{ + register int i; + + i = strlen(string) + 1; + if (charcnt + i > TZ_MAX_CHARS) { + error("too many, or too long, time zone abbreviations"); + (void) exit(EXIT_FAILURE); + } + (void) strcpy(&chars[charcnt], string); + charcnt += eitol(i); +} + +static int +mkdirs(argname) +char * const argname; +{ + register char * name; + register char * cp; + + if (argname == NULL || *argname == '\0') + return 0; + cp = name = ecpyalloc(argname); + while ((cp = strchr(cp + 1, '/')) != 0) { + *cp = '\0'; +#ifndef unix + /* + ** MS-DOS drive specifier? + */ + if (strlen(name) == 2 && isascii(name[0]) && + isalpha(name[0]) && name[1] == ':') { + *cp = '/'; + continue; + } +#endif /* !defined unix */ + if (!itsdir(name)) { + /* + ** It doesn't seem to exist, so we try to create it. + */ + if (emkdir(name, 0755) != 0) { + (void) fprintf(stderr, + "%s: Can't create directory ", + progname); + (void) perror(name); + ifree(name); + return -1; + } + } + *cp = '/'; + } + ifree(name); + return 0; +} + +static long +eitol(i) +const int i; +{ + long l; + + l = i; + if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0)) { + (void) fprintf(stderr, + "%s: %d did not sign extend correctly\n", + progname, i); + (void) exit(EXIT_FAILURE); + } + return l; +} + +/* +** UNIX was a registered trademark of UNIX System Laboratories in 1993. +*/ |