summaryrefslogtreecommitdiffstats
path: root/time
diff options
context:
space:
mode:
Diffstat (limited to 'time')
-rw-r--r--time/Makefile318
-rw-r--r--time/README.time73
-rw-r--r--time/Theory120
-rw-r--r--time/africa603
-rw-r--r--time/antarctica19
-rw-r--r--time/asctime.c56
-rw-r--r--time/asia803
-rw-r--r--time/australasia783
-rw-r--r--time/backward75
-rw-r--r--time/date.1153
-rw-r--r--time/date.c900
-rw-r--r--time/difftime.c74
-rw-r--r--time/emkdir.c85
-rw-r--r--time/etcetera54
-rw-r--r--time/europe2072
-rw-r--r--time/factory8
-rw-r--r--time/getopt.c93
-rw-r--r--time/ialloc.c103
-rw-r--r--time/leapseconds41
-rw-r--r--time/localtime.c1569
-rw-r--r--time/logwtmp.c65
-rw-r--r--time/newctime.3220
-rw-r--r--time/newtzset.3236
-rw-r--r--time/northamerica953
-rw-r--r--time/optind.c10
-rw-r--r--time/pacificnew26
-rw-r--r--time/private.h210
-rw-r--r--time/scheck.c62
-rw-r--r--time/solar87386
-rw-r--r--time/solar88386
-rw-r--r--time/solar89391
-rw-r--r--time/southamerica397
-rw-r--r--time/strftime.c576
-rw-r--r--time/systemv35
-rw-r--r--time/time2posix.3119
-rw-r--r--time/tzfile.5123
-rw-r--r--time/tzfile.h170
-rw-r--r--time/usno1988111
-rw-r--r--time/usno1989452
-rw-r--r--time/usno1989a452
-rw-r--r--time/yearistype.sh26
-rw-r--r--time/zdump.840
-rw-r--r--time/zdump.c331
-rw-r--r--time/zic.8406
-rw-r--r--time/zic.c1956
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.
+*/