[Midnightbsd-cvs] src [7736] vendor/tzcode/dist: tzcode 2016f
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sun Aug 14 21:50:22 EDT 2016
Revision: 7736
http://svnweb.midnightbsd.org/src/?rev=7736
Author: laffer1
Date: 2016-08-14 21:50:22 -0400 (Sun, 14 Aug 2016)
Log Message:
-----------
tzcode 2016f
Modified Paths:
--------------
vendor/tzcode/dist/Makefile
vendor/tzcode/dist/README
vendor/tzcode/dist/Theory
vendor/tzcode/dist/asctime.c
vendor/tzcode/dist/date.1
vendor/tzcode/dist/date.1.txt
vendor/tzcode/dist/date.c
vendor/tzcode/dist/difftime.c
vendor/tzcode/dist/localtime.c
vendor/tzcode/dist/newctime.3
vendor/tzcode/dist/newctime.3.txt
vendor/tzcode/dist/newstrftime.3
vendor/tzcode/dist/newstrftime.3.txt
vendor/tzcode/dist/newtzset.3
vendor/tzcode/dist/newtzset.3.txt
vendor/tzcode/dist/private.h
vendor/tzcode/dist/strftime.c
vendor/tzcode/dist/time2posix.3
vendor/tzcode/dist/time2posix.3.txt
vendor/tzcode/dist/tz-art.htm
vendor/tzcode/dist/tz-link.htm
vendor/tzcode/dist/tzfile.5
vendor/tzcode/dist/tzfile.5.txt
vendor/tzcode/dist/tzfile.h
vendor/tzcode/dist/tzselect.8
vendor/tzcode/dist/tzselect.8.txt
vendor/tzcode/dist/tzselect.ksh
vendor/tzcode/dist/workman.sh
vendor/tzcode/dist/zdump.8
vendor/tzcode/dist/zdump.8.txt
vendor/tzcode/dist/zdump.c
vendor/tzcode/dist/zic.8
vendor/tzcode/dist/zic.8.txt
vendor/tzcode/dist/zic.c
Added Paths:
-----------
vendor/tzcode/dist/CONTRIBUTING
vendor/tzcode/dist/LICENSE
vendor/tzcode/dist/NEWS
vendor/tzcode/dist/tz-how-to.html
Added: vendor/tzcode/dist/CONTRIBUTING
===================================================================
--- vendor/tzcode/dist/CONTRIBUTING (rev 0)
+++ vendor/tzcode/dist/CONTRIBUTING 2016-08-15 01:50:22 UTC (rev 7736)
@@ -0,0 +1,73 @@
+Contributing to the tz code and data
+
+The time zone database is by no means authoritative: governments
+change timekeeping rules erratically and sometimes with little
+warning, the data entries do not cover all of civil time before
+1970, and undoubtedly errors remain in the code and data. Feel
+free to fill gaps or fix mistakes, and please email improvements
+to tz at iana.org for use in the future.
+
+To email small changes, please run a POSIX shell command like
+'diff -u old/europe new/europe >myfix.patch', and attach
+myfix.patch to the email.
+
+For more-elaborate changes, please read the Theory file and browse
+the mailing list archives <http://mm.icann.org/pipermail/tz/> for
+examples of patches that tend to work well. Ideally, additions to
+data should contain commentary citing reliable sources as
+justification.
+
+Please submit changes against either the latest release in
+<ftp://ftp.iana.org/tz/> or the master branch of the experimental
+Git repository. If you use Git the following workflow may be helpful:
+
+ * Copy the experimental repository.
+
+ git clone https://github.com/eggert/tz.git
+ cd tz
+
+ * Get current with the master branch.
+
+ git checkout master
+ git pull
+
+ * Switch to a new branch for the changes. Choose a different
+ branch name for each change set.
+
+ git checkout -b mybranch
+
+ * Edit source files. Include commentary that justifies the
+ changes by citing reliable sources.
+
+ * Debug the changes, e.g.:
+
+ make check
+ make install
+ ./zdump -v America/Los_Angeles
+
+ * For each separable change, commit it in the new branch, e.g.:
+
+ git add northamerica
+ git commit
+
+ See recent 'git log' output for the commit-message style.
+
+ * Create patch files 0001-*, 0002-*, ...
+
+ git format-patch master
+
+ * After reviewing the patch files, send the patches to tz at iana.org
+ for others to review.
+
+ git send-email master
+
+ * Start anew by getting current with the master branch again
+ (the second step above).
+
+Please do not create issues or pull requests on GitHub, as the
+proper procedure for proposing and distributing patches is via
+email as illustrated above.
+
+-----
+
+This file is in the public domain.
Added: vendor/tzcode/dist/LICENSE
===================================================================
--- vendor/tzcode/dist/LICENSE (rev 0)
+++ vendor/tzcode/dist/LICENSE 2016-08-15 01:50:22 UTC (rev 7736)
@@ -0,0 +1,4 @@
+With a few exceptions, all files in the tz code and data (including
+this one) are in the public domain. The exceptions are tzcode's
+date.c, newstrftime.3, and strftime.c, which contain material derived
+from BSD and which use the BSD 3-clause license.
Modified: vendor/tzcode/dist/Makefile
===================================================================
--- vendor/tzcode/dist/Makefile 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/Makefile 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,4 +1,3 @@
-# <pre>
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
@@ -6,8 +5,11 @@
PACKAGE= tzcode
# Version numbers of the code and data distributions.
-VERSION= 2012j
+VERSION= 2016f
+# Email address for bug reports.
+BUGEMAIL= tz at iana.org
+
# 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
@@ -25,7 +27,7 @@
# 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 UTC offsets of standard and
+# times; the environment variable itself specifies UT offsets of standard and
# summer time.)
# Alternately, if you discover you've got the wrong time zone, you can just
# zic -p rightzone
@@ -48,8 +50,12 @@
# (and subdirectories).
# Use an absolute path name for TZDIR unless you're just testing the software.
-TZDIR= $(TOPDIR)/etc/zoneinfo
+TZDIR_BASENAME= zoneinfo
+TZDIR= $(TOPDIR)/etc/$(TZDIR_BASENAME)
+# Types to try, as an alternative to time_t. int64_t should be first.
+TIME_T_ALTERNATIVES= int64_t int32_t uint32_t uint64_t
+
# The "tzselect", "zic", and "zdump" commands get installed in. . .
ETCDIR= $(TOPDIR)/etc
@@ -65,7 +71,6 @@
# Library functions are put in an archive in LIBDIR.
LIBDIR= $(TOPDIR)/lib
-TZLIB= $(LIBDIR)/libtz.a
# If you always want time values interpreted as "seconds since the epoch
# (not counting leap seconds)", use
@@ -79,60 +84,86 @@
# 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".
+# below. POSIX mandates that leap seconds not be counted; for compatibility
+# with it, use "posix_only" or "posix_right".
REDO= posix_right
+# If you want out-of-scope and often-wrong data from the file 'backzone', use
+# PACKRATDATA= backzone
+# To omit this data, use
+# PACKRATDATA=
+
+PACKRATDATA=
+
# Since "." may not be in PATH...
YEARISTYPE= ./yearistype
# Non-default libraries needed to link.
-# Add -lintl if you want to use `gettext' on Solaris.
+# Add -lintl if you want to use 'gettext' on Solaris.
LDLIBS=
# Add the following to the end of the "CFLAGS=" line as needed.
-# -DHAVE_ADJTIME=0 if `adjtime' does not exist (SVR0?)
-# -DHAVE_GETTEXT=1 if `gettext' works (GNU, Linux, Solaris); also see LDLIBS
+# -DBIG_BANG=-9999999LL if the Big Bang occurred at time -9999999 (see zic.c)
+# -DHAVE_DECL_ASCTIME_R=0 if <time.h> does not declare asctime_r
+# -DHAVE_DIRECT_H if mkdir needs <direct.h> (MS-Windows)
+# -DHAVE_DOS_FILE_NAMES if file names have drive specifiers etc. (MS-DOS)
+# -DHAVE_GETTEXT=1 if 'gettext' works (GNU, Linux, Solaris); also see LDLIBS
# -DHAVE_INCOMPATIBLE_CTIME_R=1 if your system's time.h declares
# ctime_r and asctime_r incompatibly with the POSIX standard (Solaris 8).
-# -DHAVE_SETTIMEOFDAY=0 if settimeofday does not exist (SVR0?)
-# -DHAVE_SETTIMEOFDAY=1 if settimeofday has just 1 arg (SVR4)
-# -DHAVE_SETTIMEOFDAY=2 if settimeofday uses 2nd arg (4.3BSD)
-# -DHAVE_SETTIMEOFDAY=3 if settimeofday ignores 2nd arg (4.4BSD)
+# -DHAVE_INTTYPES_H=1 if you have a pre-C99 compiler with "inttypes.h"
+# -DHAVE_LINK=0 if your system lacks a link function
+# -DHAVE_LOCALTIME_R=0 if your system lacks a localtime_r function
+# -DHAVE_LOCALTIME_RZ=0 if you do not want zdump to use localtime_rz
+# This defaults to 1 if a working localtime_rz seems to be available.
+# localtime_rz can make zdump significantly faster, but is nonstandard.
+# -DHAVE_POSIX_DECLS=0 if your system's include files do not declare
+# functions like 'link' or variables like 'tzname' required by POSIX
# -DHAVE_STDINT_H=1 if you have a pre-C99 compiler with "stdint.h"
+# -DHAVE_STRFTIME_L=1 if <time.h> declares locale_t and strftime_l
+# This defaults to 0 if _POSIX_VERSION < 200809, 1 otherwise.
+# -DHAVE_STRDUP=0 if your system lacks the strdup function
# -DHAVE_SYMLINK=0 if your system lacks the symlink function
# -DHAVE_SYS_STAT_H=0 if your compiler lacks a "sys/stat.h"
# -DHAVE_SYS_WAIT_H=0 if your compiler lacks a "sys/wait.h"
-# -DLOCALE_HOME=\"path\" if locales are in "path", not "/usr/lib/locale"
+# -DHAVE_TZSET=0 if your system lacks a tzset function
# -DHAVE_UNISTD_H=0 if your compiler lacks a "unistd.h" (Microsoft C++ 7?)
-# -DHAVE_UTMPX_H=1 if your compiler has a "utmpx.h"
-# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
-# DST transitions if the time zone files cannot be accessed
-# -DTZ_DOMAIN=\"foo\" to use "foo" for gettext domain name; default is "tz"
-# -TTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
-# the default is system-supplied, typically "/usr/lib/locale"
-# $(GCC_DEBUG_FLAGS) if you are using GCC and want lots of checking
# -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1
# if you do not want run time warnings about formats that may cause
# year 2000 grief
+# -Dssize_t=long on ancient hosts that lack ssize_t
+# -DTHREAD_SAFE=1 to make localtime.c thread-safe, as POSIX requires;
+# not needed by the main-program tz code, which is single-threaded.
+# Append other compiler flags as needed, e.g., -pthread on GNU/Linux.
+# -Dtime_tz=\"T\" to use T as the time_t type, rather than the system time_t
+# -DTZ_DOMAIN=\"foo\" to use "foo" for gettext domain name; default is "tz"
+# -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
+# the default is system-supplied, typically "/usr/lib/locale"
+# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
+# DST transitions if the time zone files cannot be accessed
+# -DUNINIT_TRAP=1 if reading uninitialized storage can cause problems
+# other than simply getting garbage data
+# -DUSE_LTZ=0 to build zdump with the system time zone library
+# Also set TZDOBJS=zdump.o and CHECK_TIME_T_ALTERNATIVES= below.
# -DZIC_MAX_ABBR_LEN_WO_WARN=3
# (or some other number) to set the maximum time zone abbreviation length
# that zic will accept without a warning (the default is 6)
+# $(GCC_DEBUG_FLAGS) if you are using recent GCC and want lots of checking
GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \
-Wall -Wextra \
- -Wbad-function-cast -Wcast-align -Wcast-qual \
- -Wformat=2 -Winit-self \
- -Wmissing-declarations -Wmissing-noreturn -Wmissing-prototypes \
- -Wnested-externs \
- -Wno-format-nonliteral -Wno-sign-compare -Wno-sign-conversion \
- -Wno-type-limits \
- -Wno-unused-parameter -Woverlength-strings -Wpointer-arith \
+ -Wbad-function-cast -Wcast-align -Wdate-time \
+ -Wdeclaration-after-statement \
+ -Wdouble-promotion \
+ -Wformat=2 -Winit-self -Wjump-misses-init \
+ -Wlogical-op -Wmissing-prototypes -Wnested-externs \
+ -Wold-style-definition -Woverlength-strings -Wpointer-arith \
-Wshadow -Wstrict-prototypes -Wsuggest-attribute=const \
- -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure -Wtrampolines \
- -Wwrite-strings
+ -Wsuggest-attribute=format -Wsuggest-attribute=noreturn \
+ -Wsuggest-attribute=pure -Wtrampolines \
+ -Wunused -Wwrite-strings \
+ -Wno-address -Wno-format-nonliteral -Wno-sign-compare \
+ -Wno-type-limits -Wno-unused-parameter
#
# If you want to use System V compatibility code, add
# -DUSG_COMPAT
@@ -144,25 +175,12 @@
# (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 Linux and BSD 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
+# to the end of the "CFLAGS=" line. If not defined, the code attempts to
+# guess TM_GMTOFF from other macros; define NO_TM_GMTOFF to suppress this.
+# Similarly, if your system has a "zone abbreviation" field, define
# -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.
+# and define NO_TM_ZONE to suppress any guessing. These two fields are not
+# required by POSIX, but are widely available on GNU/Linux and BSD systems.
#
# If you want functions that were inspired by early versions of X3J11's work,
# add
@@ -177,7 +195,7 @@
# 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 UTC (rather than local time as "timelocal" does).
+# a time_t using UT (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.
@@ -186,18 +204,17 @@
# 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 don't want functions that were inspired by NetBSD, add
+# -DNETBSD_INSPIRED=0
+# to the end of the "CFLAGS=" line. Otherwise, the functions
+# "localtime_rz", "mktime_z", "tzalloc", and "tzfree" are added to the
+# time library, and if STD_INSPIRED is also defined the functions
+# "posix2time_z" and "time2posix_z" are added as well.
+# The functions ending in "_z" (or "_rz") are like their unsuffixed
+# (or suffixed-by-"_r") counterparts, except with an extra first
+# argument of opaque type timezone_t that specifies the time zone.
+# "tzalloc" allocates a timezone_t value, and "tzfree" frees it.
#
-# 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.
@@ -207,11 +224,6 @@
# 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
@@ -232,24 +244,41 @@
LDFLAGS= $(LFLAGS)
+# For leap seconds, this Makefile uses LEAPSECONDS='-L leapseconds' in
+# submake command lines. The default is no leap seconds.
+
+LEAPSECONDS=
+
+# The zic command and its arguments.
+
zic= ./zic
ZIC= $(zic) $(ZFLAGS)
-# The name of a Posix-compliant `awk' on your system.
+ZFLAGS=
+
+# How to use zic to install tzdata binary files.
+
+ZIC_INSTALL= $(ZIC) -y $(YEARISTYPE) -d $(DESTDIR)$(TZDIR) $(LEAPSECONDS)
+
+# The name of a Posix-compliant 'awk' on your system.
AWK= awk
-# The full path name of a Posix-compliant shell that supports the Korn shell's
-# 'select' statement, as an extension. These days, Bash is the most popular.
+# The full path name of a Posix-compliant shell, preferably one that supports
+# the Korn shell's 'select' statement as an extension.
+# These days, Bash is the most popular.
+# It should be OK to set this to /bin/sh, on platforms where /bin/sh
+# lacks 'select' or doesn't completely conform to Posix, but /bin/bash
+# is typically nicer if it works.
KSHELL= /bin/bash
-# The path where SGML DTDs are kept.
-# The default is appropriate for Ubuntu.
+# The path where SGML DTDs are kept and the catalog file(s) to use when
+# validating. The default is appropriate for Ubuntu 13.10.
SGML_TOPDIR= /usr
-SGML_SEARCH_PATH= $(SGML_TOPDIR)/share/xml/xhtml/schema/dtd/REC-html401-19991224
+SGML_DTDDIR= $(SGML_TOPDIR)/share/xml/w3c-sgml-lib/schema/dtd
+SGML_SEARCH_PATH= $(SGML_DTDDIR)/REC-html401-19991224
+SGML_CATALOG_FILES= \
+ $(SGML_TOPDIR)/share/doc/w3-recs/html/www.w3.org/TR/1999/REC-html401-19991224/HTML4.cat
-# The catalog file(s) to use when validating.
-SGML_CATALOG_FILES= HTML4.cat
-
# The name, arguments and environment of a program to validate your web pages.
# See <http://www.jclark.com/sp/> for a validator, and
# <http://validator.w3.org/source/> for a validation library.
@@ -261,6 +290,40 @@
SP_CHARSET_FIXED=YES \
SP_ENCODING=UTF-8
+# This expensive test requires USE_LTZ.
+# To suppress it, define this macro to be empty.
+CHECK_TIME_T_ALTERNATIVES = check_time_t_alternatives
+
+# SAFE_CHAR is a regular expression that matches a safe character.
+# Some parts of this distribution are limited to safe characters;
+# others can use any UTF-8 character.
+# For now, the safe characters are a safe subset of ASCII.
+# The caller must set the shell variable 'sharp' to the character '#',
+# since Makefile macros cannot contain '#'.
+# TAB_CHAR is a single tab character, in single quotes.
+TAB_CHAR= ' '
+SAFE_CHARSET1= $(TAB_CHAR)' !\"'$$sharp'$$%&'\''()*+,./0123456789:;<=>?@'
+SAFE_CHARSET2= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\^_`'
+SAFE_CHARSET3= 'abcdefghijklmnopqrstuvwxyz{|}~'
+SAFE_CHARSET= $(SAFE_CHARSET1)$(SAFE_CHARSET2)$(SAFE_CHARSET3)
+SAFE_CHAR= '[]'$(SAFE_CHARSET)'-]'
+
+# OK_CHAR matches any character allowed in the distributed files.
+# This is the same as SAFE_CHAR, except that multibyte letters are
+# also allowed so that commentary can contain people's names and quote
+# non-English sources. For non-letters the sources are limited to
+# ASCII renderings for the convenience of maintainers whose text editors
+# mishandle UTF-8 by default (e.g., XEmacs 21.4.22).
+OK_CHAR= '[][:alpha:]'$(SAFE_CHARSET)'-]'
+
+# SAFE_LINE matches a line of safe characters.
+# SAFE_SHARP_LINE is similar, except any OK character can follow '#';
+# this is so that comments can contain non-ASCII characters.
+# OK_LINE matches a line of OK characters.
+SAFE_LINE= '^'$(SAFE_CHAR)'*$$'
+SAFE_SHARP_LINE='^'$(SAFE_CHAR)'*('$$sharp$(OK_CHAR)'*)?$$'
+OK_LINE= '^'$(OK_CHAR)'*$$'
+
# Flags to give 'tar' when making a distribution.
# Try to use flags appropriate for GNU tar.
GNUTARFLAGS= --numeric-owner --owner=0 --group=0 --mode=go+u,go-w
@@ -274,37 +337,47 @@
###############################################################################
+#MAKE= make
+
cc= cc
CC= $(cc) -DTZDIR=\"$(TZDIR)\"
-TZCSRCS= zic.c localtime.c asctime.c scheck.c ialloc.c
-TZCOBJS= zic.o localtime.o asctime.o scheck.o ialloc.o
-TZDSRCS= zdump.c localtime.c ialloc.c
-TZDOBJS= zdump.o localtime.o ialloc.o
-DATESRCS= date.c localtime.c strftime.c asctime.c
+AR= ar
+
+# ':' on typical hosts; 'ranlib' on the ancient hosts that still need ranlib.
+RANLIB= :
+
+TZCOBJS= zic.o
+TZDOBJS= zdump.o localtime.o asctime.o
DATEOBJS= date.o localtime.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
+NONLIBSRCS= zic.c zdump.c
NEWUCBSRCS= date.c strftime.c
-SOURCES= $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) tzselect.ksh
+SOURCES= $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) \
+ tzselect.ksh workman.sh
MANS= newctime.3 newstrftime.3 newtzset.3 time2posix.3 \
tzfile.5 tzselect.8 zic.8 zdump.8
-COMMON= Makefile
-DOCS= README Theory $(MANS) date.1
+MANTXTS= newctime.3.txt newstrftime.3.txt newtzset.3.txt \
+ time2posix.3.txt \
+ tzfile.5.txt tzselect.8.txt zic.8.txt zdump.8.txt \
+ date.1.txt
+COMMON= CONTRIBUTING LICENSE Makefile NEWS README Theory
+WEB_PAGES= tz-art.htm tz-how-to.html tz-link.htm
+DOCS= $(MANS) date.1 $(MANTXTS) $(WEB_PAGES)
PRIMARY_YDATA= africa antarctica asia australasia \
europe northamerica southamerica
YDATA= $(PRIMARY_YDATA) pacificnew etcetera backward
NDATA= systemv factory
-SDATA= solar87 solar88 solar89
-TDATA= $(YDATA) $(NDATA) $(SDATA)
-TABDATA= iso3166.tab zone.tab
-DATA= $(YDATA) $(NDATA) $(SDATA) $(TABDATA) leapseconds yearistype.sh
-WEB_PAGES= tz-art.htm tz-link.htm
-MISC= usno1988 usno1989 usno1989a usno1995 usno1997 usno1998 \
- $(WEB_PAGES) checktab.awk workman.sh \
- zoneinfo2tdf.pl
+TDATA= $(YDATA) $(NDATA)
+ZONETABLES= zone1970.tab zone.tab
+TABDATA= iso3166.tab leapseconds $(ZONETABLES)
+LEAP_DEPS= leapseconds.awk leap-seconds.list
+DATA= $(YDATA) $(NDATA) backzone $(TABDATA) \
+ leap-seconds.list yearistype.sh
+AWK_SCRIPTS= checklinks.awk checktab.awk leapseconds.awk
+MISC= $(AWK_SCRIPTS) zoneinfo2tdf.pl
ENCHILADA= $(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC)
# And for the benefit of csh users on systems that assume the user
@@ -312,44 +385,38 @@
SHELL= /bin/sh
-all: tzselect zic zdump $(LIBOBJS)
+all: tzselect yearistype zic zdump libtz.a $(TABDATA)
-ALL: all date
+ALL: all date $(ENCHILADA)
-install: all $(DATA) $(REDO) $(TZLIB) $(MANS) $(TABDATA)
- $(ZIC) -y $(YEARISTYPE) \
- -d $(TZDIR) -l $(LOCALTIME) -p $(POSIXRULES)
- -rm -f $(TZDIR)/iso3166.tab $(TZDIR)/zone.tab
- cp iso3166.tab zone.tab $(TZDIR)/.
- -mkdir $(TOPDIR) $(ETCDIR)
- cp tzselect zic zdump $(ETCDIR)/.
- -mkdir $(TOPDIR) $(MANDIR) \
- $(MANDIR)/man3 $(MANDIR)/man5 $(MANDIR)/man8
- -rm -f $(MANDIR)/man3/newctime.3 \
- $(MANDIR)/man3/newtzset.3 \
- $(MANDIR)/man5/tzfile.5 \
- $(MANDIR)/man8/tzselect.8 \
- $(MANDIR)/man8/zdump.8 \
- $(MANDIR)/man8/zic.8
- cp newctime.3 newtzset.3 $(MANDIR)/man3/.
- cp tzfile.5 $(MANDIR)/man5/.
- cp tzselect.8 zdump.8 zic.8 $(MANDIR)/man8/.
+install: all $(DATA) $(REDO) $(MANS)
+ mkdir -p $(DESTDIR)$(ETCDIR) $(DESTDIR)$(TZDIR) \
+ $(DESTDIR)$(LIBDIR) \
+ $(DESTDIR)$(MANDIR)/man3 $(DESTDIR)$(MANDIR)/man5 \
+ $(DESTDIR)$(MANDIR)/man8
+ $(ZIC_INSTALL) -l $(LOCALTIME) -p $(POSIXRULES)
+ cp -f iso3166.tab $(ZONETABLES) $(DESTDIR)$(TZDIR)/.
+ cp tzselect zic zdump $(DESTDIR)$(ETCDIR)/.
+ cp libtz.a $(DESTDIR)$(LIBDIR)/.
+ $(RANLIB) $(DESTDIR)$(LIBDIR)/libtz.a
+ cp -f newctime.3 newtzset.3 $(DESTDIR)$(MANDIR)/man3/.
+ cp -f tzfile.5 $(DESTDIR)$(MANDIR)/man5/.
+ cp -f tzselect.8 zdump.8 zic.8 $(DESTDIR)$(MANDIR)/man8/.
INSTALL: ALL install date.1
- -mkdir $(TOPDIR) $(BINDIR)
- cp date $(BINDIR)/.
- -mkdir $(TOPDIR) $(MANDIR) $(MANDIR)/man1
- -rm -f $(MANDIR)/man1/date.1
- cp date.1 $(MANDIR)/man1/.
+ mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1
+ cp date $(DESTDIR)$(BINDIR)/.
+ cp -f date.1 $(DESTDIR)$(MANDIR)/man1/.
version.h:
(echo 'static char const PKGVERSION[]="($(PACKAGE)) ";' && \
- echo 'static char const TZVERSION[]="$(VERSION)";') >$@
+ echo 'static char const TZVERSION[]="$(VERSION)";' && \
+ echo 'static char const REPORT_BUGS_TO[]="$(BUGEMAIL)";') >$@
zdump: $(TZDOBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(TZDOBJS) $(LDLIBS)
-zic: $(TZCOBJS) yearistype
+zic: $(TZCOBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(TZCOBJS) $(LDLIBS)
yearistype: yearistype.sh
@@ -356,12 +423,32 @@
cp yearistype.sh yearistype
chmod +x yearistype
-posix_only: zic $(TDATA)
- $(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L /dev/null $(TDATA)
+leapseconds: $(LEAP_DEPS)
+ $(AWK) -f leapseconds.awk leap-seconds.list >$@
-right_only: zic leapseconds $(TDATA)
- $(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L leapseconds $(TDATA)
+# Arguments to pass to submakes of install_data.
+# They can be overridden by later submake arguments.
+INSTALLARGS = \
+ DESTDIR=$(DESTDIR) \
+ LEAPSECONDS='$(LEAPSECONDS)' \
+ PACKRATDATA='$(PACKRATDATA)' \
+ TZDIR=$(TZDIR) \
+ YEARISTYPE=$(YEARISTYPE) \
+ ZIC='$(ZIC)'
+# 'make install_data' installs one set of tz binary files.
+# It can be tailored by setting LEAPSECONDS, PACKRATDATA, etc.
+install_data: zic leapseconds yearistype $(PACKRATDATA) $(TDATA)
+ $(ZIC_INSTALL) $(TDATA)
+ $(AWK) '/^Rule/' $(TDATA) | $(ZIC_INSTALL) - $(PACKRATDATA)
+
+posix_only:
+ $(MAKE) $(INSTALLARGS) LEAPSECONDS= install_data
+
+right_only:
+ $(MAKE) $(INSTALLARGS) LEAPSECONDS='-L leapseconds' \
+ install_data
+
# In earlier versions of this makefile, the other two directories were
# subdirectories of $(TZDIR). However, this led to configuration errors.
# For example, with posix_right under the earlier scheme,
@@ -371,22 +458,28 @@
# Therefore, the other two directories are now siblings of $(TZDIR).
# You must replace all of $(TZDIR) to switch from not using leap seconds
# to using them, or vice versa.
-other_two: zic leapseconds $(TDATA)
- $(ZIC) -y $(YEARISTYPE) -d $(TZDIR)-posix -L /dev/null $(TDATA)
- $(ZIC) -y $(YEARISTYPE) \
- -d $(TZDIR)-leaps -L leapseconds $(TDATA)
+right_posix: right_only
+ rm -fr $(DESTDIR)$(TZDIR)-leaps
+ ln -s $(TZDIR_BASENAME) $(DESTDIR)$(TZDIR)-leaps || \
+ $(MAKE) $(INSTALLARGS) TZDIR=$(TZDIR)-leaps right_only
+ $(MAKE) $(INSTALLARGS) TZDIR=$(TZDIR)-posix posix_only
-posix_right: posix_only other_two
+posix_right: posix_only
+ rm -fr $(DESTDIR)$(TZDIR)-posix
+ ln -s $(TZDIR_BASENAME) $(DESTDIR)$(TZDIR)-posix || \
+ $(MAKE) $(INSTALLARGS) TZDIR=$(TZDIR)-posix posix_only
+ $(MAKE) $(INSTALLARGS) TZDIR=$(TZDIR)-leaps right_only
-right_posix: right_only other_two
+# This obsolescent rule is present for backwards compatibility with
+# tz releases 2014g through 2015g. It should go away eventually.
+posix_packrat:
+ $(MAKE) $(INSTALLARGS) PACKRATDATA=backzone posix_only
zones: $(REDO)
-$(TZLIB): $(LIBOBJS)
- -mkdir $(TOPDIR) $(LIBDIR)
- ar ru $@ $(LIBOBJS)
- if [ -x /usr/ucb/ranlib ] || [ -x /usr/bin/ranlib ]; \
- then ranlib $@ ; fi
+libtz.a: $(LIBOBJS)
+ $(AR) ru $@ $(LIBOBJS)
+ $(RANLIB) $@
date: $(DATEOBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(DATEOBJS) $(LDLIBS)
@@ -396,78 +489,170 @@
-e 's|#!/bin/bash|#!$(KSHELL)|g' \
-e 's|AWK=[^}]*|AWK=$(AWK)|g' \
-e 's|\(PKGVERSION\)=.*|\1='\''($(PACKAGE)) '\''|' \
+ -e 's|\(REPORT_BUGS_TO\)=.*|\1=$(BUGEMAIL)|' \
-e 's|TZDIR=[^}]*|TZDIR=$(TZDIR)|' \
-e 's|\(TZVERSION\)=.*|\1=$(VERSION)|' \
<$? >$@
chmod +x $@
-check: check_tables check_web
+check: check_character_set check_white_space check_links check_sorted \
+ check_tables check_web
-check_tables: checktab.awk $(PRIMARY_YDATA)
- $(AWK) -f checktab.awk $(PRIMARY_YDATA)
+check_character_set: $(ENCHILADA)
+ LC_ALL=en_US.utf8 && export LC_ALL && \
+ sharp='#' && \
+ ! grep -Env $(SAFE_LINE) Makefile $(MANS) date.1 $(MANTXTS) \
+ $(MISC) $(SOURCES) $(WEB_PAGES) && \
+ ! grep -Env $(SAFE_SHARP_LINE) $(TDATA) backzone \
+ leapseconds yearistype.sh zone.tab && \
+ ! grep -Env $(OK_LINE) $(ENCHILADA)
+check_white_space: $(ENCHILADA)
+ ! grep -En ' '$(TAB_CHAR)"|$$(printf '[\f\r\v]')" $(ENCHILADA)
+ ! grep -n '[[:space:]]$$' $(ENCHILADA)
+
+CHECK_CC_LIST = { n = split($$1,a,/,/); for (i=2; i<=n; i++) print a[1], a[i]; }
+
+check_sorted: backward backzone iso3166.tab zone.tab zone1970.tab
+ $(AWK) '/^Link/ {print $$3}' backward | LC_ALL=C sort -cu
+ $(AWK) '/^Zone/ {print $$2}' backzone | LC_ALL=C sort -cu
+ $(AWK) '/^[^#]/ {print $$1}' iso3166.tab | LC_ALL=C sort -cu
+ $(AWK) '/^[^#]/ {print $$1}' zone.tab | LC_ALL=C sort -c
+ $(AWK) '/^[^#]/ {print substr($$0, 1, 2)}' zone1970.tab | \
+ LC_ALL=C sort -c
+ $(AWK) '/^[^#]/ $(CHECK_CC_LIST)' zone1970.tab | \
+ LC_ALL=C sort -cu
+
+check_links: checklinks.awk $(TDATA)
+ $(AWK) -f checklinks.awk $(TDATA)
+
+check_tables: checktab.awk $(PRIMARY_YDATA) $(ZONETABLES)
+ for tab in $(ZONETABLES); do \
+ $(AWK) -f checktab.awk -v zone_table=$$tab $(PRIMARY_YDATA) \
+ || exit; \
+ done
+
check_web: $(WEB_PAGES)
$(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) $(WEB_PAGES)
-clean:
+clean_misc:
rm -f core *.o *.out \
- date tzselect version.h zdump zic yearistype
- rm -f -r tzpublic
+ date tzselect version.h zdump zic yearistype libtz.a
+clean: clean_misc
+ rm -fr tzpublic
maintainer-clean: clean
@echo 'This command is intended for maintainers to use; it'
@echo 'deletes files that may need special tools to rebuild.'
- rm -f *.[1-8].txt *.asc *.tar.gz
+ rm -f leapseconds $(MANTXTS) *.asc *.tar.gz
names:
@echo $(ENCHILADA)
-public: check check_public set-timestamps tarballs signatures
+public: check check_public $(CHECK_TIME_T_ALTERNATIVES) \
+ tarballs signatures
+date.1.txt: date.1
+newctime.3.txt: newctime.3
+newstrftime.3.txt: newstrftime.3
+newtzset.3.txt: newtzset.3
+time2posix.3.txt: time2posix.3
+tzfile.5.txt: tzfile.5
+tzselect.8.txt: tzselect.8
+zdump.8.txt: zdump.8
+zic.8.txt: zic.8
+
+$(MANTXTS): workman.sh
+ LC_ALL=C sh workman.sh `expr $@ : '\(.*\)\.txt$$'` >$@
+
# Set the time stamps to those of the git repository, if available,
# and if the files have not changed since then.
# This uses GNU 'touch' syntax 'touch -d at N FILE',
# where N is the number of seconds since 1970.
-# If git or GNU 'touch' is absent, do nothing.
-set-timestamps:
- -TZ=UTC0 && export TZ && files=`git ls-files` && \
- touch -d @1 test.out && rm -f test.out && \
- for file in $$files; do \
- test -z "`git diff --name-only $$file`" || continue; \
- cmd="touch -d @`git log -1 --format='format:%ct' $$file \
- ` $$file" && \
- echo "$$cmd" && \
- $$cmd || exit; \
+# If git or GNU 'touch' is absent, don't bother to sync with git timestamps.
+# Also, set the timestamp of each prebuilt file like 'leapseconds'
+# to be the maximum of the files it depends on.
+set-timestamps.out: $(ENCHILADA)
+ rm -f $@
+ if files=`git ls-files $(ENCHILADA)` && \
+ touch -md @1 test.out; then \
+ rm -f test.out && \
+ for file in $$files; do \
+ if git diff --quiet $$file; then \
+ time=`git log -1 --format='tformat:%ct' $$file` && \
+ touch -cmd @$$time $$file; \
+ else \
+ echo >&2 "$$file: warning: does not match repository"; \
+ fi || exit; \
+ done; \
+ fi
+ touch -cmr `ls -t $(LEAP_DEPS) | sed 1q` leapseconds
+ for file in `ls $(MANTXTS) | sed 's/\.txt$$//'`; do \
+ touch -cmr `ls -t $$file workman.sh | sed 1q` $$file.txt || \
+ exit; \
done
+ touch $@
# The zics below ensure that each data file can stand on its own.
# We also do an all-files run to catch links to links.
-check_public: $(ENCHILADA)
- make maintainer-clean
- make "CFLAGS=$(GCC_DEBUG_FLAGS)"
+check_public:
+ $(MAKE) maintainer-clean
+ $(MAKE) "CFLAGS=$(GCC_DEBUG_FLAGS)" ALL
mkdir tzpublic
for i in $(TDATA) ; do \
$(zic) -v -d tzpublic $$i 2>&1 || exit; \
done
$(zic) -v -d tzpublic $(TDATA)
- rm -f -r tzpublic
+ rm -fr tzpublic
+# Check that the code works under various alternative
+# implementations of time_t.
+check_time_t_alternatives:
+ if diff -q Makefile Makefile 2>/dev/null; then \
+ quiet_option='-q'; \
+ else \
+ quiet_option=''; \
+ fi && \
+ zones=`$(AWK) '/^[^#]/ { print $$3 }' <zone1970.tab` && \
+ for type in $(TIME_T_ALTERNATIVES); do \
+ mkdir -p tzpublic/$$type && \
+ $(MAKE) clean_misc && \
+ $(MAKE) TOPDIR=`pwd`/tzpublic/$$type \
+ CFLAGS='$(CFLAGS) -Dtime_tz='"'$$type'" \
+ REDO='$(REDO)' \
+ install && \
+ diff $$quiet_option -r \
+ tzpublic/int64_t/etc/zoneinfo \
+ tzpublic/$$type/etc/zoneinfo && \
+ case $$type in \
+ int32_t) range=-2147483648,2147483647;; \
+ uint32_t) range=0,4294967296;; \
+ int64_t) continue;; \
+ *u*) range=0,10000000000;; \
+ *) range=-10000000000,10000000000;; \
+ esac && \
+ echo checking $$type zones ... && \
+ tzpublic/int64_t/etc/zdump -V -t $$range $$zones \
+ >tzpublic/int64_t.out && \
+ tzpublic/$$type/etc/zdump -V -t $$range $$zones \
+ >tzpublic/$$type.out && \
+ diff -u tzpublic/int64_t.out tzpublic/$$type.out \
+ || exit; \
+ done
+ rm -fr tzpublic
+
tarballs: tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz
-tzcode$(VERSION).tar.gz: $(COMMON) $(DOCS) $(SOURCES) $(MISC)
- for i in *.[1-8] ; do \
- LC_ALL=C sh workman.sh $$i > $$i.txt && \
- touch -r $$i $$i.txt || exit; \
- done
+tzcode$(VERSION).tar.gz: set-timestamps.out
LC_ALL=C && export LC_ALL && \
tar $(TARFLAGS) -cf - \
- $(COMMON) $(DOCS) $(SOURCES) $(MISC) *.[1-8].txt | \
+ $(COMMON) $(DOCS) $(SOURCES) | \
gzip $(GZIPFLAGS) > $@
-tzdata$(VERSION).tar.gz: $(COMMON) $(DATA)
+tzdata$(VERSION).tar.gz: set-timestamps.out
LC_ALL=C && export LC_ALL && \
- tar $(TARFLAGS) -cf - $(COMMON) $(DATA) | \
+ tar $(TARFLAGS) -cf - $(COMMON) $(DATA) $(MISC) | \
gzip $(GZIPFLAGS) > $@
signatures: tzcode$(VERSION).tar.gz.asc tzdata$(VERSION).tar.gz.asc
@@ -479,12 +664,12 @@
gpg --armor --detach-sign $?
typecheck:
- make clean
- for i in "long long" unsigned double; \
+ $(MAKE) clean
+ for i in "long long" unsigned; \
do \
- make CFLAGS="-DTYPECHECK -D__time_t_defined -D_TIME_T \"-Dtime_t=$$i\"" ; \
+ $(MAKE) CFLAGS="-DTYPECHECK -D__time_t_defined -D_TIME_T \"-Dtime_t=$$i\"" ; \
./zdump -v Europe/Rome ; \
- make clean ; \
+ $(MAKE) clean ; \
done
zonenames: $(TDATA)
@@ -493,11 +678,18 @@
asctime.o: private.h tzfile.h
date.o: private.h
difftime.o: private.h
-ialloc.o: private.h
localtime.o: private.h tzfile.h
-scheck.o: private.h
-strftime.o: tzfile.h
+strftime.o: private.h tzfile.h
zdump.o: version.h
zic.o: private.h tzfile.h version.h
.KEEP_STATE:
+
+.PHONY: ALL INSTALL all
+.PHONY: check check_character_set check_links
+.PHONY: check_public check_sorted check_tables
+.PHONY: check_time_t_alternatives check_web check_white_space clean clean_misc
+.PHONY: install install_data maintainer-clean names
+.PHONY: posix_only posix_packrat posix_right
+.PHONY: public right_only right_posix signatures tarballs typecheck
+.PHONY: zonenames zones
Added: vendor/tzcode/dist/NEWS
===================================================================
--- vendor/tzcode/dist/NEWS (rev 0)
+++ vendor/tzcode/dist/NEWS 2016-08-15 01:50:22 UTC (rev 7736)
@@ -0,0 +1,3541 @@
+News for the tz database
+
+Release 2016f - 2016-07-05 16:26:51 +0200
+
+ Changes affecting future time stamps
+
+ The Egyptian government changed its mind on short notice, and
+ Africa/Cairo will not introduce DST starting 2016-07-07 after all.
+ (Thanks to Mina Samuel.)
+
+ Asia/Novosibirsk switches from +06 to +07 on 2016-07-24 at 02:00.
+ (Thanks to Stepan Golosunov.)
+
+ Changes to past and future time stamps
+
+ Asia/Novokuznetsk and Asia/Novosibirsk now use numeric time zone
+ abbreviations instead of invented ones.
+
+ Changes affecting past time stamps
+
+ Europe/Minsk's 1992-03-29 spring-forward transition was at 02:00 not 00:00.
+ (Thanks to Stepan Golosunov.)
+
+
+Release 2016e - 2016-06-14 08:46:16 -0700
+
+ Changes affecting future time stamps
+
+ Africa/Cairo observes DST in 2016 from July 7 to the end of October.
+ Guess October 27 and 24:00 transitions. (Thanks to Steffen Thorsen.)
+ For future years, guess April's last Thursday to October's last
+ Thursday except for Ramadan.
+
+ Changes affecting past time stamps
+
+ Locations while uninhabited now use '-00', not 'zzz', as a
+ placeholder time zone abbreviation. This is inspired by Internet
+ RFC 3339 and is more consistent with numeric time zone
+ abbreviations already used elsewhere. The change affects several
+ arctic and antarctic locations, e.g., America/Cambridge_Bay before
+ 1920 and Antarctica/Troll before 2005.
+
+ Asia/Baku's 1992-09-27 transition from +04 (DST) to +04 (non-DST) was
+ at 03:00, not 23:00 the previous day. (Thanks to Michael Deckers.)
+
+ Changes to code
+
+ zic now outputs a dummy transition at time 2**31 - 1 in zones
+ whose POSIX-style TZ strings contain a '<'. This mostly works
+ around Qt bug 53071 <https://bugreports.qt.io/browse/QTBUG-53071>.
+ (Thanks to Zhanibek Adilbekov for reporting the Qt bug.)
+
+ Changes affecting documentation and commentary
+
+ tz-link.htm says why governments should give plenty of notice for
+ time zone or DST changes, and refers to Matt Johnson's blog post.
+
+ tz-link.htm mentions Tzdata for Elixir. (Thanks to Matt Johnson.)
+
+
+Release 2016d - 2016-04-17 22:50:29 -0700
+
+ Changes affecting future time stamps
+
+ America/Caracas switches from -0430 to -04 on 2016-05-01 at 02:30.
+ (Thanks to Alexander Krivenyshev for the heads-up.)
+
+ Asia/Magadan switches from +10 to +11 on 2016-04-24 at 02:00.
+ (Thanks to Alexander Krivenyshev and Matt Johnson.)
+
+ New zone Asia/Tomsk, split off from Asia/Novosibirsk. It covers
+ Tomsk Oblast, Russia, which switches from +06 to +07 on 2016-05-29
+ at 02:00. (Thanks to Stepan Golosunov.)
+
+ Changes affecting past time stamps
+
+ New zone Europe/Kirov, split off from Europe/Volgograd. It covers
+ Kirov Oblast, Russia, which switched from +04/+05 to +03/+04 on
+ 1989-03-26 at 02:00, roughly a year after Europe/Volgograd made
+ the same change. (Thanks to Stepan Golosunov.)
+
+ Russia and nearby locations had daylight-saving transitions on
+ 1992-03-29 at 02:00 and 1992-09-27 at 03:00, instead of on
+ 1992-03-28 at 23:00 and 1992-09-26 at 23:00. (Thanks to Stepan
+ Golosunov.)
+
+ Many corrections to historical time in Kazakhstan from 1991
+ through 2005. (Thanks to Stepan Golosunov.) Replace Kazakhstan's
+ invented time zone abbreviations with numeric abbreviations.
+
+ Changes to commentary
+
+ Mention Internet RFCs 7808 (TZDIST) and 7809 (CalDAV time zone references).
+
+
+Release 2016c - 2016-03-23 00:51:27 -0700
+
+ Changes affecting future time stamps
+
+ Azerbaijan no longer observes DST. (Thanks to Steffen Thorsen.)
+
+ Chile reverts from permanent to seasonal DST. (Thanks to Juan
+ Correa for the heads-up, and to Tim Parenti for corrections.)
+ Guess that future transitions are August's and May's second
+ Saturdays at 24:00 mainland time. Also, call the period from
+ 2014-09-07 through 2016-05-14 daylight saving time instead of
+ standard time, as that seems more appropriate now.
+
+ Changes affecting past time stamps
+
+ Europe/Kaliningrad and Europe/Vilnius changed from +03/+04 to
+ +02/+03 on 1989-03-26, not 1991-03-31. Europe/Volgograd changed
+ from +04/+05 to +03/+04 on 1988-03-27, not 1989-03-26.
+ (Thanks to Stepan Golosunov.)
+
+ Changes to commentary
+
+ Several updates and URLs for historical and proposed Russian changes.
+ (Thanks to Stepan Golosunov, Matt Johnson, and Alexander Krivenyshev.)
+
+
+Release 2016b - 2016-03-12 17:30:14 -0800
+
+ Compatibility note
+
+ Starting with release 2016b, some data entries cause zic implementations
+ derived from tz releases 2005j through 2015e to issue warnings like
+ "time zone abbreviation differs from POSIX standard (+03)".
+ These warnings should not otherwise affect zic's output and can safely be
+ ignored on today's platforms, as the warnings refer to a restriction in
+ POSIX.1-1988 that was removed in POSIX.1-2001. One way to suppress the
+ warnings is to upgrade to zic derived from tz releases 2015f and later.
+
+ Changes affecting future time stamps
+
+ New zones Europe/Astrakhan and Europe/Ulyanovsk for Astrakhan and
+ Ulyanovsk Oblasts, Russia, both of which will switch from +03 to +04 on
+ 2016-03-27 at 02:00 local time. They need distinct zones since their
+ post-1970 histories disagree. New zone Asia/Barnaul for Altai Krai and
+ Altai Republic, Russia, which will switch from +06 to +07 on the same date
+ and local time. The Astrakhan change is already official; the others have
+ passed the first reading in the State Duma and are extremely likely.
+ Also, Asia/Sakhalin moves from +10 to +11 on 2016-03-27 at 02:00.
+ (Thanks to Alexander Krivenyshev for the heads-up, and to Matt Johnson
+ and Stepan Golosunov for followup.)
+
+ As a trial of a new system that needs less information to be made up,
+ the new zones use numeric time zone abbreviations like "+04"
+ instead of invented abbreviations like "ASTT".
+
+ Haiti will not observe DST in 2016. (Thanks to Jean Antoine via
+ Steffen Thorsen.)
+
+ Palestine's spring-forward transition on 2016-03-26 is at 01:00, not 00:00.
+ (Thanks to Hannah Kreitem.) Guess future transitions will be March's last
+ Saturday at 01:00, not March's last Friday at 24:00.
+
+ Changes affecting past time stamps
+
+ Europe/Chisinau observed DST during 1990, and switched from +04 to
+ +03 at 1990-05-06 02:00, instead of switching from +03 to +02.
+ (Thanks to Stepan Golosunov.)
+
+ 1991 abbreviations in Europe/Samara should be SAMT/SAMST, not
+ KUYT/KUYST. (Thanks to Stepan Golosunov.)
+
+ Changes to code
+
+ tzselect's diagnostics and checking, and checktab.awk's checking,
+ have been improved. (Thanks to J William Piggott.)
+
+ tzcode now builds under MinGW. (Thanks to Ian Abbott and Esben Haabendal.)
+
+ tzselect now tests Julian-date TZ settings more accurately.
+ (Thanks to J William Piggott.)
+
+ Changes to commentary
+
+ Comments in zone tables have been improved. (Thanks to J William Piggott.)
+
+ tzselect again limits its menu comments so that menus fit on a
+ 24x80 alphanumeric display.
+
+ A new web page tz-how-to.html. (Thanks to Bill Seymour.)
+
+ In the Theory file, the description of possible time zone abbreviations in
+ tzdata has been cleaned up, as the old description was unclear and
+ inconsistent. (Thanks to Alain Mouette for reporting the problem.)
+
+
+Release 2016a - 2016-01-26 23:28:02 -0800
+
+ Changes affecting future time stamps
+
+ America/Cayman will not observe daylight saving this year after all.
+ Revert our guess that it would. (Thanks to Matt Johnson.)
+
+ Asia/Chita switches from +0800 to +0900 on 2016-03-27 at 02:00.
+ (Thanks to Alexander Krivenyshev.)
+
+ Asia/Tehran now has DST predictions for the year 2038 and later,
+ to be March 21 00:00 to September 21 00:00. This is likely better
+ than predicting no DST, albeit off by a day every now and then.
+
+ Changes affecting past and future time stamps
+
+ America/Metlakatla switched from PST all year to AKST/AKDT on
+ 2015-11-01 at 02:00. (Thanks to Steffen Thorsen.)
+
+ America/Santa_Isabel has been removed, and replaced with a
+ backward compatibility link to America/Tijuana. Its contents were
+ apparently based on a misreading of Mexican legislation.
+
+ Changes affecting past time stamps
+
+ Asia/Karachi's two transition times in 2002 were off by a minute.
+ (Thanks to Matt Johnson.)
+
+ Changes affecting build procedure
+
+ An installer can now combine leap seconds with use of the backzone file,
+ e.g., with 'make PACKRATDATA=backzone REDO=posix_right zones'.
+ The old 'make posix_packrat' rule is now marked as obsolescent.
+ (Thanks to Ian Abbott for an initial implementation.)
+
+ Changes affecting documentation and commentary
+
+ A new file LICENSE makes it easier to see that the code and data
+ are mostly public-domain. (Thanks to James Knight.) The three
+ non-public-domain files now use the current (3-clause) BSD license
+ instead of older versions of that license.
+
+ tz-link.htm mentions the BDE library (thanks to Andrew Paprocki),
+ CCTZ (thanks to Tim Parenti), TimeJones.com, and has a new section
+ on editing tz source files (with a mention of Sublime zoneinfo,
+ thanks to Gilmore Davidson).
+
+ The Theory and asia files now mention the 2015 book "The Global
+ Transformation of Time, 1870-1950", and cite a couple of reviews.
+
+ The America/Chicago entry now documents the informal use of US
+ central time in Fort Pierre, South Dakota. (Thanks to Rick
+ McDermid, Matt Johnson, and Steve Jones.)
+
+
+Release 2015g - 2015-10-01 00:39:51 -0700
+
+ Changes affecting future time stamps
+
+ Turkey's 2015 fall-back transition is scheduled for Nov. 8, not Oct. 25.
+ (Thanks to Fatih.)
+
+ Norfolk moves from +1130 to +1100 on 2015-10-04 at 02:00 local time.
+ (Thanks to Alexander Krivenyshev.)
+
+ Fiji's 2016 fall-back transition is scheduled for January 17, not 24.
+ (Thanks to Ken Rylander.)
+
+ Fort Nelson, British Columbia will not fall back on 2015-11-01. It has
+ effectively been on MST (-0700) since it advanced its clocks on 2015-03-08.
+ New zone America/Fort_Nelson. (Thanks to Matt Johnson.)
+
+ Changes affecting past time stamps
+
+ Norfolk observed DST from 1974-10-27 02:00 to 1975-03-02 02:00.
+
+ Changes affecting code
+
+ localtime no longer mishandles America/Anchorage after 2037.
+ (Thanks to Bradley White for reporting the bug.)
+
+ On hosts with signed 32-bit time_t, localtime no longer mishandles
+ Pacific/Fiji after 2038-01-16 14:00 UTC.
+
+ The localtime module allows the variables 'timezone', 'daylight',
+ and 'altzone' to be in common storage shared with other modules,
+ and declares them in case the system <time.h> does not.
+ (Problems reported by Kees Dekker.)
+
+ On platforms with tm_zone, strftime.c now assumes it is not NULL.
+ This simplifies the code and is consistent with zdump.c.
+ (Problem reported by Christos Zoulas.)
+
+ Changes affecting documentation
+
+ The tzfile man page now documents that transition times denote the
+ starts (not the ends) of the corresponding time periods.
+ (Ambiguity reported by Bill Seymour.)
+
+
+Release 2015f - 2015-08-10 18:06:56 -0700
+
+ Changes affecting future time stamps
+
+ North Korea switches to +0830 on 2015-08-15. (Thanks to Steffen Thorsen.)
+ The abbreviation remains "KST". (Thanks to Robert Elz.)
+
+ Uruguay no longer observes DST. (Thanks to Steffen Thorsen
+ and Pablo Camargo.)
+
+ Changes affecting past and future time stamps
+
+ Moldova starts and ends DST at 00:00 UTC, not at 01:00 UTC.
+ (Thanks to Roman Tudos.)
+
+ Changes affecting data format and code
+
+ zic's '-y YEARISTYPE' option is no longer documented. The TYPE
+ field of a Rule line should now be '-'; the old values 'even',
+ 'odd', 'uspres', 'nonpres', 'nonuspres' were already undocumented.
+ Although the implementation has not changed, these features do not
+ work in the default installation, they are not used in the data,
+ and they are now considered obsolescent.
+
+ zic now checks that two rules don't take effect at the same time.
+ (Thanks to Jon Skeet and Arthur David Olson.) Constraints on
+ simultaneity are now documented.
+
+ The two characters '%z' in a zone format now stand for the UTC
+ offset, e.g., '-07' for seven hours behind UTC and '+0530' for
+ five hours and thirty minutes ahead. This better supports time
+ zone abbreviations conforming to POSIX.1-2001 and later.
+
+ Changes affecting installed data files
+
+ Comments for America/Halifax and America/Glace_Bay have been improved.
+ (Thanks to Brian Inglis.)
+
+ Data entries have been simplified for Atlantic/Canary, Europe/Simferopol,
+ Europe/Sofia, and Europe/Tallinn. This yields slightly smaller
+ installed data files for Europe/Simferopol and Europe/Tallinn.
+ It does not affect timestamps. (Thanks to Howard Hinnant.)
+
+ Changes affecting code
+
+ zdump and zic no longer warn about valid time zone abbreviations
+ like '-05'.
+
+ Some Visual Studio 2013 warnings have been suppressed.
+ (Thanks to Kees Dekker.)
+
+ 'date' no longer sets the time of day and its -a, -d, -n and -t
+ options have been removed. Long obsolescent, the implementation
+ of these features had porting problems. Builders no longer need
+ to configure HAVE_ADJTIME, HAVE_SETTIMEOFDAY, or HAVE_UTMPX_H.
+ (Thanks to Kees Dekker for pointing out the problem.)
+
+ Changes affecting documentation
+
+ The Theory file mentions naming issues earlier, as these seem to be
+ poorly publicized (thanks to Gilmore Davidson for reporting the problem).
+
+ tz-link.htm mentions Time Zone Database Parser (thanks to Howard Hinnant).
+
+ Mention that Herbert Samuel introduced the term "Summer Time".
+
+
+Release 2015e - 2015-06-13 10:56:02 -0700
+
+ Changes affecting future time stamps
+
+ Morocco will suspend DST from 2015-06-14 03:00 through 2015-07-19 02:00,
+ not 06-13 and 07-18 as we had guessed. (Thanks to Milamber.)
+
+ Assume Cayman Islands will observe DST starting next year, using US rules.
+ Although it isn't guaranteed, it is the most likely.
+
+ Changes affecting data format
+
+ The file 'iso3166.tab' now uses UTF-8, so that its entries can better
+ spell the names of Åland Islands, Côte d'Ivoire, and Réunion.
+
+ Changes affecting code
+
+ When displaying data, tzselect converts it to the current locale's
+ encoding if the iconv command works. (Problem reported by random832.)
+
+ tzselect no longer mishandles Dominica, fixing a bug introduced
+ in Release 2014f. (Problem reported by Owen Leibman.)
+
+ zic -l no longer fails when compiled with -DTZDEFAULT=\"/etc/localtime\".
+ This fixes a bug introduced in Release 2014f.
+ (Problem reported by Leonardo Chiquitto.)
+
+
+Release 2015d - 2015-04-24 08:09:46 -0700
+
+ Changes affecting future time stamps
+
+ Egypt will not observe DST in 2015 and will consider canceling it
+ permanently. For now, assume no DST indefinitely.
+ (Thanks to Ahmed Nazmy and Tim Parenti.)
+
+ Changes affecting past time stamps
+
+ America/Whitehorse switched from UTC-9 to UTC-8 on 1967-05-28, not
+ 1966-07-01. Also, Yukon's time zone history is documented better.
+ (Thanks to Brian Inglis and Dennis Ferguson.)
+
+ Change affecting past and future time zone abbreviations
+
+ The abbreviations for Hawaii-Aleutian standard and daylight times
+ have been changed from HAST/HADT to HST/HDT, as per US Government
+ Printing Office style. This affects only America/Adak since 1983,
+ as America/Honolulu was already using the new style.
+
+ Changes affecting code
+
+ zic has some minor performance improvements.
+
+
+Release 2015c - 2015-04-11 08:55:55 -0700
+
+ Changes affecting future time stamps
+
+ Egypt's spring-forward transition is at 24:00 on April's last Thursday,
+ not 00:00 on April's last Friday. 2015's transition will therefore be on
+ Thursday, April 30 at 24:00, not Friday, April 24 at 00:00. Similar fixes
+ apply to 2026, 2037, 2043, etc. (Thanks to Steffen Thorsen.)
+
+ Changes affecting past time stamps
+
+ The following changes affect some pre-1991 Chile-related time stamps
+ in America/Santiago, Antarctica/Palmer, and Pacific/Easter.
+
+ The 1910 transition was January 10, not January 1.
+
+ The 1918 transition was September 10, not September 1.
+
+ The UTC-4 time observed from 1932 to 1942 is now considered to be
+ standard time, not year-round DST.
+
+ Santiago observed DST (UTC-3) from 1946-07-15 through 1946-08-31,
+ then reverted to standard time, then switched its time zone to
+ UTC-5 on 1947-04-01.
+
+ Assume transitions before 1968 were at 00:00, since we have no data
+ saying otherwise.
+
+ The spring 1988 transition was 1988-10-09, not 1988-10-02.
+ The fall 1990 transition was 1990-03-11, not 1990-03-18.
+
+ Assume no UTC offset change for Pacific/Easter on 1890-01-01,
+ and omit all transitions on Pacific/Easter from 1942 through 1946
+ since we have no data suggesting that they existed.
+
+ One more zone has been turned into a link, as it differed
+ from an existing zone only for older time stamps. As usual,
+ this change affects UTC offsets in pre-1970 time stamps only.
+ The zone's old contents have been moved to the 'backzone' file.
+ The affected zone is America/Montreal.
+
+ Changes affecting commentary
+
+ Mention the TZUpdater tool.
+
+ Mention "The Time Now". (Thanks to Brandon Ramsey.)
+
+
+Release 2015b - 2015-03-19 23:28:11 -0700
+
+ Changes affecting future time stamps
+
+ Mongolia will start observing DST again this year, from the last
+ Saturday in March at 02:00 to the last Saturday in September at 00:00.
+ (Thanks to Ganbold Tsagaankhuu.)
+
+ Palestine will start DST on March 28, not March 27. Also,
+ correct the fall 2014 transition from September 26 to October 24.
+ Adjust future predictions accordingly. (Thanks to Steffen Thorsen.)
+
+ Changes affecting past time stamps
+
+ The 1982 zone shift in Pacific/Easter has been corrected, fixing a 2015a
+ regression. (Thanks to Stuart Bishop for reporting the problem.)
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: America/Antigua, America/Cayman,
+ Pacific/Midway, and Pacific/Saipan.
+
+ Changes affecting time zone abbreviations
+
+ Correct the 1992-2010 DST abbreviation in Volgograd from "MSK" to "MSD".
+ (Thanks to Hank W.)
+
+ Changes affecting code
+
+ Fix integer overflow bug in reference 'mktime' implementation.
+ (Problem reported by Jörg Richter.)
+
+ Allow -Dtime_tz=time_t compilations, and allow -Dtime_tz=... libraries
+ to be used in the same executable as standard-library time_t functions.
+ (Problems reported by Bradley White.)
+
+ Changes affecting commentary
+
+ Cite the recent Mexican decree changing Quintana Roo's time zone.
+ (Thanks to Carlos Raúl Perasso.)
+
+ Likewise for the recent Chilean decree. (Thanks to Eduardo Romero Urra.)
+
+ Update info about Mars time.
+
+
+Release 2015a - 2015-01-29 22:35:20 -0800
+
+ Changes affecting future time stamps
+
+ The Mexican state of Quintana Roo, represented by America/Cancun,
+ will shift from Central Time with DST to Eastern Time without DST
+ on 2015-02-01 at 02:00. (Thanks to Steffen Thorsen and Gwillim Law.)
+
+ Chile will not change clocks in April or thereafter; its new standard time
+ will be its old daylight saving time. This affects America/Santiago,
+ Pacific/Easter, and Antarctica/Palmer. (Thanks to Juan Correa.)
+
+ New leap second 2015-06-30 23:59:60 UTC as per IERS Bulletin C 49.
+ (Thanks to Tim Parenti.)
+
+ Changes affecting past time stamps
+
+ Iceland observed DST in 1919 and 1921, and its 1939 fallback
+ transition was Oct. 29, not Nov. 29. Remove incorrect data from
+ Shanks about time in Iceland between 1837 and 1908.
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: Asia/Aden, Asia/Bahrain, Asia/Kuwait,
+ and Asia/Muscat.
+
+ Changes affecting code
+
+ tzalloc now scrubs time zone abbreviations compatibly with the way
+ that tzset always has, by replacing invalid bytes with '_' and by
+ shortening too-long abbreviations.
+
+ tzselect ports to POSIX awk implementations, no longer mishandles
+ POSIX TZ settings when GNU awk is used, and reports POSIX TZ
+ settings to the user. (Thanks to Stefan Kuhn.)
+
+ Changes affecting build procedure
+
+ 'make check' now checks for links to links in the data.
+ One such link (for Africa/Asmera) has been fixed.
+ (Thanks to Stephen Colebourne for pointing out the problem.)
+
+ Changes affecting commentary
+
+ The leapseconds file commentary now mentions the expiration date.
+ (Problem reported by Martin Burnicki.)
+
+ Update Mexican Library of Congress URL.
+
+
+Release 2014j - 2014-11-10 17:37:11 -0800
+
+ Changes affecting current and future time stamps
+
+ Turks & Caicos' switch from US eastern time to UTC-4 year-round
+ did not occur on 2014-11-02 at 02:00. It's currently scheduled
+ for 2015-11-01 at 02:00. (Thanks to Chris Walton.)
+
+ Changes affecting past time stamps
+
+ Many pre-1989 time stamps have been corrected for Asia/Seoul and
+ Asia/Pyongyang, based on sources for the Korean-language Wikipedia
+ entry for time in Korea. (Thanks to Sanghyuk Jung.) Also, no
+ longer guess that Pyongyang mimicked Seoul time after World War II,
+ as this is politically implausible.
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: Africa/Addis_Ababa, Africa/Asmara,
+ Africa/Dar_es_Salaam, Africa/Djibouti, Africa/Kampala,
+ Africa/Mogadishu, Indian/Antananarivo, Indian/Comoro, and
+ Indian/Mayotte.
+
+ Changes affecting commentary
+
+ The commentary is less enthusiastic about Shanks as a source,
+ and is more careful to distinguish UT from UTC.
+
+
+Release 2014i - 2014-10-21 22:04:57 -0700
+
+ Changes affecting future time stamps
+
+ Pacific/Fiji will observe DST from 2014-11-02 02:00 to 2015-01-18 03:00.
+ (Thanks to Ken Rylander for the heads-up.) Guess that future
+ years will use a similar pattern.
+
+ A new Zone Pacific/Bougainville, for the part of Papua New Guinea
+ that plans to switch from UTC+10 to UTC+11 on 2014-12-28 at 02:00.
+ (Thanks to Kiley Walbom for the heads-up.)
+
+ Changes affecting time zone abbreviations
+
+ Since Belarus is not changing its clocks even though Moscow is,
+ the time zone abbreviation in Europe/Minsk is changing from FET
+ to its more-traditional value MSK on 2014-10-26 at 01:00.
+ (Thanks to Alexander Bokovoy for the heads-up about Belarus.)
+
+ The new abbreviation IDT stands for the pre-1976 use of UT+8 in
+ Indochina, to distinguish it better from ICT (UT+7).
+
+ Changes affecting past time stamps
+
+ Many time stamps have been corrected for Asia/Ho_Chi_Minh before 1976
+ (thanks to Trần Ngọc Quân for an indirect pointer to Trần Tiến Bình's
+ authoritative book). Asia/Ho_Chi_Minh has been added to
+ zone1970.tab, to give tzselect users in Vietnam two choices,
+ since north and south Vietnam disagreed after our 1970 cutoff.
+
+ Asia/Phnom_Penh and Asia/Vientiane have been turned into links, as
+ they differed from existing zones only for older time stamps. As
+ usual, these changes affect pre-1970 time stamps only. Their old
+ contents have been moved to the 'backzone' file.
+
+ Changes affecting code
+
+ The time-related library functions now set errno on failure, and
+ some crashes in the new tzalloc-related library functions have
+ been fixed. (Thanks to Christos Zoulas for reporting most of
+ these problems and for suggesting fixes.)
+
+ If USG_COMPAT is defined and the requested time stamp is standard time,
+ the tz library's localtime and mktime functions now set the extern
+ variable timezone to a value appropriate for that time stamp; and
+ similarly for ALTZONE, daylight saving time, and the altzone variable.
+ This change is a companion to the tzname change in 2014h, and is
+ designed to make timezone and altzone more compatible with tzname.
+
+ The tz library's functions now set errno to EOVERFLOW if they fail
+ because the result cannot be represented. ctime and ctime_r now
+ return NULL and set errno when a time stamp is out of range, rather
+ than having undefined behavior.
+
+ Some bugs associated with the new 2014g functions have been fixed.
+ This includes a bug that largely incapacitated the new functions
+ time2posix_z and posix2time_z. (Thanks to Christos Zoulas.)
+ It also includes some uses of uninitialized variables after tzalloc.
+ The new code uses the standard type 'ssize_t', which the Makefile
+ now gives porting advice about.
+
+ Changes affecting commentary
+
+ Updated URLs for NRC Canada (thanks to Matt Johnson and Brian Inglis).
+
+
+Release 2014h - 2014-09-25 18:59:03 -0700
+
+ Changes affecting past time stamps
+
+ America/Jamaica's 1974 spring-forward transition was Jan. 6, not Apr. 28.
+
+ Shanks says Asia/Novokuznetsk switched from LMT (not "NMT") on 1924-05-01,
+ not 1920-01-06. The old entry was based on a misinterpretation of Shanks.
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: Africa/Blantyre, Africa/Bujumbura,
+ Africa/Gaborone, Africa/Harare, Africa/Kigali, Africa/Lubumbashi,
+ Africa/Lusaka, Africa/Maseru, and Africa/Mbabane.
+
+ Changes affecting code
+
+ zdump -V and -v now output gmtoff= values on all platforms,
+ not merely on platforms defining TM_GMTOFF.
+
+ The tz library's localtime and mktime functions now set tzname to a value
+ appropriate for the requested time stamp, and zdump now uses this
+ on platforms not defining TM_ZONE, fixing a 2014g regression.
+ (Thanks to Tim Parenti for reporting the problem.)
+
+ The tz library no longer sets tzname if localtime or mktime fails.
+
+ zdump -c no longer mishandles transitions near year boundaries.
+ (Thanks to Tim Parenti for reporting the problem.)
+
+ An access to uninitalized data has been fixed.
+ (Thanks to Jörg Richter for reporting the problem.)
+
+ When THREAD_SAFE is defined, the code ports to the C11 memory model.
+ A memory leak has been fixed if ALL_STATE and THREAD_SAFE are defined
+ and two threads race to initialize data used by gmtime-like functions.
+ (Thanks to Andy Heninger for reporting the problems.)
+
+ Changes affecting build procedure
+
+ 'make check' now checks better for properly-sorted data.
+
+ Changes affecting documentation and commentary
+
+ zdump's gmtoff=N output is now documented, and its isdst=D output
+ is now documented to possibly output D values other than 0 or 1.
+
+ zdump -c's treatment of years is now documented to use the
+ Gregorian calendar and Universal Time without leap seconds,
+ and its behavior at cutoff boundaries is now documented better.
+ (Thanks to Arthur David Olson and Tim Parenti for reporting the problems.)
+
+ Programs are now documented to use the proleptic Gregorian calendar.
+ (Thanks to Alan Barrett for the suggestion.)
+
+ Fractional-second GMT offsets have been documented for civil time
+ in 19th-century Chennai, Jakarta, and New York.
+
+
+Release 2014g - 2014-08-28 12:31:23 -0700
+
+ Changes affecting future time stamps
+
+ Turks & Caicos is switching from US eastern time to UTC-4 year-round,
+ modeled as a switch from EST/EDT to AST on 2014-11-02 at 02:00.
+ [As noted in 2014j, this switch was later delayed.]
+
+ Changes affecting past time stamps
+
+ Time in Russia or the USSR before 1926 or so has been corrected by
+ a few seconds in the following zones: Asia/Irkutsk,
+ Asia/Krasnoyarsk, Asia/Omsk, Asia/Samarkand, Asia/Tbilisi,
+ Asia/Vladivostok, Asia/Yakutsk, Europe/Riga, Europe/Samara. For
+ Asia/Yekaterinburg the correction is a few minutes. (Thanks to
+ Vladimir Karpinsky.)
+
+ The Portuguese decree of 1911-05-26 took effect on 1912-01-01.
+ This affects 1911 time stamps in Africa/Bissau, Africa/Luanda,
+ Atlantic/Azores, and Atlantic/Madeira. Also, Lisbon's pre-1912
+ GMT offset was -0:36:45 (rounded from -0:36:44.68), not -0:36:32.
+ (Thanks to Stephen Colebourne for pointing to the decree.)
+
+ Asia/Dhaka ended DST on 2009-12-31 at 24:00, not 23:59.
+
+ A new file 'backzone' contains data which may appeal to
+ connoisseurs of old time stamps, although it is out of scope for
+ the tz database, is often poorly sourced, and contains some data
+ that is known to be incorrect. The new file is not recommended
+ for ordinary use and its entries are not installed by default.
+ (Thanks to Lester Caine for the high-quality Jersey, Guernsey, and
+ Isle of Man entries.)
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: Africa/Bangui, Africa/Brazzaville,
+ Africa/Douala, Africa/Kinshasa, Africa/Libreville, Africa/Luanda,
+ Africa/Malabo, Africa/Niamey, and Africa/Porto-Novo.
+
+ Changes affecting code
+
+ Unless NETBSD_INSPIRED is defined to 0, the tz library now
+ supplies functions for creating and using objects that represent
+ time zones. The new functions are tzalloc, tzfree, localtime_rz,
+ mktime_z, and (if STD_INSPIRED is also defined) posix2time_z and
+ time2posix_z. They are intended for performance: for example,
+ localtime_rz (unlike localtime_r) is trivially thread-safe without
+ locking. (Thanks to Christos Zoulas for proposing NetBSD-inspired
+ functions, and to Alan Barrett and Jonathan Lennox for helping to
+ debug the change.)
+
+ zdump now builds with the tz library unless USE_LTZ is defined to 0,
+ This lets zdump use tz features even if the system library lacks them.
+ To build zdump with the system library, use 'make CFLAGS=-DUSE_LTZ=0
+ TZDOBJS=zdump.o CHECK_TIME_T_ALTERNATIVES='.
+
+ zdump now uses localtime_rz if available, as it's significantly faster,
+ and it can help zdump better diagnose invalid time zone names.
+ Define HAVE_LOCALTIME_RZ to 0 to suppress this. HAVE_LOCALTIME_RZ
+ defaults to 1 if NETBSD_INSPIRED && USE_LTZ. When localtime_rz is
+ not available, zdump now uses localtime_r and tzset if available,
+ as this is a bit cleaner and faster than plain localtime. Compile
+ with -DHAVE_LOCALTIME_R=0 and/or -DHAVE_TZSET=0 if your system
+ lacks these two functions.
+
+ If THREAD_SAFE is defined to 1, the tz library is now thread-safe.
+ Although not needed for tz's own applications, which are single-threaded,
+ this supports POSIX better if the tz library is used in multithreaded apps.
+
+ Some crashes have been fixed when zdump or the tz library is given
+ invalid or outlandish input.
+
+ The tz library no longer mishandles leap seconds on platforms with
+ unsigned time_t in time zones that lack ordinary transitions after 1970.
+
+ The tz code now attempts to infer TM_GMTOFF and TM_ZONE if not
+ already defined, to make it easier to configure on common platforms.
+ Define NO_TM_GMTOFF and NO_TM_ZONE to suppress this.
+
+ Unless the new macro UNINIT_TRAP is defined to 1, the tz code now
+ assumes that reading uninitialized memory yields garbage values
+ but does not cause other problems such as traps.
+
+ If TM_GMTOFF is defined and UNINIT_TRAP is 0, mktime is now
+ more likely to guess right for ambiguous time stamps near
+ transitions where tm_isdst does not change.
+
+ If HAVE_STRFTIME_L is defined to 1, the tz library now defines
+ strftime_l for compatibility with recent versions of POSIX.
+ Only the C locale is supported, though. HAVE_STRFTIME_L defaults
+ to 1 on recent POSIX versions, and to 0 otherwise.
+
+ tzselect -c now uses a hybrid distance measure that works better
+ in Africa. (Thanks to Alan Barrett for noting the problem.)
+
+ The C source code now ports to NetBSD when GCC_DEBUG_FLAGS is used,
+ or when time_tz is defined.
+
+ When HAVE_UTMPX_H is set the 'date' command now builds on systems
+ whose <utmpx.h> file does not define WTMPX_FILE, and when setting
+ the date it updates the wtmpx file if _PATH_WTMPX is defined.
+ This affects GNU/Linux and similar systems.
+
+ For easier maintenance later, some C code has been simplified,
+ some lint has been removed, and the code has been tweaked so that
+ plain 'make' is more likely to work.
+
+ The C type 'bool' is now used for boolean values, instead of 'int'.
+
+ The long-obsolete LOCALE_HOME code has been removed.
+
+ The long-obsolete 'gtime' function has been removed.
+
+ Changes affecting build procedure
+
+ 'zdump' no longer links in ialloc.o, as it's not needed.
+
+ 'make check_time_t_alternatives' no longer assumes GNU diff.
+
+ Changes affecting distribution tarballs
+
+ The files checktab.awk and zoneinfo2tdf.pl are now distributed in
+ the tzdata tarball instead of the tzcode tarball, since they help
+ maintain the data. The NEWS and Theory files are now also
+ distributed in the tzdata tarball, as they're relevant for data.
+ (Thanks to Alan Barrett for pointing this out.) Also, the
+ leapseconds.awk file is no longer distributed in the tzcode
+ tarball, since it belongs in the tzdata tarball (where 2014f
+ inadvertently also distributed it).
+
+ Changes affecting documentation and commentary
+
+ A new file CONTRIBUTING is distributed. (Thanks to Tim Parenti for
+ suggesting a CONTRIBUTING file, and to Tony Finch and Walter Harms
+ for debugging it.)
+
+ The man pages have been updated to use function prototypes,
+ to document thread-safe variants like localtime_r, and to document
+ the NetBSD-inspired functions tzalloc, tzfree, localtime_rz, and
+ mktime_z.
+
+ The fields in Link lines have been renamed to be more descriptive
+ and more like the parameters of 'ln'. LINK-FROM has become TARGET,
+ and LINK-TO has become LINK-NAME.
+
+ tz-link.htm mentions the IETF's tzdist working group; Windows
+ Runtime etc. (thanks to Matt Johnson); and HP-UX's tztab.
+
+ Some broken URLs have been fixed in the commentary. (Thanks to
+ Lester Caine.)
+
+ Commentary about Philippines DST has been updated, and commentary
+ on pre-1970 time in India has been added.
+
+
+Release 2014f - 2014-08-05 17:42:36 -0700
+
+ Changes affecting future time stamps
+
+ Russia will subtract an hour from most of its time zones on 2014-10-26
+ at 02:00 local time. (Thanks to Alexander Krivenyshev.)
+ There are a few exceptions: Magadan Oblast (Asia/Magadan) and Zabaykalsky
+ Krai are subtracting two hours; conversely, Chukotka Autonomous Okrug
+ (Asia/Anadyr), Kamchatka Krai (Asia/Kamchatka), Kemerovo Oblast
+ (Asia/Novokuznetsk), and the Samara Oblast and the Udmurt Republic
+ (Europe/Samara) are not changing their clocks. The changed zones are
+ Europe/Kaliningrad, Europe/Moscow, Europe/Simferopol, Europe/Volgograd,
+ Asia/Yekaterinburg, Asia/Omsk, Asia/Novosibirsk, Asia/Krasnoyarsk,
+ Asia/Irkutsk, Asia/Yakutsk, Asia/Vladivostok, Asia/Khandyga,
+ Asia/Sakhalin, and Asia/Ust-Nera; Asia/Magadan will have two hours
+ subtracted; and Asia/Novokuznetsk's time zone abbreviation is affected,
+ but not its UTC offset. Two zones are added: Asia/Chita (split
+ from Asia/Yakutsk, and also with two hours subtracted) and
+ Asia/Srednekolymsk (split from Asia/Magadan, but with only one hour
+ subtracted). (Thanks to Tim Parenti for much of the above.)
+
+ Changes affecting time zone abbreviations
+
+ Australian eastern time zone abbreviations are now AEST/AEDT not EST,
+ and similarly for the other Australian zones. That is, for eastern
+ standard and daylight saving time the abbreviations are AEST and AEDT
+ instead of the former EST for both; similarly, ACST/ACDT, ACWST/ACWDT,
+ and AWST/AWDT are now used instead of the former CST, CWST, and WST.
+ This change does not affect UTC offsets, only time zone abbreviations.
+ (Thanks to Rich Tibbett and many others.)
+
+ Asia/Novokuznetsk shifts from NOVT to KRAT (remaining on UTC+7)
+ effective 2014-10-26 at 02:00 local time.
+
+ The time zone abbreviation for Xinjiang Time (observed in Ürümqi)
+ has been changed from URUT to XJT. (Thanks to Luther Ma.)
+
+ Prefer MSK/MSD for Moscow time in Russia, even in other cities.
+ Similarly, prefer EET/EEST for eastern European time in Russia.
+
+ Change time zone abbreviations in (western) Samoa to use "ST" and
+ "DT" suffixes, as this is more likely to match common practice.
+ Prefix "W" to (western) Samoa time when its standard-time offset
+ disagrees with that of American Samoa.
+
+ America/Metlakatla now uses PST, not MeST, to abbreviate its time zone.
+
+ Time zone abbreviations have been updated for Japan's two time
+ zones used 1896-1937. JWST now stands for Western Standard
+ Time, and JCST for Central Standard Time (formerly this was CJT).
+ These abbreviations are now used for time in Korea, Taiwan,
+ and Sakhalin while controlled by Japan.
+
+ Changes affecting past time stamps
+
+ China's five zones have been simplified to two, since the post-1970
+ differences in the other three seem to have been imaginary. The
+ zones Asia/Harbin, Asia/Chongqing, and Asia/Kashgar have been
+ removed; backwards-compatibility links still work, albeit with
+ different behaviors for time stamps before May 1980. Asia/Urumqi's
+ 1980 transition to UTC+8 has been removed, so that it is now at
+ UTC+6 and not UTC+8. (Thanks to Luther Ma and to Alois Treindl;
+ Treindl sent helpful translations of two papers by Guo Qingsheng.)
+
+ Some zones have been turned into links, when they differed from existing
+ zones only for older UTC offsets where data entries were likely invented.
+ These changes affect UTC offsets in pre-1970 time stamps only. This is
+ similar to the change in release 2013e, except this time for western
+ Africa. The affected zones are: Africa/Bamako, Africa/Banjul,
+ Africa/Conakry, Africa/Dakar, Africa/Freetown, Africa/Lome,
+ Africa/Nouakchott, Africa/Ouagadougou, Africa/Sao_Tome, and
+ Atlantic/St_Helena. This also affects the backwards-compatibility
+ link Africa/Timbuktu. (Thanks to Alan Barrett, Stephen Colebourne,
+ Tim Parenti, and David Patte for reporting problems in earlier
+ versions of this change.)
+
+ Asia/Shanghai's pre-standard-time UT offset has been changed from
+ 8:05:57 to 8:05:43, the location of Xujiahui Observatory. Its
+ transition to standard time has been changed from 1928 to 1901.
+
+ Asia/Taipei switched to JWST on 1896-01-01, then to JST on 1937-10-01,
+ then to CST on 1945-09-21 at 01:00, and did not observe DST in 1945.
+ In 1946 it observed DST from 05-15 through 09-30; in 1947
+ from 04-15 through 10-31; and in 1979 from 07-01 through 09-30.
+ (Thanks to Yu-Cheng Chuang.)
+
+ Asia/Riyadh's transition to standard time is now 1947-03-14, not 1950.
+
+ Europe/Helsinki's 1942 fall-back transition was 10-04 at 01:00, not
+ 10-03 at 00:00. (Thanks to Konstantin Hyppönen.)
+
+ Pacific/Pago_Pago has been changed from UTC-11:30 to UTC-11 for the period
+ from 1911 to 1950.
+
+ Pacific/Chatham has been changed to New Zealand standard time plus
+ 45 minutes for the period before 1957, reflecting a 1956 remark in
+ the New Zealand parliament.
+
+ Europe/Budapest has several pre-1946 corrections: in 1918 the transition
+ out of DST was on 09-16, not 09-29; in 1919 it was on 11-24, not 09-15; in
+ 1945 it was on 11-01, not 11-03; in 1941 the transition to DST was 04-08
+ not 04-06 at 02:00; and there was no DST in 1920.
+
+ Africa/Accra is now assumed to have observed DST from 1920 through 1935.
+
+ Time in Russia before 1927 or so has been corrected by a few seconds in
+ the following zones: Europe/Moscow, Asia/Irkutsk, Asia/Tbilisi,
+ Asia/Tashkent, Asia/Vladivostok, Asia/Yekaterinburg, Europe/Helsinki, and
+ Europe/Riga. Also, Moscow's location has been changed to its Kilometer 0
+ point. (Thanks to Vladimir Karpinsky for the Moscow changes.)
+
+ Changes affecting data format
+
+ A new file 'zone1970.tab' supersedes 'zone.tab' in the installed data.
+ The new file's extended format allows multiple country codes per zone.
+ The older file is still installed but is deprecated; its format is
+ not changing and it will still be distributed for a while, but new
+ applications should use the new file.
+
+ The new file format simplifies maintenance of obscure locations.
+ To test this, it adds coverage for the Crozet Islands and the
+ Scattered Islands. (Thanks to Tobias Conradi and Antoine Leca.)
+
+ The file 'iso3166.tab' is planned to switch from ASCII to UTF-8.
+ It is still ASCII now, but commentary about the switch has been added.
+ The new file 'zone1970.tab' already uses UTF-8.
+
+ Changes affecting code
+
+ 'localtime', 'mktime', etc. now use much less stack space if ALL_STATE
+ is defined. (Thanks to Elliott Hughes for reporting the problem.)
+
+ 'zic' no longer mishandles input when ignoring case in locales that
+ are not compatible with English, e.g., unibyte Turkish locales when
+ compiled with HAVE_GETTEXT.
+
+ Error diagnostics of 'zic' and 'yearistype' have been reworded so that
+ they no longer use ASCII '-' as if it were a dash.
+
+ 'zic' now rejects output file names that contain '.' or '..' components.
+ (Thanks to Tim Parenti for reporting the problem.)
+
+ 'zic -v' now warns about output file names that do not follow
+ POSIX rules, or that contain a digit or '.'. (Thanks to Arthur
+ David Olson for starting the ball rolling on this.)
+
+ Some lint has been removed when using GCC_DEBUG_FLAGS with GCC 4.9.0.
+
+ Changes affecting build procedure
+
+ 'zic' no longer links in localtime.o and asctime.o, as they're not needed.
+ (Thanks to John Cochran.)
+
+ Changes affecting documentation and commentary
+
+ The 'Theory' file documents legacy names, the longstanding
+ exceptions to the POSIX-inspired file name rules.
+
+ The 'zic' documentation clarifies the role of time types when
+ interpreting dates. (Thanks to Arthur David Olson.)
+
+ Documentation and commentary now prefer UTF-8 to US-ASCII,
+ allowing the use of proper accents in foreign words and names.
+ Code and data have not changed because of this. (Thanks to
+ Garrett Wollman, Ian Abbott, and Guy Harris for helping to debug
+ this.)
+
+ Non-HTML documentation and commentary now use plain-text URLs instead of
+ HTML insertions, and are more consistent about bracketing URLs when they
+ are not already surrounded by white space. (Thanks to suggestions by
+ Steffen Nurpmeso.)
+
+ There is new commentary about Xujiahui Observatory, the five time-zone
+ project in China from 1918 to 1949, timekeeping in Japanese-occupied
+ Shanghai, and Tibet Time in the 1950s. The sharp-eyed can spot the
+ warlord Jin Shuren in the data.
+
+ Commentary about the coverage of each Russian zone has been standardized.
+ (Thanks to Tim Parenti).
+
+ There is new commentary about contemporary timekeeping in Ethiopia.
+
+ Obsolete comments about a 2007 proposal for DST in Kuwait has been removed.
+
+ There is new commentary about time in Poland in 1919.
+
+ Proper credit has been given to DST inventor George Vernon Hudson.
+
+ Commentary about time in Metlakatla, AK and Resolute, NU has been
+ improved, with a new source for the former.
+
+ In zone.tab, Pacific/Easter no longer mentions Salas y Gómez, as it
+ is uninhabited.
+
+ Commentary about permanent Antarctic bases has been updated.
+
+ Several typos have been corrected. (Thanks to Tim Parenti for
+ contributing some of these fixes.)
+
+ tz-link.htm now mentions the JavaScript libraries Moment Timezone,
+ TimezoneJS.Date, Walltime-js, and Timezone. (Thanks to a heads-up
+ from Matt Johnson.) Also, it mentions the Go 'latlong' package.
+ (Thanks to a heads-up from Dirkjan Ochtman.)
+
+ The files usno1988, usno1989, usno1989a, usno1995, usno1997, and usno1998
+ have been removed. These obsolescent US Naval Observatory entries were no
+ longer helpful for maintenance. (Thanks to Tim Parenti for the suggestion.)
+
+
+Release 2014e - 2014-06-12 21:53:52 -0700
+
+ Changes affecting near-future time stamps
+
+ Egypt's 2014 Ramadan-based transitions are June 26 and July 31 at 24:00.
+ (Thanks to Imed Chihi.) Guess that from 2015 on Egypt will temporarily
+ switch to standard time at 24:00 the last Thursday before Ramadan, and
+ back to DST at 00:00 the first Friday after Ramadan.
+
+ Similarly, Morocco's are June 28 at 03:00 and August 2 at 02:00. (Thanks
+ to Milamber Space Network.) Guess that from 2015 on Morocco will
+ temporarily switch to standard time at 03:00 the last Saturday before
+ Ramadan, and back to DST at 02:00 the first Saturday after Ramadan.
+
+ Changes affecting past time stamps
+
+ The abbreviation "MSM" (Moscow Midsummer Time) is now used instead of
+ "MSD" for Moscow's double daylight time in summer 1921. Also, a typo
+ "VLASST" has been repaired to be "VLAST" for Vladivostok summer time
+ in 1991. (Thanks to Hank W. for reporting the problems.)
+
+ Changes affecting commentary
+
+ tz-link.htm now cites RFC 7265 for jCal, mentions PTP and the
+ draft CalDAV extension, updates URLs for TSP, TZInfo, IATA, and
+ removes stale pointers to World Time Explorer and WORLDTIME.
+
+
+Release 2014d - 2014-05-27 21:34:40 -0700
+
+ Changes affecting code
+
+ zic no longer generates files containing time stamps before the Big Bang.
+ This works around GNOME bug 730332
+ <https://bugzilla.gnome.org/show_bug.cgi?id=730332>.
+ (Thanks to Leonardo Chiquitto for reporting the bug, and to
+ Arthur David Olson and James Cloos for suggesting improvements to the fix.)
+
+ Changes affecting documentation
+
+ tz-link.htm now mentions GNOME.
+
+
+Release 2014c - 2014-05-13 07:44:13 -0700
+
+ Changes affecting near-future time stamps
+
+ Egypt observes DST starting 2014-05-15 at 24:00.
+ (Thanks to Ahmad El-Dardiry and Gunther Vermier.)
+ Details have not been announced, except that DST will not be observed
+ during Ramadan. Guess that DST will stop during the same Ramadan dates as
+ Morocco, and that Egypt's future spring and fall transitions will be the
+ same as 2010 when it last observed DST, namely April's last Friday at
+ 00:00 to September's last Thursday at 23:00 standard time. Also, guess
+ that Ramadan transitions will be at 00:00 standard time.
+
+ Changes affecting code
+
+ zic now generates transitions for minimum time values, eliminating guesswork
+ when handling low-valued time stamps. (Thanks to Arthur David Olson.)
+
+ Port to Cygwin sans glibc. (Thanks to Arthur David Olson.)
+
+ Changes affecting commentary and documentation
+
+ Remove now-confusing comment about Jordan. (Thanks to Oleksii Nochovnyi.)
+
+
+Release 2014b - 2014-03-24 21:28:50 -0700
+
+ Changes affecting near-future time stamps
+
+ Crimea switches to Moscow time on 2014-03-30 at 02:00 local time.
+ (Thanks to Alexander Krivenyshev.) Move its zone.tab entry from UA to RU.
+
+ New entry for Troll station, Antarctica. (Thanks to Paul-Inge Flakstad and
+ Bengt-Inge Larsson.) This is currently an approximation; a better version
+ will require the zic and localtime fixes mentioned below, and the plan is
+ to wait for a while until at least the zic fixes propagate.
+
+ Changes affecting code
+
+ 'zic' and 'localtime' no longer reject locations needing four transitions
+ per year for the foreseeable future. (Thanks to Andrew Main (Zefram).)
+ Also, 'zic' avoids some unlikely failures due to integer overflow.
+
+ Changes affecting build procedure
+
+ 'make check' now detects Rule lines defined but never used.
+ The NZAQ rules, an instance of this problem, have been removed.
+
+ Changes affecting commentary and documentation
+
+ Fix Tuesday/Thursday typo in description of time in Israel.
+ (Thanks to Bert Katz via Pavel Kharitonov and Mike Frysinger.)
+
+ Microsoft Windows 8.1 doesn't support tz database names. (Thanks
+ to Donald MacQueen.) Instead, the Microsoft Windows Store app
+ library supports them.
+
+ Add comments about Johnston Island time in the 1960s.
+ (Thanks to Lyle McElhaney.)
+
+ Morocco's 2014 DST start will be as predicted.
+ (Thanks to Sebastien Willemijns.)
+
+
+Release 2014a - 2014-03-07 23:30:29 -0800
+
+ Changes affecting near-future time stamps
+
+ Turkey begins DST on 2014-03-31, not 03-30. (Thanks to Faruk Pasin for
+ the heads-up, and to Tim Parenti for simplifying the update.)
+
+ Changes affecting past time stamps
+
+ Fiji ended DST on 2014-01-19 at 02:00, not the previously-scheduled 03:00.
+ (Thanks to Steffen Thorsen.)
+
+ Ukraine switched from Moscow to Eastern European time on 1990-07-01
+ (not 1992-01-01), and observed DST during the entire next winter.
+ (Thanks to Vladimir in Moscow via Alois Treindl.)
+
+ In 1988 Israel observed DST from 04-10 to 09-04, not 04-09 to 09-03.
+ (Thanks to Avigdor Finkelstein.)
+
+ Changes affecting code
+
+ A uninitialized-storage bug in 'localtime' has been fixed.
+ (Thanks to Logan Chien.)
+
+ Changes affecting the build procedure
+
+ The settings for 'make check_web' now default to Ubuntu 13.10.
+
+ Changes affecting commentary and documentation
+
+ The boundary of the US Pacific time zone is given more accurately.
+ (Thanks to Alan Mintz.)
+
+ Chile's 2014 DST will be as predicted. (Thanks to José Miguel Garrido.)
+
+ Paraguay's 2014 DST will be as predicted. (Thanks to Carlos Raúl Perasso.)
+
+ Better descriptions of countries with same time zone history as
+ Trinidad and Tobago since 1970. (Thanks to Alan Barrett for suggestion.)
+
+ Several changes affect tz-link.htm, the main web page.
+
+ Mention Time.is (thanks to Even Scharning) and WX-now (thanks to
+ David Braverman).
+
+ Mention xCal (Internet RFC 6321) and jCal.
+
+ Microsoft has some support for tz database names.
+
+ CLDR data formats include both XML and JSON.
+
+ Mention Maggiolo's map of solar vs standard time.
+ (Thanks to Arthur David Olson.)
+
+ Mention TZ4Net. (Thanks to Matt Johnson.)
+
+ Mention the timezone-olson Haskell package.
+
+ Mention zeitverschiebung.net. (Thanks to Martin Jäger.)
+
+ Remove moribund links to daylight-savings-time.info and to
+ Simple Timer + Clocks.
+
+ Update two links. (Thanks to Oscar van Vlijmen.)
+
+ Fix some formatting glitches, e.g., remove random newlines from
+ abbr elements' title attributes.
+
+
+Release 2013i - 2013-12-17 07:25:23 -0800
+
+ Changes affecting near-future time stamps:
+
+ Jordan switches back to standard time at 00:00 on December 20, 2013.
+ The 2006-2011 transition schedule is planned to resume in 2014.
+ (Thanks to Steffen Thorsen.)
+
+ Changes affecting past time stamps:
+
+ In 2004, Cuba began DST on March 28, not April 4.
+ (Thanks to Steffen Thorsen.)
+
+ Changes affecting code
+
+ The compile-time flag NOSOLAR has been removed, as nowadays the
+ benefit of slightly shrinking runtime table size is outweighed by the
+ cost of disallowing potential future updates that exceed old limits.
+
+ Changes affecting documentation and commentary
+
+ The files solar87, solar88, and solar89 are no longer distributed.
+ They were a negative experiment - that is, a demonstration that
+ tz data can represent solar time only with some difficulty and error.
+ Their presence in the distribution caused confusion, as Riyadh
+ civil time was generally not solar time in those years.
+
+ tz-link.htm now mentions Noda Time. (Thanks to Matt Johnson.)
+
+
+Release 2013h - 2013-10-25 15:32:32 -0700
+
+ Changes affecting current and future time stamps:
+
+ Libya has switched its time zone back to UTC+2 without DST,
+ instead of UTC+1 with DST. (Thanks to Even Scharning.)
+
+ Western Sahara (Africa/El_Aaiun) uses Morocco's DST rules.
+ (Thanks to Gwillim Law.)
+
+ Changes affecting future time stamps:
+
+ Acre and (we guess) western Amazonas will switch from UTC-4 to UTC-5
+ on 2013-11-10. This affects America/Rio_Branco and America/Eirunepe.
+ (Thanks to Steffen Thorsen.)
+
+ Add entries for DST transitions in Morocco in the year 2038.
+ This avoids some year-2038 glitches introduced in 2013g.
+ (Thanks to Yoshito Umaoka for reporting the problem.)
+
+ Changes affecting API
+
+ The 'tzselect' command no longer requires the 'select' command,
+ and should now work with /bin/sh on more platforms. It also works
+ around a bug in BusyBox awk before version 1.21.0. (Thanks to
+ Patrick 'P. J.' McDermott and Alan Barrett.)
+
+ Changes affecting code
+
+ Fix localtime overflow bugs with 32-bit unsigned time_t.
+
+ zdump no longer assumes sscanf returns maximal values on overflow.
+
+ Changes affecting the build procedure
+
+ The builder can specify which programs to use, if any, instead of
+ 'ar' and 'ranlib', and libtz.a is now built locally before being
+ installed. (Thanks to Michael Forney.)
+
+ A dependency typo in the 'zdump' rule has been fixed.
+ (Thanks to Andrew Paprocki.)
+
+ The Makefile has been simplified by assuming that 'mkdir -p' and 'cp -f'
+ work as specified by POSIX.2-1992 or later; this is portable nowadays.
+
+ 'make clean' no longer removes 'leapseconds', since it's
+ host-independent and is part of the distribution.
+
+ The unused makefile macros TZCSRCS, TZDSRCS, DATESRCS have been removed.
+
+ Changes affecting documentation and commentary
+
+ tz-link.htm now mentions TC TIMEZONE's draft time zone service protocol
+ (thanks to Mike Douglass) and TimezoneJS.Date (thanks to Jim Fehrle).
+
+ Update URLs in tz-link page. Add URLs for Microsoft Windows, since
+ 8.1 introduces tz support. Remove URLs for Tru64 and UnixWare (no
+ longer maintained) and for old advisories. SOFA now does C.
+
+Release 2013g - 2013-09-30 21:08:26 -0700
+
+ Changes affecting current and near-future time stamps
+
+ Morocco now observes DST from the last Sunday in March to the last
+ Sunday in October, not April to September respectively. (Thanks
+ to Steffen Thorsen.)
+
+ Changes affecting 'zic'
+
+ 'zic' now runs on platforms that lack both hard links and symlinks.
+ (Thanks to Theo Veenker for reporting the problem, for MinGW.)
+ Also, fix some bugs on platforms that lack hard links but have symlinks.
+
+ 'zic -v' again warns that Asia/Tehran has no POSIX environment variable
+ to predict the far future, fixing a bug introduced in 2013e.
+
+ Changes affecting the build procedure
+
+ The 'leapseconds' file is again put into the tzdata tarball.
+ Also, 'leapseconds.awk', so tzdata is self-contained. (Thanks to
+ Matt Burgess and Ian Abbott.) The timestamps of these and other
+ dependent files in tarballs are adjusted more consistently.
+
+ Changes affecting documentation and commentary
+
+ The README file is now part of the data tarball as well as the code.
+ It now states that files are public domain unless otherwise specified.
+ (Thanks to Andrew Main (Zefram) for asking for clarifications.)
+ Its details about the 1989 release moved to a place of honor near
+ the end of NEWS.
+
+
+Release 2013f - 2013-09-24 23:37:36 -0700
+
+ Changes affecting near-future time stamps
+
+ Tocantins will very likely not observe DST starting this spring.
+ (Thanks to Steffen Thorsen.)
+
+ Jordan will likely stay at UTC+3 indefinitely, and will not fall
+ back this fall.
+
+ Palestine will fall back at 00:00, not 01:00. (Thanks to Steffen Thorsen.)
+
+ Changes affecting API
+
+ The types of the global variables 'timezone' and 'altzone' (if present)
+ have been changed back to 'long'. This is required for 'timezone'
+ by POSIX, and for 'altzone' by common practice, e.g., Solaris 11.
+ These variables were originally 'long' in the tz code, but were
+ mistakenly changed to 'time_t' in 1987; nobody reported the
+ incompatibility until now. The difference matters on x32, where
+ 'long' is 32 bits and 'time_t' is 64. (Thanks to Elliott Hughes.)
+
+ Changes affecting the build procedure
+
+ Avoid long strings in leapseconds.awk to work around a mawk bug.
+ (Thanks to Cyril Baurand.)
+
+ Changes affecting documentation and commentary
+
+ New file 'NEWS' that contains release notes like this one.
+
+ Paraguay's law does not specify DST transition time; 00:00 is customary.
+ (Thanks to Waldemar Villamayor-Venialbo.)
+
+ Minor capitalization fixes.
+
+ Changes affecting version-control only
+
+ The experimental GitHub repository now contains annotated and
+ signed tags for recent releases, e.g., '2013e' for Release 2013e.
+ Releases are tagged starting with 2012e; earlier releases were
+ done differently, and tags would either not have a simple name or
+ not exactly match what was released.
+
+ 'make set-timestamps' is now simpler and a bit more portable.
+
+
+Release 2013e - 2013-09-19 23:50:04 -0700
+
+ Changes affecting near-future time stamps
+
+ This year Fiji will start DST on October 27, not October 20.
+ (Thanks to David Wheeler for the heads-up.) For now, guess that
+ Fiji will continue to spring forward the Sunday before the fourth
+ Monday in October.
+
+ Changes affecting current and future time zone abbreviations
+
+ Use WIB/WITA/WIT rather than WIT/CIT/EIT for alphabetic Indonesian
+ time zone abbreviations since 1932. (Thanks to George Ziegler,
+ Priyadi Iman Nurcahyo, Zakaria, Jason Grimes, Martin Pitt, and
+ Benny Lin.) This affects Asia/Dili, Asia/Jakarta, Asia/Jayapura,
+ Asia/Makassar, and Asia/Pontianak.
+
+ Use ART (UTC-3, standard time), rather than WARST (also UTC-3, but
+ daylight saving time) for San Luis, Argentina since 2009.
+
+ Changes affecting Godthåb time stamps after 2037 if version mismatch
+
+ Allow POSIX-like TZ strings where the transition time's hour can
+ range from -167 through 167, instead of the POSIX-required 0
+ through 24. E.g., TZ='FJT-12FJST,M10.3.1/146,M1.3.4/75' for the
+ new Fiji rules. This is a more-compact way to represent
+ far-future time stamps for America/Godthab, America/Santiago,
+ Antarctica/Palmer, Asia/Gaza, Asia/Hebron, Asia/Jerusalem,
+ Pacific/Easter, and Pacific/Fiji. Other zones are unaffected by
+ this change. (Derived from a suggestion by Arthur David Olson.)
+
+ Allow POSIX-like TZ strings where daylight saving time is in
+ effect all year. E.g., TZ='WART4WARST,J1/0,J365/25' for Western
+ Argentina Summer Time all year. This supports a more-compact way
+ to represent the 2013d data for America/Argentina/San_Luis.
+ Because of the change for San Luis noted above this change does not
+ affect the current data. (Thanks to Andrew Main (Zefram) for
+ suggestions that improved this change.)
+
+ Where these two TZ changes take effect, there is a minor extension
+ to the tz file format in that it allows new values for the
+ embedded TZ-format string, and the tz file format version number
+ has therefore been increased from 2 to 3 as a precaution.
+ Version-2-based client code should continue to work as before for
+ all time stamps before 2038. Existing version-2-based client code
+ (tzcode, GNU/Linux, Solaris) has been tested on version-3-format
+ files, and typically works in practice even for time stamps after
+ 2037; the only known exception is America/Godthab.
+
+ Changes affecting time stamps before 1970
+
+ Pacific/Johnston is now a link to Pacific/Honolulu. This corrects
+ some errors before 1947.
+
+ Some zones have been turned into links, when they differ from existing
+ zones only in older data entries that were likely invented or that
+ differ only in LMT or transitions from LMT. These changes affect
+ only time stamps before 1943. The affected zones are:
+ Africa/Juba, America/Anguilla, America/Aruba, America/Dominica,
+ America/Grenada, America/Guadeloupe, America/Marigot,
+ America/Montserrat, America/St_Barthelemy, America/St_Kitts,
+ America/St_Lucia, America/St_Thomas, America/St_Vincent,
+ America/Tortola, and Europe/Vaduz. (Thanks to Alois Treindl for
+ confirming that the old Europe/Vaduz zone was wrong and the new
+ link is better for WWII-era times.)
+
+ Change Kingston Mean Time from -5:07:12 to -5:07:11. This affects
+ America/Cayman, America/Jamaica and America/Grand_Turk time stamps
+ from 1890 to 1912.
+
+ Change the UT offset of Bern Mean Time from 0:29:44 to 0:29:46.
+ This affects Europe/Zurich time stamps from 1853 to 1894. (Thanks
+ to Alois Treindl).
+
+ Change the date of the circa-1850 Zurich transition from 1849-09-12
+ to 1853-07-16, overriding Shanks with data from Messerli about
+ postal and telegraph time in Switzerland.
+
+ Changes affecting time zone abbreviations before 1970
+
+ For Asia/Jakarta, use BMT (not JMT) for mean time from 1923 to 1932,
+ as Jakarta was called Batavia back then.
+
+ Changes affecting API
+
+ The 'zic' command now outputs a dummy transition when far-future
+ data can't be summarized using a TZ string, and uses a 402-year
+ window rather than a 400-year window. For the current data, this
+ affects only the Asia/Tehran file. It does not affect any of the
+ time stamps that this file represents, so zdump outputs the same
+ information as before. (Thanks to Andrew Main (Zefram).)
+
+ The 'date' command has a new '-r' option, which lets you specify
+ the integer time to display, a la FreeBSD.
+
+ The 'tzselect' command has two new options '-c' and '-n', which lets you
+ select a zone based on latitude and longitude.
+
+ The 'zic' command's '-v' option now warns about constructs that
+ require the new version-3 binary file format. (Thanks to Arthur
+ David Olson for the suggestion.)
+
+ Support for floating-point time_t has been removed.
+ It was always dicey, and POSIX no longer requires it.
+ (Thanks to Eric Blake for suggesting to the POSIX committee to
+ remove it, and thanks to Alan Barrett, Clive D.W. Feather, Andy
+ Heninger, Arthur David Olson, and Alois Treindl, for reporting
+ bugs and elucidating some of the corners of the old floating-point
+ implementation.)
+
+ The signatures of 'offtime', 'timeoff', and 'gtime' have been
+ changed back to the old practice of using 'long' to represent UT
+ offsets. This had been inadvertently and mistakenly changed to
+ 'int_fast32_t'. (Thanks to Christos Zoulas.)
+
+ The code avoids undefined behavior on integer overflow in some
+ more places, including gmtime, localtime, mktime and zdump.
+
+ Changes affecting the zdump utility
+
+ zdump now outputs "UT" when referring to Universal Time, not "UTC".
+ "UTC" does not make sense for time stamps that predate the introduction
+ of UTC, whereas "UT", a more-generic term, does. (Thanks to Steve Allen
+ for clarifying UT vs UTC.)
+
+ Data changes affecting behavior of tzselect and similar programs
+
+ Country code BQ is now called the more-common name "Caribbean Netherlands"
+ rather than the more-official "Bonaire, St Eustatius & Saba".
+
+ Remove from zone.tab the names America/Montreal, America/Shiprock,
+ and Antarctica/South_Pole, as they are equivalent to existing
+ same-country-code zones for post-1970 time stamps. The data entries for
+ these names are unchanged, so the names continue to work as before.
+
+ Changes affecting code internals
+
+ zic -c now runs way faster on 64-bit hosts when given large numbers.
+
+ zic now uses vfprintf to avoid allocating and freeing some memory.
+
+ tzselect now computes the list of continents from the data,
+ rather than have it hard-coded.
+
+ Minor changes pacify GCC 4.7.3 and GCC 4.8.1.
+
+ Changes affecting the build procedure
+
+ The 'leapseconds' file is now generated automatically from a
+ new file 'leap-seconds.list', which is a copy of
+ <ftp://time.nist.gov/pub/leap-seconds.list>.
+ A new source file 'leapseconds.awk' implements this.
+ The goal is simplification of the future maintenance of 'leapseconds'.
+
+ When building the 'posix' or 'right' subdirectories, if the
+ subdirectory would be a copy of the default subdirectory, it is
+ now made a symbolic link if that is supported. This saves about
+ 2 MB of file system space.
+
+ The links America/Shiprock and Antarctica/South_Pole have been
+ moved to the 'backward' file. This affects only nondefault builds
+ that omit 'backward'.
+
+ Changes affecting version-control only
+
+ .gitignore now ignores 'date'.
+
+ Changes affecting documentation and commentary
+
+ Changes to the 'tzfile' man page
+
+ It now mentions that the binary file format may be extended in
+ future versions by appending data.
+
+ It now refers to the 'zdump' and 'zic' man pages.
+
+ Changes to the 'zic' man page
+
+ It lists conditions that elicit a warning with '-v'.
+
+ It says that the behavior is unspecified when duplicate names
+ are given, or if the source of one link is the target of another.
+
+ Its examples are updated to match the latest data.
+
+ The definition of white space has been clarified slightly.
+ (Thanks to Michael Deckers.)
+
+ Changes to the 'Theory' file
+
+ There is a new section about the accuracy of the tz database,
+ describing the many ways that errors can creep in, and
+ explaining why so many of the pre-1970 time stamps are wrong or
+ misleading (thanks to Steve Allen, Lester Caine, and Garrett
+ Wollman for discussions that contributed to this).
+
+ The 'Theory' file describes LMT better (this follows a
+ suggestion by Guy Harris).
+
+ It refers to the 2013 edition of POSIX rather than the 2004 edition.
+
+ It's mentioned that excluding 'backward' should not affect the
+ other data, and it suggests at least one zone.tab name per
+ inhabited country (thanks to Stephen Colebourne).
+
+ Some longstanding restrictions on names are documented, e.g.,
+ 'America/New_York' precludes 'America/New_York/Bronx'.
+
+ It gives more reasons for the 1970 cutoff.
+
+ It now mentions which time_t variants are supported, such as
+ signed integer time_t. (Thanks to Paul Goyette for reporting
+ typos in an experimental version of this change.)
+
+ (Thanks to Philip Newton for correcting typos in these changes.)
+
+ Documentation and commentary is more careful to distinguish UT in
+ general from UTC in particular. (Thanks to Steve Allen.)
+
+ Add a better source for the Zurich 1894 transition.
+ (Thanks to Pierre-Yves Berger.)
+
+ Update shapefile citations in tz-link.htm. (Thanks to Guy Harris.)
+
+
+Release 2013d - 2013-07-05 07:38:01 -0700
+
+ Changes affecting future time stamps:
+
+ Morocco's midsummer transitions this year are July 7 and August 10,
+ not July 9 and August 8. (Thanks to Andrew Paprocki.)
+
+ Israel now falls back on the last Sunday of October.
+ (Thanks to Ephraim Silverberg.)
+
+ Changes affecting past time stamps:
+
+ Specify Jerusalem's location more precisely; this changes the pre-1880
+ times by 2 s.
+
+ Changing affecting metadata only:
+
+ Fix typos in the entries for country codes BQ and SX.
+
+ Changes affecting code:
+
+ Rework the code to fix a bug with handling Australia/Macquarie on
+ 32-bit hosts (thanks to Arthur David Olson).
+
+ Port to platforms like NetBSD, where time_t can be wider than long.
+
+ Add support for testing time_t types other than the system's.
+ Run 'make check_time_t_alternatives' to try this out.
+ Currently, the tests fail for unsigned time_t;
+ this should get fixed at some point.
+
+ Changes affecting documentation and commentary:
+
+ Deemphasize the significance of national borders.
+
+ Update the zdump man page.
+
+ Remove obsolete NOID comment (thanks to Denis Excoffier).
+
+ Update several URLs and comments in the web pages.
+
+ Spelling fixes (thanks to Kevin Lyda and Jonathan Leffler).
+
+ Update URL for CLDR Zone->Tzid table (thanks to Yoshito Umaoka).
+
+
+Release 2013c - 2013-04-19 16:17:40 -0700
+
+ Changes affecting current and future time stamps:
+
+ Palestine observed DST starting March 29, 2013. (Thanks to
+ Steffen Thorsen.) From 2013 on, Gaza and Hebron both observe DST,
+ with the predicted rules being the last Thursday in March at 24:00
+ to the first Friday on or after September 21 at 01:00.
+
+ Assume that the recent change to Paraguay's DST rules is permanent,
+ by moving the end of DST to the 4th Sunday in March every year.
+ (Thanks to Carlos Raúl Perasso.)
+
+ Changes affecting past time stamps:
+
+ Fix some historical data for Palestine to agree with that of
+ timeanddate.com, as follows:
+
+ The spring 2008 change in Gaza and Hebron was on 00:00 Mar 28, not
+ 00:00 Apr 1.
+
+ The fall 2009 change in Gaza and Hebron on Sep 4 was at 01:00, not
+ 02:00.
+
+ The spring 2010 change in Hebron was 00:00 Mar 26, not 00:01 Mar 27.
+
+ The spring 2011 change in Gaza was 00:01 Apr 1, not 12:01 Apr 2.
+
+ The spring 2011 change in Hebron on Apr 1 was at 00:01, not 12:01.
+
+ The fall 2011 change in Hebron on Sep 30 was at 00:00, not 03:00.
+
+ Fix times of habitation for Macquarie to agree with the Tasmania
+ Parks & Wildlife Service history, which indicates that permanent
+ habitation was 1899-1919 and 1948 on.
+
+ Changing affecting metadata only:
+
+ Macquarie Island is politically part of Australia, not Antarctica.
+ (Thanks to Tobias Conradi.)
+
+ Sort Macquarie more-consistently with other parts of Australia.
+ (Thanks to Tim Parenti.)
+
+
+Release 2013b - 2013-03-10 22:33:40 -0700
+
+ Changes affecting current and future time stamps:
+
+ Haiti uses US daylight-saving rules this year, and presumably future years.
+ This changes time stamps starting today. (Thanks to Steffen Thorsen.)
+
+ Paraguay will end DST on March 24 this year.
+ (Thanks to Steffen Thorsen.) For now, assume it's just this year.
+
+ Morocco does not observe DST during Ramadan;
+ try to predict Ramadan in Morocco as best we can.
+ (Thanks to Erik Homoet for the heads-up.)
+
+ Changes affecting commentary:
+
+ Update URLs in tz-link page. Add URLs for webOS, BB10, iOS.
+ Update URL for Solaris. Mention Internet RFC 6557.
+ Update Internet RFCs 2445->5545, 2822->5322.
+ Switch from FTP to HTTP for Internet RFCs.
+
+
+Release 2013a - 2013-02-27 09:20:35 -0800
+
+ Change affecting binary data format:
+
+ The zone offset at the end of version-2-format zone files is now
+ allowed to be 24:00, as per POSIX.1-2008. (Thanks to Arthur David Olson.)
+
+ Changes affecting current and future time stamps:
+
+ Chile's 2013 rules, and we guess rules for 2014 and later, will be
+ the same as 2012, namely Apr Sun>=23 03:00 UTC to Sep Sun>=2 04:00 UTC.
+ (Thanks to Steffen Thorsen and Robert Elz.)
+
+ New Zones Asia/Khandyga, Asia/Ust-Nera, Europe/Busingen.
+ (Thanks to Tobias Conradi and Arthur David Olson.)
+
+ Many changes affect historical time stamps before 1940.
+ These were deduced from: Milne J. Civil time. Geogr J. 1899
+ Feb;13(2):173-94 <http://www.jstor.org/stable/1774359>.
+
+ Changes affecting the code:
+
+ Fix zic bug that mishandled Egypt's 2010 changes (this also affected
+ the data). (Thanks to Arthur David Olson.)
+
+ Fix localtime bug when time_t is unsigned and data files were generated
+ by a signed time_t system. (Thanks to Doug Bailey for reporting and
+ to Arthur David Olson for fixing.)
+
+ Allow the email address for bug reports to be set by the packager.
+ The default is tz at iana.org, as before. (Thanks to Joseph S. Myers.)
+
+ Update HTML checking to be compatible with Ubuntu 12.10.
+
+ Check that files are a safe subset of ASCII. At some point we may
+ relax this requirement to a safe subset of UTF-8. Without the
+ check, some non-UTF-8 encodings were leaking into the distribution.
+
+ Commentary changes:
+
+ Restore a comment about copyright notices that was inadvertently deleted.
+ (Thanks to Arthur David Olson.)
+
+ Improve the commentary about which districts observe what times
+ in Russia. (Thanks to Oscar van Vlijmen and Arthur David Olson).
+
+ Add web page links to tz.js.
+
+ Add "Run by the Monkeys" to tz-art. (Thanks to Arthur David Olson.)
+
+
+Release 2012j - 2012-11-12 18:34:49 -0800
+
+ Libya moved to CET this weekend, but with DST planned next year.
+ (Thanks to Even Scharning, Steffen Thorsen, and Tim Parenti.)
+
+ Signatures now have the extension .asc, not .sign, as that's more
+ standard. (Thanks to Phil Pennock.)
+
+ The output of 'zdump --version', and of 'zic --version', now
+ uses a format that is more typical for --version.
+ (Thanks to Joseph S. Myers.)
+
+ The output of 'tzselect --help', 'zdump --help', and 'zic --help'
+ now uses tz at iana.org rather than the old elsie address.
+
+ zic -v now complains about abbreviations that are less than 3
+ or more than 6 characters, as per Posix. Formerly, it checked
+ for abbreviations that were more than 3.
+
+ 'make public' no longer puts its temporary directory under /tmp,
+ and uses the just-built zic rather than the system zic.
+
+ Various fixes to documentation and commentary.
+
+
+Release 2012i - 2012-11-03 12:57:09 -0700
+
+ Cuba switches from DST tomorrow at 01:00. (Thanks to Steffen Thorsen.)
+
+ Linker flags can now be specified via LDFLAGS.
+ AWK now defaults to 'awk', not 'nawk'.
+ The shell in tzselect now defaults to /bin/bash, but this can
+ be overridden by specifying KSHELL.
+ The main web page now mentions the unofficial GitHub repository.
+ (Thanks to Mike Frysinger.)
+
+ Tarball signatures can now be built by running 'make signatures'.
+ There are also new makefile rules 'tarballs', 'check_public', and
+ separate makefile rules for each tarball and signature file.
+ A few makefile rules are now more portable to strict POSIX.
+
+ The main web page now lists the canonical IANA URL.
+
+
+Release 2012h - 2012-10-26 22:49:10 -0700
+
+ Bahia no longer has DST. (Thanks to Kelley Cook.)
+
+ Tocantins has DST. (Thanks to Rodrigo Severo.)
+
+ Israel has new DST rules next year. (Thanks to Ephraim Silverberg.)
+
+ Jordan stays on DST this winter. (Thanks to Steffen Thorsen.)
+
+ Web page updates.
+
+ More C modernization, except that at Arthur David Olson's suggestion
+ the instances of 'register' were kept.
+
+
+Release 2012g - 2012-10-17 20:59:45 -0700
+
+ Samoa fall 2012 and later. (Thanks to Nicholas Pereira and Robert Elz.)
+
+ Palestine fall 2012. (Thanks to Steffen Thorsen.)
+
+ Assume C89.
+
+ To attack the version-number problem, this release ships the file
+ 'Makefile' (which contains the release number) in both the tzcode and
+ the tzdata tarballs. The two Makefiles are identical, and should be
+ identical in any matching pair of tarballs, so it shouldn't matter
+ which order you extract the tarballs. Perhaps we can come up with a
+ better version-number scheme at some point; this scheme does have the
+ virtue of not adding more files.
+
+
+Release 2012f - 2012-09-12 23:17:03 -0700
+
+ * australasia (Pacific/Fiji): Fiji DST is October 21 through January
+ 20 this year. (Thanks to Steffen Thorsen.)
+
+
+Release 2012e - 2012-08-02 20:44:55 -0700
+
+ * australasia (Pacific/Fakaofo): Tokelau is UTC+13, not UTC+14.
+ (Thanks to Steffen Thorsen.)
+
+ * Use a single version number for both code and data.
+
+ * .gitignore: New file.
+
+ * Remove trailing white space.
+
+
+Release code2012c-data2012d - 2012-07-19 16:35:33 -0700
+
+ Changes for Morocco's time stamps, which take effect in a couple of
+ hours, along with infrastructure changes to accommodate how the tz
+ code and data are released on IANA.
+
+
+Release data2012c - 2012-03-27 12:17:25 -0400
+
+ africa
+ Summer time changes for Morocco (to start late April 2012)
+
+ asia
+ Changes for 2012 for Gaza & the West Bank (Hebron) and Syria
+
+ northamerica
+ Haiti following US/Canada rules for 2012 (and we're assuming,
+ for now anyway, for the future).
+
+
+Release 2012b - 2012-03-02 12:29:15 +0700
+
+ There is just one change to tzcode2012b (compared with 2012a):
+ the Makefile that was accidentally included with 2012a has been
+ replaced with the version that should have been there, which is
+ identical with the previous version (from tzcode2011i).
+
+ There are just two changes in tzdata2012b compared with 2012a.
+
+ Most significantly, summer time in Cuba has been delayed 3 weeks
+ (now starts April 1 rather than March 11). Since Mar 11 (the old start
+ date, as listed in 2012a) is just a little over a week away, this
+ change is urgent.
+
+ Less importantly, an excess tab in one of the changes in zone.tab
+ in 2012a has been removed.
+
+
+Release 2012a - 2012-03-01 18:28:10 +0700
+
+ The changes in tzcode2012a (compared to the previous version, 2011i)
+ are entirely to the README and tz-art.htm and tz-link.htm files, if
+ none of those concern you, you can ignore the code update. The changes
+ reflect the changed addresses for the mailing list and the code and
+ data distribution points & methods (and a link to DateTime::TimeZone::Tzfile
+ has been added to tz-link.htm).
+
+ In tzdata2012a (compared to the previous release, which was 2011n)
+ the major changes are:
+ Chile 2011/2012 and 2012/2013 summer time date adjustments.
+ Falkland Islands onto permanent summer time (we're assuming for the
+ foreseeable future, though 2012 is all we're fairly certain of.)
+ Armenia has abolished Summer Time.
+ Tokelau jumped the International Date Line back last December
+ (just the same as their near neighbour, Samoa).
+ America/Creston is a new zone for a small area of British Columbia
+ There will be a leapsecond 2012-06-30 23:59:60 UTC.
+
+ Other minor changes are:
+ Corrections to 1918 Canadian summer time end dates.
+ Updated URL for UK time zone history (in comments)
+ A few typos in Le Corre's list of free French place names (comments)
+
+
+Release data2011n - 2011-10-30 14:57:54 +0700
+
+ There are three changes of note - most urgently, Cuba (America/Havana)
+ has extended summer time by two weeks, now to end on Nov 13, rather than
+ the (already past) Oct 30. Second, the Pridnestrovian Moldavian Republic
+ (Europe/Tiraspol) decided not to split from the rest of Moldova after
+ all, and consequently that zone has been removed (again) and reinstated
+ in the "backward" file as a link to Europe/Chisinau. And third, the
+ end date for Fiji's summer time this summer was moved forward from the
+ earlier planned Feb 26, to Jan 22.
+
+ Apart from that, Moldova (MD) returns to a single entry in zone.tab
+ (and the incorrect syntax that was in the 2011m version of that file
+ is so fixed - it would have been fixed in a different way had this
+ change not happened - that's the "missing" sccs version id).
+
+
+Release data2011m - 2011-10-24 21:42:16 +0700
+
+ In particular, the typos in comments in the data (2011-11-17 should have
+ been 2011-10-17 as Alan Barrett noted, and spelling of Tiraspol that
+ Tim Parenti noted) have been fixed, and the change for Ukraine has been
+ made in all 4 Ukrainian zones, rather than just Kiev (again, thanks to
+ Tim Parenti, and also Denys Gavrysh)
+
+ In addition, I added Europe/Tiraspol to zone.tab.
+
+ This time, all the files have new version numbers... (including the files
+ otherwise unchanged in 2011m that were changed in 2011l but didn't get new
+ version numbers there...)
+
+
+Release data2011l - 2011-10-10 11:15:43 +0700
+
+ There are just 2 changes that cause different generated tzdata files from
+ zic, to Asia/Hebron and Pacific/Fiji - the possible change for Bahia, Brazil
+ is included, but commented out. Compared with the diff I sent out last week,
+ this version also includes attributions for the sources for the changes
+ (in much the same format as ado used, but the html tags have not been
+ checked, verified, or used in any way at all, so if there are errors there,
+ please let me know.)
+
+
+Release data2011k - 2011-09-20 17:54:03 -0400
+
+ [not summarized]
+
+
+Release data2011j - 2011-09-12 09:22:49 -0400
+
+ (contemporary changes for Samoa; past changes for Kenya, Uganda, and
+ Tanzania); there are also two spelling corrections to comments in
+ the australasia file (with thanks to Christos Zoulas).
+
+
+Release 2011i - 2011-08-29 05:56:32 -0400
+
+ [not summarized]
+
+
+Release data2011h - 2011-06-15 18:41:48 -0400
+
+ Russia and Curaçao changes
+
+
+Release 2011g - 2011-04-25 09:07:22 -0400
+
+ update the rules for Egypt to reflect its abandonment of DST this year
+
+
+Release 2011f - 2011-04-06 17:14:53 -0400
+
+ [not summarized]
+
+
+Release 2011e - 2011-03-31 16:04:38 -0400
+
+ Morocco, Chile, and tz-link changes
+
+
+Release 2011d - 2011-03-14 09:18:01 -0400
+
+ changes that impact present-day time stamps in Cuba, Samoa, and Turkey
+
+
+Release 2011c - 2011-03-07 09:30:09 -0500
+
+ These do affect current time stamps in Chile and Annette Island, Canada.
+
+
+Release 2011b - 2011-02-07 08:44:50 -0500
+
+ [not summarized]
+
+
+Release 2011a - 2011-01-24 10:30:16 -0500
+
+ [not summarized]
+
+
+Release data2010o - 2010-11-01 09:18:23 -0400
+
+ change to the end of DST in Fiji in 2011
+
+
+Release 2010n - 2010-10-25 08:19:17 -0400
+
+ [not summarized]
+
+
+Release 2010m - 2010-09-27 09:24:48 -0400
+
+ Hong Kong, Vostok, and zic.c changes
+
+
+Release 2010l - 2010-08-16 06:57:25 -0400
+
+ [not summarized]
+
+
+Release 2010k - 2010-07-26 10:42:27 -0400
+
+ [not summarized]
+
+
+Release 2010j - 2010-05-10 09:07:48 -0400
+
+ changes for Bahía de Banderas and for version naming
+
+
+Release data2010i - 2010-04-16 18:50:45 -0400
+
+ the end of DST in Morocco on 2010-08-08
+
+
+Release data2010h - 2010-04-05 09:58:56 -0400
+
+ [not summarized]
+
+
+Release data2010g - 2010-03-24 11:14:53 -0400
+
+ [not summarized]
+
+
+Release 2010f - 2010-03-22 09:45:46 -0400
+
+ [not summarized]
+
+
+Release data2010e - 2010-03-08 14:24:27 -0500
+
+ corrects the Dhaka bug found by Danvin Ruangchan
+
+
+Release data2010d - 2010-03-06 07:26:01 -0500
+
+ [not summarized]
+
+
+Release 2010c - 2010-03-01 09:20:58 -0500
+
+ changes including KRE's suggestion for earlier initialization of
+ "goahead" and "goback" structure elements
+
+
+Release code2010a - 2010-02-16 10:40:04 -0500
+
+ [not summarized]
+
+
+Release data2010b - 2010-01-20 12:37:01 -0500
+
+ Mexico changes
+
+
+Release data2010a - 2010-01-18 08:30:04 -0500
+
+ changes to Dhaka
+
+
+Release data2009u - 2009-12-26 08:32:28 -0500
+
+ changes to DST in Bangladesh
+
+
+Release 2009t - 2009-12-21 13:24:27 -0500
+
+ [not summarized]
+
+
+Release data2009s - 2009-11-14 10:26:32 -0500
+
+ (cosmetic) Antarctica change and the DST-in-Fiji-in-2009-and-2010 change
+
+
+Release 2009r - 2009-11-09 10:10:31 -0500
+
+ "antarctica" and "tz-link.htm" changes
+
+
+Release 2009q - 2009-11-02 09:12:40 -0500
+
+ with two corrections as reported by Eric Muller and Philip Newton
+
+
+Release data2009p - 2009-10-23 15:05:27 -0400
+
+ Argentina (including San Luis) changes (with the correction from
+ Mariano Absatz)
+
+
+Release data2009o - 2009-10-14 16:49:38 -0400
+
+ Samoa (commentary only), Pakistan, and Bangladesh changes
+
+
+Release data2009n - 2009-09-22 15:13:38 -0400
+
+ added commentary for Argentina and a change to the end of DST in
+ 2009 in Pakistan
+
+
+Release data2009m - 2009-09-03 10:23:43 -0400
+
+ Samoa and Palestine changes
+
+
+Release data2009l - 2009-08-14 09:13:07 -0400
+
+ Samoa (comments only) and Egypt
+
+
+Release 2009k - 2009-07-20 09:46:08 -0400
+
+ [not summarized]
+
+
+Release data2009j - 2009-06-15 06:43:59 -0400
+
+ Bangladesh change (with a short turnaround since the DST change is
+ impending)
+
+
+Release 2009i - 2009-06-08 09:21:22 -0400
+
+ updating for DST in Bangladesh this year
+
+
+Release 2009h - 2009-05-26 09:19:14 -0400
+
+ [not summarized]
+
+
+Release data2009g - 2009-04-20 16:34:07 -0400
+
+ Cairo
+
+
+Release data2009f - 2009-04-10 11:00:52 -0400
+
+ correct DST in Pakistan
+
+
+Release 2009e - 2009-04-06 09:08:11 -0400
+
+ [not summarized]
+
+
+Release 2009d - 2009-03-23 09:38:12 -0400
+
+ Morocco, Tunisia, Argentina, and American Astronomical Society changes
+
+
+Release data2009c - 2009-03-16 09:47:51 -0400
+
+ change to the start of Cuban DST
+
+
+Release 2009b - 2009-02-09 11:15:22 -0500
+
+ [not summarized]
+
+
+Release 2009a - 2009-01-21 10:09:39 -0500
+
+ [not summarized]
+
+
+Release data2008i - 2008-10-21 12:10:25 -0400
+
+ southamerica and zone.tab files, with Argentina DST rule changes and
+ United States zone reordering and recommenting
+
+
+Release 2008h - 2008-10-13 07:33:56 -0400
+
+ [not summarized]
+
+
+Release 2008g - 2008-10-06 09:03:18 -0400
+
+ Fix a broken HTML anchor and update Brazil's DST transitions;
+ there's also a slight reordering of information in tz-art.htm.
+
+
+Release data2008f - 2008-09-09 22:33:26 -0400
+
+ [not summarized]
+
+
+Release 2008e - 2008-07-28 14:11:17 -0400
+
+ changes by Arthur David Olson and Jesper Nørgaard Welen
+
+
+Release data2008d - 2008-07-07 09:51:38 -0400
+
+ changes by Arthur David Olson, Paul Eggert, and Rodrigo Severo
+
+
+Release data2008c - 2008-05-19 17:48:03 -0400
+
+ Pakistan, Morocco, and Mongolia
+
+
+Release data2008b - 2008-03-24 08:30:59 -0400
+
+ including renaming Asia/Calcutta to Asia/Kolkata, with a backward
+ link provided
+
+
+Release 2008a - 2008-03-08 05:42:16 -0500
+
+ [not summarized]
+
+
+Release 2007k - 2007-12-31 10:25:22 -0500
+
+ most importantly, changes to the "southamerica" file based on
+ Argentina's readoption of daylight saving time
+
+
+Release 2007j - 2007-12-03 09:51:01 -0500
+
+ 1. eliminate the "P" (parameter) macro;
+
+ 2. the "noncontroversial" changes circulated on the time zone
+ mailing list (less the changes to "logwtmp.c");
+
+ 3. eliminate "too many transition" errors when "min" is used in time
+ zone rules;
+
+ 4. changes by Paul Eggert (including updated information for Venezuela).
+
+
+Release data2007i - 2007-10-30 10:28:11 -0400
+
+ changes for Cuba and Syria
+
+
+Release 2007h - 2007-10-01 10:05:51 -0400
+
+ changes by Paul Eggert, as well as an updated link to the ICU
+ project in tz-link.htm
+
+
+Release 2007g - 2007-08-20 10:47:59 -0400
+
+ changes by Paul Eggert
+
+ The "leapseconds" file has been updated to incorporate the most
+ recent International Earth Rotation and Reference Systems Service
+ (IERS) bulletin.
+
+ There's an addition to tz-art.htm regarding the television show "Medium".
+
+
+Release 2007f - 2007-05-07 10:46:46 -0400
+
+ changes by Paul Eggert (including Haiti, Turks and Caicos, and New
+ Zealand)
+
+ changes to zic.c to allow hour values greater than 24 (along with
+ Paul's improved time value overflow checking)
+
+
+Release 2007e - 2007-04-02 10:11:52 -0400
+
+ Syria and Honduras changes by Paul Eggert
+
+ zic.c variable renaming changes by Arthur David Olson
+
+
+Release 2007d - 2007-03-20 08:48:30 -0400
+
+ changes by Paul Eggert
+
+ the elimination of white space at the ends of lines
+
+
+Release 2007c - 2007-02-26 09:09:37 -0500
+
+ changes by Paul Eggert
+
+
+Release 2007b - 2007-02-12 09:34:20 -0500
+
+ Paul Eggert's proposed change to the quotation handling logic in zic.c.
+
+ changes to the commentary in "leapseconds" reflecting the IERS
+ announcement that there is to be no positive leap second at the end
+ of June 2007.
+
+
+Release 2007a - 2007-01-08 12:28:29 -0500
+
+ changes by Paul Eggert
+
+ Derick Rethan's Asmara change
+
+ Oscar van Vlijmen's Easter Island local mean time change
+
+ symbolic link changes
+
+
+Release 2006p - 2006-11-27 08:54:27 -0500
+
+ changes by Paul Eggert
+
+
+Release 2006o - 2006-11-06 09:18:07 -0500
+
+ changes by Paul Eggert
+
+
+Release 2006n - 2006-10-10 11:32:06 -0400
+
+ changes by Paul Eggert
+
+
+Release 2006m - 2006-10-02 15:32:35 -0400
+
+ changes for Uruguay, Palestine, and Egypt by Paul Eggert
+
+ (minimalist) changes to zic.8 to clarify "until" information
+
+
+Release data2006l - 2006-09-18 12:58:11 -0400
+
+ Paul's best-effort work on this coming weekend's Egypt time change
+
+
+Release 2006k - 2006-08-28 12:19:09 -0400
+
+ changes by Paul Eggert
+
+
+Release 2006j - 2006-08-21 09:56:32 -0400
+
+ changes by Paul Eggert
+
+
+Release code2006i - 2006-08-07 12:30:55 -0400
+
+ localtime.c fixes
+
+ Ken Pizzini's conversion script
+
+
+Release code2006h - 2006-07-24 09:19:37 -0400
+
+ adds public domain notices to four files
+
+ includes a fix for transition times being off by a second
+
+ adds a new recording to the "arts" file (information courtesy Colin Bowern)
+
+
+Release 2006g - 2006-05-08 17:18:09 -0400
+
+ northamerica changes by Paul Eggert
+
+
+Release 2006f - 2006-05-01 11:46:00 -0400
+
+ a missing version number problem is fixed (with thanks to Bradley
+ White for catching the problem)
+
+
+Release 2006d - 2006-04-17 14:33:43 -0400
+
+ changes by Paul Eggert
+
+ added new items to tz-arts.htm that were found by Paul
+
+
+Release 2006c - 2006-04-03 10:09:32 -0400
+
+ two sets of data changes by Paul Eggert
+
+ a fencepost error fix in zic.c
+
+ changes to zic.c and the "europe" file to minimize differences
+ between output produced by the old 32-bit zic and the new 64-bit
+ version
+
+
+Release 2006b - 2006-02-20 10:08:18 -0500
+ [tz32code2006b + tz64code2006b + tzdata2006b]
+
+ 64-bit code
+
+ All SCCS IDs were bumped to "8.1" for this release.
+
+
+Release 2006a - 2006-01-30 08:59:31 -0500
+
+ changes by Paul Eggert (in particular, Indiana time zone moves)
+
+ an addition to the zic manual page to describe how special-case
+ transitions are handled
+
+
+Release 2005r - 2005-12-27 09:27:13 -0500
+
+ Canadian changes by Paul Eggert
+
+ They also add "<pre>" directives to time zone data files and reflect
+ changes to warning message logic in "zdump.c" (but with calls to
+ "gettext" kept unbundled at the suggestion of Ken Pizzini).
+
+
+Release 2005q - 2005-12-13 09:17:09 -0500
+
+ Nothing earth-shaking here:
+ 1. Electronic mail addresses have been removed.
+ 2. Casts of the return value of exit have been removed.
+ 3. Casts of the argument of is.* macros have been added.
+ 4. Indentation in one section of zic.c has been fixed.
+ 5. References to dead URLs in the data files have been dealt with.
+
+
+Release 2005p - 2005-12-05 10:30:53 -0500
+
+ "systemv", "tz-link.htm", and "zdump.c" changes
+ (less the casts of arguments to the is* macros)
+
+
+Release 2005o - 2005-11-28 10:55:26 -0500
+
+ Georgia, Cuba, Nicaragua, and Jordan changes by Paul Eggert
+
+ zdump.c lint fixes by Arthur David Olson
+
+
+Release 2005n - 2005-10-03 09:44:09 -0400
+
+ changes by Paul Eggert (both the Uruguay changes and the Kyrgyzstan
+ et al. changes)
+
+
+Release 2005m - 2005-08-29 12:15:40 -0400
+
+ changes by Paul Eggert (with a small tweak to the tz-art change)
+
+ a declaration of an unused variable has been removed from zdump.c
+
+
+Release 2005l - 2005-08-22 12:06:39 -0400
+
+ changes by Paul Eggert
+
+ overflow/underflow checks by Arthur David Olson, minus changes to
+ the "Theory" file about the pending addition of 64-bit data (I grow
+ less confident of the changes being accepted with each passing day,
+ and the changes no longer increase the data files nine-fold--there's
+ less than a doubling in size by my local Sun's reckoning)
+
+
+Release 2005k - 2005-07-14 14:14:24 -0400
+
+ The "leapseconds" file has been edited to reflect the recently
+ announced leap second at the end of 2005.
+
+ I've also deleted electronic mail addresses from the files as an
+ anti-spam measure.
+
+
+Release 2005j - 2005-06-13 14:34:13 -0400
+
+ These reflect changes to limit the length of time zone abbreviations
+ and the characters used in those abbreviations.
+
+ There are also changes to handle POSIX-style "quoted" time zone
+ environment variables.
+
+ The changes were circulated on the time zone mailing list; the only
+ change since then was the removal of a couple of minimum-length of
+ abbreviation checks.
+
+
+Release data2005i - 2005-04-21 15:04:16 -0400
+
+ changes (most importantly to Nicaragua and Haiti) by Paul Eggert
+
+
+Release 2005h - 2005-04-04 11:24:47 -0400
+
+ changes by Paul Eggert
+
+ minor changes to Makefile and zdump.c to produce more useful output
+ when doing a "make typecheck"
+
+
+Release 2005g - 2005-03-14 10:11:21 -0500
+
+ changes by Paul Eggert (a change to current DST rules in Uruguay and
+ an update to a link to time zone software)
+
+
+Release 2005f - 2005-03-01 08:45:32 -0500
+
+ data and documentation changes by Paul Eggert
+
+
+Release 2005e - 2005-02-10 15:59:44 -0500
+
+ [not summarized]
+
+
+Release code2005d - 2005-01-31 09:21:47 -0500
+
+ make zic complain about links to links if the -v flag is used
+
+ have "make public" do more code checking
+
+ add an include to "localtime.c" for the benefit of gcc systems
+
+
+Release 2005c - 2005-01-17 18:36:29 -0500
+
+ get better results when mktime runs on a system where time_t is double
+
+ changes to the data files (most importantly to Paraguay)
+
+
+Release 2005b - 2005-01-10 09:19:54 -0500
+
+ Get localtime and gmtime working on systems with exotic time_t types.
+
+ Update the leap second commentary in the "leapseconds" file.
+
+
+Release 2005a - 2005-01-01 13:13:44 -0500
+
+ [not summarized]
+
+
+Release code2004i - 2004-12-14 13:42:58 -0500
+
+ Deal with systems where time_t is unsigned.
+
+
+Release code2004h - 2004-12-07 11:40:18 -0500
+
+ 64-bit-time_t changes
+
+
+Release 2004g - 2004-11-02 09:06:01 -0500
+
+ update to Cuba (taking effect this weekend)
+
+ other changes by Paul Eggert
+
+ correction of the spelling of Oslo
+
+ changed versions of difftime.c and private.h
+
+
+Release code2004f - 2004-10-21 10:25:22 -0400
+
+ Cope with wide-ranging tm_year values.
+
+
+Release 2004e - 2004-10-11 14:47:21 -0400
+
+ Brazil/Argentina/Israel changes by Paul Eggert
+
+ changes to tz-link.htm by Paul
+
+ one small fix to Makefile
+
+
+Release 2004d - 2004-09-22 08:27:29 -0400
+
+ Avoid overflow problems when TM_YEAR_BASE is added to an integer.
+
+
+Release 2004c - 2004-08-11 12:06:26 -0400
+
+ asctime-related changes
+
+ (variants of) some of the documentation changes suggested by Paul Eggert
+
+
+Release 2004b - 2004-07-19 14:33:35 -0400
+
+ data changes by Paul Eggert - most importantly, updates for Argentina
+
+
+Release 2004a - 2004-05-27 12:00:47 -0400
+
+ changes by Paul Eggert
+
+ Handle DST transitions that occur at the end of a month in some
+ years but at the start of the following month in other years.
+
+ Add a copy of the correspondence that's the basis for claims about
+ DST in the Navajo Nation.
+
+
+Release 2003e - 2003-12-15 09:36:47 -0500
+
+ changes by Arthur David Olson (primarily code changes)
+
+ changes by Paul Eggert (primarily data changes)
+
+ minor changes to "Makefile" and "northamerica" (in the latter case,
+ optimization of the "Toronto" rules)
+
+
+Release 2003d - 2003-10-06 09:34:44 -0400
+
+ changes by Paul Eggert
+
+
+Release 2003c - 2003-09-16 10:47:05 -0400
+
+ Fix bad returns in zic.c's inleap function.
+ Thanks to Bradley White for catching the problem!
+
+
+Release 2003b - 2003-09-16 07:13:44 -0400
+
+ Add a "--version" option (and documentation) to the zic and zdump commands.
+
+ changes to overflow/underflow checking in zic
+
+ a localtime typo fix.
+
+ Update the leapseconds and tz-art.htm files.
+
+
+Release 2003a - 2003-03-24 09:30:54 -0500
+
+ changes by Paul Eggert
+
+ a few additions and modifications to the tz-art.htm file
+
+
+Release 2002d - 2002-10-15 13:12:42 -0400
+
+ changes by Paul Eggert, less the "Britain (UK)" change in iso3166.tab
+
+ There's also a new time zone quote in "tz-art.htm".
+
+
+Release 2002c - 2002-04-04 11:55:20 -0500
+
+ changes by Paul Eggert
+
+ Change zic.c to avoid creating symlinks to files that don't exist.
+
+
+Release 2002b - 2002-01-28 12:56:03 -0500
+
+ [These change notes are for Release 2002a, which was corrupted.
+ 2002b was a corrected version of 2002a.]
+
+ changes by Paul Eggert
+
+ Update the "leapseconds" file to note that there'll be no leap
+ second at the end of June, 2002.
+
+ Change "zic.c" to deal with a problem in handling the "Asia/Bishkek" zone.
+
+ Change to "difftime.c" to avoid sizeof problems.
+
+
+Release 2001d - 2001-10-09 13:31:32 -0400
+
+ changes by Paul Eggert
+
+
+Release 2001c - 2001-06-05 13:59:55 -0400
+
+ changes by Paul Eggert and Andrew Brown
+
+
+Release 2001b - 2001-04-05 16:44:38 -0400
+
+ changes by Paul Eggert (modulo jnorgard's typo fix)
+
+ tz-art.htm has been HTMLified.
+
+
+Release 2001a - 2001-03-13 12:57:44 -0500
+
+ changes by Paul Eggert
+
+ An addition to the "leapseconds" file: comments with the text of the
+ latest IERS leap second notice.
+
+ Trailing white space has been removed from data file lines, and
+ repeated spaces in "Rule Jordan" lines in the "asia" file have been
+ converted to tabs.
+
+
+Release 2000h - 2000-12-14 15:33:38 -0500
+
+ changes by Paul Eggert
+
+ one typo fix in the "art" file
+
+ With providence, this is the last update of the millennium.
+
+
+Release 2000g - 2000-10-10 11:35:22 -0400
+
+ changes by Paul Eggert
+
+ correction of John Mackin's name submitted by Robert Elz
+
+ Garry Shandling's Daylight Saving Time joke (!?!) from the recent
+ Emmy Awards broadcast.
+
+
+Release 2000f - 2000-08-10 09:31:58 -0400
+
+ changes by Paul Eggert
+
+ Added information in "tz-art.htm" on a Seinfeld reference to DST.
+
+ Error checking and messages in the "yearistype" script have been
+ improved.
+
+
+Release 2000e - 2000-07-31 09:27:54 -0400
+
+ data changes by Paul Eggert
+
+ a change to the default value of the defined constant HAVE_STRERROR
+
+ the addition of a Dave Barry quote on DST to the tz-arts file
+
+
+Release 2000d - 2000-04-20 15:43:04 -0400
+
+ changes to the documentation and code of strftime for C99 conformance
+
+ a bug fix for date.c
+
+ These are based on (though modified from) changes by Paul Eggert.
+
+
+Release 2000c - 2000-03-04 10:31:43 -0500
+
+ changes by Paul Eggert
+
+
+Release 2000b - 2000-02-21 12:16:29 -0500
+
+ changes by Paul Eggert and Joseph Myers
+
+ modest tweaks to the tz-art.htm and tz-link.htm files
+
+
+Release 2000a - 2000-01-18 09:21:26 -0500
+
+ changes by Paul Eggert
+
+ The two hypertext documents have also been renamed.
+
+
+Release code1999i-data1999j - 1999-11-15 18:43:22 -0500
+
+ Paul Eggert's changes
+
+ additions to the "zic" manual page and the "Arts.htm" file
+
+
+Release code1999h-data1999i - 1999-11-08 14:55:21 -0500
+
+ [not summarized]
+
+
+Release data1999h - 1999-10-07 03:50:29 -0400
+
+ changes by Paul Eggert to "europe" (most importantly, fixing
+ Lithuania and Estonia)
+
+
+Release 1999g - 1999-09-28 11:06:18 -0400
+
+ data changes by Paul Eggert (most importantly, the change for
+ Lebanon that buys correctness for this coming Sunday)
+
+ The "code" file contains changes to "Makefile" and "checktab.awk" to
+ allow better checking of time zone files before they are published.
+
+
+Release 1999f - 1999-09-23 09:48:14 -0400
+
+ changes by Arthur David Olson and Paul Eggert
+
+
+Release 1999e - 1999-08-17 15:20:54 -0400
+
+ changes circulated by Paul Eggert, although the change to handling
+ of DST-specifying time zone names has been commented out for now
+ (search for "XXX" in "localtime.c" for details). These files also
+ do not make any changes to the start of DST in Brazil.
+
+ In addition to Paul's changes, there are updates to "Arts.htm" and
+ cleanups of URLs.
+
+
+Release 1999d - 1999-03-30 11:31:07 -0500
+
+ changes by Paul Eggert
+
+ The Makefile's "make public" rule has also been changed to do a test
+ compile of each individual time zone data file (which should help
+ avoid problems such as the one we had with Nicosia).
+
+
+Release 1999c - 1999-03-25 09:47:47 -0500
+
+ changes by Paul Eggert, most importantly the change for Chile.
+
+
+Release 1999b - 1999-02-01 17:51:44 -0500
+
+ changes by Paul Eggert
+
+ code changes (suggested by Mani Varadarajan, mani at be.com) for
+ correct handling of symbolic links when building using a relative directory
+
+ code changes to generate correct messages for failed links
+
+ updates to the URLs in Arts.htm
+
+
+Release 1999a - 1999-01-19 16:20:29 -0500
+
+ error message internationalizations and corrections in zic.c and
+ zdump.c (as suggested by Vladimir Michl, vladimir.michl at upol.cz,
+ to whom thanks!)
+
+
+Release code1998h-data1998i - 1998-10-01 09:56:10 -0400
+
+ changes for Brazil, Chile, and Germany
+
+ support for use of "24:00" in the input files for the time zone compiler
+
+
+Release code1998g-data1998h - 1998-09-24 10:50:28 -0400
+
+ changes by Paul Eggert
+
+ correction to a define in the "private.h" file
+
+
+Release data1998g - 1998-08-11 03:28:35 -0000
+ [tzdata1998g.tar.gz is missing!]
+
+ Lithuanian change provided by mgedmin at pub.osf.it
+
+ Move creation of the GMT link with Etc/GMT to "etcetera" (from
+ "backward") to ensure that the GMT file is created even where folks
+ don't want the "backward" links (as suggested by Paul Eggert).
+
+
+Release data1998f - 1998-07-20 13:50:00 -0000
+ [tzdata1998f.tar.gz is missing!]
+
+ Update the "leapseconds" file to include the newly-announced
+ insertion at the end of 1998.
+
+
+Release code1998f - 1998-06-01 10:18:31 -0400
+
+ addition to localtime.c by Guy Harris
+
+
+Release 1998e - 1998-05-28 09:56:26 -0400
+
+ The Makefile is changed to produce zoneinfo-posix rather than
+ zoneinfo/posix, and to produce zoneinfo-leaps rather than
+ zoneinfo/right.
+
+ data changes by Paul Eggert
+
+ changes from Guy Harris to provide asctime_r and ctime_r
+
+ A usno1998 file (substantially identical to usno1997) has been added.
+
+
+Release 1998d - 1998-05-14 11:58:34 -0400
+
+ changes to comments (in particular, elimination of references to CIA maps).
+ "Arts.htm", "WWW.htm", "asia", and "australasia" are the only places
+ where changes occur.
+
+
+Release 1998c - 1998-02-28 12:32:26 -0500
+
+ changes by Paul Eggert (save the "French correction," on which I'll
+ wait for the dust to settle)
+
+ symlink changes
+
+ changes and additions to Arts.htm
+
+
+Release 1998b - 1998-01-17 14:31:51 -0500
+
+ URL cleanups and additions
+
+
+Release 1998a - 1998-01-13 12:37:35 -0500
+
+ changes by Paul Eggert
+
+
+Release code1997i-data1997k - 1997-12-29 09:53:41 -0500
+
+ changes by Paul Eggert, with minor modifications from Arthur David
+ Olson to make the files more browser friendly
+
+
+Release code1997h-data1997j - 1997-12-18 17:47:35 -0500
+
+ minor changes to put "TZif" at the start of each time zone information file
+
+ a rule has also been added to the Makefile so you can
+ make zones
+ to just recompile the zone information files (rather than doing a
+ full "make install" with its other effects).
+
+
+Release data1997i - 1997-10-07 08:45:38 -0400
+
+ changes to Africa by Paul Eggert
+
+
+Release code1997g-data1997h - 1997-09-04 16:56:54 -0400
+
+ corrections for Uruguay (and other locations)
+
+ Arthur David Olson's simple-minded fix allowing mktime to both
+ correctly handle leap seconds and correctly handle tm_sec values
+ upon which arithmetic has been performed.
+
+
+Release code1997f-data1997g - 1997-07-19 13:15:02 -0400
+
+ Paul Eggert's updates
+
+ a small change to a function prototype;
+
+ "Music" has been renamed "Arts.htm", HTMLified, and augmented to
+ include information on Around the World in Eighty Days.
+
+
+Release code1997e-data1997f - 1997-05-03 18:52:34 -0400
+
+ fixes to zic's error handling
+
+ changes inspired by the item circulated on Slovenia
+
+ The description of Web resources has been HTMLified for browsing
+ convenience.
+
+ A new piece of tz-related music has been added to the "Music" file.
+
+
+Release code1997d-data1997e - 1997-03-29 12:48:52 -0500
+
+ Paul Eggert's latest suggestions
+
+
+Release code1997c-data1997d - 1997-03-07 20:37:54 -0500
+
+ changes to "zic.c" to correct performance of the "-s" option
+
+ a new file "usno1997"
+
+
+Release data1997c - 1997-03-04 09:58:18 -0500
+
+ changes in Israel
+
+
+Release 1997b - 1997-02-27 18:34:19 -0500
+
+ The data file incorporates the 1997 leap second.
+
+ The code file incorporates Arthur David Olson's take on the
+ zic/multiprocessor/directory-creation situation.
+
+
+Release 1997a - 1997-01-21 09:11:10 -0500
+
+ Paul Eggert's Antarctica (and other changes)
+
+ Arthur David Olson finessed the "getopt" issue by checking against
+ both -1 and EOF (regardless of POSIX, SunOS 4.1.1's manual says -1
+ is returned while SunOS 5.5's manual says EOF is returned).
+
+
+Release code1996o-data1996n - 1996-12-27 21:42:05 -0500
+
+ Paul Eggert's latest changes
+
+
+Release code1996n - 1996-12-16 09:42:02 -0500
+
+ link snapping fix from Bruce Evans (via Garrett Wollman)
+
+
+Release data1996m - 1996-11-24 02:37:34 -0000
+ [tzdata1996m.tar.gz is missing!]
+
+ Paul Eggert's batch of changes
+
+
+Release code1996m-data1996l - 1996-11-05 14:00:12 -0500
+
+ No functional changes here; the files have simply been changed to
+ make more use of ISO style dates in comments. The names of the above
+ files now include the year in full.
+
+
+Release code96l - 1996-09-08 17:12:20 -0400
+
+ tzcode96k was missing a couple of pieces.
+
+
+Release 96k - 1996-09-08 16:06:22 -0400
+
+ the latest round of changes from Paul Eggert
+
+ the recent Year 2000 material
+
+
+Release code96j - 1996-07-30 13:18:53 -0400
+
+ Set sp->typecnt as suggested by Timothy Patrick Murphy.
+
+
+Release code96i - 1996-07-27 20:11:35 -0400
+
+ Paul's suggested patch for strftime %V week numbers
+
+
+Release data96i - 1996-07-01 18:13:04 -0400
+
+ "northamerica" and "europe" changes by Paul Eggert
+
+
+Release code96h - 1996-06-05 08:02:21 -0400
+
+ fix for handling transitions specified in Universal Time
+
+ Some "public domain" notices have also been added.
+
+
+Release code96g - 1996-05-16 14:00:26 -0400
+
+ fix for the simultaneous-DST-and-zone-change challenge
+
+
+Release data96h - 1996-05-09 17:40:51 -0400
+
+ changes by Paul Eggert
+
+
+Release code96f-data96g - 1996-05-03 03:09:59 -0000
+ [tzcode96f.tar.gz + tzdata96g.tar.gz are both missing!]
+
+ The changes get us some of the way to fixing the problems noted in Paul
+ Eggert's letter yesterday (in addition to a few others). The approach
+ has been to make zic a bit smarter about figuring out what time zone
+ abbreviations apply just after the time specified in the "UNTIL" part
+ of a zone line. Putting the smarts in zic means avoiding having
+ transition times show up in both "Zone" lines and "Rule" lines, which
+ in turn avoids multiple transition time entries in time zone files.
+ (This also makes the zic input files such as "europe" a bit shorter and
+ should ease maintenance.)
+
+
+Release data96f - 1996-04-19 19:20:03 -0000
+ [tzdata96f.tar.gz is missing!]
+
+ The only changes are to the "northamerica" file; the time zone
+ abbreviation for Denver is corrected to MST (and MDT), and the
+ comments for Mexico have been updated.
+
+
+Release data96e - 1996-03-19 17:37:26 -0500
+
+ Proposals by Paul Eggert, in particular the Portugal change that
+ comes into play at the end of this month.
+
+
+Release data96d - 1996-03-18 20:49:39 -0500
+
+ [not summarized]
+
+
+Release code96e - 1996-02-29 15:43:27 -0000
+ [tzcode96e.tar.gz is missing!]
+
+ internationalization changes and the fix to the documentation for strftime
+
+
+Release code96d-data96c - 1996-02-12 11:05:27 -0500
+
+ The "code" file simply updates Bob Kridle's electronic address.
+
+ The "data" file updates rules for Mexico.
+
+
+Release data96b - 1996-01-27 15:44:42 -0500
+
+ Kiribati change
+
+
+Release code96c - 1996-01-16 16:58:15 -0500
+
+ leap-year streamlining and binary-search changes
+
+ fix to newctime.3
+
+
+Release code96b - 1996-01-10 20:42:39 -0500
+
+ fixes and enhancements from Paul Eggert, including code that
+ emulates the behavior of recent versions of the SunOS "date"
+ command.
+
+
+Release 96a - 1996-01-06 09:08:24 -0500
+
+ Israel updates
+
+ fixes to strftime.c for correct ISO 8601 week number generation,
+ plus support for two new formats ('G' and 'g') to give ISO 8601 year
+ numbers (which are not necessarily the same as calendar year numbers)
+
+
+Release code95i-data95m - 1995-12-21 12:46:47 -0500
+
+ The latest revisions from Paul Eggert are included, the usno1995
+ file has been updated, and a new file ("WWW") covering useful URLs
+ has been added.
+
+
+Release code95h-data95l - 1995-12-19 18:10:12 -0500
+
+ A simplification of a macro definition, a change to data for Sudan,
+ and (for last minute shoppers) notes in the "Music" file on the CD
+ "Old Man Time".
+
+
+Release code95g-data95k - 1995-10-30 10:32:47 -0500
+
+ (slightly reformatted) 8-bit-clean proposed patch
+
+ minor patch: US/Eastern -> America/New_York
+
+ snapshot of the USNO's latest data ("usno1995")
+
+ some other minor cleanups
+
+
+Release code95f-data95j - 1995-10-28 21:01:34 -0000
+ [tzcode95f.tar.gz + tzdata95j.tar.gz are both missing!]
+
+ European cleanups
+
+ support for 64-bit time_t's
+
+ optimization in localtime.c
+
+
+Release code95e - 1995-10-13 13:23:57 -0400
+
+ the mktime change to scan from future to past when trying to find time zone
+ offsets
+
+
+Release data95i - 1995-09-26 10:43:26 -0400
+
+ For Canada/Central, guess that the Sun customer's "one week too
+ early" was just a approximation, and the true error is one month
+ too early. This is consistent with the rest of Canada.
+
+
+Release data95h - 1995-09-21 11:26:48 -0400
+
+ latest changes from Paul Eggert
+
+
+Release code95d - 1995-09-14 11:14:45 -0400
+
+ the addition of a "Music" file, which documents four recorded
+ versions of the tune "Save That Time".
+
+
+Release data95g - 1995-09-01 17:21:36 -0400
+
+ "yearistype" correction
+
+
+Release data95f - 1995-08-28 20:46:56 -0400
+
+ Paul Eggert's change to the australasia file
+
+
+Release data95e - 1995-07-08 18:02:34 -0400
+
+ The only change is a leap second at the end of this year.
+ Thanks to Bradley White for forwarding news on the leap second.
+
+
+Release data95d - 1995-07-03 13:26:22 -0400
+
+ Paul Eggert's changes
+
+
+Release data95c - 1995-07-02 19:19:28 -0400
+
+ changes to "asia", "backward", "europe", and "southamerica"
+ (read: northamericacentrics need not apply)
+
+
+Release code95c - 1995-03-13 14:00:46 -0500
+
+ one-line fix for sign extension problems in detzcode
+
+
+Release 95b - 1995-03-04 11:22:38 -0500
+
+ Minor changes in both:
+
+ The "code" file contains a workaround for the lack of "unistd.h" in
+ Microsoft C++ version 7.
+
+ The "data" file contains a fixed "Link" for America/Shiprock.
+
+
+Release 94h - 1994-12-10 12:51:14 -0500
+
+ The files:
+
+ * incorporate the changes to "zdump" and "date" to make changes to
+ the "TZ" environment variable permanent;
+
+ * incorporate the table changes by Paul Eggert;
+
+ * include (and document) support for universal time specifications in
+ data files - but do not (yet) include use of this feature in the
+ data files.
+
+ Think of this as "TZ Classic" - the software has been set up not to break if
+ universal time shows up in its input, and data entries have been
+ left as is so as not to break existing implementations.
+
+
+Release data94f - 1994-08-20 12:56:09 -0400
+
+ (with thanks!) the latest data updates from Paul Eggert
+
+
+Release data94e - 1994-06-04 13:13:53 -0400
+
+ [not summarized]
+
+
+Release code94g - 1994-05-05 12:14:07 -0400
+
+ fix missing "optind.c" and a reference to it in the Makefile
+
+
+Release code94f - 1994-05-05 13:00:33 -0000
+ [tzcode94f.tar.gz is missing!]
+
+ changes to avoid overflow in difftime, as well as changes to cope
+ with the 52/53 challenge in strftime
+
+
+Release code94e - 1994-03-30 23:32:59 -0500
+
+ change for the benefit of PCTS
+
+
+Release 94d - 1994-02-24 15:42:25 -0500
+
+ Avoid clashes with POSIX semantics for zones such as GMT+4.
+
+ Some other very minor housekeeping is also present.
+
+
+Release code94c - 1994-02-10 08:52:40 -0500
+
+ Fix bug where mkdirs was broken unless you compile with
+ -fwritable-strings (which is generally losing to do).
+
+
+Release 94b - 1994-02-07 10:04:33 -0500
+
+ work by Paul Eggert who notes:
+
+ I found another book of time zone histories by E W Whitman; it's not
+ as extensive as Shanks but has a few goodies of its own. I used it
+ to update the tables. I also fixed some more as a result of
+ correspondence with Adam David and Peter Ilieve, and move some stray
+ links from 'europe' to 'backward'. I corrected some scanning errors
+ in usno1989.
+
+ As far as the code goes, I fixed zic to allow years in the range
+ INT_MIN to INT_MAX; this fixed a few boundary conditions around 1900.
+ And I cleaned up the zic documentation a little bit.
+
+
+Release data94a - 1994-02-03 08:58:54 -0500
+
+ It simply incorporates the recently announced leap second into the
+ "leapseconds" file.
+
+
+Release 93g - 1993-11-22 17:28:27 -0500
+
+ Paul Eggert has provided a good deal of historic information (based
+ on Shanks), and there are some code changes to deal with the buglets
+ that crawled out in dealing with the new information.
+
+
+Release 93f - 1993-10-15 12:27:46 -0400
+
+ Paul Eggert's changes
+
+
+Release 93e - 1993-09-05 21:21:44 -0400
+
+ This has updated data for Israel, England, and Kwajalein. There's
+ also an update to "zdump" to cope with Kwajalein's 24-hour jump.
+ Thanks to Paul Eggert and Peter Ilieve for the changes.
+
+
+Release 93d - 1993-06-17 23:34:17 -0400
+
+ new fix and new data on Israel
+
+
+Release 93c - 1993-06-06 19:31:55 -0400
+
+ [not summarized]
+
+
+Release 93b - 1993-02-02 14:53:58 -0500
+
+ updated "leapseconds" file
+
+
+Release 93 - 1993-01-08 07:01:06 -0500
+
+ At kre's suggestion, the package has been split in two - a code piece
+ (which also includes documentation) that's only of use to folks who
+ want to recompile things and a data piece useful to anyone who can
+ run "zic".
+
+ The new version has a few changes to the data files, a few
+ portability changes, and an off-by-one fix (with thanks to
+ Tom Karzes at deshaw.com for providing a description and a
+ solution).
+
+
+Release 92c - 1992-11-21 17:35:36 -0000
+ [tz92c.tar.Z is missing!]
+
+ The fallout from the latest round of DST transitions.
+
+ There are changes for Portugal, Saskatchewan, and "Pacific-New";
+ there's also a change to "zic.c" that makes it portable to more systems.
+
+
+Release 92 - 1992-04-25 18:17:03 -0000
+ [tz92.tar.Z is missing!]
+
+ By popular demand (well, at any rate, following a request by kre at munnari)
+
+
+The 1989 update of the time zone package featured:
+
+ * POSIXization (including interpretation of POSIX-style TZ environment
+ variables, provided by Guy Harris),
+ * ANSIfication (including versions of "mktime" and "difftime"),
+ * SVIDulation (an "altzone" variable)
+ * MACHination (the "gtime" function)
+ * corrections to some time zone data (including corrections to the rules
+ for Great Britain and New Zealand)
+ * reference data from the United States Naval Observatory for folks who
+ want to do additional time zones
+ * and the 1989 data for Saudi Arabia.
+
+ (Since this code will be treated as "part of the implementation" in some
+ places and as "part of the application" in others, there's no good way to
+ name functions, such as timegm, that are not part of the proposed ANSI C
+ standard; such functions have kept their old, underscore-free names in this
+ update.)
+
+ And the "dysize" function has disappeared; it was present to allow
+ compilation of the "date" command on old BSD systems, and a version of "date"
+ is now provided in the package. The "date" command is not created when you
+ "make all" since it may lack options provided by the version distributed with
+ your operating system, or may not interact with the system in the same way
+ the native version does.
+
+ Since POSIX frowns on correct leap second handling, the default behavior of
+ the "zic" command (in the absence of a "-L" option) has been changed to omit
+ leap second information from its output files.
+
+
+-----
+Notes
+
+This file contains copies of the part of each release announcement
+that talks about the changes in that release. The text has been
+adapted and reformatted for the purposes of this file.
+
+Typically a release R consists of a pair of tarball files,
+tzcodeR.tar.gz and tzdataR.tar.gz. However, some releases (e.g.,
+code2010a, data2012c) consist of just one or the other tarball, and a
+few (e.g., code2012c-data2012d) have tarballs with mixed version
+numbers.
+
+Release time stamps are taken from the release's commit (for newer,
+git releases), from the newest file in the tarball (for older
+releases, where this info is available) or from the email announcing
+the release (if all else fails; these are marked with a time zone of
+-0000 and an "is missing!" comment).
+
+Earlier versions of the code and data were not announced on the tz
+list and are not summarized here.
+
+This file is in the public domain.
+
+Local Variables:
+coding: utf-8
+End:
Modified: vendor/tzcode/dist/README
===================================================================
--- vendor/tzcode/dist/README 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/README 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,41 +1,15 @@
README for the tz distribution
-This file is in the public domain, so clarified as of
-2009-05-17 by Arthur David Olson.
-
"What time is it?" -- Richard Deacon as The King
"Any time you want it to be." -- Frank Baxter as The Scientist
(from the Bell System film "About Time")
-The 1989 update of the time zone package featured
+The Time Zone Database (often called tz or zoneinfo) contains code and
+data that represent the history of local time for many representative
+locations around the globe. It is updated periodically to reflect
+changes made by political bodies to time zone boundaries, UTC offsets,
+and daylight-saving rules.
-* POSIXization (including interpretation of POSIX-style TZ environment
- variables, provided by Guy Harris),
-* ANSIfication (including versions of "mktime" and "difftime"),
-* SVIDulation (an "altzone" variable)
-* MACHination (the "gtime" function)
-* corrections to some time zone data (including corrections to the rules
- for Great Britain and New Zealand)
-* reference data from the United States Naval Observatory for folks who
- want to do additional time zones
-* and the 1989 data for Saudi Arabia.
-
-(Since this code will be treated as "part of the implementation" in some places
-and as "part of the application" in others, there's no good way to name
-functions, such as timegm, that are not part of the proposed ANSI C standard;
-such functions have kept their old, underscore-free names in this update.)
-
-And the "dysize" function has disappeared; it was present to allow compilation
-of the "date" command on old BSD systems, and a version of "date" is now
-provided in the package. The "date" command is not created when you "make all"
-since it may lack options provided by the version distributed with your
-operating system, or may not interact with the system in the same way the
-native version does.
-
-Since POSIX frowns on correct leap second handling, the default behavior of
-the "zic" command (in the absence of a "-L" option) has been changed to omit
-leap second information from its output files.
-
Here is a recipe for acquiring, building, installing, and testing the
tz distribution on a GNU/Linux or similar host.
@@ -53,12 +27,10 @@
make TOPDIR=$HOME/tzdir install
$HOME/tzdir/etc/zdump -v America/Los_Angeles
-To use the new functions, use a "-ltz" option when compiling or linking.
-
Historical local time information has been included here to:
* provide a compendium of data about the history of civil time
- that is useful even if the data are not 100% accurate;
+ that is useful even if not 100% accurate;
* give an idea of the variety of local time rules that have
existed in the past and thus an idea of the variety that may be
@@ -68,26 +40,24 @@
system.
The information in the time zone data files is by no means authoritative;
-the files currently do not even attempt to cover all time stamps before
-1970, and there are undoubtedly errors even for time stamps since 1970.
-If you know that the rules are different from those in a file, by all means
-feel free to change file (and please send the changed version to
-tz at iana.org for use in the future). Europeans take note!
+fixes and enhancements are welcome. Please see the file CONTRIBUTING
+for details.
-Thanks to these Timezone Caballeros who've made major contributions to the
-time conversion package: Keith Bostic; Bob Devine; Paul Eggert; Robert Elz;
+Thanks to these Time Zone Caballeros who've made major contributions to the
+time conversion package: Keith Bostic; Bob Devine; Paul Eggert; Robert Elz;
Guy Harris; Mark Horton; John Mackin; and Bradley White. Thanks also to
Michael Bloom, Art Neilson, Stephen Prince, John Sovereign, and Frank Wales
for testing work, and to Gwillim Law for checking local mean time data.
+Thanks in particular to Arthur David Olson, the project's founder and first
+maintainer, to whom the time zone community owes the greatest debt of all.
None of them are responsible for remaining errors.
-Look in <ftp://ftp.iana.org/tz/releases/>
-for updated versions of these files.
+Look in <ftp://ftp.iana.org/tz/releases/> for updated versions of these files.
Please send comments or information to tz at iana.org.
-Postscript: The README above is largely unmodified (aside from details
-of mailing list and ftp archive addresses) from that prepared many years
-ago by Arthur David Olson, to whom the timezone community owes the
-greatest debt of all. Arthur is not currently maintaining this data or
-code (though he remains involved).
+-----
+
+This file is in the public domain, so clarified as of 2009-05-17 by
+Arthur David Olson. The other files in this distribution are either
+public domain or BSD licensed; see the file LICENSE for details.
Modified: vendor/tzcode/dist/Theory
===================================================================
--- vendor/tzcode/dist/Theory 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/Theory 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,28 +1,385 @@
-This file is in the public domain, so clarified as of
-2009-05-17 by Arthur David Olson.
+Theory and pragmatics of the tz code and data
+
----- Outline -----
- Time and date functions
Scope of the tz database
- Names of time zone rule files
+ Names of time zone rules
Time zone abbreviations
+ Accuracy of the tz database
+ Time and date functions
Calendrical issues
Time and time zones on Mars
+
+----- Scope of the tz database -----
+
+The tz database attempts to record the history and predicted future of
+all computer-based clocks that track civil time. To represent this
+data, the world is partitioned into regions whose clocks all agree
+about time stamps that occur after the somewhat-arbitrary cutoff point
+of the POSIX Epoch (1970-01-01 00:00:00 UTC). For each such region,
+the database records all known clock transitions, and labels the region
+with a notable location. Although 1970 is a somewhat-arbitrary
+cutoff, there are significant challenges to moving the cutoff earlier
+even by a decade or two, due to the wide variety of local practices
+before computer timekeeping became prevalent.
+
+Clock transitions before 1970 are recorded for each such location,
+because most systems support time stamps before 1970 and could
+misbehave if data entries were omitted for pre-1970 transitions.
+However, the database is not designed for and does not suffice for
+applications requiring accurate handling of all past times everywhere,
+as it would take far too much effort and guesswork to record all
+details of pre-1970 civil timekeeping.
+
+As described below, reference source code for using the tz database is
+also available. The tz code is upwards compatible with POSIX, an
+international standard for UNIX-like systems. As of this writing, the
+current edition of POSIX is:
+
+ The Open Group Base Specifications Issue 7
+ IEEE Std 1003.1, 2013 Edition
+ <http://pubs.opengroup.org/onlinepubs/9699919799/>
+
+
+
+----- Names of time zone rules -----
+
+Each of the database's time zone rules has a unique name.
+Inexperienced users are not expected to select these names unaided.
+Distributors should provide documentation and/or a simple selection
+interface that explains the names; for one example, see the 'tzselect'
+program in the tz code. The Unicode Common Locale Data Repository
+<http://cldr.unicode.org/> contains data that may be useful for other
+selection interfaces.
+
+The time zone rule naming conventions attempt to strike a balance
+among the following goals:
+
+ * Uniquely identify every region where clocks have agreed since 1970.
+ This is essential for the intended use: static clocks keeping local
+ civil time.
+
+ * Indicate to experts where that region is.
+
+ * Be robust in the presence of political changes. For example, names
+ of countries are ordinarily not used, to avoid incompatibilities
+ when countries change their name (e.g. Zaire->Congo) or when
+ locations change countries (e.g. Hong Kong from UK colony to
+ China).
+
+ * Be portable to a wide variety of implementations.
+
+ * Use a consistent naming conventions over the entire world.
+
+Names normally have the form AREA/LOCATION, where AREA is the name
+of a continent or ocean, and LOCATION is the name of a specific
+location within that region. North and South America share the same
+area, 'America'. Typical names are 'Africa/Cairo', 'America/New_York',
+and 'Pacific/Honolulu'.
+
+Here are the general rules used for choosing location names,
+in decreasing order of importance:
+
+ Use only valid POSIX file name components (i.e., the parts of
+ names other than '/'). Do not use the file name
+ components '.' and '..'. Within a file name component,
+ use only ASCII letters, '.', '-' and '_'. Do not use
+ digits, as that might create an ambiguity with POSIX
+ TZ strings. A file name component must not exceed 14
+ characters or start with '-'. E.g., prefer 'Brunei'
+ to 'Bandar_Seri_Begawan'. Exceptions: see the discussion
+ of legacy names below.
+ A name must not be empty, or contain '//', or start or end with '/'.
+ Do not use names that differ only in case. Although the reference
+ implementation is case-sensitive, some other implementations
+ are not, and they would mishandle names differing only in case.
+ If one name A is an initial prefix of another name AB (ignoring case),
+ then B must not start with '/', as a regular file cannot have
+ the same name as a directory in POSIX. For example,
+ 'America/New_York' precludes 'America/New_York/Bronx'.
+ Uninhabited regions like the North Pole and Bouvet Island
+ do not need locations, since local time is not defined there.
+ There should typically be at least one name for each ISO 3166-1
+ officially assigned two-letter code for an inhabited country
+ or territory.
+ If all the clocks in a region have agreed since 1970,
+ don't bother to include more than one location
+ even if subregions' clocks disagreed before 1970.
+ Otherwise these tables would become annoyingly large.
+ If a name is ambiguous, use a less ambiguous alternative;
+ e.g. many cities are named San José and Georgetown, so
+ prefer 'Costa_Rica' to 'San_Jose' and 'Guyana' to 'Georgetown'.
+ Keep locations compact. Use cities or small islands, not countries
+ or regions, so that any future time zone changes do not split
+ locations into different time zones. E.g. prefer 'Paris'
+ to 'France', since France has had multiple time zones.
+ Use mainstream English spelling, e.g. prefer 'Rome' to 'Roma', and
+ prefer 'Athens' to the Greek 'Αθήνα' or the Romanized 'Athína'.
+ The POSIX file name restrictions encourage this rule.
+ Use the most populous among locations in a zone,
+ e.g. prefer 'Shanghai' to 'Beijing'. Among locations with
+ similar populations, pick the best-known location,
+ e.g. prefer 'Rome' to 'Milan'.
+ Use the singular form, e.g. prefer 'Canary' to 'Canaries'.
+ Omit common suffixes like '_Islands' and '_City', unless that
+ would lead to ambiguity. E.g. prefer 'Cayman' to
+ 'Cayman_Islands' and 'Guatemala' to 'Guatemala_City',
+ but prefer 'Mexico_City' to 'Mexico' because the country
+ of Mexico has several time zones.
+ Use '_' to represent a space.
+ Omit '.' from abbreviations in names, e.g. prefer 'St_Helena'
+ to 'St._Helena'.
+ Do not change established names if they only marginally
+ violate the above rules. For example, don't change
+ the existing name 'Rome' to 'Milan' merely because
+ Milan's population has grown to be somewhat greater
+ than Rome's.
+ If a name is changed, put its old spelling in the 'backward' file.
+ This means old spellings will continue to work.
+
+The file 'zone1970.tab' lists geographical locations used to name time
+zone rules. It is intended to be an exhaustive list of names for
+geographic regions as described above; this is a subset of the names
+in the data. Although a 'zone1970.tab' location's longitude
+corresponds to its LMT offset with one hour for every 15 degrees east
+longitude, this relationship is not exact.
+
+Older versions of this package used a different naming scheme,
+and these older names are still supported.
+See the file 'backward' for most of these older names
+(e.g., 'US/Eastern' instead of 'America/New_York').
+The other old-fashioned names still supported are
+'WET', 'CET', 'MET', and 'EET' (see the file 'europe').
+
+Older versions of this package defined legacy names that are
+incompatible with the first rule of location names, but which are
+still supported. These legacy names are mostly defined in the file
+'etcetera'. Also, the file 'backward' defines the legacy names
+'GMT0', 'GMT-0', 'GMT+0' and 'Canada/East-Saskatchewan', and the file
+'northamerica' defines the legacy names 'EST5EDT', 'CST6CDT',
+'MST7MDT', and 'PST8PDT'.
+
+Excluding 'backward' should not affect the other data. If
+'backward' is excluded, excluding 'etcetera' should not affect the
+remaining data.
+
+
+----- Time zone abbreviations -----
+
+When this package is installed, it generates time zone abbreviations
+like 'EST' to be compatible with human tradition and POSIX.
+Here are the general rules used for choosing time zone abbreviations,
+in decreasing order of importance:
+
+ Use three or more characters that are ASCII alphanumerics or '+' or '-'.
+ Previous editions of this database also used characters like
+ ' ' and '?', but these characters have a special meaning to
+ the shell and cause commands like
+ set `date`
+ to have unexpected effects.
+ Previous editions of this rule required upper-case letters,
+ but the Congressman who introduced Chamorro Standard Time
+ preferred "ChST", so lower-case letters are now allowed.
+ Also, POSIX from 2001 on relaxed the rule to allow '-', '+',
+ and alphanumeric characters from the portable character set
+ in the current locale. In practice ASCII alphanumerics and
+ '+' and '-' are safe in all locales.
+
+ In other words, in the C locale the POSIX extended regular
+ expression [-+[:alnum:]]{3,} should match the abbreviation.
+ This guarantees that all abbreviations could have been
+ specified by a POSIX TZ string.
+
+ Use abbreviations that are in common use among English-speakers,
+ e.g. 'EST' for Eastern Standard Time in North America.
+ We assume that applications translate them to other languages
+ as part of the normal localization process; for example,
+ a French application might translate 'EST' to 'HNE'.
+
+ For zones whose times are taken from a city's longitude, use the
+ traditional xMT notation, e.g. 'PMT' for Paris Mean Time.
+ The only name like this in current use is 'GMT'.
+
+ Use 'LMT' for local mean time of locations before the introduction
+ of standard time; see "Scope of the tz database".
+
+ If there is no common English abbreviation, use numeric offsets like
+ -05 and +0830 that are generated by zic's %z notation.
+
+ [The remaining guidelines predate the introduction of %z.
+ They are problematic as they mean tz data entries invent
+ notation rather than record it. These guidelines are now
+ deprecated and the plan is to gradually move to %z for
+ inhabited locations and to "-00" for uninhabited locations.]
+
+ If there is no common English abbreviation, abbreviate the English
+ translation of the usual phrase used by native speakers.
+ If this is not available or is a phrase mentioning the country
+ (e.g. "Cape Verde Time"), then:
+
+ When a country is identified with a single or principal zone,
+ append 'T' to the country's ISO code, e.g. 'CVT' for
+ Cape Verde Time. For summer time append 'ST';
+ for double summer time append 'DST'; etc.
+ Otherwise, take the first three letters of an English place
+ name identifying each zone and append 'T', 'ST', etc.
+ as before; e.g. 'VLAST' for VLAdivostok Summer Time.
+
+ Use UT (with time zone abbreviation '-00') for locations while
+ uninhabited. The leading '-' is a flag that the time
+ zone is in some sense undefined; this notation is
+ derived from Internet RFC 3339.
+
+Application writers should note that these abbreviations are ambiguous
+in practice: e.g. 'CST' has a different meaning in China than
+it does in the United States. In new applications, it's often better
+to use numeric UT offsets like '-0600' instead of time zone
+abbreviations like 'CST'; this avoids the ambiguity.
+
+
+----- Accuracy of the tz database -----
+
+The tz database is not authoritative, and it surely has errors.
+Corrections are welcome and encouraged; see the file CONTRIBUTING.
+Users requiring authoritative data should consult national standards
+bodies and the references cited in the database's comments.
+
+Errors in the tz database arise from many sources:
+
+ * The tz database predicts future time stamps, and current predictions
+ will be incorrect after future governments change the rules.
+ For example, if today someone schedules a meeting for 13:00 next
+ October 1, Casablanca time, and tomorrow Morocco changes its
+ daylight saving rules, software can mess up after the rule change
+ if it blithely relies on conversions made before the change.
+
+ * The pre-1970 entries in this database cover only a tiny sliver of how
+ clocks actually behaved; the vast majority of the necessary
+ information was lost or never recorded. Thousands more zones would
+ be needed if the tz database's scope were extended to cover even
+ just the known or guessed history of standard time; for example,
+ the current single entry for France would need to split into dozens
+ of entries, perhaps hundreds. And in most of the world even this
+ approach would be misleading due to widespread disagreement or
+ indifference about what times should be observed. In her 2015 book
+ "The Global Transformation of Time, 1870-1950", Vanessa Ogle writes
+ "Outside of Europe and North America there was no system of time
+ zones at all, often not even a stable landscape of mean times,
+ prior to the middle decades of the twentieth century". See:
+ Timothy Shenk, Booked: A Global History of Time. Dissent 2015-12-17
+ https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanessa-ogle
+
+ * Most of the pre-1970 data entries come from unreliable sources, often
+ astrology books that lack citations and whose compilers evidently
+ invented entries when the true facts were unknown, without
+ reporting which entries were known and which were invented.
+ These books often contradict each other or give implausible entries,
+ and on the rare occasions when they are checked they are
+ typically found to be incorrect.
+
+ * For the UK the tz database relies on years of first-class work done by
+ Joseph Myers and others; see <http://www.polyomino.org.uk/british-time/>.
+ Other countries are not done nearly as well.
+
+ * Sometimes, different people in the same city would maintain clocks
+ that differed significantly. Railway time was used by railroad
+ companies (which did not always agree with each other),
+ church-clock time was used for birth certificates, etc.
+ Often this was merely common practice, but sometimes it was set by law.
+ For example, from 1891 to 1911 the UT offset in France was legally
+ 0:09:21 outside train stations and 0:04:21 inside.
+
+ * Although a named location in the tz database stands for the
+ containing region, its pre-1970 data entries are often accurate for
+ only a small subset of that region. For example, Europe/London
+ stands for the United Kingdom, but its pre-1847 times are valid
+ only for locations that have London's exact meridian, and its 1847
+ transition to GMT is known to be valid only for the L&NW and the
+ Caledonian railways.
+
+ * The tz database does not record the earliest time for which a zone's
+ data entries are thereafter valid for every location in the region.
+ For example, Europe/London is valid for all locations in its
+ region after GMT was made the standard time, but the date of
+ standardization (1880-08-02) is not in the tz database, other than
+ in commentary. For many zones the earliest time of validity is
+ unknown.
+
+ * The tz database does not record a region's boundaries, and in many
+ cases the boundaries are not known. For example, the zone
+ America/Kentucky/Louisville represents a region around the city of
+ Louisville, the boundaries of which are unclear.
+
+ * Changes that are modeled as instantaneous transitions in the tz
+ database were often spread out over hours, days, or even decades.
+
+ * Even if the time is specified by law, locations sometimes
+ deliberately flout the law.
+
+ * Early timekeeping practices, even assuming perfect clocks, were
+ often not specified to the accuracy that the tz database requires.
+
+ * Sometimes historical timekeeping was specified more precisely
+ than what the tz database can handle. For example, from 1909 to
+ 1937 Netherlands clocks were legally UT+00:19:32.13, but the tz
+ database cannot represent the fractional second.
+
+ * Even when all the timestamp transitions recorded by the tz database
+ are correct, the tz rules that generate them may not faithfully
+ reflect the historical rules. For example, from 1922 until World
+ War II the UK moved clocks forward the day following the third
+ Saturday in April unless that was Easter, in which case it moved
+ clocks forward the previous Sunday. Because the tz database has no
+ way to specify Easter, these exceptional years are entered as
+ separate tz Rule lines, even though the legal rules did not change.
+
+ * The tz database models pre-standard time using the proleptic Gregorian
+ calendar and local mean time (LMT), but many people used other
+ calendars and other timescales. For example, the Roman Empire used
+ the Julian calendar, and had 12 varying-length daytime hours with a
+ non-hour-based system at night.
+
+ * Early clocks were less reliable, and data entries do not represent
+ this unreliability.
+
+ * As for leap seconds, civil time was not based on atomic time before
+ 1972, and we don't know the history of earth's rotation accurately
+ enough to map SI seconds to historical solar time to more than
+ about one-hour accuracy. See: Morrison LV, Stephenson FR.
+ Historical values of the Earth's clock error Delta T and the
+ calculation of eclipses. J Hist Astron. 2004;35:327-36
+ <http://adsabs.harvard.edu/full/2004JHA....35..327M>;
+ Historical values of the Earth's clock error. J Hist Astron. 2005;36:339
+ <http://adsabs.harvard.edu/full/2005JHA....36..339M>.
+
+ * The relationship between POSIX time (that is, UTC but ignoring leap
+ seconds) and UTC is not agreed upon after 1972. Although the POSIX
+ clock officially stops during an inserted leap second, at least one
+ proposed standard has it jumping back a second instead; and in
+ practice POSIX clocks more typically either progress glacially during
+ a leap second, or are slightly slowed while near a leap second.
+
+ * The tz database does not represent how uncertain its information is.
+ Ideally it would contain information about when data entries are
+ incomplete or dicey. Partial temporal knowledge is a field of
+ active research, though, and it's not clear how to apply it here.
+
+In short, many, perhaps most, of the tz database's pre-1970 and future
+time stamps are either wrong or misleading. Any attempt to pass the
+tz database off as the definition of time should be unacceptable to
+anybody who cares about the facts. In particular, the tz database's
+LMT offsets should not be considered meaningful, and should not prompt
+creation of zones merely because two locations differ in LMT or
+transitioned to standard time at different dates.
+
+
----- Time and date functions -----
-These time and date functions are upwards compatible with POSIX,
-an international standard for UNIX-like systems.
-As of this writing, the current edition of POSIX is:
+The tz code contains time and date functions that are upwards
+compatible with those of POSIX.
- Standard for Information technology
- -- Portable Operating System Interface (POSIX (R))
- -- System Interfaces
- IEEE Std 1003.1, 2004 Edition
- <http://www.opengroup.org/online-pubs?DOC=7999959899>
- <http://www.opengroup.org/pubs/catalog/t041.htm>
-
POSIX has the following properties and limitations.
* In POSIX, time display in a process is controlled by the
@@ -34,7 +391,7 @@
The POSIX TZ string takes the following form:
- stdoffset[dst[offset],date[/time],date[/time]]
+ stdoffset[dst[offset][,date[/time],date[/time]]]
where:
@@ -45,15 +402,17 @@
in a quoted form like "<UTC+10>"; this allows
"+" and "-" in the names.
offset
- is of the form `[-]hh:[mm[:ss]]' and specifies the
- offset west of UTC. The default DST offset is one hour
- ahead of standard time.
+ is of the form '[+-]hh:[mm[:ss]]' and specifies the
+ offset west of UT. 'hh' may be a single digit; 0<=hh<=24.
+ The default DST offset is one hour ahead of standard time.
date[/time],date[/time]
specifies the beginning and end of DST. If this is absent,
the system supplies its own rules for DST, and these can
differ from year to year; typically US DST rules are used.
time
- takes the form `hh:[mm[:ss]]' and defaults to 02:00.
+ takes the form 'hh:[mm[:ss]]' and defaults to 02:00.
+ This is the same format as the offset, except that a
+ leading '+' or '-' is not allowed.
date
takes one of the following forms:
Jn (1<=n<=365)
@@ -63,8 +422,10 @@
Mm.n.d (0[Sunday]<=d<=6[Saturday], 1<=n<=5, 1<=m<=12)
for the dth day of week n of month m of the year,
where week 1 is the first week in which day d appears,
- and `5' stands for the last week in which day d appears
+ and '5' stands for the last week in which day d appears
(which may be either the 4th or 5th week).
+ Typically, this is the only useful form;
+ the n and Jn forms are rarely used.
Here is an example POSIX TZ string, for US Pacific time using rules
appropriate from 1987 through 2006:
@@ -86,15 +447,28 @@
* In POSIX, there's no tamper-proof way for a process to learn the
system's best idea of local wall clock. (This is important for
- applications that an administrator wants used only at certain times--
+ applications that an administrator wants used only at certain times -
without regard to whether the user has fiddled the "TZ" environment
variable. While an administrator can "do everything in UTC" to get
around the problem, doing so is inconvenient and precludes handling
- daylight saving time shifts--as might be required to limit phone
+ daylight saving time shifts - as might be required to limit phone
calls to off-peak hours.)
* POSIX requires that systems ignore leap seconds.
+* The tz code attempts to support all the time_t implementations
+ allowed by POSIX. The time_t type represents a nonnegative count of
+ seconds since 1970-01-01 00:00:00 UTC, ignoring leap seconds.
+ In practice, time_t is usually a signed 64- or 32-bit integer; 32-bit
+ signed time_t values stop working after 2038-01-19 03:14:07 UTC, so
+ new implementations these days typically use a signed 64-bit integer.
+ Unsigned 32-bit integers are used on one or two platforms,
+ and 36-bit and 40-bit integers are also used occasionally.
+ Although earlier POSIX versions allowed time_t to be a
+ floating-point type, this was not supported by any practical
+ systems, and POSIX.1-2013 and the tz code both require time_t
+ to be an integer type.
+
These are the extensions that have been made to the POSIX functions:
* The "TZ" environment variable is used in generating the name of a file
@@ -113,7 +487,7 @@
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;
+ 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
@@ -142,10 +516,12 @@
"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"
+ 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.)
+* Negative time_t values are supported, on systems where time_t is signed.
+
* These functions can account for leap seconds, thanks to Bradley White.
Points of interest to folks with other systems:
@@ -155,7 +531,7 @@
On such hosts, the primary use of this package
is to update obsolete time zone rule tables.
To do this, you may need to compile the time zone compiler
- `zic' supplied with this package instead of using the system `zic',
+ 'zic' supplied with this package instead of using the system 'zic',
since the format of zic's input changed slightly in late 1994,
and many vendors still do not support the new input format.
@@ -173,12 +549,12 @@
but this functionality was removed in later versions of BSD.
* In SVR2, time conversion fails for near-minimum or near-maximum
- time_t values when doing conversions for places that don't use UTC.
+ time_t values when doing conversions for places that don't use UT.
This package takes care to do these conversions correctly.
The functions that are conditionally compiled if STD_INSPIRED is defined
should, at this point, be looked on primarily as food for thought. They are
-not in any sense "standard compatible"--some are not, in fact, specified in
+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.
@@ -192,193 +568,6 @@
better.
------ Scope of the tz database -----
-
-The tz database attempts to record the history and predicted future of
-all computer-based clocks that track civil time. To represent this
-data, the world is partitioned into regions whose clocks all agree
-about time stamps that occur after the somewhat-arbitrary cutoff point
-of the POSIX Epoch (1970-01-01 00:00:00 UTC). For each such region,
-the database records all known clock transitions, and labels the region
-with a notable location.
-
-Clock transitions before 1970 are recorded for each such location,
-because most POSIX-compatible systems support negative time stamps and
-could misbehave if data were omitted for pre-1970 transitions.
-However, the database is not designed for and does not suffice for
-applications requiring accurate handling of all past times everywhere,
-as it would take far too much effort and guesswork to record all
-details of pre-1970 civil timekeeping.
-
-As noted in the README file, the tz database is not authoritative
-(particularly not for pre-1970 time stamps), and it surely has errors.
-Corrections are welcome and encouraged. Users requiring authoritative
-data should consult national standards bodies and the references cited
-in the database's comments.
-
-
------ Names of time zone rule files -----
-
-The time zone rule file naming conventions attempt to strike a balance
-among the following goals:
-
- * Uniquely identify every national region where clocks have all
- agreed since 1970. This is essential for the intended use: static
- clocks keeping local civil time.
-
- * Indicate to humans as to where that region is. This simplifies use.
-
- * Be robust in the presence of political changes. This reduces the
- number of updates and backward-compatibility hacks. For example,
- names of countries are ordinarily not used, to avoid
- incompatibilities when countries change their name
- (e.g. Zaire->Congo) or when locations change countries
- (e.g. Hong Kong from UK colony to China).
-
- * Be portable to a wide variety of implementations.
- This promotes use of the technology.
-
- * Use a consistent naming convention over the entire world.
- This simplifies both use and maintenance.
-
-This naming convention is not intended for use by inexperienced users
-to select TZ values by themselves (though they can of course examine
-and reuse existing settings). Distributors should provide
-documentation and/or a simple selection interface that explains the
-names; see the 'tzselect' program supplied with this distribution for
-one example.
-
-Names normally have the form AREA/LOCATION, where AREA is the name
-of a continent or ocean, and LOCATION is the name of a specific
-location within that region. North and South America share the same
-area, `America'. Typical names are `Africa/Cairo', `America/New_York',
-and `Pacific/Honolulu'.
-
-Here are the general rules used for choosing location names,
-in decreasing order of importance:
-
- Use only valid POSIX file name components (i.e., the parts of
- names other than `/'). Within a file name component,
- use only ASCII letters, `.', `-' and `_'. Do not use
- digits, as that might create an ambiguity with POSIX
- TZ strings. A file name component must not exceed 14
- characters or start with `-'. E.g., prefer `Brunei'
- to `Bandar_Seri_Begawan'.
- Include at least one location per time zone rule set per country.
- One such location is enough. Use ISO 3166 (see the file
- iso3166.tab) to help decide whether something is a country.
- However, uninhabited ISO 3166 regions like Bouvet Island
- do not need locations, since local time is not defined there.
- If all the clocks in a country's region have agreed since 1970,
- don't bother to include more than one location
- even if subregions' clocks disagreed before 1970.
- Otherwise these tables would become annoyingly large.
- If a name is ambiguous, use a less ambiguous alternative;
- e.g. many cities are named San Jose and Georgetown, so
- prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'.
- Keep locations compact. Use cities or small islands, not countries
- or regions, so that any future time zone changes do not split
- locations into different time zones. E.g. prefer `Paris'
- to `France', since France has had multiple time zones.
- Use mainstream English spelling, e.g. prefer `Rome' to `Roma', and
- prefer `Athens' to the true name (which uses Greek letters).
- The POSIX file name restrictions encourage this rule.
- Use the most populous among locations in a country's time zone,
- e.g. prefer `Shanghai' to `Beijing'. Among locations with
- similar populations, pick the best-known location,
- e.g. prefer `Rome' to `Milan'.
- Use the singular form, e.g. prefer `Canary' to `Canaries'.
- Omit common suffixes like `_Islands' and `_City', unless that
- would lead to ambiguity. E.g. prefer `Cayman' to
- `Cayman_Islands' and `Guatemala' to `Guatemala_City',
- but prefer `Mexico_City' to `Mexico' because the country
- of Mexico has several time zones.
- Use `_' to represent a space.
- Omit `.' from abbreviations in names, e.g. prefer `St_Helena'
- to `St._Helena'.
- Do not change established names if they only marginally
- violate the above rules. For example, don't change
- the existing name `Rome' to `Milan' merely because
- Milan's population has grown to be somewhat greater
- than Rome's.
- If a name is changed, put its old spelling in the `backward' file.
-
-The file `zone.tab' lists the geographical locations used to name
-time zone rule files. It is intended to be an exhaustive list
-of canonical names for geographic regions.
-
-Older versions of this package used a different naming scheme,
-and these older names are still supported.
-See the file `backward' for most of these older names
-(e.g. `US/Eastern' instead of `America/New_York').
-The other old-fashioned names still supported are
-`WET', `CET', `MET', and `EET' (see the file `europe').
-
-
------ Time zone abbreviations -----
-
-When this package is installed, it generates time zone abbreviations
-like `EST' to be compatible with human tradition and POSIX.
-Here are the general rules used for choosing time zone abbreviations,
-in decreasing order of importance:
-
- Use abbreviations that consist of three or more ASCII letters.
- Previous editions of this database also used characters like
- ' ' and '?', but these characters have a special meaning to
- the shell and cause commands like
- set `date`
- to have unexpected effects.
- Previous editions of this rule required upper-case letters,
- but the Congressman who introduced Chamorro Standard Time
- preferred "ChST", so the rule has been relaxed.
-
- This rule guarantees that all abbreviations could have
- been specified by a POSIX TZ string. POSIX
- requires at least three characters for an
- abbreviation. POSIX through 2000 says that an abbreviation
- cannot start with ':', and cannot contain ',', '-',
- '+', NUL, or a digit. POSIX from 2001 on changes this
- rule to say that an abbreviation can contain only '-', '+',
- and alphanumeric characters from the portable character set
- in the current locale. To be portable to both sets of
- rules, an abbreviation must therefore use only ASCII
- letters.
-
- Use abbreviations that are in common use among English-speakers,
- e.g. `EST' for Eastern Standard Time in North America.
- We assume that applications translate them to other languages
- as part of the normal localization process; for example,
- a French application might translate `EST' to `HNE'.
-
- For zones whose times are taken from a city's longitude, use the
- traditional xMT notation, e.g. `PMT' for Paris Mean Time.
- The only name like this in current use is `GMT'.
-
- If there is no common English abbreviation, abbreviate the English
- translation of the usual phrase used by native speakers.
- If this is not available or is a phrase mentioning the country
- (e.g. ``Cape Verde Time''), then:
-
- When a country has a single or principal time zone region,
- append `T' to the country's ISO code, e.g. `CVT' for
- Cape Verde Time. For summer time append `ST';
- for double summer time append `DST'; etc.
- When a country has multiple time zones, take the first three
- letters of an English place name identifying each zone
- and then append `T', `ST', etc. as before;
- e.g. `VLAST' for VLAdivostok Summer Time.
-
- Use UTC (with time zone abbreviation "zzz") for locations while
- uninhabited. The "zzz" mnemonic is that these locations are,
- in some sense, asleep.
-
-Application writers should note that these abbreviations are ambiguous
-in practice: e.g. `EST' has a different meaning in Australia than
-it does in the United States. In new applications, it's often better
-to use numeric UTC offsets like `-0500' instead of time zone
-abbreviations like `EST'; this avoids the ambiguity.
-
-
----- Calendrical issues -----
Calendrical issues are a bit out of scope for a time zone database,
@@ -385,10 +574,9 @@
but they indicate the sort of problems that we would run into if we
extended the time zone database further into the past. An excellent
resource in this area is Nachum Dershowitz and Edward M. Reingold,
-<a href="http://emr.cs.iit.edu/home/reingold/calendar-book/third-edition/">
-Calendrical Calculations: Third Edition
-</a>, Cambridge University Press (2008). Other information and
-sources are given below. They sometimes disagree.
+Calendrical Calculations: Third Edition, Cambridge University Press (2008)
+<http://emr.cs.iit.edu/home/reingold/calendar-book/third-edition/>.
+Other information and sources are given below. They sometimes disagree.
France
@@ -401,7 +589,7 @@
Russia
From Chris Carrier (1996-12-02):
-On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar''
+On 1929-10-01 the Soviet Union instituted an "Eternal Calendar"
with 30-day months plus 5 holidays, with a 5-day week.
On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the
Gregorian calendar while retaining the 6-day week; on 1940-06-27 it
@@ -417,7 +605,7 @@
Date: 14 Jan 1999 00:00:00 GMT
...
-If your source is correct, how come documents between 1929 -- 1940 were
+If your source is correct, how come documents between 1929 and 1940 were
still dated using the conventional, Gregorian calendar?
I can post a scan of a document dated December 1, 1934, signed by
@@ -429,15 +617,14 @@
Sweden (and Finland)
From: Mark Brader
-<a href="news:1996Jul6.012937.29190 at sq.com">
-Subject: Re: Gregorian reform -- a part of locale?
-</a>
+Subject: Re: Gregorian reform - a part of locale?
+<news:1996Jul6.012937.29190 at sq.com>
Date: 1996-07-06
In 1700, Denmark made the transition from Julian to Gregorian. Sweden
decided to *start* a transition in 1700 as well, but rather than have one of
those unsightly calendar gaps :-), they simply decreed that the next leap
-year after 1696 would be in 1744 -- putting the whole country on a calendar
+year after 1696 would be in 1744 - putting the whole country on a calendar
different from both Julian and Gregorian for a period of 40 years.
However, in 1704 something went wrong and the plan was not carried through;
@@ -449,9 +636,9 @@
getting there only 13 years behind the original schedule.
(A previous posting of this story was challenged, and Swedish readers
-produced the following references to support it: "Tiderakning och historia"
-by Natanael Beckman (1924) and "Tid, en bok om tiderakning och
-kalendervasen" by Lars-Olof Lode'n (no date was given).)
+produced the following references to support it: "Tideräkning och historia"
+by Natanael Beckman (1924) and "Tid, en bok om tideräkning och
+kalenderväsen" by Lars-Olof Lodén (1968).
Grotefend's data
@@ -472,23 +659,23 @@
21 Dec 1582/
01 Jan 1583 - Holland, Brabant, Flanders, Hennegau
-10/21 Feb 1583 - bishopric of Liege (L"uttich)
+10/21 Feb 1583 - bishopric of Liege (Lüttich)
13/24 Feb 1583 - bishopric of Augsburg
04/15 Oct 1583 - electorate of Trier
05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg,
Salzburg, Brixen
-13/24 Oct 1583 - Austrian Oberelsass and Breisgau
+13/24 Oct 1583 - Austrian Oberelsaß and Breisgau
20/31 Oct 1583 - bishopric of Basel
-02/13 Nov 1583 - duchy of J"ulich-Berg
-02/13 Nov 1583 - electorate and city of K"oln
-04/15 Nov 1583 - bishopric of W"urzburg
+02/13 Nov 1583 - duchy of Jülich-Berg
+02/13 Nov 1583 - electorate and city of Köln
+04/15 Nov 1583 - bishopric of Würzburg
11/22 Nov 1583 - electorate of Mainz
16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden
-17/28 Nov 1583 - bishopric of M"unster and duchy of Cleve
+17/28 Nov 1583 - bishopric of Münster and duchy of Cleve
14/25 Dec 1583 - Steiermark
06/17 Jan 1584 - Austria and Bohemia
-11/22 Jan 1584 - Luzern, Uri, Schwyz, Zug, Freiburg, Solothurn
+11/22 Jan 1584 - Lucerne, Uri, Schwyz, Zug, Freiburg, Solothurn
12/23 Jan 1584 - Silesia and the Lausitz
22 Jan/
02 Feb 1584 - Hungary (legally on 21 Oct 1587)
@@ -507,7 +694,7 @@
1617 - duchy of Kurland (reverted to the Julian calendar in
1796)
- 1624 - bishopric of Osnabr"uck
+ 1624 - bishopric of Osnabrück
1630 - bishopric of Minden
@@ -526,7 +713,7 @@
12 Dec 1700 - Utrecht, Overijssel
31 Dec 1700/
- 12 Jan 1701 - Friesland, Groningen, Z"urich, Bern, Basel, Geneva,
+ 12 Jan 1701 - Friesland, Groningen, Zürich, Bern, Basel, Geneva,
Turgau, and Schaffhausen
1724 - Glarus, Appenzell, and the city of St. Gallen
@@ -538,21 +725,23 @@
17 Feb/
01 Mar 1753 - Sweden
-1760-1812 - Graub"unden
+1760-1812 - Graubünden
The Russian empire (including Finland and the Baltic states) did not
convert to the Gregorian calendar until the Soviet revolution of 1917.
-Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen
+Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen
Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend
-(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28.
+(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28.
----- Time and time zones on Mars -----
-Some people have adjusted their work schedules to fit Mars time.
-Dozens of special Mars watches were built for Jet Propulsion
-Laboratory workers who kept Mars time during the Mars Exploration
+Some people's work schedules use Mars time. Jet Propulsion Laboratory
+(JPL) coordinators have kept Mars time on and off at least since 1997
+for the Mars Pathfinder mission. Some of their family members have
+also adapted to Mars time. Dozens of special Mars watches were built
+for JPL workers who kept Mars time during the Mars Exploration
Rovers mission (2004). These timepieces look like normal Seikos and
Citizens but use Mars seconds rather than terrestrial seconds.
@@ -587,7 +776,21 @@
Michael Allison and Robert Schmunk,
"Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock"
-<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2004-07-30).
+<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2012-08-08).
Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times
+<http://articles.latimes.com/2004/jan/14/science/sci-marstime14>
(2004-01-14), pp A1, A20-A21.
+
+Tom Chmielewski, "Jet Lag Is Worse on Mars", The Atlantic (2015-02-26)
+<http://www.theatlantic.com/technology/archive/2015/02/jet-lag-is-worse-on-mars/386033/>
+
+-----
+
+This file is in the public domain, so clarified as of 2009-05-17 by
+Arthur David Olson.
+
+-----
+Local Variables:
+coding: utf-8
+End:
Modified: vendor/tzcode/dist/asctime.c
===================================================================
--- vendor/tzcode/dist/asctime.c 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/asctime.c 2016-08-15 01:50:22 UTC (rev 7736)
@@ -55,7 +55,7 @@
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
** (two three-character abbreviations, five strings denoting integers,
** seven explicit spaces, two explicit colons, a newline,
-** and a trailing ASCII nul).
+** and a trailing NUL byte).
** The values above are for systems where an int is 32 bits and are provided
** as an example; the define below calculates the maximum for the system at
** hand.
@@ -99,11 +99,11 @@
** Assume that strftime is unaffected by other out-of-range members
** (e.g., timeptr->tm_mday) when processing "%Y".
*/
- (void) strftime(year, sizeof year, "%Y", timeptr);
+ strftime(year, sizeof year, "%Y", timeptr);
/*
** We avoid using snprintf since it's not available on all systems.
*/
- (void) sprintf(result,
+ sprintf(result,
((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
wn, mn,
timeptr->tm_mday, timeptr->tm_hour,
@@ -112,11 +112,7 @@
if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
return strcpy(buf, result);
else {
-#ifdef EOVERFLOW
errno = EOVERFLOW;
-#else /* !defined EOVERFLOW */
- errno = EINVAL;
-#endif /* !defined EOVERFLOW */
return NULL;
}
}
Modified: vendor/tzcode/dist/date.1
===================================================================
--- vendor/tzcode/dist/date.1 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/date.1 2016-08-15 01:50:22 UTC (rev 7736)
@@ -4,27 +4,29 @@
.SH SYNOPSIS
.if n .nh
.if n .na
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
.B date
[
-.B \-u
+.B \*-u
] [
-.B \-c
+.B \*-c
] [
-.B \-n
+.B \*-r
+.I seconds
] [
-.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
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
.I Date
without arguments writes the date and time to the standard output in
the form
@@ -39,13 +41,13 @@
environment variable if set).
The exact output format depends on the locale.
.PP
-If a command-line argument starts with a plus sign
-.RB (` + '),
+If a command-line argument starts with a plus sign (\c
+.q "\fB+\fP" ),
the rest of the argument is used as a
.I format
that controls what appears in the output.
-In the format, when a percent sign
-.RB (` % ')
+In the format, when a percent sign (\c
+.q "\fB%\fP"
appears,
it and the character after it are not output,
but rather identify part of the date or time
@@ -103,7 +105,8 @@
.PP
In Sunday-based week numbering,
the first Sunday of the year begins week 1;
-days preceding it are part of ``week 0.''
+days preceding it are part of
+.q "week 0" .
In Monday-based week numbering,
the first Monday of the year begins week 1.
.PP
@@ -130,31 +133,16 @@
.PP
These options are available:
.TP
-.BR \-u " or " \-c
-Use UTC when setting and showing the date and time.
+.BR \*-u " or " \*-c
+Use Universal Time 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 UTC'' 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.
+.BI "\*-r " seconds
+Output the date that corresponds to
+.I seconds
+past the epoch of 1970-01-01 00:00:00 UTC, where
+.I seconds
+should be an integer, either decimal, octal (leading 0), or
+hexadecimal (leading 0x), preceded by an optional sign.
.SH FILES
.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u
/usr/lib/locale/\f2L\fP/LC_TIME description of time locale \f2L\fP
Modified: vendor/tzcode/dist/date.1.txt
===================================================================
--- vendor/tzcode/dist/date.1.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/date.1.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,11 +1,11 @@
-DATE(1) DATE(1)
+DATE(1) General Commands Manual DATE(1)
NAME
date - show and set date and time
SYNOPSIS
- date [ -u ] [ -c ] [ -n ] [ -d dsttype ] [ -t minutes-west ] [ -a
- [+|-]sss.fff ] [ +format ] [ [yyyy]mmddhhmm[yy][.ss] ]
+ date [ -u ] [ -c ] [ -r seconds ] [ +format ] [ [yyyy]mmddhhmm[yy][.ss]
+ ]
DESCRIPTION
Date without arguments writes the date and time to the standard output
@@ -15,9 +15,9 @@
abbreviation for the time zone specified in the TZ environment variable
if set). The exact output format depends on the locale.
- If a command-line argument starts with a plus sign (`+'), the rest of
+ If a command-line argument starts with a plus sign ("+"), the rest of
the argument is used as a format that controls what appears in the
- output. In the format, when a percent sign (`%') appears, it and the
+ output. In the format, when a percent sign ("%" 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):
@@ -64,7 +64,7 @@
newline character is always added at the end of the output.
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
+ week 1; days preceding it are part of "week 0". In Monday-based week
numbering, the first Monday of the year begins week 1.
To set the date, use a command line argument with one of the following
@@ -85,29 +85,14 @@
These options are available:
-u or -c
- Use UTC when setting and showing the date and time.
+ Use Universal Time when setting and showing the date and time.
- -n Do not notify other networked systems of the time change.
+ -r seconds
+ Output the date that corresponds to seconds past the epoch of
+ 1970-01-01 00:00:00 UTC, where seconds should be an integer,
+ either decimal, octal (leading 0), or hexadecimal (leading 0x),
+ preceded by an optional sign.
- -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.)
-
- -t minutes-west
- Set the kernel-stored ``minutes west of UTC'' value to the one
- given on the command line. (The kernel-stored DST type is used
- mostly by ``old'' binaries.)
-
- -a adjustment
- Change the time forward (or backward) by the number of seconds
- (and fractions thereof) specified in the 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.
-
FILES
/usr/lib/locale/L/LC_TIME description of time locale L
/usr/local/etc/zoneinfo time zone information directory
Modified: vendor/tzcode/dist/date.c
===================================================================
--- vendor/tzcode/dist/date.c 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/date.c 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,47 +1,35 @@
-/*
- * 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.
- */
+/* Display or set the current time and date. */
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1985, 1987, 1988 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
+/* Copyright 1985, 1987, 1988 The Regents of the University of California.
+ All rights reserved.
-#ifndef lint
-static char sccsid[] = "@(#)date.c 4.23 (Berkeley) 9/20/88";
-#endif /* not lint */
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE. */
+
#include "private.h"
-#if HAVE_ADJTIME || HAVE_SETTIMEOFDAY
-#include "sys/time.h" /* for struct timeval, struct timezone */
-#endif /* HAVE_ADJTIME || HAVE_SETTIMEOFDAY */
#include "locale.h"
-#include "utmp.h" /* for OLD_TIME (or its absence) */
-#if HAVE_UTMPX_H
-#include "utmpx.h"
-#endif
-#ifndef OTIME_MSG
-#define OTIME_MSG "old time"
-#endif
-#ifndef NTIME_MSG
-#define NTIME_MSG "new time"
-#endif
-
/*
** The two things date knows about time are. . .
*/
@@ -54,128 +42,71 @@
#define SECSPERMIN 60
#endif /* !defined SECSPERMIN */
-extern double atof();
+#if !HAVE_POSIX_DECLS
extern char ** environ;
-extern char * getlogin();
-extern time_t mktime();
extern char * optarg;
extern int optind;
-extern char * strchr();
-extern time_t time();
-extern char * tzname[2];
+extern char * tzname[];
+#endif
static int retval = EXIT_SUCCESS;
-static void checkfinal(const char *, int, time_t, time_t);
-static time_t convert(const char *, int, time_t);
-static void display(const char *);
+static void display(const char *, time_t);
static void dogmt(void);
static void errensure(void);
-static void iffy(time_t, time_t, const char *, const char *);
-int main(int, char**);
-static const char * nondigit(const char *);
-static void oops(const char *);
-static void reset(time_t, int);
-static int sametm(const struct tm *, const struct tm *);
static void timeout(FILE *, const char *, const struct tm *);
static void usage(void);
-static void wildinput(const char *, const char *,
- const char *);
int
main(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 double adjust;
- time_t now;
+ register bool rflag = false;
time_t t;
+ intmax_t secs;
+ char * endarg;
- INITIALIZE(dousg);
- INITIALIZE(minuteswest);
- INITIALIZE(dsttime);
- INITIALIZE(adjust);
- INITIALIZE(t);
#ifdef LC_ALL
- (void) setlocale(LC_ALL, "");
+ setlocale(LC_ALL, "");
#endif /* defined(LC_ALL) */
#if HAVE_GETTEXT
#ifdef TZ_DOMAINDIR
- (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
+ bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined(TEXTDOMAINDIR) */
- (void) textdomain(TZ_DOMAIN);
+ textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT */
- (void) time(&now);
- format = value = NULL;
- while ((ch = getopt(argc, argv, "ucnd:t:a:")) != EOF && ch != -1) {
+ t = time(NULL);
+ format = NULL;
+ while ((ch = getopt(argc, argv, "ucr:")) != EOF && ch != -1) {
switch (ch) {
default:
usage();
- case 'u': /* do it in UTC */
+ case 'u': /* do it in UT */
case 'c':
dogmt();
break;
- case 'n': /* don't set network */
- nflag = 1;
- break;
- case 'd': /* daylight saving time */
- if (dflag) {
- (void) fprintf(stderr,
- _("date: error: multiple -d's used"));
+ case 'r': /* seconds since 1970 */
+ if (rflag) {
+ fprintf(stderr,
+ _("date: error: multiple -r'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 UTC */
- if (tflag) {
- (void) fprintf(stderr,
- _("date: error: multiple -t's used"));
- usage();
+ rflag = true;
+ errno = 0;
+ secs = strtoimax (optarg, &endarg, 0);
+ if (*endarg || optarg == endarg)
+ errno = EINVAL;
+ else if (! (time_t_min <= secs && secs <= time_t_max))
+ errno = ERANGE;
+ if (errno) {
+ perror(optarg);
+ errensure();
+ exit(retval);
}
- 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"));
+ t = secs;
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) {
@@ -184,119 +115,18 @@
if (format == NULL)
format = cp + 1;
else {
- (void) fprintf(stderr,
+ 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=America/New_York date 8712312359.60
- ** doesn't get misdiagnosed. (It was
- ** TZ=America/New_York date 8712311859.60
- ** when the leap second was inserted.)
- ** The normal check won't work since
- ** the given time is valid in UTC.
- */
- 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"));
+ else {
+ fprintf(stderr, _("date: unknown operand: %s\n"), cp);
+ usage();
}
}
- /*
- ** Entire command line has now been checked.
- */
- if (aflag) {
-#if HAVE_ADJTIME
- struct timeval tv;
- tv.tv_sec = (int) adjust;
- tv.tv_usec = (int) ((adjust - tv.tv_sec) * 1000000L);
- if (adjtime(&tv, NULL) != 0)
- oops("adjtime");
-#endif /* HAVE_ADJTIME */
-#if !HAVE_ADJTIME
- reset(now + adjust, nflag);
-#endif /* !HAVE_ADJTIME */
- /*
- ** Sun silently ignores everything else; we follow suit.
- */
- exit(retval);
- }
- if (dflag || tflag) {
-#if HAVE_SETTIMEOFDAY == 2
- struct timezone tz;
-
- if (!dflag || !tflag)
- if (gettimeofday(NULL, &tz) != 0)
- oops("gettimeofday");
- if (dflag)
- tz.tz_dsttime = dsttime;
- if (tflag)
- tz.tz_minuteswest = minuteswest;
- if (settimeofday(NULL, &tz) != 0)
- oops("settimeofday");
-#endif /* HAVE_SETTIMEOFDAY == 2 */
-#if HAVE_SETTIMEOFDAY != 2
- (void) fprintf(stderr,
-_("date: warning: kernel doesn't keep -d/-t information, option ignored\n"));
-#endif /* HAVE_SETTIMEOFDAY != 2 */
- }
-
- 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);
- exit(retval);
- }
-#endif /* defined EBUG */
-
- display(format);
-
- /* gcc -Wall pacifier */
- for ( ; ; )
- continue;
+ display(format, t);
+ return retval;
}
static void
@@ -314,7 +144,7 @@
continue;
fakeenv = malloc((n + 2) * sizeof *fakeenv);
if (fakeenv == NULL) {
- (void) perror(_("Memory exhausted"));
+ perror(_("Memory exhausted"));
errensure();
exit(retval);
}
@@ -328,166 +158,7 @@
}
}
-#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(const time_t newt, const int nflag)
-{
- register int fid;
- time_t oldt;
- static struct {
- struct utmp before;
- struct utmp after;
- } s;
-#if HAVE_UTMPX_H
- static struct {
- struct utmpx before;
- struct utmpx after;
- } sx;
-#endif
-
- /*
- ** Wouldn't it be great if stime returned the old time?
- */
- (void) time(&oldt);
- if (stime(&newt) != 0)
- oops("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(_("log file open"));
- if (write(fid, (char *) &s, sizeof s) != sizeof s)
- oops(_("log file write"));
- if (close(fid) != 0)
- oops(_("log file close"));
-#if !HAVE_UTMPX_H
- pututline(&s.before);
- pututline(&s.after);
-#endif /* !HAVE_UTMPX_H */
-#if HAVE_UTMPX_H
- sx.before.ut_type = OLD_TIME;
- sx.before.ut_tv.tv_sec = oldt;
- (void) strcpy(sx.before.ut_line, OTIME_MSG);
- sx.after.ut_type = NEW_TIME;
- sx.after.ut_tv.tv_sec = newt;
- (void) strcpy(sx.after.ut_line, NTIME_MSG);
-#if !SUPPRESS_WTMPX_FILE_UPDATE
- /* In Solaris 2.5 (and presumably other systems),
- `date' does not update /var/adm/wtmpx.
- This must be a bug. If you'd like to reproduce the bug,
- define SUPPRESS_WTMPX_FILE_UPDATE to be nonzero. */
- fid = open(WTMPX_FILE, O_WRONLY | O_APPEND);
- if (fid < 0)
- oops(_("log file open"));
- if (write(fid, (char *) &sx, sizeof sx) != sizeof sx)
- oops(_("log file write"));
- if (close(fid) != 0)
- oops(_("log file close"));
-#endif /* !SUPPRESS_WTMPX_FILE_UPDATE */
- pututxline(&sx.before);
- pututxline(&sx.after);
-#endif /* HAVE_UTMPX_H */
-}
-
-#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"
-
-extern int logwtmp();
-
-#if HAVE_SETTIMEOFDAY == 1
-#define settimeofday(t, tz) (settimeofday)(t)
-#endif /* HAVE_SETTIMEOFDAY == 1 */
-
-#ifdef TSP_SETDATE
-static int netsettime(struct timeval);
-#endif
-
-#ifndef TSP_SETDATE
-/*ARGSUSED*/
-#endif /* !defined TSP_SETDATE */
-static void
-reset(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, NULL) == 0) {
- logwtmp("{", TIME_NAME, ""); /* } */
- syslog(LOG_AUTH | LOG_NOTICE, _("date set by %s"),
- username);
- } else oops("settimeofday");
- }
-}
-
-#endif /* !defined OLD_TIME */
-
-static void
-wildinput(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(void)
{
if (retval == EXIT_SUCCESS)
@@ -494,73 +165,63 @@
retval = EXIT_FAILURE;
}
-static const char *
-nondigit(register const char *cp)
-{
- while (is_digit(*cp))
- ++cp;
- return cp;
-}
-
static void
usage(void)
{
- (void) fprintf(stderr, _("date: usage is date [-u] [-c] [-n] [-d dst] \
-[-t min-west] [-a sss.fff] [[yyyy]mmddhhmm[yyyy][.ss]] [+format]\n"));
+ fprintf(stderr,
+ _("date: usage: date [-u] [-c] [-r seconds]"
+ " [+format]\n"));
errensure();
exit(retval);
}
static void
-oops(const char *const string)
+display(char const *format, time_t now)
{
- int e = errno;
+ struct tm *tmp;
- (void) fprintf(stderr, _("date: error: "));
- errno = e;
- (void) perror(string);
- errensure();
- display(NULL);
-}
-
-static void
-display(const char *const format)
-{
- struct tm tm;
- time_t now;
-
- (void) time(&now);
- tm = *localtime(&now);
- timeout(stdout, format ? format : "%+", &tm);
- (void) putchar('\n');
- (void) fflush(stdout);
- (void) fflush(stderr);
+ tmp = localtime(&now);
+ if (!tmp) {
+ fprintf(stderr,
+ _("date: error: time out of range\n"));
+ errensure();
+ return;
+ }
+ timeout(stdout, format ? format : "%+", tmp);
+ putchar('\n');
+ fflush(stdout);
+ fflush(stderr);
if (ferror(stdout) || ferror(stderr)) {
- (void) fprintf(stderr,
+ fprintf(stderr,
_("date: error: couldn't write results\n"));
errensure();
}
- exit(retval);
}
-extern size_t strftime();
-
#define INCR 1024
static void
-timeout(FILE *const fp, const char *const format, const struct tm *const tmp)
+timeout(FILE *fp, char const *format, struct tm const *tmp)
{
char * cp;
size_t result;
size_t size;
+ struct tm tm;
if (*format == '\0')
return;
+ if (!tmp) {
+ fprintf(stderr, _("date: error: time out of range\n"));
+ errensure();
+ return;
+ }
+ tm = *tmp;
+ tmp = &tm;
size = INCR;
cp = malloc(size);
for ( ; ; ) {
if (cp == NULL) {
- (void) fprintf(stderr,
+ fprintf(stderr,
_("date: error: can't get memory\n"));
errensure();
exit(retval);
@@ -572,353 +233,6 @@
size += INCR;
cp = realloc(cp, size);
}
- (void) fwrite(cp, 1, result, fp);
+ fwrite(cp, 1, result, fp);
free(cp);
}
-
-static int
-sametm(register const struct tm *const atmp,
- register const struct tm *const btmp)
-{
- return atmp->tm_year == btmp->tm_year &&
- atmp->tm_mon == btmp->tm_mon &&
- atmp->tm_mday == btmp->tm_mday &&
- atmp->tm_hour == btmp->tm_hour &&
- atmp->tm_min == btmp->tm_min &&
- atmp->tm_sec == btmp->tm_sec;
-}
-
-/*
-** 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(register const char * const value, const int dousg, const time_t t)
-{
- register const char * cp;
- register const char * dotp;
- register int cent, year_in_cent, month, hour, day, mins, secs;
- struct tm tm, outtm;
- time_t outt;
-
- tm = *localtime(&t);
-#define DIVISOR 100
- year_in_cent = tm.tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
- cent = tm.tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
- year_in_cent / DIVISOR;
- year_in_cent %= DIVISOR;
- if (year_in_cent < 0) {
- year_in_cent += DIVISOR;
- --cent;
- }
- 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 (!is_digit(*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 sametm(&tm, &outtm) ? 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(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 &&
- sametm(&tm, &othertm))
- 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 (sametm(&tm, &othertm))
- iffy(t, othert, value,
- _("multiple matching times exist"));
- }
-}
-
-static void
-iffy(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);
- /*
- ** Avoid running afoul of SCCS!
- */
- timeout(stderr, _("Time was set as if you used\n\tdate -u %m%d%H\
-%M\
-%Y.%S\n"), &tm);
- tm = *localtime(&thist);
- timeout(stderr, _("to get %c"), &tm);
- (void) fprintf(stderr, _(" (%s). Use\n"),
- tm.tm_isdst ? _("summer time") : _("standard time"));
- tm = *gmtime(&thatt);
- timeout(stderr, _("\tdate -u %m%d%H\
-%M\
-%Y.%S\n"), &tm);
- tm = *localtime(&thatt);
- timeout(stderr, _("to get %c"), &tm);
- (void) fprintf(stderr, _(" (%s).\n"),
- tm.tm_isdst ? _("summer time") : _("standard time"));
- errensure();
- exit(retval);
-}
-
-#ifdef TSP_SETDATE
-#define WAITACK 2 /* seconds */
-#define WAITDATEACK 5 /* seconds */
-
-/*
- * 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.
- */
-static int
-netsettime(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) {
- 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(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(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(0);
- msg.tsp_time.tv_sec = htonl(ntv.tv_sec);
- msg.tsp_time.tv_usec = htonl(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, NULL, NULL, &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 */
Modified: vendor/tzcode/dist/difftime.c
===================================================================
--- vendor/tzcode/dist/difftime.c 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/difftime.c 2016-08-15 01:50:22 UTC (rev 7736)
@@ -5,53 +5,54 @@
/*LINTLIBRARY*/
-#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
+#include "private.h" /* for time_t and TYPE_SIGNED */
-double
-difftime(const time_t time1, const time_t time0)
+/* Return -X as a double. Using this avoids casting to 'double'. */
+static double
+dminus(double x)
{
+ return -x;
+}
+
+double ATTRIBUTE_CONST
+difftime(time_t time1, time_t time0)
+{
/*
- ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
+ ** If double is large enough, simply convert and subtract
** (assuming that the larger type has more precision).
- ** This is the common real-world case circa 2004.
*/
- if (sizeof (double) > sizeof (time_t))
- return (double) time1 - (double) time0;
- if (!TYPE_INTEGRAL(time_t)) {
- /*
- ** time_t is floating.
- */
- return time1 - time0;
+ if (sizeof (time_t) < sizeof (double)) {
+ double t1 = time1, t0 = time0;
+ return t1 - t0;
}
- if (!TYPE_SIGNED(time_t)) {
- /*
- ** time_t is integral and unsigned.
- ** The difference of two unsigned values can't overflow
- ** if the minuend is greater than or equal to the subtrahend.
- */
- if (time1 >= time0)
- return time1 - time0;
- else return -((double) (time0 - time1));
+
+ /*
+ ** The difference of two unsigned values can't overflow
+ ** if the minuend is greater than or equal to the subtrahend.
+ */
+ if (!TYPE_SIGNED(time_t))
+ return time0 <= time1 ? time1 - time0 : dminus(time0 - time1);
+
+ /* Use uintmax_t if wide enough. */
+ if (sizeof (time_t) <= sizeof (uintmax_t)) {
+ uintmax_t t1 = time1, t0 = time0;
+ return time0 <= time1 ? t1 - t0 : dminus(t0 - t1);
}
+
/*
- ** time_t is integral and signed.
** Handle cases where both time1 and time0 have the same sign
** (meaning that their difference cannot overflow).
*/
if ((time1 < 0) == (time0 < 0))
- return time1 - time0;
+ return time1 - time0;
+
/*
- ** time1 and time0 have opposite signs.
- ** Punt if unsigned long is too narrow.
+ ** The values have opposite signs and uintmax_t is too narrow.
+ ** This suffers from double rounding; attempt to lessen that
+ ** by using long double temporaries.
*/
- if (sizeof (unsigned long) < sizeof (time_t))
- return (double) time1 - (double) time0;
- /*
- ** Stay calm...decent optimizers will eliminate the complexity below.
- */
- if (time1 >= 0 /* && time0 < 0 */)
- return (unsigned long) time1 +
- (unsigned long) (-(time0 + 1)) + 1;
- return -(double) ((unsigned long) time0 +
- (unsigned long) (-(time1 + 1)) + 1);
+ {
+ long double t1 = time1, t0 = time0;
+ return t1 - t0;
+ }
}
Modified: vendor/tzcode/dist/localtime.c
===================================================================
--- vendor/tzcode/dist/localtime.c 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/localtime.c 2016-08-15 01:50:22 UTC (rev 7736)
@@ -10,11 +10,30 @@
/*LINTLIBRARY*/
+#define LOCALTIME_IMPLEMENTATION
#include "private.h"
+
#include "tzfile.h"
#include "fcntl.h"
-#include "float.h" /* for FLT_MAX and DBL_MAX */
+#if THREAD_SAFE
+# include <pthread.h>
+static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER;
+static int lock(void) { return pthread_mutex_lock(&locallock); }
+static void unlock(void) { pthread_mutex_unlock(&locallock); }
+#else
+static int lock(void) { return 0; }
+static void unlock(void) { }
+#endif
+
+/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
+ NETBSD_INSPIRED is defined, and are private otherwise. */
+#if NETBSD_INSPIRED
+# define NETBSD_INSPIRED_EXTERN
+#else
+# define NETBSD_INSPIRED_EXTERN static
+#endif
+
#ifndef TZ_ABBR_MAX_LEN
#define TZ_ABBR_MAX_LEN 16
#endif /* !defined TZ_ABBR_MAX_LEN */
@@ -62,7 +81,7 @@
#define WILDABBR " "
#endif /* !defined WILDABBR */
-static char wildabbr[] = WILDABBR;
+static const char wildabbr[] = WILDABBR;
static const char gmt[] = "GMT";
@@ -78,18 +97,19 @@
#endif /* !defined TZDEFDST */
struct ttinfo { /* time type information */
- long tt_gmtoff; /* UTC offset in seconds */
- int tt_isdst; /* used to set tm_isdst */
+ int_fast32_t tt_gmtoff; /* UT offset in seconds */
+ bool tt_isdst; /* used to set tm_isdst */
int tt_abbrind; /* abbreviation list index */
- int tt_ttisstd; /* TRUE if transition is std time */
- int tt_ttisgmt; /* TRUE if transition is UTC */
+ bool tt_ttisstd; /* transition is std time */
+ bool tt_ttisgmt; /* transition is UT */
};
struct lsinfo { /* leap second information */
time_t ls_trans; /* transition time */
- long ls_corr; /* correction to apply */
+ int_fast64_t ls_corr; /* correction to apply */
};
+#define SMALLEST(a, b) (((a) < (b)) ? (a) : (b))
#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
#ifdef TZNAME_MAX
@@ -104,8 +124,8 @@
int timecnt;
int typecnt;
int charcnt;
- int goback;
- int goahead;
+ bool goback;
+ bool goahead;
time_t ats[TZ_MAX_TIMES];
unsigned char types[TZ_MAX_TIMES];
struct ttinfo ttis[TZ_MAX_TYPES];
@@ -112,73 +132,33 @@
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
(2 * (MY_TZNAME_MAX + 1)))];
struct lsinfo lsis[TZ_MAX_LEAPS];
+ int defaulttype; /* for early times or if no transitions */
};
+enum r_type {
+ JULIAN_DAY, /* Jn = Julian day */
+ DAY_OF_YEAR, /* n = day of year */
+ MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
+};
+
struct rule {
- int r_type; /* type of rule--see below */
+ enum r_type r_type; /* type of rule */
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 */
+ int_fast32_t 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 */
+static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t,
+ struct tm *);
+static bool increment_overflow(int *, int);
+static bool increment_overflow_time(time_t *, int_fast32_t);
+static bool normalize_overflow32(int_fast32_t *, int *, int);
+static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
+ struct tm *);
+static bool typesequiv(struct state const *, int, int);
+static bool tzparse(char const *, struct state *, bool);
-/*
-** Prototypes for static functions.
-*/
-
-static long detzcode(const char * codep);
-static time_t detzcode64(const char * codep);
-static int differ_by_repeat(time_t t1, time_t t0);
-static const char * getzname(const char * strp) ATTRIBUTE_PURE;
-static const char * getqzname(const char * strp, const int delim)
- ATTRIBUTE_PURE;
-static const char * getnum(const char * strp, int * nump, int min,
- int max);
-static const char * getsecs(const char * strp, long * secsp);
-static const char * getoffset(const char * strp, long * offsetp);
-static const char * getrule(const char * strp, struct rule * rulep);
-static void gmtload(struct state * sp);
-static struct tm * gmtsub(const time_t * timep, long offset,
- struct tm * tmp);
-static struct tm * localsub(const time_t * timep, long offset,
- struct tm * tmp);
-static int increment_overflow(int * number, int delta);
-static int leaps_thru_end_of(int y) ATTRIBUTE_PURE;
-static int long_increment_overflow(long * number, int delta);
-static int long_normalize_overflow(long * tensptr,
- int * unitsptr, int base);
-static int normalize_overflow(int * tensptr, int * unitsptr,
- int base);
-static void settzname(void);
-static time_t time1(struct tm * tmp,
- struct tm * (*funcp)(const time_t *,
- long, struct tm *),
- long offset);
-static time_t time2(struct tm *tmp,
- struct tm * (*funcp)(const time_t *,
- long, struct tm*),
- long offset, int * okayp);
-static time_t time2sub(struct tm *tmp,
- struct tm * (*funcp)(const time_t *,
- long, struct tm*),
- long offset, int * okayp, int do_norm_secs);
-static struct tm * timesub(const time_t * timep, long offset,
- const struct state * sp, struct tm * tmp);
-static int tmcomp(const struct tm * atmp,
- const struct tm * btmp);
-static time_t transtime(time_t janfirst, int year,
- const struct rule * rulep, long offset)
- ATTRIBUTE_PURE;
-static int typesequiv(const struct state * sp, int a, int b);
-static int tzload(const char * name, struct state * sp,
- int doextend);
-static int tzparse(const char * name, struct state * sp,
- int lastditch);
-
#ifdef ALL_STATE
static struct state * lclptr;
static struct state * gmtptr;
@@ -197,13 +177,7 @@
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,
@@ -214,47 +188,99 @@
static struct tm tm;
-#ifdef USG_COMPAT
-time_t timezone = 0;
-int daylight = 0;
-#endif /* defined USG_COMPAT */
+#if !HAVE_POSIX_DECLS
+char * tzname[2] = {
+ (char *) wildabbr,
+ (char *) wildabbr
+};
+# ifdef USG_COMPAT
+long timezone;
+int daylight;
+# endif
+#endif
#ifdef ALTZONE
-time_t altzone = 0;
+long altzone;
#endif /* defined ALTZONE */
-static long
+/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
+static void
+init_ttinfo(struct ttinfo *s, int_fast32_t gmtoff, bool isdst, int abbrind)
+{
+ s->tt_gmtoff = gmtoff;
+ s->tt_isdst = isdst;
+ s->tt_abbrind = abbrind;
+ s->tt_ttisstd = false;
+ s->tt_ttisgmt = false;
+}
+
+static int_fast32_t
detzcode(const char *const codep)
{
- register long result;
- register int i;
+ register int_fast32_t result;
+ register int i;
+ int_fast32_t one = 1;
+ int_fast32_t halfmaxval = one << (32 - 2);
+ int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
+ int_fast32_t minval = -1 - maxval;
- result = (codep[0] & 0x80) ? ~0L : 0;
- for (i = 0; i < 4; ++i)
+ result = codep[0] & 0x7f;
+ for (i = 1; i < 4; ++i)
result = (result << 8) | (codep[i] & 0xff);
+
+ if (codep[0] & 0x80) {
+ /* Do two's-complement negation even on non-two's-complement machines.
+ If the result would be minval - 1, return minval. */
+ result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
+ result += minval;
+ }
return result;
}
-static time_t
+static int_fast64_t
detzcode64(const char *const codep)
{
- register time_t result;
+ register uint_fast64_t result;
register int i;
+ int_fast64_t one = 1;
+ int_fast64_t halfmaxval = one << (64 - 2);
+ int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
+ int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
- result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0;
- for (i = 0; i < 8; ++i)
- result = result * 256 + (codep[i] & 0xff);
+ result = codep[0] & 0x7f;
+ for (i = 1; i < 8; ++i)
+ result = (result << 8) | (codep[i] & 0xff);
+
+ if (codep[0] & 0x80) {
+ /* Do two's-complement negation even on non-two's-complement machines.
+ If the result would be minval - 1, return minval. */
+ result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
+ result += minval;
+ }
return result;
}
static void
+update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
+{
+ tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
+#ifdef USG_COMPAT
+ if (!ttisp->tt_isdst)
+ timezone = - ttisp->tt_gmtoff;
+#endif
+#ifdef ALTZONE
+ if (ttisp->tt_isdst)
+ altzone = - ttisp->tt_gmtoff;
+#endif
+}
+
+static void
settzname(void)
{
register struct state * const sp = lclptr;
register int i;
- tzname[0] = wildabbr;
- tzname[1] = wildabbr;
+ tzname[0] = tzname[1] = (char *) wildabbr;
#ifdef USG_COMPAT
daylight = 0;
timezone = 0;
@@ -262,35 +288,34 @@
#ifdef ALTZONE
altzone = 0;
#endif /* defined ALTZONE */
-#ifdef ALL_STATE
if (sp == NULL) {
- tzname[0] = tzname[1] = gmt;
+ tzname[0] = tzname[1] = (char *) gmt;
return;
}
-#endif /* defined ALL_STATE */
/*
** And to get the latest zone names into tzname. . .
*/
+ for (i = 0; i < sp->typecnt; ++i) {
+ register const struct ttinfo * const ttisp = &sp->ttis[i];
+ update_tzname_etc(sp, ttisp);
+ }
for (i = 0; i < sp->timecnt; ++i) {
register const struct ttinfo * const ttisp =
&sp->ttis[
sp->types[i]];
-
- tzname[ttisp->tt_isdst] =
- &sp->chars[ttisp->tt_abbrind];
+ update_tzname_etc(sp, ttisp);
#ifdef USG_COMPAT
if (ttisp->tt_isdst)
daylight = 1;
- if (!ttisp->tt_isdst)
- timezone = -(ttisp->tt_gmtoff);
#endif /* defined USG_COMPAT */
-#ifdef ALTZONE
- if (ttisp->tt_isdst)
- altzone = -(ttisp->tt_gmtoff);
-#endif /* defined ALTZONE */
}
+}
+
+static void
+scrub_abbrs(struct state *sp)
+{
+ int i;
/*
- ** Finally, scrub the abbreviations.
** First, replace bogus characters.
*/
for (i = 0; i < sp->charcnt; ++i)
@@ -309,156 +334,208 @@
}
}
-static int
+static bool
differ_by_repeat(const time_t t1, const time_t t0)
{
- if (TYPE_INTEGRAL(time_t) &&
- TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
- return 0;
+ if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
+ return 0;
return t1 - t0 == SECSPERREPEAT;
}
+/* Input buffer for data read from a compiled tz file. */
+union input_buffer {
+ /* The first part of the buffer, interpreted as a header. */
+ struct tzhead tzhead;
+
+ /* The entire buffer. */
+ char buf[2 * sizeof(struct tzhead) + 2 * sizeof (struct state)
+ + 4 * TZ_MAX_TIMES];
+};
+
+/* Local storage needed for 'tzloadbody'. */
+union local_storage {
+ /* The file name to be opened. */
+ char fullname[FILENAME_MAX + 1];
+
+ /* The results of analyzing the file's contents after it is opened. */
+ struct {
+ /* The input buffer. */
+ union input_buffer u;
+
+ /* A temporary state used for parsing a TZ string in the file. */
+ struct state st;
+ } u;
+};
+
+/* Load tz data from the file named NAME into *SP. Read extended
+ format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
+ success, an errno value on failure. */
static int
-tzload(register const char *name, register struct state *const sp,
- register const int doextend)
+tzloadbody(char const *name, struct state *sp, bool doextend,
+ union local_storage *lsp)
{
- register const char * p;
register int i;
register int fid;
register int stored;
- register int nread;
- typedef union {
- struct tzhead tzhead;
- char buf[2 * sizeof(struct tzhead) +
- 2 * sizeof *sp +
- 4 * TZ_MAX_TIMES];
- } u_t;
-#ifdef ALL_STATE
- register u_t * up;
+ register ssize_t nread;
+ register bool doaccess;
+ register char *fullname = lsp->fullname;
+ register union input_buffer *up = &lsp->u.u;
+ register int tzheadsize = sizeof (struct tzhead);
- up = (u_t *) calloc(1, sizeof *up);
- if (up == NULL)
- return -1;
-#else /* !defined ALL_STATE */
- u_t u;
- register u_t * const up = &u;
-#endif /* !defined ALL_STATE */
+ sp->goback = sp->goahead = false;
- sp->goback = sp->goahead = FALSE;
- if (name == NULL && (name = TZDEFAULT) == NULL)
- goto oops;
- {
- register int doaccess;
- /*
- ** Section 4.9.1 of the C standard says that
- ** "FILENAME_MAX expands to an integral constant expression
- ** that is the size needed for an array of char large enough
- ** to hold the longest file name string that the implementation
- ** guarantees can be opened."
- */
- char fullname[FILENAME_MAX + 1];
+ if (! name) {
+ name = TZDEFAULT;
+ if (! name)
+ return EINVAL;
+ }
- if (name[0] == ':')
- ++name;
- doaccess = name[0] == '/';
- if (!doaccess) {
- if ((p = TZDIR) == NULL)
- goto oops;
- if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
- goto oops;
- (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, R_OK) != 0)
- goto oops;
- if ((fid = open(name, OPEN_MODE)) == -1)
- goto oops;
+ if (name[0] == ':')
+ ++name;
+ doaccess = name[0] == '/';
+ if (!doaccess) {
+ char const *p = TZDIR;
+ if (! p)
+ return EINVAL;
+ if (sizeof lsp->fullname - 1 <= strlen(p) + strlen(name))
+ return ENAMETOOLONG;
+ strcpy(fullname, p);
+ strcat(fullname, "/");
+ strcat(fullname, name);
+ /* Set doaccess if '.' (as in "../") shows up in name. */
+ if (strchr(name, '.'))
+ doaccess = true;
+ name = fullname;
}
+ if (doaccess && access(name, R_OK) != 0)
+ return errno;
+ fid = open(name, OPEN_MODE);
+ if (fid < 0)
+ return errno;
+
nread = read(fid, up->buf, sizeof up->buf);
- if (close(fid) < 0 || nread <= 0)
- goto oops;
+ if (nread < tzheadsize) {
+ int err = nread < 0 ? errno : EINVAL;
+ close(fid);
+ return err;
+ }
+ if (close(fid) < 0)
+ return errno;
for (stored = 4; stored <= 8; stored *= 2) {
- int ttisstdcnt;
- int ttisgmtcnt;
+ int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
+ int_fast32_t ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
+ int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
+ int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
+ int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
+ int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
+ char const *p = up->buf + tzheadsize;
+ if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
+ && 0 < typecnt && typecnt < TZ_MAX_TYPES
+ && 0 <= timecnt && timecnt < TZ_MAX_TIMES
+ && 0 <= charcnt && charcnt < TZ_MAX_CHARS
+ && (ttisstdcnt == typecnt || ttisstdcnt == 0)
+ && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
+ return EINVAL;
+ if (nread
+ < (tzheadsize /* struct tzhead */
+ + timecnt * stored /* ats */
+ + timecnt /* types */
+ + typecnt * 6 /* ttinfos */
+ + charcnt /* chars */
+ + leapcnt * (stored + 4) /* lsinfos */
+ + ttisstdcnt /* ttisstds */
+ + ttisgmtcnt)) /* ttisgmts */
+ return EINVAL;
+ sp->leapcnt = leapcnt;
+ sp->timecnt = timecnt;
+ sp->typecnt = typecnt;
+ sp->charcnt = charcnt;
- ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt);
- ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt);
- sp->leapcnt = (int) detzcode(up->tzhead.tzh_leapcnt);
- sp->timecnt = (int) detzcode(up->tzhead.tzh_timecnt);
- sp->typecnt = (int) detzcode(up->tzhead.tzh_typecnt);
- sp->charcnt = (int) detzcode(up->tzhead.tzh_charcnt);
- p = up->tzhead.tzh_charcnt + sizeof up->tzhead.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) ||
- (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
- goto oops;
- if (nread - (p - up->buf) <
- sp->timecnt * stored + /* ats */
- sp->timecnt + /* types */
- sp->typecnt * 6 + /* ttinfos */
- sp->charcnt + /* chars */
- sp->leapcnt * (stored + 4) + /* lsinfos */
- ttisstdcnt + /* ttisstds */
- ttisgmtcnt) /* ttisgmts */
- goto oops;
+ /* Read transitions, discarding those out of time_t range.
+ But pretend the last transition before time_t_min
+ occurred at time_t_min. */
+ timecnt = 0;
for (i = 0; i < sp->timecnt; ++i) {
- sp->ats[i] = (stored == 4) ?
- detzcode(p) : detzcode64(p);
+ int_fast64_t at
+ = stored == 4 ? detzcode(p) : detzcode64(p);
+ sp->types[i] = at <= time_t_max;
+ if (sp->types[i]) {
+ time_t attime
+ = ((TYPE_SIGNED(time_t) ? at < time_t_min : at < 0)
+ ? time_t_min : at);
+ if (timecnt && attime <= sp->ats[timecnt - 1]) {
+ if (attime < sp->ats[timecnt - 1])
+ return EINVAL;
+ sp->types[i - 1] = 0;
+ timecnt--;
+ }
+ sp->ats[timecnt++] = attime;
+ }
p += stored;
}
+
+ timecnt = 0;
for (i = 0; i < sp->timecnt; ++i) {
- sp->types[i] = (unsigned char) *p++;
- if (sp->types[i] >= sp->typecnt)
- goto oops;
+ unsigned char typ = *p++;
+ if (sp->typecnt <= typ)
+ return EINVAL;
+ if (sp->types[i])
+ sp->types[timecnt++] = typ;
}
+ sp->timecnt = timecnt;
for (i = 0; i < sp->typecnt; ++i) {
register struct ttinfo * ttisp;
+ unsigned char isdst, abbrind;
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)
- goto oops;
- ttisp->tt_abbrind = (unsigned char) *p++;
- if (ttisp->tt_abbrind < 0 ||
- ttisp->tt_abbrind > sp->charcnt)
- goto oops;
+ isdst = *p++;
+ if (! (isdst < 2))
+ return EINVAL;
+ ttisp->tt_isdst = isdst;
+ abbrind = *p++;
+ if (! (abbrind < sp->charcnt))
+ return EINVAL;
+ ttisp->tt_abbrind = abbrind;
}
for (i = 0; i < sp->charcnt; ++i)
sp->chars[i] = *p++;
sp->chars[i] = '\0'; /* ensure '\0' at end */
+
+ /* Read leap seconds, discarding those out of time_t range. */
+ leapcnt = 0;
for (i = 0; i < sp->leapcnt; ++i) {
- register struct lsinfo * lsisp;
+ int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
+ int_fast32_t corr = detzcode(p + stored);
+ p += stored + 4;
+ if (tr <= time_t_max) {
+ time_t trans
+ = ((TYPE_SIGNED(time_t) ? tr < time_t_min : tr < 0)
+ ? time_t_min : tr);
+ if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans) {
+ if (trans < sp->lsis[leapcnt - 1].ls_trans)
+ return EINVAL;
+ leapcnt--;
+ }
+ sp->lsis[leapcnt].ls_trans = trans;
+ sp->lsis[leapcnt].ls_corr = corr;
+ leapcnt++;
+ }
+ }
+ sp->leapcnt = leapcnt;
- lsisp = &sp->lsis[i];
- lsisp->ls_trans = (stored == 4) ?
- detzcode(p) : detzcode64(p);
- p += stored;
- 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;
+ ttisp->tt_ttisstd = false;
else {
+ if (*p != true && *p != false)
+ return EINVAL;
ttisp->tt_ttisstd = *p++;
- if (ttisp->tt_ttisstd != TRUE &&
- ttisp->tt_ttisstd != FALSE)
- goto oops;
}
}
for (i = 0; i < sp->typecnt; ++i) {
@@ -466,88 +543,74 @@
ttisp = &sp->ttis[i];
if (ttisgmtcnt == 0)
- ttisp->tt_ttisgmt = FALSE;
+ ttisp->tt_ttisgmt = false;
else {
+ if (*p != true && *p != false)
+ return EINVAL;
ttisp->tt_ttisgmt = *p++;
- if (ttisp->tt_ttisgmt != TRUE &&
- ttisp->tt_ttisgmt != FALSE)
- goto oops;
}
}
/*
- ** Out-of-sort ats should mean we're running on a
- ** signed time_t system but using a data file with
- ** unsigned values (or vice versa).
- */
- for (i = 0; i < sp->timecnt - 2; ++i)
- if (sp->ats[i] > sp->ats[i + 1]) {
- ++i;
- if (TYPE_SIGNED(time_t)) {
- /*
- ** Ignore the end (easy).
- */
- sp->timecnt = i;
- } else {
- /*
- ** Ignore the beginning (harder).
- */
- register int j;
-
- for (j = 0; j + i < sp->timecnt; ++j) {
- sp->ats[j] = sp->ats[j + i];
- sp->types[j] = sp->types[j + i];
- }
- sp->timecnt = j;
- }
- break;
- }
- /*
** If this is an old file, we're done.
*/
if (up->tzhead.tzh_version[0] == '\0')
break;
nread -= p - up->buf;
- for (i = 0; i < nread; ++i)
- up->buf[i] = p[i];
- /*
- ** If this is a narrow integer time_t system, we're done.
- */
- if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
- break;
+ memmove(up->buf, p, nread);
}
if (doextend && nread > 2 &&
up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
sp->typecnt + 2 <= TZ_MAX_TYPES) {
- struct state ts;
- register int result;
+ struct state *ts = &lsp->u.st;
up->buf[nread - 1] = '\0';
- result = tzparse(&up->buf[1], &ts, FALSE);
- if (result == 0 && ts.typecnt == 2 &&
- sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
- for (i = 0; i < 2; ++i)
- ts.ttis[i].tt_abbrind +=
- sp->charcnt;
- for (i = 0; i < ts.charcnt; ++i)
- sp->chars[sp->charcnt++] =
- ts.chars[i];
- i = 0;
- while (i < ts.timecnt &&
- ts.ats[i] <=
- sp->ats[sp->timecnt - 1])
- ++i;
- while (i < ts.timecnt &&
- sp->timecnt < TZ_MAX_TIMES) {
- sp->ats[sp->timecnt] =
- ts.ats[i];
- sp->types[sp->timecnt] =
- sp->typecnt +
- ts.types[i];
- ++sp->timecnt;
- ++i;
- }
- sp->ttis[sp->typecnt++] = ts.ttis[0];
- sp->ttis[sp->typecnt++] = ts.ttis[1];
+ if (tzparse(&up->buf[1], ts, false)
+ && ts->typecnt == 2) {
+
+ /* Attempt to reuse existing abbreviations.
+ Without this, America/Anchorage would stop
+ working after 2037 when TZ_MAX_CHARS is 50, as
+ sp->charcnt equals 42 (for LMT CAT CAWT CAPT AHST
+ AHDT YST AKDT AKST) and ts->charcnt equals 10
+ (for AKST AKDT). Reusing means sp->charcnt can
+ stay 42 in this example. */
+ int gotabbr = 0;
+ int charcnt = sp->charcnt;
+ for (i = 0; i < 2; i++) {
+ char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
+ int j;
+ for (j = 0; j < charcnt; j++)
+ if (strcmp(sp->chars + j, tsabbr) == 0) {
+ ts->ttis[i].tt_abbrind = j;
+ gotabbr++;
+ break;
+ }
+ if (! (j < charcnt)) {
+ int tsabbrlen = strlen(tsabbr);
+ if (j + tsabbrlen < TZ_MAX_CHARS) {
+ strcpy(sp->chars + j, tsabbr);
+ charcnt = j + tsabbrlen + 1;
+ ts->ttis[i].tt_abbrind = j;
+ gotabbr++;
+ }
+ }
+ }
+ if (gotabbr == 2) {
+ sp->charcnt = charcnt;
+ for (i = 0; i < ts->timecnt; i++)
+ if (sp->ats[sp->timecnt - 1] < ts->ats[i])
+ break;
+ while (i < ts->timecnt
+ && sp->timecnt < TZ_MAX_TIMES) {
+ sp->ats[sp->timecnt] = ts->ats[i];
+ sp->types[sp->timecnt] = (sp->typecnt
+ + ts->types[i]);
+ sp->timecnt++;
+ i++;
+ }
+ sp->ttis[sp->typecnt++] = ts->ttis[0];
+ sp->ttis[sp->typecnt++] = ts->ttis[1];
+ }
}
}
if (sp->timecnt > 1) {
@@ -554,7 +617,7 @@
for (i = 1; i < sp->timecnt; ++i)
if (typesequiv(sp, sp->types[i], sp->types[0]) &&
differ_by_repeat(sp->ats[i], sp->ats[0])) {
- sp->goback = TRUE;
+ sp->goback = true;
break;
}
for (i = sp->timecnt - 2; i >= 0; --i)
@@ -562,30 +625,76 @@
sp->types[i]) &&
differ_by_repeat(sp->ats[sp->timecnt - 1],
sp->ats[i])) {
- sp->goahead = TRUE;
+ sp->goahead = true;
break;
}
}
-#ifdef ALL_STATE
- free(up);
-#endif /* defined ALL_STATE */
+ /*
+ ** If type 0 is is unused in transitions,
+ ** it's the type to use for early times.
+ */
+ for (i = 0; i < sp->timecnt; ++i)
+ if (sp->types[i] == 0)
+ break;
+ i = i < sp->timecnt ? -1 : 0;
+ /*
+ ** Absent the above,
+ ** if there are transition times
+ ** and the first transition is to a daylight time
+ ** find the standard type less than and closest to
+ ** the type of the first transition.
+ */
+ if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
+ i = sp->types[0];
+ while (--i >= 0)
+ if (!sp->ttis[i].tt_isdst)
+ break;
+ }
+ /*
+ ** If no result yet, find the first standard type.
+ ** If there is none, punt to type zero.
+ */
+ if (i < 0) {
+ i = 0;
+ while (sp->ttis[i].tt_isdst)
+ if (++i >= sp->typecnt) {
+ i = 0;
+ break;
+ }
+ }
+ sp->defaulttype = i;
return 0;
-oops:
-#ifdef ALL_STATE
- free(up);
-#endif /* defined ALL_STATE */
- return -1;
}
+/* Load tz data from the file named NAME into *SP. Read extended
+ format if DOEXTEND. Return 0 on success, an errno value on failure. */
static int
-typesequiv(const struct state *const sp, const int a, const int b)
+tzload(char const *name, struct state *sp, bool doextend)
{
- register int result;
+#ifdef ALL_STATE
+ union local_storage *lsp = malloc(sizeof *lsp);
+ if (!lsp)
+ return errno;
+ else {
+ int err = tzloadbody(name, sp, doextend, lsp);
+ free(lsp);
+ return err;
+ }
+#else
+ union local_storage ls;
+ return tzloadbody(name, sp, doextend, &ls);
+#endif
+}
+static bool
+typesequiv(const struct state *sp, int a, int b)
+{
+ register bool result;
+
if (sp == NULL ||
a < 0 || a >= sp->typecnt ||
b < 0 || b >= sp->typecnt)
- result = FALSE;
+ result = false;
else {
register const struct ttinfo * ap = &sp->ttis[a];
register const struct ttinfo * bp = &sp->ttis[b];
@@ -614,7 +723,7 @@
** character.
*/
-static const char *
+static const char * ATTRIBUTE_PURE
getzname(register const char *strp)
{
register char c;
@@ -634,7 +743,7 @@
** We don't do any checking here; checking is done later in common-case code.
*/
-static const char *
+static const char * ATTRIBUTE_PURE
getqzname(register const char *strp, const int delim)
{
register int c;
@@ -681,20 +790,20 @@
*/
static const char *
-getsecs(register const char *strp, long *const secsp)
+getsecs(register const char *strp, int_fast32_t *const secsp)
{
int num;
/*
- ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
+ ** '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''.
+ ** "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;
+ *secsp = num * (int_fast32_t) SECSPERHOUR;
if (*strp == ':') {
++strp;
strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
@@ -703,7 +812,7 @@
*secsp += num * SECSPERMIN;
if (*strp == ':') {
++strp;
- /* `SECSPERMIN' allows for leap seconds. */
+ /* 'SECSPERMIN' allows for leap seconds. */
strp = getnum(strp, &num, 0, SECSPERMIN);
if (strp == NULL)
return NULL;
@@ -721,12 +830,12 @@
*/
static const char *
-getoffset(register const char *strp, long *const offsetp)
+getoffset(register const char *strp, int_fast32_t *const offsetp)
{
- register int neg = 0;
+ register bool neg = false;
if (*strp == '-') {
- neg = 1;
+ neg = true;
++strp;
} else if (*strp == '+')
++strp;
@@ -786,23 +895,22 @@
** Time specified.
*/
++strp;
- strp = getsecs(strp, &rulep->r_time);
+ strp = getoffset(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 UTC, in a year, the
-** year, a rule, and the offset from UTC at the time that rule takes effect,
-** calculate the Epoch-relative time that rule takes effect.
+** Given a year, a rule, and the offset from UT at the time that rule takes
+** effect, calculate the year-relative time that rule takes effect.
*/
-static time_t
-transtime(const time_t janfirst, const int year,
- register const struct rule *const rulep, const long offset)
+static int_fast32_t ATTRIBUTE_PURE
+transtime(const int year, register const struct rule *const rulep,
+ const int_fast32_t offset)
{
- register int leapyear;
- register time_t value;
+ register bool leapyear;
+ register int_fast32_t value;
register int i;
int d, m1, yy0, yy1, yy2, dow;
@@ -818,7 +926,7 @@
** 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;
+ value = (rulep->r_day - 1) * SECSPERDAY;
if (leapyear && rulep->r_day >= 60)
value += SECSPERDAY;
break;
@@ -829,7 +937,7 @@
** Just add SECSPERDAY times the day number to the time of
** January 1, midnight, to get the day.
*/
- value = janfirst + rulep->r_day * SECSPERDAY;
+ value = rulep->r_day * SECSPERDAY;
break;
case MONTH_NTH_DAY_OF_WEEK:
@@ -836,9 +944,6 @@
/*
** 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
@@ -871,15 +976,17 @@
/*
** "d" is the day-of-month (zero-origin) of the day we want.
*/
- value += d * SECSPERDAY;
+ value = d * SECSPERDAY;
+ for (i = 0; i < rulep->r_mon - 1; ++i)
+ value += mon_lengths[leapyear][i] * SECSPERDAY;
break;
}
/*
- ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
- ** question. To get the Epoch-relative time of the specified local
+ ** "value" is the year-relative time of 00:00:00 UT on the day in
+ ** question. To get the year-relative time of the specified local
** time on that day, add the transition time and the current offset
- ** from UTC.
+ ** from UT.
*/
return value + rulep->r_time + offset;
}
@@ -889,29 +996,23 @@
** appropriate.
*/
-static int
-tzparse(const char *name, register struct state *const sp,
- const int lastditch)
+static bool
+tzparse(const char *name, struct state *sp, bool 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;
+ size_t charcnt;
+ int_fast32_t stdoffset;
+ int_fast32_t dstoffset;
register char * cp;
- register int load_result;
- static struct ttinfo zttinfo;
+ register bool load_ok;
- INITIALIZE(dstname);
stdname = name;
if (lastditch) {
- stdlen = strlen(name); /* length of standard zone name */
+ stdlen = sizeof gmt - 1;
name += stdlen;
- if (stdlen >= sizeof sp->chars)
- stdlen = (sizeof sp->chars) - 1;
stdoffset = 0;
} else {
if (*name == '<') {
@@ -919,7 +1020,7 @@
stdname = name;
name = getqzname(name, '>');
if (*name != '>')
- return (-1);
+ return false;
stdlen = name - stdname;
name++;
} else {
@@ -926,14 +1027,17 @@
name = getzname(name);
stdlen = name - stdname;
}
- if (*name == '\0')
- return -1;
+ if (!stdlen)
+ return false;
name = getoffset(name, &stdoffset);
if (name == NULL)
- return -1;
+ return false;
}
- load_result = tzload(TZDEFRULES, sp, FALSE);
- if (load_result != 0)
+ charcnt = stdlen + 1;
+ if (sizeof sp->chars < charcnt)
+ return false;
+ load_ok = tzload(TZDEFRULES, sp, false) == 0;
+ if (!load_ok)
sp->leapcnt = 0; /* so, we're off a little */
if (*name != '\0') {
if (*name == '<') {
@@ -940,7 +1044,7 @@
dstname = ++name;
name = getqzname(name, '>');
if (*name != '>')
- return -1;
+ return false;
dstlen = name - dstname;
name++;
} else {
@@ -948,83 +1052,93 @@
name = getzname(name);
dstlen = name - dstname; /* length of DST zone name */
}
+ if (!dstlen)
+ return false;
+ charcnt += dstlen + 1;
+ if (sizeof sp->chars < charcnt)
+ return false;
if (*name != '\0' && *name != ',' && *name != ';') {
name = getoffset(name, &dstoffset);
if (name == NULL)
- return -1;
+ return false;
} else dstoffset = stdoffset - SECSPERHOUR;
- if (*name == '\0' && load_result != 0)
+ if (*name == '\0' && !load_ok)
name = TZDEFRULESTRING;
if (*name == ',' || *name == ';') {
struct rule start;
struct rule end;
register int year;
- register time_t janfirst;
- time_t starttime;
- time_t endtime;
+ register int yearlim;
+ register int timecnt;
+ time_t janfirst;
++name;
if ((name = getrule(name, &start)) == NULL)
- return -1;
+ return false;
if (*name++ != ',')
- return -1;
+ return false;
if ((name = getrule(name, &end)) == NULL)
- return -1;
+ return false;
if (*name != '\0')
- return -1;
+ return false;
sp->typecnt = 2; /* standard time and DST */
/*
** Two transitions per year, from EPOCH_YEAR forward.
*/
- sp->ttis[0] = sp->ttis[1] = zttinfo;
- 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;
+ init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
+ init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
+ sp->defaulttype = 0;
+ timecnt = 0;
janfirst = 0;
- sp->timecnt = 0;
- for (year = EPOCH_YEAR;
- sp->timecnt + 2 <= TZ_MAX_TIMES;
- ++year) {
- time_t newfirst;
-
- 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 */
+ yearlim = EPOCH_YEAR + YEARSPERREPEAT;
+ for (year = EPOCH_YEAR; year < yearlim; year++) {
+ int_fast32_t
+ starttime = transtime(year, &start, stdoffset),
+ endtime = transtime(year, &end, dstoffset);
+ int_fast32_t
+ yearsecs = (year_lengths[isleap(year)]
+ * SECSPERDAY);
+ bool reversed = endtime < starttime;
+ if (reversed) {
+ int_fast32_t swap = starttime;
+ starttime = endtime;
+ endtime = swap;
}
- sp->timecnt += 2;
- newfirst = janfirst;
- newfirst += year_lengths[isleap(year)] *
- SECSPERDAY;
- if (newfirst <= janfirst)
+ if (reversed
+ || (starttime < endtime
+ && (endtime - starttime
+ < (yearsecs
+ + (stdoffset - dstoffset))))) {
+ if (TZ_MAX_TIMES - 2 < timecnt)
+ break;
+ yearlim = year + YEARSPERREPEAT + 1;
+ sp->ats[timecnt] = janfirst;
+ if (increment_overflow_time
+ (&sp->ats[timecnt], starttime))
+ break;
+ sp->types[timecnt++] = reversed;
+ sp->ats[timecnt] = janfirst;
+ if (increment_overflow_time
+ (&sp->ats[timecnt], endtime))
+ break;
+ sp->types[timecnt++] = !reversed;
+ }
+ if (increment_overflow_time(&janfirst, yearsecs))
break;
- janfirst = newfirst;
}
+ sp->timecnt = timecnt;
+ if (!timecnt)
+ sp->typecnt = 1; /* Perpetual DST. */
} else {
- register long theirstdoffset;
- register long theirdstoffset;
- register long theiroffset;
- register int isdst;
- register int i;
- register int j;
+ register int_fast32_t theirstdoffset;
+ register int_fast32_t theirdstoffset;
+ register int_fast32_t theiroffset;
+ register bool isdst;
+ register int i;
+ register int j;
if (*name != '\0')
- return -1;
+ return false;
/*
** Initial values of theirstdoffset and theirdstoffset.
*/
@@ -1049,7 +1163,7 @@
/*
** Initially we're assumed to be in standard time.
*/
- isdst = FALSE;
+ isdst = false;
theiroffset = theirstdoffset;
/*
** Now juggle transition times and types
@@ -1091,161 +1205,206 @@
/*
** Finally, fill in ttis.
*/
- sp->ttis[0] = sp->ttis[1] = zttinfo;
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = FALSE;
- sp->ttis[0].tt_abbrind = 0;
- sp->ttis[1].tt_gmtoff = -dstoffset;
- sp->ttis[1].tt_isdst = TRUE;
- sp->ttis[1].tt_abbrind = stdlen + 1;
+ init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
+ init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
sp->typecnt = 2;
+ sp->defaulttype = 0;
}
} else {
dstlen = 0;
sp->typecnt = 1; /* only standard time */
sp->timecnt = 0;
- sp->ttis[0] = zttinfo;
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = 0;
- sp->ttis[0].tt_abbrind = 0;
+ init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
+ sp->defaulttype = 0;
}
- sp->charcnt = stdlen + 1;
- if (dstlen != 0)
- sp->charcnt += dstlen + 1;
- if ((size_t) sp->charcnt > sizeof sp->chars)
- return -1;
+ sp->charcnt = charcnt;
cp = sp->chars;
- (void) strncpy(cp, stdname, stdlen);
+ memcpy(cp, stdname, stdlen);
cp += stdlen;
*cp++ = '\0';
if (dstlen != 0) {
- (void) strncpy(cp, dstname, dstlen);
+ memcpy(cp, dstname, dstlen);
*(cp + dstlen) = '\0';
}
- return 0;
+ return true;
}
static void
gmtload(struct state *const sp)
{
- if (tzload(gmt, sp, TRUE) != 0)
- (void) tzparse(gmt, sp, TRUE);
+ if (tzload(gmt, sp, true) != 0)
+ 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(void)
+/* Initialize *SP to a value appropriate for the TZ setting NAME.
+ Return 0 on success, an errno value on failure. */
+static int
+zoneinit(struct state *sp, char const *name)
{
- if (lcl_is_set < 0)
- return;
- lcl_is_set = -1;
+ if (name && ! name[0]) {
+ /*
+ ** User wants it fast rather than right.
+ */
+ sp->leapcnt = 0; /* so, we're off a little */
+ sp->timecnt = 0;
+ sp->typecnt = 0;
+ sp->charcnt = 0;
+ sp->goback = sp->goahead = false;
+ init_ttinfo(&sp->ttis[0], 0, false, 0);
+ strcpy(sp->chars, gmt);
+ sp->defaulttype = 0;
+ return 0;
+ } else {
+ int err = tzload(name, sp, true);
+ if (err != 0 && name && name[0] != ':' && tzparse(name, sp, false))
+ err = 0;
+ if (err == 0)
+ scrub_abbrs(sp);
+ return err;
+ }
+}
+static void
+tzsetlcl(char const *name)
+{
+ struct state *sp = lclptr;
+ int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
+ if (lcl < 0
+ ? lcl_is_set < 0
+ : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)
+ return;
#ifdef ALL_STATE
- if (lclptr == NULL) {
- lclptr = calloc(1, sizeof *lclptr);
- if (lclptr == NULL) {
- settzname(); /* all we can do */
- return;
- }
- }
+ if (! sp)
+ lclptr = sp = malloc(sizeof *lclptr);
#endif /* defined ALL_STATE */
- if (tzload(NULL, lclptr, TRUE) != 0)
- gmtload(lclptr);
- settzname();
+ if (sp) {
+ if (zoneinit(sp, name) != 0)
+ zoneinit(sp, "");
+ if (0 < lcl)
+ strcpy(lcl_TZname, name);
+ }
+ settzname();
+ lcl_is_set = lcl;
}
+#ifdef STD_INSPIRED
void
-tzset(void)
+tzsetwall(void)
{
- register const char * name;
+ if (lock() != 0)
+ return;
+ tzsetlcl(NULL);
+ unlock();
+}
+#endif
- name = getenv("TZ");
- if (name == NULL) {
- tzsetwall();
- return;
- }
+static void
+tzset_unlocked(void)
+{
+ tzsetlcl(getenv("TZ"));
+}
- 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);
+void
+tzset(void)
+{
+ if (lock() != 0)
+ return;
+ tzset_unlocked();
+ unlock();
+}
+static void
+gmtcheck(void)
+{
+ static bool gmt_is_set;
+ if (lock() != 0)
+ return;
+ if (! gmt_is_set) {
#ifdef ALL_STATE
- if (lclptr == NULL) {
- lclptr = calloc(1, 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->typecnt = 0;
- lclptr->ttis[0].tt_isdst = 0;
- lclptr->ttis[0].tt_gmtoff = 0;
- lclptr->ttis[0].tt_abbrind = 0;
- (void) strcpy(lclptr->chars, gmt);
- } else if (tzload(name, lclptr, TRUE) != 0)
- if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
- (void) gmtload(lclptr);
- settzname();
+ gmtptr = malloc(sizeof *gmtptr);
+#endif
+ if (gmtptr)
+ gmtload(gmtptr);
+ gmt_is_set = true;
+ }
+ unlock();
}
+#if NETBSD_INSPIRED
+
+timezone_t
+tzalloc(char const *name)
+{
+ timezone_t sp = malloc(sizeof *sp);
+ if (sp) {
+ int err = zoneinit(sp, name);
+ if (err != 0) {
+ free(sp);
+ errno = err;
+ return NULL;
+ }
+ }
+ return sp;
+}
+
+void
+tzfree(timezone_t sp)
+{
+ free(sp);
+}
+
/*
+** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
+** ctime_r are obsolescent and have potential security problems that
+** ctime_rz would share. Callers can instead use localtime_rz + strftime.
+**
+** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
+** in zones with three or more time zone abbreviations.
+** Callers can instead use localtime_rz + strftime.
+*/
+
+#endif
+
+/*
** 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--
+** 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.
+** If successful and SETNAME is nonzero,
+** set the applicable parts of tzname, timezone and altzone;
+** however, it's OK to omit this step if the time zone is POSIX-compatible,
+** since in that case tzset should have already done this step correctly.
+** SETNAME's type is intfast32_t for compatibility with gmtsub,
+** but it is actually a boolean and its value should be 0 or 1.
*/
/*ARGSUSED*/
static struct tm *
-localsub(const time_t *const timep, const long offset, struct tm *const tmp)
+localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
+ struct tm *const tmp)
{
- register struct state * sp;
register const struct ttinfo * ttisp;
register int i;
register struct tm * result;
const time_t t = *timep;
- sp = lclptr;
-#ifdef ALL_STATE
- if (sp == NULL)
- return gmtsub(timep, offset, tmp);
-#endif /* defined ALL_STATE */
+ if (sp == NULL) {
+ /* Don't bother to set tzname etc.; tzset has already done it. */
+ return gmtsub(gmtptr, timep, 0, tmp);
+ }
if ((sp->goback && t < sp->ats[0]) ||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
time_t newt = t;
register time_t seconds;
- register time_t tcycles;
- register int_fast64_t icycles;
+ register time_t years;
if (t < sp->ats[0])
seconds = sp->ats[0] - t;
else seconds = t - sp->ats[sp->timecnt - 1];
--seconds;
- tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
- ++tcycles;
- icycles = tcycles;
- if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
- return NULL;
- seconds = icycles;
- seconds *= YEARSPERREPEAT;
- seconds *= AVGSECSPERYEAR;
+ years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
+ seconds = years * AVGSECSPERYEAR;
if (t < sp->ats[0])
newt += seconds;
else newt -= seconds;
@@ -1252,27 +1411,22 @@
if (newt < sp->ats[0] ||
newt > sp->ats[sp->timecnt - 1])
return NULL; /* "cannot happen" */
- result = localsub(&newt, offset, tmp);
- if (result == tmp) {
- register time_t newy;
+ result = localsub(sp, &newt, setname, tmp);
+ if (result) {
+ register int_fast64_t newy;
- newy = tmp->tm_year;
+ newy = result->tm_year;
if (t < sp->ats[0])
- newy -= icycles * YEARSPERREPEAT;
- else newy += icycles * YEARSPERREPEAT;
- tmp->tm_year = newy;
- if (tmp->tm_year != newy)
+ newy -= years;
+ else newy += years;
+ if (! (INT_MIN <= newy && newy <= INT_MAX))
return NULL;
+ result->tm_year = newy;
}
return result;
}
if (sp->timecnt == 0 || t < sp->ats[0]) {
- i = 0;
- while (sp->ttis[i].tt_isdst)
- if (++i >= sp->typecnt) {
- i = 0;
- break;
- }
+ i = sp->defaulttype;
} else {
register int lo = 1;
register int hi = sp->timecnt;
@@ -1294,93 +1448,101 @@
** timesub(&t, 0L, sp, tmp);
*/
result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
- tmp->tm_isdst = ttisp->tt_isdst;
- tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
+ if (result) {
+ result->tm_isdst = ttisp->tt_isdst;
#ifdef TM_ZONE
- tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
+ result->TM_ZONE = (char *) &sp->chars[ttisp->tt_abbrind];
#endif /* defined TM_ZONE */
+ if (setname)
+ update_tzname_etc(sp, ttisp);
+ }
return result;
}
+#if NETBSD_INSPIRED
+
struct tm *
-localtime(const time_t *const timep)
+localtime_rz(struct state *sp, time_t const *timep, struct tm *tmp)
{
- tzset();
- return localsub(timep, 0L, &tm);
+ return localsub(sp, timep, 0, tmp);
}
-/*
-** Re-entrant version of localtime.
-*/
+#endif
+static struct tm *
+localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
+{
+ int err = lock();
+ if (err) {
+ errno = err;
+ return NULL;
+ }
+ if (setname || !lcl_is_set)
+ tzset_unlocked();
+ tmp = localsub(lclptr, timep, setname, tmp);
+ unlock();
+ return tmp;
+}
+
struct tm *
-localtime_r(const time_t *const timep, struct tm *tmp)
+localtime(const time_t *timep)
{
- return localsub(timep, 0L, tmp);
+ return localtime_tzset(timep, &tm, true);
}
+struct tm *
+localtime_r(const time_t *timep, struct tm *tmp)
+{
+ return localtime_tzset(timep, tmp, false);
+}
+
/*
** gmtsub is to gmtime as localsub is to localtime.
*/
static struct tm *
-gmtsub(const time_t *const timep, const long offset, struct tm *const tmp)
+gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
+ struct tm *tmp)
{
register struct tm * result;
- if (!gmt_is_set) {
- gmt_is_set = TRUE;
-#ifdef ALL_STATE
- gmtptr = calloc(1, sizeof *gmtptr);
- if (gmtptr != NULL)
-#endif /* defined ALL_STATE */
- gmtload(gmtptr);
- }
result = timesub(timep, offset, gmtptr, tmp);
#ifdef TM_ZONE
/*
** Could get fancy here and deliver something such as
- ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
+ ** "UT+xxxx" or "UT-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 */
- }
+ tmp->TM_ZONE = ((char *)
+ (offset ? wildabbr : gmtptr ? gmtptr->chars : gmt));
#endif /* defined TM_ZONE */
return result;
}
-struct tm *
-gmtime(const time_t *const timep)
-{
- return gmtsub(timep, 0L, &tm);
-}
-
/*
* Re-entrant version of gmtime.
*/
struct tm *
-gmtime_r(const time_t *const timep, struct tm *tmp)
+gmtime_r(const time_t *timep, struct tm *tmp)
{
- return gmtsub(timep, 0L, tmp);
+ gmtcheck();
+ return gmtsub(gmtptr, timep, 0, tmp);
}
+struct tm *
+gmtime(const time_t *timep)
+{
+ return gmtime_r(timep, &tm);
+}
+
#ifdef STD_INSPIRED
struct tm *
-offtime(const time_t *const timep, const long offset)
+offtime(const time_t *timep, long offset)
{
- return gmtsub(timep, offset, &tm);
+ gmtcheck();
+ return gmtsub(gmtptr, timep, offset, &tm);
}
#endif /* defined STD_INSPIRED */
@@ -1390,7 +1552,7 @@
** where, to make the math easy, the answer for year zero is defined as zero.
*/
-static int
+static int ATTRIBUTE_PURE
leaps_thru_end_of(register const int y)
{
return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
@@ -1398,28 +1560,22 @@
}
static struct tm *
-timesub(const time_t *const timep, const long offset,
- register const struct state *const sp,
- register struct tm *const tmp)
+timesub(const time_t *timep, int_fast32_t offset,
+ const struct state *sp, struct tm *tmp)
{
register const struct lsinfo * lp;
register time_t tdays;
register int idays; /* unsigned would be so 2003 */
- register long rem;
+ register int_fast64_t rem;
int y;
register const int * ip;
- register long corr;
- register int hit;
+ register int_fast64_t corr;
+ register bool hit;
register int i;
corr = 0;
- hit = 0;
-#ifdef ALL_STATE
+ hit = false;
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) {
@@ -1442,7 +1598,7 @@
}
y = EPOCH_YEAR;
tdays = *timep / SECSPERDAY;
- rem = *timep - tdays * SECSPERDAY;
+ rem = *timep % SECSPERDAY;
while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
int newy;
register time_t tdelta;
@@ -1450,14 +1606,15 @@
register int leapdays;
tdelta = tdays / DAYSPERLYEAR;
+ if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
+ && tdelta <= INT_MAX))
+ goto out_of_range;
idelta = tdelta;
- if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
- return NULL;
if (idelta == 0)
idelta = (tdays < 0) ? -1 : 1;
newy = y;
if (increment_overflow(&newy, idelta))
- return NULL;
+ goto out_of_range;
leapdays = leaps_thru_end_of(newy - 1) -
leaps_thru_end_of(y - 1);
tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
@@ -1464,13 +1621,6 @@
tdays -= leapdays;
y = newy;
}
- {
- register long seconds;
-
- seconds = tdays * SECSPERDAY + 0.5;
- tdays = seconds / SECSPERDAY;
- rem += seconds - tdays * SECSPERDAY;
- }
/*
** Given the range, we can now fearlessly cast...
*/
@@ -1486,17 +1636,17 @@
}
while (idays < 0) {
if (increment_overflow(&y, -1))
- return NULL;
+ goto out_of_range;
idays += year_lengths[isleap(y)];
}
while (idays >= year_lengths[isleap(y)]) {
idays -= year_lengths[isleap(y)];
if (increment_overflow(&y, 1))
- return NULL;
+ goto out_of_range;
}
tmp->tm_year = y;
if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
- return NULL;
+ goto out_of_range;
tmp->tm_yday = idays;
/*
** The "extra" mods below avoid overflow problems.
@@ -1527,10 +1677,14 @@
tmp->TM_GMTOFF = offset;
#endif /* defined TM_GMTOFF */
return tmp;
+
+ out_of_range:
+ errno = EOVERFLOW;
+ return NULL;
}
char *
-ctime(const time_t *const timep)
+ctime(const time_t *timep)
{
/*
** Section 4.12.3.2 of X3.159-1989 requires that
@@ -1538,15 +1692,16 @@
** to local time in the form of a string. It is equivalent to
** asctime(localtime(timer))
*/
- return asctime(localtime(timep));
+ struct tm *tmp = localtime(timep);
+ return tmp ? asctime(tmp) : NULL;
}
char *
-ctime_r(const time_t *const timep, char *buf)
+ctime_r(const time_t *timep, char *buf)
{
- struct tm mytm;
-
- return asctime_r(localtime_r(timep, &mytm), buf);
+ struct tm mytm;
+ struct tm *tmp = localtime_r(timep, &mytm);
+ return tmp ? asctime_r(tmp, buf) : NULL;
}
/*
@@ -1566,8 +1721,8 @@
** Normalize logic courtesy Paul Eggert.
*/
-static int
-increment_overflow(int *const ip, int j)
+static bool
+increment_overflow(int *ip, int j)
{
register int const i = *ip;
@@ -1578,23 +1733,39 @@
** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
*/
if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
- return TRUE;
+ return true;
*ip += j;
- return FALSE;
+ return false;
}
-static int
-long_increment_overflow(long *const lp, int const m)
+static bool
+increment_overflow32(int_fast32_t *const lp, int const m)
{
- register long const l = *lp;
+ register int_fast32_t const l = *lp;
- if ((l >= 0) ? (m > LONG_MAX - l) : (m < LONG_MIN - l))
- return TRUE;
+ if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
+ return true;
*lp += m;
- return FALSE;
+ return false;
}
-static int
+static bool
+increment_overflow_time(time_t *tp, int_fast32_t j)
+{
+ /*
+ ** This is like
+ ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
+ ** except that it does the right thing even if *tp + j would overflow.
+ */
+ if (! (j < 0
+ ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
+ : *tp <= time_t_max - j))
+ return true;
+ *tp += j;
+ return false;
+}
+
+static bool
normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
{
register int tensdelta;
@@ -1606,8 +1777,8 @@
return increment_overflow(tensptr, tensdelta);
}
-static int
-long_normalize_overflow(long *const tensptr, int *const unitsptr, const int base)
+static bool
+normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
{
register int tensdelta;
@@ -1615,7 +1786,7 @@
(*unitsptr / base) :
(-1 - (-1 - *unitsptr) / base);
*unitsptr -= tensdelta * base;
- return long_increment_overflow(tensptr, tensdelta);
+ return increment_overflow32(tensptr, tensdelta);
}
static int
@@ -1624,8 +1795,9 @@
{
register int result;
- if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
- (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+ if (atmp->tm_year != btmp->tm_year)
+ return atmp->tm_year < btmp->tm_year ? -1 : 1;
+ if ((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)
@@ -1635,24 +1807,25 @@
static time_t
time2sub(struct tm *const tmp,
- struct tm *(*const funcp)(const time_t *, long, struct tm *),
- const long offset,
- int *const okayp,
- const int do_norm_secs)
+ struct tm *(*funcp)(struct state const *, time_t const *,
+ int_fast32_t, struct tm *),
+ struct state const *sp,
+ const int_fast32_t offset,
+ bool *okayp,
+ bool do_norm_secs)
{
- register const struct state * sp;
register int dir;
register int i, j;
register int saved_seconds;
- register long li;
+ register int_fast32_t li;
register time_t lo;
register time_t hi;
- long y;
+ int_fast32_t y;
time_t newt;
time_t t;
struct tm yourtm, mytm;
- *okayp = FALSE;
+ *okayp = false;
yourtm = *tmp;
if (do_norm_secs) {
if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
@@ -1664,16 +1837,16 @@
if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
return WRONG;
y = yourtm.tm_year;
- if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
+ if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
return WRONG;
/*
** Turn y into an actual year number for now.
** It is converted back to an offset from TM_YEAR_BASE later.
*/
- if (long_increment_overflow(&y, TM_YEAR_BASE))
+ if (increment_overflow32(&y, TM_YEAR_BASE))
return WRONG;
while (yourtm.tm_mday <= 0) {
- if (long_increment_overflow(&y, -1))
+ if (increment_overflow32(&y, -1))
return WRONG;
li = y + (1 < yourtm.tm_mon);
yourtm.tm_mday += year_lengths[isleap(li)];
@@ -1681,7 +1854,7 @@
while (yourtm.tm_mday > DAYSPERLYEAR) {
li = y + (1 < yourtm.tm_mon);
yourtm.tm_mday -= year_lengths[isleap(li)];
- if (long_increment_overflow(&y, 1))
+ if (increment_overflow32(&y, 1))
return WRONG;
}
for ( ; ; ) {
@@ -1691,15 +1864,15 @@
yourtm.tm_mday -= i;
if (++yourtm.tm_mon >= MONSPERYEAR) {
yourtm.tm_mon = 0;
- if (long_increment_overflow(&y, 1))
+ if (increment_overflow32(&y, 1))
return WRONG;
}
}
- if (long_increment_overflow(&y, -TM_YEAR_BASE))
+ if (increment_overflow32(&y, -TM_YEAR_BASE))
return WRONG;
+ if (! (INT_MIN <= y && y <= INT_MAX))
+ return WRONG;
yourtm.tm_year = y;
- if (yourtm.tm_year != y)
- return WRONG;
if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
saved_seconds = 0;
else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
@@ -1722,20 +1895,8 @@
/*
** Do a binary search (this works whatever time_t's type is).
*/
- if (!TYPE_SIGNED(time_t)) {
- lo = 0;
- hi = lo - 1;
- } else if (!TYPE_INTEGRAL(time_t)) {
- if (sizeof(time_t) > sizeof(float))
- hi = (time_t) DBL_MAX;
- else hi = (time_t) FLT_MAX;
- lo = -hi;
- } else {
- lo = 1;
- for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
- lo *= 2;
- hi = -(lo + 1);
- }
+ lo = time_t_min;
+ hi = time_t_max;
for ( ; ; ) {
t = lo / 2 + hi / 2;
if (t < lo)
@@ -1742,7 +1903,7 @@
t = lo;
else if (t > hi)
t = hi;
- if ((*funcp)(&t, offset, &mytm) == NULL) {
+ if (! funcp(sp, &t, offset, &mytm)) {
/*
** Assume that t is too extreme to be represented in
** a struct tm; arrange things so that it is less
@@ -1752,14 +1913,14 @@
} else dir = tmcomp(&mytm, &yourtm);
if (dir != 0) {
if (t == lo) {
+ if (t == time_t_max)
+ return WRONG;
++t;
- if (t <= lo)
- return WRONG;
++lo;
} else if (t == hi) {
+ if (t == time_t_min)
+ return WRONG;
--t;
- if (t >= hi)
- return WRONG;
--hi;
}
if (lo > hi)
@@ -1769,6 +1930,35 @@
else lo = t;
continue;
}
+#if defined TM_GMTOFF && ! UNINIT_TRAP
+ if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
+ && (yourtm.TM_GMTOFF < 0
+ ? (-SECSPERDAY <= yourtm.TM_GMTOFF
+ && (mytm.TM_GMTOFF <=
+ (SMALLEST (INT_FAST32_MAX, LONG_MAX)
+ + yourtm.TM_GMTOFF)))
+ : (yourtm.TM_GMTOFF <= SECSPERDAY
+ && ((BIGGEST (INT_FAST32_MIN, LONG_MIN)
+ + yourtm.TM_GMTOFF)
+ <= mytm.TM_GMTOFF)))) {
+ /* MYTM matches YOURTM except with the wrong UTC offset.
+ YOURTM.TM_GMTOFF is plausible, so try it instead.
+ It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
+ since the guess gets checked. */
+ time_t altt = t;
+ int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF;
+ if (!increment_overflow_time(&altt, diff)) {
+ struct tm alttm;
+ if (funcp(sp, &altt, offset, &alttm)
+ && alttm.tm_isdst == mytm.tm_isdst
+ && alttm.TM_GMTOFF == yourtm.TM_GMTOFF
+ && tmcomp(&alttm, &yourtm) == 0) {
+ t = altt;
+ mytm = alttm;
+ }
+ }
+ }
+#endif
if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
break;
/*
@@ -1777,12 +1967,8 @@
** It's okay to guess wrong since the guess
** gets checked.
*/
- sp = (const struct state *)
- ((funcp == localsub) ? lclptr : gmtptr);
-#ifdef ALL_STATE
if (sp == NULL)
return WRONG;
-#endif /* defined ALL_STATE */
for (i = sp->typecnt - 1; i >= 0; --i) {
if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
continue;
@@ -1791,7 +1977,7 @@
continue;
newt = t + sp->ttis[j].tt_gmtoff -
sp->ttis[i].tt_gmtoff;
- if ((*funcp)(&newt, offset, &mytm) == NULL)
+ if (! funcp(sp, &newt, offset, &mytm))
continue;
if (tmcomp(&mytm, &yourtm) != 0)
continue;
@@ -1811,16 +1997,18 @@
if ((newt < t) != (saved_seconds < 0))
return WRONG;
t = newt;
- if ((*funcp)(&t, offset, tmp))
- *okayp = TRUE;
+ if (funcp(sp, &t, offset, tmp))
+ *okayp = true;
return t;
}
static time_t
time2(struct tm * const tmp,
- struct tm * (*const funcp)(const time_t *, long, struct tm *),
- const long offset,
- int *const okayp)
+ struct tm *(*funcp)(struct state const *, time_t const *,
+ int_fast32_t, struct tm *),
+ struct state const *sp,
+ const int_fast32_t offset,
+ bool *okayp)
{
time_t t;
@@ -1829,24 +2017,25 @@
** (in case tm_sec contains a value associated with a leap second).
** If that fails, try with normalization of seconds.
*/
- t = time2sub(tmp, funcp, offset, okayp, FALSE);
- return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
+ t = time2sub(tmp, funcp, sp, offset, okayp, false);
+ return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
}
static time_t
time1(struct tm *const tmp,
- struct tm *(*const funcp) (const time_t *, long, struct tm *),
- const long offset)
+ struct tm *(*funcp) (struct state const *, time_t const *,
+ int_fast32_t, struct tm *),
+ struct state const *sp,
+ const int_fast32_t offset)
{
register time_t t;
- register const struct state * sp;
register int samei, otheri;
register int sameind, otherind;
register int i;
register int nseen;
- int seen[TZ_MAX_TYPES];
- int types[TZ_MAX_TYPES];
- int okay;
+ char seen[TZ_MAX_TYPES];
+ unsigned char types[TZ_MAX_TYPES];
+ bool okay;
if (tmp == NULL) {
errno = EINVAL;
@@ -1854,18 +2043,16 @@
}
if (tmp->tm_isdst > 1)
tmp->tm_isdst = 1;
- t = time2(tmp, funcp, offset, &okay);
-#ifdef PCTS
- /*
- ** PCTS code courtesy Grant Sullivan.
- */
+ t = time2(tmp, funcp, sp, offset, &okay);
if (okay)
return t;
if (tmp->tm_isdst < 0)
+#ifdef PCTS
+ /*
+ ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
+ */
tmp->tm_isdst = 0; /* reset to std and try again */
-#endif /* defined PCTS */
-#ifndef PCTS
- if (okay || tmp->tm_isdst < 0)
+#else
return t;
#endif /* !defined PCTS */
/*
@@ -1874,17 +2061,14 @@
** We try to divine the type they started from and adjust to the
** type they need.
*/
- sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr);
-#ifdef ALL_STATE
if (sp == NULL)
return WRONG;
-#endif /* defined ALL_STATE */
for (i = 0; i < sp->typecnt; ++i)
- seen[i] = FALSE;
+ seen[i] = false;
nseen = 0;
for (i = sp->timecnt - 1; i >= 0; --i)
if (!seen[sp->types[i]]) {
- seen[sp->types[i]] = TRUE;
+ seen[sp->types[i]] = true;
types[nseen++] = sp->types[i];
}
for (sameind = 0; sameind < nseen; ++sameind) {
@@ -1898,7 +2082,7 @@
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);
+ t = time2(tmp, funcp, sp, offset, &okay);
if (okay)
return t;
tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
@@ -1909,17 +2093,46 @@
return WRONG;
}
+static time_t
+mktime_tzname(struct state *sp, struct tm *tmp, bool setname)
+{
+ if (sp)
+ return time1(tmp, localsub, sp, setname);
+ else {
+ gmtcheck();
+ return time1(tmp, gmtsub, gmtptr, 0);
+ }
+}
+
+#if NETBSD_INSPIRED
+
time_t
-mktime(struct tm *const tmp)
+mktime_z(struct state *sp, struct tm *tmp)
{
- tzset();
- return time1(tmp, localsub, 0L);
+ return mktime_tzname(sp, tmp, false);
}
+#endif
+
+time_t
+mktime(struct tm *tmp)
+{
+ time_t t;
+ int err = lock();
+ if (err) {
+ errno = err;
+ return -1;
+ }
+ tzset_unlocked();
+ t = mktime_tzname(lclptr, tmp, true);
+ unlock();
+ return t;
+}
+
#ifdef STD_INSPIRED
time_t
-timelocal(struct tm *const tmp)
+timelocal(struct tm *tmp)
{
if (tmp != NULL)
tmp->tm_isdst = -1; /* in case it wasn't initialized */
@@ -1927,43 +2140,23 @@
}
time_t
-timegm(struct tm *const tmp)
+timegm(struct tm *tmp)
{
- if (tmp != NULL)
- tmp->tm_isdst = 0;
- return time1(tmp, gmtsub, 0L);
+ return timeoff(tmp, 0);
}
time_t
-timeoff(struct tm *const tmp, const long offset)
+timeoff(struct tm *tmp, long offset)
{
- if (tmp != NULL)
- tmp->tm_isdst = 0;
- return time1(tmp, gmtsub, offset);
+ if (tmp)
+ tmp->tm_isdst = 0;
+ gmtcheck();
+ return time1(tmp, gmtsub, gmtptr, offset);
}
#endif /* defined STD_INSPIRED */
-#ifdef CMUCS
-
/*
-** The following is supplied for compatibility with
-** previous versions of the CMUCS runtime library.
-*/
-
-long
-gtime(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??
*/
@@ -1977,37 +2170,48 @@
** when exchanging timestamps with POSIX conforming systems.
*/
-static long
-leapcorr(time_t *timep)
+static int_fast64_t
+leapcorr(struct state const *sp, time_t t)
{
- register struct state * sp;
- register struct lsinfo * lp;
+ register struct lsinfo const * lp;
register int i;
- sp = lclptr;
i = sp->leapcnt;
while (--i >= 0) {
lp = &sp->lsis[i];
- if (*timep >= lp->ls_trans)
+ if (t >= lp->ls_trans)
return lp->ls_corr;
}
return 0;
}
+NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
+time2posix_z(struct state *sp, time_t t)
+{
+ return t - leapcorr(sp, t);
+}
+
time_t
time2posix(time_t t)
{
- tzset();
- return t - leapcorr(&t);
+ int err = lock();
+ if (err) {
+ errno = err;
+ return -1;
+ }
+ if (!lcl_is_set)
+ tzset_unlocked();
+ if (lclptr)
+ t = time2posix_z(lclptr, t);
+ unlock();
+ return t;
}
-time_t
-posix2time(time_t t)
+NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
+posix2time_z(struct state *sp, 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
@@ -2014,24 +2218,54 @@
** hit, the corresponding time doesn't exist,
** so we return an adjacent second.
*/
- x = t + leapcorr(&t);
- y = x - leapcorr(&x);
+ x = t + leapcorr(sp, t);
+ y = x - leapcorr(sp, x);
if (y < t) {
do {
x++;
- y = x - leapcorr(&x);
+ y = x - leapcorr(sp, x);
} while (y < t);
- if (t != y)
- return x - 1;
+ x -= y != t;
} else if (y > t) {
do {
--x;
- y = x - leapcorr(&x);
+ y = x - leapcorr(sp, x);
} while (y > t);
- if (t != y)
- return x + 1;
+ x += y != t;
}
return x;
}
+time_t
+posix2time(time_t t)
+{
+ int err = lock();
+ if (err) {
+ errno = err;
+ return -1;
+ }
+ if (!lcl_is_set)
+ tzset_unlocked();
+ if (lclptr)
+ t = posix2time_z(lclptr, t);
+ unlock();
+ return t;
+}
+
#endif /* defined STD_INSPIRED */
+
+#ifdef time_tz
+
+/* Convert from the underlying system's time_t to the ersatz time_tz,
+ which is called 'time_t' in this file. */
+
+time_t
+time(time_t *p)
+{
+ time_t r = sys_time(0);
+ if (p)
+ *p = r;
+ return r;
+}
+
+#endif
Modified: vendor/tzcode/dist/newctime.3
===================================================================
--- vendor/tzcode/dist/newctime.3 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/newctime.3 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,43 +1,59 @@
.TH NEWCTIME 3
.SH NAME
-asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time to ASCII
+asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
.SH SYNOPSIS
.nf
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
+.B #include <time.h>
+.PP
.B extern char *tzname[2];
.PP
-.B void tzset()
+.B char *ctime(time_t const *clock);
.PP
-.B #include <sys/types.h>
+.B char *ctime_r(time_t const *clock, char *buf);
.PP
-.B char *ctime(clock)
-.B const time_t *clock;
+.B double difftime(time_t time1, time_t time0);
.PP
-.B double difftime(time1, time0)
-.B time_t time1;
-.B time_t time0;
+.B char *asctime(struct tm const *tm);
.PP
-.B #include <time.h>
+.B "char *asctime_r(struct tm const *restrict tm,"
+.B " char *restrict result);"
.PP
-.B char *asctime(tm)
-.B const struct tm *tm;
+.B struct tm *localtime(time_t const *clock);
.PP
-.B struct tm *localtime(clock)
-.B const time_t *clock;
+.B "struct tm *localtime_r(time_t const *restrict clock,"
+.B " struct tm *restrict result);"
.PP
-.B struct tm *gmtime(clock)
-.B const time_t *clock;
+.B "struct tm *localtime_rz(timezone_t restrict zone,"
+.B " time_t const *restrict clock,"
+.B " struct tm *restrict result);"
.PP
-.B time_t mktime(tm)
-.B struct tm *tm;
+.B struct tm *gmtime(time_t const *clock);
.PP
-.B cc ... -ltz
+.B "struct tm *gmtime_r(time_t const *restrict clock,"
+.B " struct tm *restrict result);"
+.PP
+.B time_t mktime(struct tm *tm);
+.PP
+.B "time_t mktime_z(timezone_t restrict zone,"
+.B " struct tm *restrict tm);"
+.PP
+.B cc ... \*-ltz
.fi
.SH DESCRIPTION
-.I Ctime\^
+.ie '\(en'' .ds en \-
+.el .ds en \(en
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
+.I Ctime
converts a long integer, pointed to by
.IR clock ,
-representing the time in seconds since
-00:00:00 UTC, 1970-01-01,
and returns a pointer to a
string of the form
.br
@@ -59,34 +75,49 @@
software that expects exactly 26 bytes of output will mistakenly output
misleading values for out-of-range years.
.PP
-.I Localtime\^
+The
+.BI * clock
+time stamp represents the time in seconds since 1970-01-01 00:00:00
+Coordinated Universal Time (UTC).
+The POSIX standard says that time stamps must be nonnegative
+and must ignore leap seconds.
+Many implementations extend POSIX by allowing negative time stamps,
+and can therefore represent time stamps that predate the
+introduction of UTC and are some other flavor of Universal Time (UT).
+Some implementations support leap seconds, in contradiction to POSIX.
+.PP
+.I Localtime
and
-.I gmtime\^
-return pointers to ``tm'' structures, described below.
-.I Localtime\^
+.I gmtime
+return pointers to
+.q "tm"
+structures, described below.
+.I Localtime
corrects for the time zone and any time zone adjustments
(such as Daylight Saving Time in the United States).
-After filling in the ``tm'' structure,
+After filling in the
+.q "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
+to a pointer to a string that's the time zone abbreviation to be used with
.IR localtime 's
return value.
.PP
-.I Gmtime\^
+.I Gmtime
converts to Coordinated Universal Time.
.PP
-.I Asctime\^
+.I Asctime
converts a time value contained in a
-``tm'' structure to a string,
+.q "tm"
+structure to a string,
as shown in the above example,
and returns a pointer to the string.
.PP
-.I Mktime\^
+.I Mktime
converts the broken-down time,
expressed as local time,
in the structure pointed to by
@@ -131,22 +162,50 @@
and
.B tm_year
are determined.
-.I Mktime\^
+.I Mktime
returns the specified calendar time;
If the calendar time cannot be represented,
-it returns
-.BR -1 .
+it returns \-1.
.PP
-.I Difftime\^
+.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,
+.IR Ctime_r ,
+.IR localtime_r ,
+.IR gmtime_r ,
+and
+.I asctime_r
+are like their unsuffixed counterparts, except that they accept an
+additional argument specifying where to store the result if successful.
+.PP
+.IR Localtime_rz
+and
+.I mktime_z
+are like their unsuffixed counterparts, except that they accept an
+extra initial
+.B zone
+argument specifying the time zone to be used for conversion.
+If
+.B zone
+is null, UTC is used; otherwise,
+.B zone
+should be have been allocated by
+.I tzalloc
+and should not be freed until after all uses (e.g., by calls to
+.IR strftime )
+of the filled-in
+.B tm_zone
+fields.
+.PP
+Declarations of all the functions and externals, and the
+.q "tm"
+structure,
are in the
-.B <time.h>\^
+.B <time.h>
header file.
The structure (of type)
.B struct tm
@@ -155,17 +214,17 @@
.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_sec; /\(** seconds (0\*(en60) \(**/
+ int tm_min; /\(** minutes (0\*(en59) \(**/
+ int tm_hour; /\(** hours (0\*(en23) \(**/
+ int tm_mday; /\(** day of month (1\*(en31) \(**/
+ int tm_mon; /\(** month of year (0\*(en11) \(**/
int tm_year; /\(** year \- 1900 \(**/
int tm_wday; /\(** day of week (Sunday = 0) \(**/
- int tm_yday; /\(** day of year (0 - 365) \(**/
+ int tm_yday; /\(** day of year (0\*(en365) \(**/
int tm_isdst; /\(** is summer time in effect? \(**/
- char \(**tm_zone; /\(** abbreviation of timezone name \(**/
- long tm_gmtoff; /\(** offset from UTC in seconds \(**/
+ char \(**tm_zone; /\(** abbreviation of time zone name \(**/
+ long tm_gmtoff; /\(** offset from UT in seconds \(**/
.fi
.RE
.PP
@@ -179,13 +238,14 @@
There is no guarantee that these fields will continue to exist
in this form in future releases of this code.
.PP
-.I Tm_isdst\^
+.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
+from UT, with positive values indicating east
of the Prime Meridian.
+The field's name is derived from Greenwich Mean Time, a precursor of UT.
.SH FILES
.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u
/usr/local/etc/zoneinfo time zone information directory
@@ -208,33 +268,39 @@
time(2),
tzfile(5)
.SH NOTES
-The return values point to static data;
-the data is overwritten by each call.
+The return values of
+.IR asctime ,
+.IR ctime ,
+.IR gmtime ,
+and
+.I localtime
+point to static data
+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 ).
+can be overwritten by later calls to
+.IR tzset .
+The remaining functions and data are thread-safe.
.PP
-.I Asctime\^
+.IR Asctime ,
+.IR asctime_r ,
+.IR ctime ,
and
-.I ctime\^
+.I ctime_r
behave strangely for years before 1000 or after 9999.
The 1989 and 1999 editions of the C Standard say
that years from \-99 through 999 are converted without
extra spaces, but this conflicts with longstanding
tradition and with this implementation.
+The 2011 edition says that the behavior
+is undefined if the year is before 1000 or after 9999.
Traditional implementations of these two functions are
restricted to years in the range 1900 through 2099.
To avoid this portability mess, new programs should use
-.I strftime\^
+.I strftime
instead.
-.PP
-Avoid using out-of-range values with
-.I mktime
-when setting up lunch with promptness sticklers in Riyadh.
.\" This file is in the public domain, so clarified as of
.\" 2009-05-17 by Arthur David Olson.
Modified: vendor/tzcode/dist/newctime.3.txt
===================================================================
--- vendor/tzcode/dist/newctime.3.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/newctime.3.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,43 +1,49 @@
-NEWCTIME(3) NEWCTIME(3)
+NEWCTIME(3) Library Functions Manual NEWCTIME(3)
NAME
asctime, ctime, difftime, gmtime, localtime, mktime - convert date and
- time to ASCII
+ time
SYNOPSIS
+ #include <time.h>
+
extern char *tzname[2];
- void tzset()
+ char *ctime(time_t const *clock);
- #include <sys/types.h>
+ char *ctime_r(time_t const *clock, char *buf);
- char *ctime(clock)
- const time_t *clock;
+ double difftime(time_t time1, time_t time0);
- double difftime(time1, time0)
- time_t time1;
- time_t time0;
+ char *asctime(struct tm const *tm);
- #include <time.h>
+ char *asctime_r(struct tm const *restrict tm,
+ char *restrict result);
- char *asctime(tm)
- const struct tm *tm;
+ struct tm *localtime(time_t const *clock);
- struct tm *localtime(clock)
- const time_t *clock;
+ struct tm *localtime_r(time_t const *restrict clock,
+ struct tm *restrict result);
- struct tm *gmtime(clock)
- const time_t *clock;
+ struct tm *localtime_rz(timezone_t restrict zone,
+ time_t const *restrict clock,
+ struct tm *restrict result);
- time_t mktime(tm)
- struct tm *tm;
+ struct tm *gmtime(time_t const *clock);
+ struct tm *gmtime_r(time_t const *restrict clock,
+ struct tm *restrict result);
+
+ time_t mktime(struct tm *tm);
+
+ time_t mktime_z(timezone_t restrict zone,
+ struct tm *restrict tm);
+
cc ... -ltz
DESCRIPTION
- Ctime converts a long integer, pointed to by clock, representing the
- time in seconds since 00:00:00 UTC, 1970-01-01, and returns a pointer
- to a string of the form
+ Ctime converts a long integer, pointed to by clock, and returns a
+ pointer to a string of the form
Thu Nov 24 18:22:48 1986\n\0
Years requiring fewer than four characters are padded with leading
zeroes. For years longer than four characters, the string is of the
@@ -48,16 +54,24 @@
bytes of output will mistakenly output misleading values for out-of-
range years.
- Localtime and gmtime return pointers to ``tm'' structures, described
+ The *clock time stamp represents the time in seconds since 1970-01-01
+ 00:00:00 Coordinated Universal Time (UTC). The POSIX standard says
+ that time stamps must be nonnegative and must ignore leap seconds.
+ Many implementations extend POSIX by allowing negative time stamps, and
+ can therefore represent time stamps that predate the introduction of
+ UTC and are some other flavor of Universal Time (UT). Some
+ implementations support leap seconds, in contradiction to POSIX.
+
+ Localtime and gmtime return pointers to "tm" structures, described
below. Localtime corrects for the time zone and any time zone
adjustments (such as Daylight Saving Time in the United States). After
- filling in the ``tm'' structure, localtime sets the tm_isdst'th element
- of tzname to a pointer to an ASCII string that's the time zone
- abbreviation to be used with localtime's return value.
+ filling in the "tm" structure, localtime sets the tm_isdst'th element
+ of tzname to a pointer to a string that's the time zone abbreviation to
+ be used with localtime's return value.
Gmtime converts to Coordinated Universal Time.
- Asctime converts a time value contained in a ``tm'' structure to a
+ Asctime converts a time value contained in a "tm" structure to a
string, as shown in the above example, and returns a pointer to the
string.
@@ -84,21 +98,32 @@
Difftime returns the difference between two calendar times, (time1 -
time0), expressed in seconds.
- Declarations of all the functions and externals, and the ``tm''
+ Ctime_r, localtime_r, gmtime_r, and asctime_r are like their unsuffixed
+ counterparts, except that they accept an additional argument specifying
+ where to store the result if successful.
+
+ Localtime_rz and mktime_z are like their unsuffixed counterparts,
+ except that they accept an extra initial zone argument specifying the
+ time zone to be used for conversion. If zone is null, UTC is used;
+ otherwise, zone should be have been allocated by tzalloc and should not
+ be freed until after all uses (e.g., by calls to strftime) of the
+ filled-in tm_zone fields.
+
+ Declarations of all the functions and externals, and the "tm"
structure, are in the <time.h> header file. The structure (of type)
struct tm includes the following fields:
- 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_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_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 */
+ char *tm_zone; /* abbreviation of time zone name */
+ long tm_gmtoff; /* offset from UT in seconds */
The tm_zone and tm_gmtoff fields exist, and are filled in, only if
arrangements to do so were made when the library containing these
@@ -107,8 +132,9 @@
Tm_isdst is non-zero if summer time is in effect.
- Tm_gmtoff is the offset (in seconds) of the time represented from UTC,
- with positive values indicating east of the Prime Meridian.
+ Tm_gmtoff is the offset (in seconds) of the time represented from UT,
+ with positive values indicating east of the Prime Meridian. The
+ field's name is derived from Greenwich Mean Time, a precursor of UT.
FILES
/usr/local/etc/zoneinfo time zone information directory
@@ -123,20 +149,20 @@
getenv(3), newstrftime(3), newtzset(3), time(2), tzfile(5)
NOTES
- The return values point to static data; the data is overwritten by each
- call. The tm_zone field of a returned struct tm points to a static
- array of characters, which will also be overwritten at the next call
- (and by calls to tzset).
+ The return values of asctime, ctime, gmtime, and localtime point to
+ static data overwritten by each call. The tm_zone field of a returned
+ struct tm points to a static array of characters, which can be
+ overwritten by later calls to tzset. The remaining functions and data
+ are thread-safe.
- Asctime and ctime behave strangely for years before 1000 or after 9999.
- The 1989 and 1999 editions of the C Standard say that years from -99
- through 999 are converted without extra spaces, but this conflicts with
- longstanding tradition and with this implementation. Traditional
+ Asctime, asctime_r, ctime, and ctime_r behave strangely for years
+ before 1000 or after 9999. The 1989 and 1999 editions of the C
+ Standard say that years from -99 through 999 are converted without
+ extra spaces, but this conflicts with longstanding tradition and with
+ this implementation. The 2011 edition says that the behavior is
+ undefined if the year is before 1000 or after 9999. Traditional
implementations of these two functions are restricted to years in the
range 1900 through 2099. To avoid this portability mess, new programs
should use strftime instead.
- Avoid using out-of-range values with mktime when setting up lunch with
- promptness sticklers in Riyadh.
-
NEWCTIME(3)
Modified: vendor/tzcode/dist/newstrftime.3
===================================================================
--- vendor/tzcode/dist/newstrftime.3 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/newstrftime.3 2016-08-15 01:50:22 UTC (rev 7736)
@@ -14,15 +14,11 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
@@ -35,7 +31,7 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
-.\" $Id: newstrftime.3,v 1.1.1.1 2012-12-02 00:08:52 laffer1 Exp $
+.\" $Id: strftime.3,v 1.4 1993/12/15 20:33:00 jtc Exp $
.\"
.TH NEWSTRFTIME 3
.SH NAME
@@ -42,29 +38,29 @@
strftime \- format date and time
.SH SYNOPSIS
.nf
-.B #include <sys/types.h>
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
.B #include <time.h>
.PP
-.B size_t strftime(buf, maxsize, format, timeptr)
-.B char *buf;
-.B size_t maxsize;
-.B const char *format;
-.B const struct tm *timeptr
+.B "size_t strftime(char *restrict buf, size_t maxsize,"
+.B " char const *restrict format, struct tm const *restrict timeptr);"
.PP
-.B cc ... -ltz
+.B cc ... \-ltz
.fi
.SH DESCRIPTION
+.ie '\(en'' .ds en \-
+.el .ds en \(en
The
-.I strftime\^
+.I strftime
function formats the information from
-.I timeptr\^
+.I timeptr
into the buffer
-.I buf\^
+.I buf
according to the string pointed to by
-.IR format\^ .
+.IR format .
.PP
The
-.I format\^
+.I format
string consists of zero or more conversion specifications and
ordinary characters.
All ordinary characters are copied directly into the buffer.
@@ -73,12 +69,12 @@
and one other character.
.PP
No more than
-.I maxsize\^
-characters are be placed into the array.
+.I maxsize
+characters are placed into the array.
If the total number of resulting characters, including the terminating
null character, is not more than
-.IR maxsize\^ ,
-.I strftime\^
+.IR maxsize ,
+.I strftime
returns the number of characters in the array, not counting the
terminating null.
Otherwise, zero is returned.
@@ -100,7 +96,7 @@
.TP
%C
is replaced by the century (a year divided by 100 and truncated to an integer)
-as a decimal number (00-99).
+as a decimal number (00\*(en99).
.TP
%c
is replaced by the locale's appropriate date and time representation.
@@ -109,43 +105,43 @@
is replaced by the date in the format %m/%d/%y.
.TP
%d
-is replaced by the day of the month as a decimal number (01-31).
+is replaced by the day of the month as a decimal number (01\*(en31).
.TP
%e
-is replaced by the day of month as a decimal number (1-31);
+is replaced by the day of month as a decimal number (1\*(en31);
single digits are preceded by a blank.
.TP
%F
-is replaced by the date in the format %Y-%m-%d.
+is replaced by the date in the format %Y\*-%m\*-%d.
.TP
%G
is replaced by the ISO 8601 year with century as a decimal number.
.TP
%g
-is replaced by the ISO 8601 year without century as a decimal number (00-99).
+is replaced by the ISO 8601 year without century as a decimal number (00\*(en99).
.TP
%H
-is replaced by the hour (24-hour clock) as a decimal number (00-23).
+is replaced by the hour (24-hour clock) as a decimal number (00\*(en23).
.TP
%I
-is replaced by the hour (12-hour clock) as a decimal number (01-12).
+is replaced by the hour (12-hour clock) as a decimal number (01\*(en12).
.TP
%j
-is replaced by the day of the year as a decimal number (001-366).
+is replaced by the day of the year as a decimal number (001\*(en366).
.TP
%k
-is replaced by the hour (24-hour clock) as a decimal number (0-23);
+is replaced by the hour (24-hour clock) as a decimal number (0\*(en23);
single digits are preceded by a blank.
.TP
%l
-is replaced by the hour (12-hour clock) as a decimal number (1-12);
+is replaced by the hour (12-hour clock) as a decimal number (1\*(en12);
single digits are preceded by a blank.
.TP
%M
-is replaced by the minute as a decimal number (00-59).
+is replaced by the minute as a decimal number (00\*(en59).
.TP
%m
-is replaced by the month as a decimal number (01-12).
+is replaced by the month as a decimal number (01\*(en12).
.TP
%n
is replaced by a newline.
@@ -161,10 +157,10 @@
using AM/PM notation.
.TP
%S
-is replaced by the second as a decimal number (00-60).
+is replaced by the second as a decimal number (00\*(en60).
.TP
%s
-is replaced by the number of seconds since the Epoch, UTC (see mktime(3)).
+is replaced by the number of seconds since the Epoch (see newctime(3)).
.TP
%T
is replaced by the time in the format %H:%M:%S.
@@ -174,25 +170,25 @@
.TP
%U
is replaced by the week number of the year (Sunday as the first day of
-the week) as a decimal number (00-53).
+the week) as a decimal number (00\*(en53).
.TP
%u
is replaced by the weekday (Monday as the first day of the week)
-as a decimal number (1-7).
+as a decimal number (1\*(en7).
.TP
%V
is replaced by the week number of the year (Monday as the first day of
-the week) as a decimal number (01-53). If the week containing January
+the week) as a decimal number (01\*(en53). 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.
.TP
%W
is replaced by the week number of the year (Monday as the first day of
-the week) as a decimal number (00-53).
+the week) as a decimal number (00\*(en53).
.TP
%w
is replaced by the weekday (Sunday as the first day of the week)
-as a decimal number (0-6).
+as a decimal number (0\*(en6).
.TP
%X
is replaced by the locale's appropriate time representation.
@@ -204,7 +200,7 @@
is replaced by the year with century as a decimal number.
.TP
%y
-is replaced by the year without century as a decimal number (00-99).
+is replaced by the year without century as a decimal number (00\*(en99).
.TP
%Z
is replaced by the time zone name,
@@ -211,7 +207,8 @@
or by the empty string if this is not determinable.
.TP
%z
-is replaced by the offset from UTC in the format +HHMM or -HHMM as appropriate,
+is replaced by the offset from the Prime Meridian
+in the format +HHMM or \*-HHMM as appropriate,
with positive values representing locations east of Greenwich,
or by the empty string if this is not determinable.
.TP
Modified: vendor/tzcode/dist/newstrftime.3.txt
===================================================================
--- vendor/tzcode/dist/newstrftime.3.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/newstrftime.3.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,17 +1,13 @@
-NEWSTRFTIME(3) NEWSTRFTIME(3)
+NEWSTRFTIME(3) Library Functions Manual NEWSTRFTIME(3)
NAME
strftime - format date and time
SYNOPSIS
- #include <sys/types.h>
#include <time.h>
- size_t strftime(buf, maxsize, format, timeptr)
- char *buf;
- size_t maxsize;
- const char *format;
- const struct tm *timeptr
+ size_t strftime(char *restrict buf, size_t maxsize,
+ char const *restrict format, struct tm const *restrict timeptr);
cc ... -ltz
@@ -24,7 +20,7 @@
into the buffer. A conversion specification consists of a percent sign
and one other character.
- No more than maxsize characters are be placed into the array. If the
+ No more than maxsize characters are placed into the array. If the
total number of resulting characters, including the terminating null
character, is not more than maxsize, strftime returns the number of
characters in the array, not counting the terminating null. Otherwise,
@@ -93,8 +89,8 @@
%S is replaced by the second as a decimal number (00-60).
- %s is replaced by the number of seconds since the Epoch, UTC (see
- mktime(3)).
+ %s is replaced by the number of seconds since the Epoch (see
+ newctime(3)).
%T is replaced by the time in the format %H:%M:%S.
@@ -130,10 +126,10 @@
%Z is replaced by the time zone name, or by the empty string if
this is not determinable.
- %z is replaced by the offset from UTC in the format +HHMM or -HHMM
- as appropriate, with positive values representing locations east
- of Greenwich, or by the empty string if this is not
- determinable.
+ %z is replaced by the offset from the Prime Meridian in the format
+ +HHMM or -HHMM as appropriate, with positive values representing
+ locations east of Greenwich, or by the empty string if this is
+ not determinable.
%% is replaced by a single %.
Modified: vendor/tzcode/dist/newtzset.3
===================================================================
--- vendor/tzcode/dist/newtzset.3 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/newtzset.3 2016-08-15 01:50:22 UTC (rev 7736)
@@ -3,33 +3,83 @@
tzset \- initialize time conversion information
.SH SYNOPSIS
.nf
-.B void tzset()
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
+.B #include <time.h>
.PP
-.B cc ... -ltz
+.B timezone_t tzalloc(char const *TZ);
+.PP
+.B void tzfree(timezone_t tz);
+.PP
+.B void tzset(void);
+.PP
+.B cc ... \*-ltz
.fi
.SH DESCRIPTION
+.ie '\(en'' .ds en \-
+.el .ds en \(en
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
+.I Tzalloc
+allocates and returns a time zone object described by
+.BR TZ .
+If
+.B TZ
+is not a valid time zone description, or if the object cannot be allocated,
+.I tzalloc
+returns a null pointer and sets
+.BR errno .
+.PP
+.I Tzfree
+frees a time zone object
+.BR tz ,
+which should have been successfully allocated by
+.IR tzalloc .
+This invalidates any
+.B tm_zone
+pointers that
+.B tz
+was used to set.
+.PP
.I Tzset
-uses the value of the environment variable
-.B TZ
-to set time conversion information used by
-.IR localtime .
+acts like
+.BR tzalloc(getenv("TZ")) ,
+except it saves any resulting time zone object into internal
+storage that is accessed by
+.IR localtime ,
+.IR localtime_r ,
+and
+.IR mktime .
+The anonymous shared time zone object is freed by the next call to
+.IR tzset .
+If the implied call to
+.B tzalloc
+fails,
+.I tzset
+falls back on UTC.
+.PP
If
.B TZ
-does not appear in the environment,
-the best available approximation to local wall clock time, as specified
-by the
+is null, 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 .
+in the system time conversion information directory, is used.
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
+is the empty string,
+Universal Time (UT) is used, with the abbreviation "UTC"
+and without leap second correction; please see
+.IR newctime (3)
+for more about UT, UTC, and leap seconds. If
.B TZ
-appears in the environment and its value is not a null string:
+is nonnull and nonempty:
.IP
if the value begins with a colon, it is used as a pathname of a file
from which to read the time conversion information;
@@ -73,11 +123,11 @@
.RB ( : ),
digits, comma
.RB ( , ),
-minus
-.RB ( \(mi ),
-plus
-.RB ( \(pl ),
-and ASCII NUL are allowed.
+ASCII minus
+.RB ( \*- ),
+ASCII plus
+.RB ( + ),
+and NUL bytes are allowed.
.TP
.I offset
Indicates the value one must add to the local time to arrive at
@@ -106,11 +156,11 @@
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 '',
+seconds) \*(en if present \*(en between zero and 59. If preceded by a
+.q "\*-" ,
the time zone shall be east of the Prime Meridian; otherwise it shall be
west (which may be indicated by an optional preceding
-.RB `` \(pl '').
+.q "+" .
.TP
.I rule
Indicates when to change to and back from summer time. The
@@ -130,6 +180,10 @@
.I time
field describes when, in current local time, the change to the other
time is made.
+As an extension to POSIX, daylight saving is assumed to be in effect
+all year if it begins January 1 at 00:00 and ends December 31 at
+24:00 plus the difference between daylight saving and standard time,
+leaving no room for standard time in the calendar.
.IP
The format of
.I date
@@ -140,8 +194,8 @@
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
+Leap days are not counted; that is, in all years \*(en including leap
+years \*(en February 28 is day 59 and March 1 is day 60. It is
impossible to explicitly refer to the occasional February 29.
.TP
.I n
@@ -161,10 +215,8 @@
of the year
.RI "(1\ \(<=" "\ n\ " "\(<=\ 5,
.RI "1\ \(<=" "\ m\ " "\(<=\ 12,
-where week 5 means ``the last
-.I d
-day in month
-.IR m ''
+where week 5 means
+.q "the last \fId\fP day in month \fIm\fP"
which may occur in either the fourth or the fifth week). Week 1 is the
first week in which the
.IR d' th
@@ -175,16 +227,59 @@
.I time
has the same format as
.I offset
-except that no leading sign
-.RB (`` \(mi ''
+except that POSIX does not allow a leading sign (\c
+.q "\*-"
or
-.RB `` \(pl '')
-is allowed. The default, if
+.q "+" ).
+As an extension to POSIX, the hours part of
.I time
+can range from \-167 through 167; this allows for unusual rules such
+as
+.q "the Saturday before the first Sunday of March" .
+The default, if
+.I time
is not given, is
.BR 02:00:00 .
.RE
.LP
+Here are some examples of
+.B TZ
+values that directly specify the time zone rules; they use some of the
+extensions to POSIX.
+.TP
+.B EST5
+stands for US Eastern Standard
+Time (EST), 5 hours behind UTC, without daylight saving.
+.TP
+.B FJT\*-12FJST,M11.1.0,M1.3.4/75
+stands for Fiji Time (FJT) and Fiji Summer Time (FJST), 12 hours ahead
+of UTC, springing forward on November's first Sunday at 02:00, and
+falling back on January's third Thursday at 75:00 (i.e., 03:00 on the
+first Sunday on or after January 18).
+.TP
+.B IST\*-2IDT,M3.4.4/26,M10.5.0
+stands for Israel Standard Time (IST) and Israel Daylight Time (IDT),
+2 hours ahead of UTC, springing forward on March's fourth
+Thursday at 26:00 (i.e., 02:00 on the first Friday on or after March
+23), and falling back on October's last Sunday at 02:00.
+.TP
+.B WART4WARST,J1/0,J365/25
+stands for Western Argentina Summer Time (WARST), 3 hours behind UTC.
+There is a dummy fall-back transition on December 31 at 25:00 daylight
+saving time (i.e., 24:00 standard time, equivalent to January 1 at
+00:00 standard time), and a simultaneous spring-forward transition on
+January 1 at 00:00 standard time, so daylight saving time is in effect
+all year and the initial
+.B WART
+is a placeholder.
+.TP
+.B WGT3WGST,M3.5.0/\*-2,M10.5.0/\*-1
+stands for Western Greenland Time (WGT) and Western Greenland Summer
+Time (WGST), 3 hours behind UTC, where clocks follow the EU rules of
+springing forward on March's last Sunday at 01:00 UTC (\-02:00 local
+time) and falling back on October's last Sunday at 01:00 UTC
+(\-01:00 local time).
+.PP
If no
.I rule
is present in
@@ -206,13 +301,6 @@
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
Modified: vendor/tzcode/dist/newtzset.3.txt
===================================================================
--- vendor/tzcode/dist/newtzset.3.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/newtzset.3.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,23 +1,41 @@
-NEWTZSET(3) NEWTZSET(3)
+NEWTZSET(3) Library Functions Manual NEWTZSET(3)
NAME
tzset - initialize time conversion information
SYNOPSIS
- void tzset()
+ #include <time.h>
+ timezone_t tzalloc(char const *TZ);
+
+ void tzfree(timezone_t tz);
+
+ void tzset(void);
+
cc ... -ltz
DESCRIPTION
- Tzset uses the value of the environment variable TZ to set time
- conversion information used by localtime. If TZ does not appear in the
- environment, the best available approximation to local wall clock time,
- as specified by the tzfile(5)-format file localtime in the system time
- conversion information directory, is used by localtime. If TZ appears
- in the environment but its value is a null string, Coordinated
- Universal Time (UTC) is used (without leap second correction). If TZ
- appears in the environment and its value is not a null string:
+ Tzalloc allocates and returns a time zone object described by TZ. If
+ TZ is not a valid time zone description, or if the object cannot be
+ allocated, tzalloc returns a null pointer and sets errno.
+ Tzfree frees a time zone object tz, which should have been successfully
+ allocated by tzalloc. This invalidates any tm_zone pointers that tz
+ was used to set.
+
+ Tzset acts like tzalloc(getenv("TZ")), except it saves any resulting
+ time zone object into internal storage that is accessed by localtime,
+ localtime_r, and mktime. The anonymous shared time zone object is
+ freed by the next call to tzset. If the implied call to tzalloc fails,
+ tzset falls back on UTC.
+
+ If TZ is null, the best available approximation to local wall clock
+ time, as specified by the tzfile(5)-format file localtime in the system
+ time conversion information directory, is used. If TZ is the empty
+ string, Universal Time (UT) is used, with the abbreviation "UTC" and
+ without leap second correction; please see newctime(3) for more about
+ UT, UTC, and leap seconds. If TZ is nonnull and nonempty:
+
if the value begins with a colon, it is used as a pathname of a
file from which to read the time conversion information;
@@ -45,8 +63,8 @@
summer time does not apply in this locale.
Upper- and lowercase letters are explicitly
allowed. Any characters except a leading colon
- (:), digits, comma (,), minus (-), plus (+), and
- ASCII NUL are allowed.
+ (:), digits, comma (,), ASCII minus (-), ASCII
+ plus (+), and NUL bytes are allowed.
offset Indicates the value one must add to the local
time to arrive at Coordinated Universal Time.
@@ -62,11 +80,11 @@
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) -- if present -- between zero and 59.
- If preceded by a ``-'', the time zone shall be
- east of the Prime Meridian; otherwise it shall be
- west (which may be indicated by an optional
- preceding ``+'').
+ seconds) - if present - between zero and 59. If
+ preceded by a "-", the time zone shall be east of
+ the Prime Meridian; otherwise it shall be west
+ (which may be indicated by an optional preceding
+ "+".
rule Indicates when to change to and back from summer
time. The rule has the form:
@@ -78,16 +96,21 @@
second date describes when the change back
happens. Each time field describes when, in
current local time, the change to the other time
- is made.
+ is made. As an extension to POSIX, daylight
+ saving is assumed to be in effect all year if it
+ begins January 1 at 00:00 and ends December 31 at
+ 24:00 plus the difference between daylight saving
+ and standard time, leaving no room for standard
+ time in the calendar.
The format of date is one of the following:
Jn The Julian day n (1 <= n <= 365). Leap
days are not counted; that is, in all
- years -- including leap years --
- February 28 is day 59 and March 1 is
- day 60. It is impossible to explicitly
- refer to the occasional February 29.
+ years - including leap years - February
+ 28 is day 59 and March 1 is day 60. It
+ is impossible to explicitly refer to
+ the occasional February 29.
n The zero-based Julian day
(0 <= n <= 365). Leap days are
@@ -96,8 +119,8 @@
Mm.n.d The d'th day (0 <= d <= 6) of week n of
month m of the year (1 <= n <= 5,
- 1 <= m <= 12, where week 5 means ``the
- last d day in month m'' which may occur
+ 1 <= m <= 12, where week 5 means "the
+ last d day in month m" which may occur
in either the fourth or the fifth
week). Week 1 is the first week in
which the d'th day occurs. Day zero is
@@ -104,9 +127,47 @@
Sunday.
The time has the same format as offset except
- that no leading sign (``-'' or ``+'') is allowed.
- The default, if time is not given, is 02:00:00.
+ that POSIX does not allow a leading sign ("-" or
+ "+"). As an extension to POSIX, the hours part
+ of time can range from -167 through 167; this
+ allows for unusual rules such as "the Saturday
+ before the first Sunday of March". The default,
+ if time is not given, is 02:00:00.
+ Here are some examples of TZ values that directly specify the time zone
+ rules; they use some of the extensions to POSIX.
+
+ EST5 stands for US Eastern Standard Time (EST), 5 hours behind UTC,
+ without daylight saving.
+
+ FJT-12FJST,M11.1.0,M1.3.4/75
+ stands for Fiji Time (FJT) and Fiji Summer Time (FJST), 12 hours
+ ahead of UTC, springing forward on November's first Sunday at
+ 02:00, and falling back on January's third Thursday at 75:00
+ (i.e., 03:00 on the first Sunday on or after January 18).
+
+ IST-2IDT,M3.4.4/26,M10.5.0
+ stands for Israel Standard Time (IST) and Israel Daylight Time
+ (IDT), 2 hours ahead of UTC, springing forward on March's fourth
+ Thursday at 26:00 (i.e., 02:00 on the first Friday on or after
+ March 23), and falling back on October's last Sunday at 02:00.
+
+ WART4WARST,J1/0,J365/25
+ stands for Western Argentina Summer Time (WARST), 3 hours behind
+ UTC. There is a dummy fall-back transition on December 31 at
+ 25:00 daylight saving time (i.e., 24:00 standard time,
+ equivalent to January 1 at 00:00 standard time), and a
+ simultaneous spring-forward transition on January 1 at 00:00
+ standard time, so daylight saving time is in effect all year and
+ the initial WART is a placeholder.
+
+ WGT3WGST,M3.5.0/-2,M10.5.0/-1
+ stands for Western Greenland Time (WGT) and Western Greenland
+ Summer Time (WGST), 3 hours behind UTC, where clocks follow the
+ EU rules of springing forward on March's last Sunday at 01:00
+ UTC (-02:00 local time) and falling back on October's last
+ Sunday at 01:00 UTC (-01:00 local time).
+
If no rule is present in TZ, the rules specified by the
tzfile(5)-format file posixrules in the system time conversion
information directory are used, with the standard and summer time
@@ -116,9 +177,6 @@
For compatibility with System V Release 3.1, a semicolon (;) may be
used to separate the rule from the rest of the specification.
- If the TZ environment variable does not specify a tzfile(5)-format and
- cannot be interpreted as a direct specification, UTC is used.
-
FILES
/usr/local/etc/zoneinfo time zone information directory
/usr/local/etc/zoneinfo/localtime local time zone file
Modified: vendor/tzcode/dist/private.h
===================================================================
--- vendor/tzcode/dist/private.h 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/private.h 2016-08-15 01:50:22 UTC (rev 7736)
@@ -19,12 +19,12 @@
/*
** Defaults for preprocessor symbols.
-** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
+** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
*/
-#ifndef HAVE_ADJTIME
-#define HAVE_ADJTIME 1
-#endif /* !defined HAVE_ADJTIME */
+#ifndef HAVE_DECL_ASCTIME_R
+#define HAVE_DECL_ASCTIME_R 1
+#endif
#ifndef HAVE_GETTEXT
#define HAVE_GETTEXT 0
@@ -34,10 +34,18 @@
#define HAVE_INCOMPATIBLE_CTIME_R 0
#endif /* !defined INCOMPATIBLE_CTIME_R */
-#ifndef HAVE_SETTIMEOFDAY
-#define HAVE_SETTIMEOFDAY 3
-#endif /* !defined HAVE_SETTIMEOFDAY */
+#ifndef HAVE_LINK
+#define HAVE_LINK 1
+#endif /* !defined HAVE_LINK */
+#ifndef HAVE_POSIX_DECLS
+#define HAVE_POSIX_DECLS 1
+#endif
+
+#ifndef HAVE_STRDUP
+#define HAVE_STRDUP 1
+#endif
+
#ifndef HAVE_SYMLINK
#define HAVE_SYMLINK 1
#endif /* !defined HAVE_SYMLINK */
@@ -55,12 +63,12 @@
#endif /* !defined HAVE_UNISTD_H */
#ifndef HAVE_UTMPX_H
-#define HAVE_UTMPX_H 0
+#define HAVE_UTMPX_H 1
#endif /* !defined HAVE_UTMPX_H */
-#ifndef LOCALE_HOME
-#define LOCALE_HOME "/usr/lib/locale"
-#endif /* !defined LOCALE_HOME */
+#ifndef NETBSD_INSPIRED
+# define NETBSD_INSPIRED 1
+#endif
#if HAVE_INCOMPATIBLE_CTIME_R
#define asctime_r _incompatible_asctime_r
@@ -67,18 +75,52 @@
#define ctime_r _incompatible_ctime_r
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
+/* Enable tm_gmtoff and tm_zone on GNUish systems. */
+#define _GNU_SOURCE 1
+/* Fix asctime_r on Solaris 10. */
+#define _POSIX_PTHREAD_SEMANTICS 1
+/* Enable strtoimax on Solaris 10. */
+#define __EXTENSIONS__ 1
+
/*
** Nested includes
*/
+/* Avoid clashes with NetBSD by renaming NetBSD's declarations. */
+#define localtime_rz sys_localtime_rz
+#define mktime_z sys_mktime_z
+#define posix2time_z sys_posix2time_z
+#define time2posix_z sys_time2posix_z
+#define timezone_t sys_timezone_t
+#define tzalloc sys_tzalloc
+#define tzfree sys_tzfree
+#include <time.h>
+#undef localtime_rz
+#undef mktime_z
+#undef posix2time_z
+#undef time2posix_z
+#undef timezone_t
+#undef tzalloc
+#undef tzfree
+
#include "sys/types.h" /* for time_t */
#include "stdio.h"
-#include "errno.h"
#include "string.h"
#include "limits.h" /* for CHAR_BIT et al. */
-#include "time.h"
#include "stdlib.h"
+#include "errno.h"
+
+#ifndef ENAMETOOLONG
+# define ENAMETOOLONG EINVAL
+#endif
+#ifndef ENOTSUP
+# define ENOTSUP EINVAL
+#endif
+#ifndef EOVERFLOW
+# define EOVERFLOW EINVAL
+#endif
+
#if HAVE_GETTEXT
#include "libintl.h"
#endif /* HAVE_GETTEXT */
@@ -98,6 +140,14 @@
#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */
#endif /* HAVE_UNISTD_H */
+#ifndef HAVE_STRFTIME_L
+# if _POSIX_VERSION < 200809
+# define HAVE_STRFTIME_L 0
+# else
+# define HAVE_STRFTIME_L 1
+# endif
+#endif
+
#ifndef F_OK
#define F_OK 0
#endif /* !defined F_OK */
@@ -116,8 +166,9 @@
*/
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H \
- (199901 <= __STDC_VERSION__ || \
- 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
+ (199901 <= __STDC_VERSION__ \
+ || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
+ || __CYGWIN__)
#endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
@@ -124,19 +175,109 @@
#include "stdint.h"
#endif /* !HAVE_STDINT_H */
+#ifndef HAVE_INTTYPES_H
+# define HAVE_INTTYPES_H HAVE_STDINT_H
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
+#ifdef __LONG_LONG_MAX__
+# ifndef LLONG_MAX
+# define LLONG_MAX __LONG_LONG_MAX__
+# endif
+# ifndef LLONG_MIN
+# define LLONG_MIN (-1 - LLONG_MAX)
+# endif
+#endif
+
#ifndef INT_FAST64_MAX
-/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
-#if defined LLONG_MAX || defined __LONG_LONG_MAX__
+# ifdef LLONG_MAX
typedef long long int_fast64_t;
-#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#if (LONG_MAX >> 31) < 0xffffffff
+# define INT_FAST64_MIN LLONG_MIN
+# define INT_FAST64_MAX LLONG_MAX
+# else
+# if LONG_MAX >> 31 < 0xffffffff
Please use a compiler that supports a 64-bit integer type (or wider);
you may need to compile with "-DHAVE_STDINT_H".
-#endif /* (LONG_MAX >> 31) < 0xffffffff */
+# endif
typedef long int_fast64_t;
-#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#endif /* !defined INT_FAST64_MAX */
+# define INT_FAST64_MIN LONG_MIN
+# define INT_FAST64_MAX LONG_MAX
+# endif
+#endif
+#ifndef SCNdFAST64
+# if INT_FAST64_MAX == LLONG_MAX
+# define SCNdFAST64 "lld"
+# else
+# define SCNdFAST64 "ld"
+# endif
+#endif
+
+#ifndef INT_FAST32_MAX
+# if INT_MAX >> 31 == 0
+typedef long int_fast32_t;
+# define INT_FAST32_MAX LONG_MAX
+# define INT_FAST32_MIN LONG_MIN
+# else
+typedef int int_fast32_t;
+# define INT_FAST32_MAX INT_MAX
+# define INT_FAST32_MIN INT_MIN
+# endif
+#endif
+
+#ifndef INTMAX_MAX
+# ifdef LLONG_MAX
+typedef long long intmax_t;
+# define strtoimax strtoll
+# define INTMAX_MAX LLONG_MAX
+# define INTMAX_MIN LLONG_MIN
+# else
+typedef long intmax_t;
+# define strtoimax strtol
+# define INTMAX_MAX LONG_MAX
+# define INTMAX_MIN LONG_MIN
+# endif
+#endif
+
+#ifndef PRIdMAX
+# if INTMAX_MAX == LLONG_MAX
+# define PRIdMAX "lld"
+# else
+# define PRIdMAX "ld"
+# endif
+#endif
+
+#ifndef UINT_FAST64_MAX
+# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+typedef unsigned long long uint_fast64_t;
+# else
+# if ULONG_MAX >> 31 >> 1 < 0xffffffff
+Please use a compiler that supports a 64-bit integer type (or wider);
+you may need to compile with "-DHAVE_STDINT_H".
+# endif
+typedef unsigned long uint_fast64_t;
+# endif
+#endif
+
+#ifndef UINTMAX_MAX
+# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+typedef unsigned long long uintmax_t;
+# else
+typedef unsigned long uintmax_t;
+# endif
+#endif
+
+#ifndef PRIuMAX
+# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+# define PRIuMAX "llu"
+# else
+# define PRIuMAX "lu"
+# endif
+#endif
+
#ifndef INT32_MAX
#define INT32_MAX 0x7fffffff
#endif /* !defined INT32_MAX */
@@ -144,46 +285,209 @@
#define INT32_MIN (-1 - INT32_MAX)
#endif /* !defined INT32_MIN */
-#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) -1)
+#endif
+
+#if 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define ATTRIBUTE_CONST __attribute__ ((const))
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
+# define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
#else
+# define ATTRIBUTE_CONST /* empty */
# define ATTRIBUTE_PURE /* empty */
+# define ATTRIBUTE_FORMAT(spec) /* empty */
#endif
+#if !defined _Noreturn && __STDC_VERSION__ < 201112
+# if 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
+# define _Noreturn __attribute__ ((__noreturn__))
+# else
+# define _Noreturn
+# endif
+#endif
+
+#if __STDC_VERSION__ < 199901 && !defined restrict
+# define restrict /* empty */
+#endif
+
/*
** Workarounds for compilers/systems.
*/
/*
-** Some time.h implementations don't declare asctime_r.
-** Others might define it as a macro.
-** Fix the former without affecting the latter.
+** Compile with -Dtime_tz=T to build the tz package with a private
+** time_t type equivalent to T rather than the system-supplied time_t.
+** This debugging feature can test unusual design decisions
+** (e.g., time_t wider than 'long', or unsigned time_t) even on
+** typical platforms.
*/
+#ifdef time_tz
+# ifdef LOCALTIME_IMPLEMENTATION
+static time_t sys_time(time_t *x) { return time(x); }
+# endif
-#ifndef asctime_r
-extern char * asctime_r(struct tm const *, char *);
+typedef time_tz tz_time_t;
+
+# undef ctime
+# define ctime tz_ctime
+# undef ctime_r
+# define ctime_r tz_ctime_r
+# undef difftime
+# define difftime tz_difftime
+# undef gmtime
+# define gmtime tz_gmtime
+# undef gmtime_r
+# define gmtime_r tz_gmtime_r
+# undef localtime
+# define localtime tz_localtime
+# undef localtime_r
+# define localtime_r tz_localtime_r
+# undef localtime_rz
+# define localtime_rz tz_localtime_rz
+# undef mktime
+# define mktime tz_mktime
+# undef mktime_z
+# define mktime_z tz_mktime_z
+# undef offtime
+# define offtime tz_offtime
+# undef posix2time
+# define posix2time tz_posix2time
+# undef posix2time_z
+# define posix2time_z tz_posix2time_z
+# undef time
+# define time tz_time
+# undef time2posix
+# define time2posix tz_time2posix
+# undef time2posix_z
+# define time2posix_z tz_time2posix_z
+# undef time_t
+# define time_t tz_time_t
+# undef timegm
+# define timegm tz_timegm
+# undef timelocal
+# define timelocal tz_timelocal
+# undef timeoff
+# define timeoff tz_timeoff
+# undef tzalloc
+# define tzalloc tz_tzalloc
+# undef tzfree
+# define tzfree tz_tzfree
+# undef tzset
+# define tzset tz_tzset
+# undef tzsetwall
+# define tzsetwall tz_tzsetwall
+
+char *ctime(time_t const *);
+char *ctime_r(time_t const *, char *);
+double difftime(time_t, time_t);
+struct tm *gmtime(time_t const *);
+struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
+struct tm *localtime(time_t const *);
+struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
+time_t mktime(struct tm *);
+time_t time(time_t *);
+void tzset(void);
#endif
+#if !HAVE_DECL_ASCTIME_R && !defined asctime_r
+extern char *asctime_r(struct tm const *restrict, char *restrict);
+#endif
+
+#if !HAVE_POSIX_DECLS
+# ifdef USG_COMPAT
+# ifndef timezone
+extern long timezone;
+# endif
+# ifndef daylight
+extern int daylight;
+# endif
+# endif
+#endif
+
+#if defined ALTZONE && !defined altzone
+extern long altzone;
+#endif
+
/*
-** Private function declarations.
+** The STD_INSPIRED functions are similar, but most also need
+** declarations if time_tz is defined.
*/
-char * icatalloc(char * old, const char * new);
-char * icpyalloc(const char * string);
-const char * scheck(const char * string, const char * format);
+#ifdef STD_INSPIRED
+# if !defined tzsetwall || defined time_tz
+void tzsetwall(void);
+# endif
+# if !defined offtime || defined time_tz
+struct tm *offtime(time_t const *, long);
+# endif
+# if !defined timegm || defined time_tz
+time_t timegm(struct tm *);
+# endif
+# if !defined timelocal || defined time_tz
+time_t timelocal(struct tm *);
+# endif
+# if !defined timeoff || defined time_tz
+time_t timeoff(struct tm *, long);
+# endif
+# if !defined time2posix || defined time_tz
+time_t time2posix(time_t);
+# endif
+# if !defined posix2time || defined time_tz
+time_t posix2time(time_t);
+# endif
+#endif
+/* Infer TM_ZONE on systems where this information is known, but suppress
+ guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
+#if (defined __GLIBC__ \
+ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
+ || (defined __APPLE__ && defined __MACH__))
+# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
+# define TM_GMTOFF tm_gmtoff
+# endif
+# if !defined TM_ZONE && !defined NO_TM_ZONE
+# define TM_ZONE tm_zone
+# endif
+#endif
+
/*
+** Define functions that are ABI compatible with NetBSD but have
+** better prototypes. NetBSD 6.1.4 defines a pointer type timezone_t
+** and labors under the misconception that 'const timezone_t' is a
+** pointer to a constant. This use of 'const' is ineffective, so it
+** is not done here. What we call 'struct state' NetBSD calls
+** 'struct __state', but this is a private name so it doesn't matter.
+*/
+#if NETBSD_INSPIRED
+typedef struct state *timezone_t;
+struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
+ struct tm *restrict);
+time_t mktime_z(timezone_t restrict, struct tm *restrict);
+timezone_t tzalloc(char const *);
+void tzfree(timezone_t);
+# ifdef STD_INSPIRED
+# if !defined posix2time_z || defined time_tz
+time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_PURE;
+# endif
+# if !defined time2posix_z || defined time_tz
+time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
+# endif
+# endif
+#endif
+
+/*
** Finally, some convenience items.
*/
-#ifndef TRUE
-#define TRUE 1
-#endif /* !defined TRUE */
+#if __STDC_VERSION__ < 199901
+# define true 1
+# define false 0
+# define bool int
+#else
+# include <stdbool.h>
+#endif
-#ifndef FALSE
-#define FALSE 0
-#endif /* !defined FALSE */
-
#ifndef TYPE_BIT
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
#endif /* !defined TYPE_BIT */
@@ -192,15 +496,21 @@
#define TYPE_SIGNED(type) (((type) -1) < 0)
#endif /* !defined TYPE_SIGNED */
-/*
-** Since the definition of TYPE_INTEGRAL contains floating point numbers,
-** it cannot be used in preprocessor directives.
-*/
+#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
-#ifndef TYPE_INTEGRAL
-#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
-#endif /* !defined TYPE_INTEGRAL */
+/* Max and min values of the integer type T, of which only the bottom
+ B bits are used, and where the highest-order used bit is considered
+ to be a sign bit if T is signed. */
+#define MAXVAL(t, b) \
+ ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
+ - 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
+#define MINVAL(t, b) \
+ ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
+/* The minimum and maximum finite time values. This assumes no padding. */
+static time_t const time_t_min = MINVAL(time_t, TYPE_BIT(time_t));
+static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
+
#ifndef INT_STRLEN_MAXIMUM
/*
** 302 / 1000 is log10(2.0) rounded up.
@@ -217,29 +527,19 @@
** INITIALIZE(x)
*/
-#ifndef GNUC_or_lint
#ifdef lint
-#define GNUC_or_lint
-#endif /* defined lint */
-#ifndef lint
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined lint */
-#endif /* !defined GNUC_or_lint */
+# define INITIALIZE(x) ((x) = 0)
+#else
+# define INITIALIZE(x)
+#endif
-#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 */
+#ifndef UNINIT_TRAP
+# define UNINIT_TRAP 0
+#endif
/*
** For the benefit of GNU folk...
-** `_(MSGID)' uses the current locale's message library string for MSGID.
+** '_(MSGID)' uses the current locale's message library string for MSGID.
** The default is to use gettext if available, and use MSGID otherwise.
*/
@@ -251,9 +551,9 @@
#endif /* !HAVE_GETTEXT */
#endif /* !defined _ */
-#ifndef TZ_DOMAIN
-#define TZ_DOMAIN "tz"
-#endif /* !defined TZ_DOMAIN */
+#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
+# define TZ_DOMAIN "tz"
+#endif
#if HAVE_INCOMPATIBLE_CTIME_R
#undef asctime_r
@@ -282,8 +582,4 @@
#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
#endif /* !defined SECSPERREPEAT_BITS */
-/*
-** UNIX was a registered trademark of The Open Group in 2003.
-*/
-
#endif /* !defined PRIVATE_H */
Modified: vendor/tzcode/dist/strftime.c
===================================================================
--- vendor/tzcode/dist/strftime.c 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/strftime.c 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,27 +1,39 @@
-#include "private.h"
+/* Convert a broken-down time stamp to a string. */
+/* Copyright 1989 The Regents of the University of California.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE. */
+
/*
-** Copyright (c) 1989 The Regents of the University of California.
-** All rights reserved.
+** Based on the UCB version with the copyright notice appearing above.
**
-** 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.
+** This is ANSIish only when "multibyte character == plain character".
*/
-#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 "private.h"
#include "tzfile.h"
#include "fcntl.h"
@@ -40,15 +52,7 @@
const char * date_fmt;
};
-#ifdef LOCALE_HOME
-#include "sys/stat.h"
-static struct lc_time_T localebuf;
-static struct lc_time_T * _loc(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 = {
{
@@ -100,9 +104,11 @@
static char * _conv(int, const char *, char *, const char *);
static char * _fmt(const char *, const struct tm *, char *, const char *,
int *);
-static char * _yconv(int, int, int, int, char *, const char *);
+static char * _yconv(int, int, bool, bool, char *, char const *);
+#if !HAVE_POSIX_DECLS
extern char * tzname[];
+#endif
#ifndef YEAR_2000_NAME
#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
@@ -113,33 +119,39 @@
#define IN_THIS 2
#define IN_ALL 3
+#if HAVE_STRFTIME_L
size_t
-strftime(char * const s, const size_t maxsize, const char *const format,
- const struct tm *const t)
+strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
+ locale_t locale)
{
+ /* Just call strftime, as only the C locale is supported. */
+ return strftime(s, maxsize, format, t);
+}
+#endif
+
+size_t
+strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
+{
char * p;
int warn;
tzset();
-#ifdef LOCALE_HOME
- localebuf.mon[0] = 0;
-#endif /* defined LOCALE_HOME */
warn = IN_NONE;
p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
- (void) fprintf(stderr, "\n");
+ fprintf(stderr, "\n");
if (format == NULL)
- (void) fprintf(stderr, "NULL strftime format ");
- else (void) fprintf(stderr, "strftime format \"%s\" ",
+ fprintf(stderr, "NULL strftime format ");
+ else fprintf(stderr, "strftime format \"%s\" ",
format);
- (void) fprintf(stderr, "yields only two digits of years in ");
+ fprintf(stderr, "yields only two digits of years in ");
if (warn == IN_SOME)
- (void) fprintf(stderr, "some locales");
+ fprintf(stderr, "some locales");
else if (warn == IN_THIS)
- (void) fprintf(stderr, "the current locale");
- else (void) fprintf(stderr, "all locales");
- (void) fprintf(stderr, "\n");
+ fprintf(stderr, "the current locale");
+ else fprintf(stderr, "all locales");
+ fprintf(stderr, "\n");
}
#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
if (p == s + maxsize)
@@ -149,8 +161,8 @@
}
static char *
-_fmt(const char *format, const struct tm *const t, char * pt,
- const char *const ptlim, int *warnp)
+_fmt(const char *format, const struct tm *t, char *pt,
+ const char *ptlim, int *warnp)
{
for ( ; *format; ++format) {
if (*format == '%') {
@@ -192,8 +204,8 @@
** something completely different.
** (ado, 1993-05-24)
*/
- pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0,
- pt, ptlim);
+ pt = _yconv(t->tm_year, TM_YEAR_BASE,
+ true, false, pt, ptlim);
continue;
case 'c':
{
@@ -310,10 +322,10 @@
tm = *t;
mkt = mktime(&tm);
if (TYPE_SIGNED(time_t))
- (void) sprintf(buf, "%ld",
- (long) mkt);
- else (void) sprintf(buf, "%lu",
- (unsigned long) mkt);
+ sprintf(buf, "%"PRIdMAX,
+ (intmax_t) mkt);
+ else sprintf(buf, "%"PRIuMAX,
+ (uintmax_t) mkt);
pt = _add(buf, pt, ptlim);
}
continue;
@@ -348,7 +360,7 @@
** (01-53)."
** (ado, 1993-05-24)
**
-** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
+** From <http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html> by Markus Kuhn:
** "Week 01 of a year is per definition the first week which has the
** Thursday in this year, which is equivalent to the week which contains
** the fourth day of January. In other words, the first week of a new year
@@ -421,9 +433,11 @@
pt, ptlim);
else if (*format == 'g') {
*warnp = IN_ALL;
- pt = _yconv(year, base, 0, 1,
+ pt = _yconv(year, base,
+ false, true,
pt, ptlim);
- } else pt = _yconv(year, base, 1, 1,
+ } else pt = _yconv(year, base,
+ true, true,
pt, ptlim);
}
continue;
@@ -461,22 +475,23 @@
continue;
case 'y':
*warnp = IN_ALL;
- pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1,
+ pt = _yconv(t->tm_year, TM_YEAR_BASE,
+ false, true,
pt, ptlim);
continue;
case 'Y':
- pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1,
+ pt = _yconv(t->tm_year, TM_YEAR_BASE,
+ true, true,
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 */
+ pt = _add(t->TM_ZONE, pt, ptlim);
+#else
if (t->tm_isdst >= 0)
pt = _add(tzname[t->tm_isdst != 0],
pt, ptlim);
+#endif
/*
** C99 says that %Z must be replaced by the
** empty string if the time zone is not
@@ -485,7 +500,7 @@
continue;
case 'z':
{
- int diff;
+ long diff;
char const * sign;
if (t->tm_isdst < 0)
@@ -494,7 +509,7 @@
diff = t->TM_GMTOFF;
#else /* !defined TM_GMTOFF */
/*
- ** C99 says that the UTC offset must
+ ** C99 says that the UT offset must
** be computed by looking only at
** tm_isdst. This requirement is
** incorrect, since it means the code
@@ -558,17 +573,16 @@
}
static char *
-_conv(const int n, const char *const format, char *const pt,
- const char *const ptlim)
+_conv(int n, const char *format, char *pt, const char *ptlim)
{
char buf[INT_STRLEN_MAXIMUM(int) + 1];
- (void) sprintf(buf, format, n);
+ sprintf(buf, format, n);
return _add(buf, pt, ptlim);
}
static char *
-_add(const char *str, char *pt, const char *const ptlim)
+_add(const char *str, char *pt, const char *ptlim)
{
while (pt < ptlim && (*pt = *str++) != '\0')
++pt;
@@ -584,8 +598,8 @@
*/
static char *
-_yconv(const int a, const int b, const int convert_top, const int convert_yy,
- char *pt, const char *const ptlim)
+_yconv(int a, int b, bool convert_top, bool convert_yy,
+ char *pt, const char *ptlim)
{
register int lead;
register int trail;
@@ -610,124 +624,3 @@
pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim);
return pt;
}
-
-#ifdef LOCALE_HOME
-static struct lc_time_T *
-_loc(void)
-{
- static const char locale_home[] = LOCALE_HOME;
- static const char lc_time[] = "LC_TIME";
- static char * locale_buf;
-
- int fd;
- int oldsun; /* "...ain't got nothin' to do..." */
- char * lbuf;
- char * name;
- char * p;
- const char ** ap;
- const char * plim;
- char filename[FILENAME_MAX];
- struct stat st;
- size_t namesize;
- size_t bufsize;
-
- /*
- ** Use localebuf.mon[0] to signal whether locale is already set up.
- */
- if (localebuf.mon[0])
- return &localebuf;
- name = setlocale(LC_TIME, NULL);
- if (name == NULL || *name == '\0')
- goto no_locale;
- /*
- ** If the locale name is the same as our cache, use the cache.
- */
- lbuf = locale_buf;
- if (lbuf != NULL && strcmp(name, lbuf) == 0) {
- p = lbuf;
- for (ap = (const char **) &localebuf;
- ap < (const char **) (&localebuf + 1);
- ++ap)
- *ap = p += strlen(p) + 1;
- return &localebuf;
- }
- /*
- ** Slurp the locale file into the cache.
- */
- namesize = strlen(name) + 1;
- if (sizeof filename <
- ((sizeof locale_home) + namesize + (sizeof lc_time)))
- goto no_locale;
- oldsun = 0;
- (void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time);
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- /*
- ** Old Sun systems have a different naming and data convention.
- */
- oldsun = 1;
- (void) sprintf(filename, "%s/%s/%s", locale_home,
- lc_time, name);
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- goto no_locale;
- }
- if (fstat(fd, &st) != 0)
- goto bad_locale;
- if (st.st_size <= 0)
- goto bad_locale;
- bufsize = namesize + st.st_size;
- locale_buf = NULL;
- lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize);
- if (lbuf == NULL)
- goto bad_locale;
- (void) strcpy(lbuf, name);
- p = lbuf + namesize;
- plim = p + st.st_size;
- if (read(fd, p, st.st_size) != st.st_size)
- goto bad_lbuf;
- if (close(fd) != 0)
- goto bad_lbuf;
- /*
- ** Parse the locale file into localebuf.
- */
- if (plim[-1] != '\n')
- goto bad_lbuf;
- for (ap = (const char **) &localebuf;
- ap < (const char **) (&localebuf + 1);
- ++ap) {
- if (p == plim)
- goto bad_lbuf;
- *ap = p;
- while (*p != '\n')
- ++p;
- *p++ = '\0';
- }
- if (oldsun) {
- /*
- ** SunOS 4 used an obsolescent format; see localdtconv(3).
- ** c_fmt had the ``short format for dates and times together''
- ** (SunOS 4 date, "%a %b %e %T %Z %Y" in the C locale);
- ** date_fmt had the ``long format for dates''
- ** (SunOS 4 strftime %C, "%A, %B %e, %Y" in the C locale).
- ** Discard the latter in favor of the former.
- */
- localebuf.date_fmt = localebuf.c_fmt;
- }
- /*
- ** Record the successful parse in the cache.
- */
- locale_buf = lbuf;
-
- return &localebuf;
-
-bad_lbuf:
- free(lbuf);
-bad_locale:
- (void) close(fd);
-no_locale:
- localebuf = C_time_locale;
- locale_buf = NULL;
- return &localebuf;
-}
-#endif /* defined LOCALE_HOME */
Modified: vendor/tzcode/dist/time2posix.3
===================================================================
--- vendor/tzcode/dist/time2posix.3 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/time2posix.3 2016-08-15 01:50:22 UTC (rev 7736)
@@ -3,23 +3,30 @@
time2posix, posix2time \- convert seconds since the Epoch
.SH SYNOPSIS
.nf
-.B #include <sys/types.h>
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
.B #include <time.h>
.PP
-.B time_t time2posix(t)
-.B time_t t
+.B time_t time2posix(time_t t);
.PP
-.B time_t posix2time(t)
-.B time_t t
+.B time_t posix2time(time_t t);
.PP
-.B cc ... -ltz
+.B cc ... \*-ltz
.fi
.SH DESCRIPTION
+.ie '\(en'' .ds en \-
+.el .ds en \(en
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
IEEE Standard 1003.1
(POSIX)
-legislates that a time_t value of
-536457599 shall correspond to "Wed Dec 31 23:59:59 UTC 1986."
-This effectively implies that POSIX time_t's cannot include leap
+requires the time_t value 536457599 to stand for 1986-12-31 23:59:59 UTC.
+This effectively implies that POSIX time_t values cannot include leap
seconds and,
therefore,
that the system time must be adjusted as each leap occurs.
@@ -29,7 +36,9 @@
however,
no such adjustment is needed and
time_t values continue to increase over leap events
-(as a true `seconds since...' value).
+(as a true
+.q "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
@@ -36,7 +45,7 @@
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
+opaque \*(en time_t values should only be obtained-from and
passed-to functions such as
.IR time(2) ,
.IR localtime(3) ,
Modified: vendor/tzcode/dist/time2posix.3.txt
===================================================================
--- vendor/tzcode/dist/time2posix.3.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/time2posix.3.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,41 +1,37 @@
-TIME2POSIX(3) TIME2POSIX(3)
+TIME2POSIX(3) Library Functions Manual TIME2POSIX(3)
NAME
time2posix, posix2time - convert seconds since the Epoch
SYNOPSIS
- #include <sys/types.h>
#include <time.h>
- time_t time2posix(t)
- time_t t
+ time_t time2posix(time_t t);
- time_t posix2time(t)
- time_t t
+ time_t posix2time(time_t t);
cc ... -ltz
DESCRIPTION
- IEEE Standard 1003.1 (POSIX) legislates that a time_t value of
- 536457599 shall correspond to "Wed Dec 31 23:59:59 UTC 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.
+ IEEE Standard 1003.1 (POSIX) requires the time_t value 536457599 to
+ stand for 1986-12-31 23:59:59 UTC. This effectively implies that POSIX
+ time_t values cannot include leap seconds and, therefore, that the
+ system time must be adjusted as each leap occurs.
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
+ 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.
Typically this is not a problem as the type time_t is intended to be
- (mostly) opaque--time_t values should only be obtained-from and passed-
- to functions such as time(2), localtime(3), mktime(3), and 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.
+ (mostly) opaque - time_t values should only be obtained-from and
+ passed-to functions such as time(2), localtime(3), mktime(3), and
+ 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.
The time2posix and posix2time functions are provided to address this
time_t mismatch by converting between local time_t values and their
Modified: vendor/tzcode/dist/tz-art.htm
===================================================================
--- vendor/tzcode/dist/tz-art.htm 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/tz-art.htm 2016-08-15 01:50:22 UTC (rev 7736)
@@ -3,22 +3,29 @@
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
-<meta http-equiv="Content-type" content='text/html; charset="US-ASCII"'>
+<meta http-equiv="Content-type" content='text/html; charset="UTF-8"'>
<title>Time and the Arts</title>
</head>
<body>
<h1>Time and the Arts</h1>
+<h2>Documentaries</h2>
+<ul>
+<li>
+"<a href="https://www.youtube.com/watch?v=84aWtseb2-4">Daylight
+Saving Time Explained</a>" (2011; 6:39) lightly covers daylight saving
+time's theory, history, pros and cons. Among other things, it explains
+Arizona's daylight-saving enclaves quite well.</li>
+<li>
+"<a href="https://www.youtube.com/watch?v=-5wpm-gesOY">The Problem
+with Time & Timezones – Computerphile</a>" (2013; 10:12) delves
+into problems that programmers have with timekeeping.</li>
+<li>
+"About Time" (1962; 53 minutes) is part of the the
+Bell Science extravaganza, with Frank Baxter, Richard Deacon, and Les Tremayne.
+(<a href="http://www.imdb.com/title/tt0154110/">IMDb entry</a>.)</li>
+</ul>
+<h2>Music</h2>
<p>
-This file is in the public domain, so clarified as of
-2009-05-17 by Arthur David Olson.
-</p>
-<p>
-Please send corrections to this web page to the
-<a href="mailto:tz at iana.org">time zone mailing list</a>.</p>
-<p>
-See also <a href="tz-link.htm">Sources for Time Zone and Daylight Saving Time Data</a>.</p>
-<hr>
-<p>
Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:</p>
<table>
<tr><td>Artist</td><td>Karrin Allyson</td></tr>
@@ -34,7 +41,7 @@
<tr><td>Notes</td><td>CD notes "additional lyric by Karrin Allyson;
arranged by Russ Long and Karrin Allyson"</td></tr>
<tr><td>ADO Rating</td><td>1 star</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=A1fdovw9ta92k">AMG Rating</a></td><td>4 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/i-didnt-know-about-you-mw0000618657">AMG Rating</a></td><td>4 stars</td></tr>
<tr><td>Penguin Rating</td><td>3.5 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Kevin Mahogany</td></tr>
@@ -49,7 +56,7 @@
Ralph Moore, tenor saxophone;
Lewis Nash, drums</td></tr>
<tr><td>ADO Rating</td><td>1.5 stars</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=Akikbikzjbb19">AMG Rating</a></td><td>3 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/double-rainbow-mw0000620371">AMG Rating</a></td><td>3 stars</td></tr>
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Joe Williams</td></tr>
@@ -63,7 +70,7 @@
<tr><td>Notes</td><td>This CD is also available as part of a 3-CD package from
Telarc, "Triple Play" (CD-83461)</td></tr>
<tr><td>ADO Rating</td><td>black dot</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=Amyyvad6kt8w1">AMG Rating</a></td><td>2 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/heres-to-life-mw0000623648">AMG Rating</a></td><td>2 stars</td></tr>
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Charles Fambrough</td></tr>
@@ -77,10 +84,8 @@
Edward Simon, piano;
Lenny White, drums;
Marion Simon, percussion</td></tr>
-<tr><td>Notes</td><td>On-line information and samples available at
-<a href="http://wwmusic.com/~music/audioq/rel/1033.html">http://wwmusic.com/~music/audioq/rel/1033.html</a></td></tr>
<tr><td>ADO Rating</td><td>2 stars</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=A5rkcikcjbb89">AMG Rating</a></td><td>unrated</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/keeper-of-the-spirit-mw0000176559">AMG Rating</a></td><td>unrated</td></tr>
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
</table>
<hr>
@@ -98,7 +103,7 @@
<tr><td>Notes</td><td>Lyrical reference to "Eastern Standard Time" in
Tom Waits' "Purple Avenue"</td></tr>
<tr><td>ADO Rating</td><td>2.5 stars</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=A3a9ds37ya3dg">AMG Rating</a></td><td>3 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/blame-it-on-my-youth-mw0000274303">AMG Rating</a></td><td>3 stars</td></tr>
<tr><td>Penguin Rating</td><td>unrated</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Milt Hinton</td></tr>
@@ -125,11 +130,11 @@
A Hot Time in the Old Town Tonight,
Four or Five Times, Now's the Time,
Time on My Hands, This Time It's Us,
-and Good Time Charlie
-On-line samples available at
-<a href="http://www.chiaroscurojazz.com/albuminfo.php4?albumid=49">http://www.chiaroscurojazz.com/albuminfo.php3?albumid=49</a></td></tr>
+and Good Time Charlie.
+<a href="http://www.chiaroscurojazz.com/album.php?C=310">Album info</a>
+is available.</td></tr>
<tr><td>ADO Rating</td><td>3 stars</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=A1cbyxdab8ola">AMG Rating</a></td><td>4.5 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/old-man-time-mw0000269353">AMG Rating</a></td><td>4.5 stars</td></tr>
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Alan Broadbent</td></tr>
@@ -143,7 +148,7 @@
Frank Gibson, Jr., drums</td></tr>
<tr><td>Notes</td><td>The CD cover features an analemma for equation-of-time fans</td></tr>
<tr><td>ADO Rating</td><td>1 star</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=Asl8zefuk8gfo">AMG Rating</a></td><td>4 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/pacific-standard-time-mw0000645433">AMG Rating</a></td><td>4 stars</td></tr>
<tr><td>Penguin Rating</td><td>3.5 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Anthony Braxton/Richard Teitelbaum</td></tr>
@@ -158,7 +163,7 @@
Leroy Jenkins, violin and miscellaneous instruments;
Richard Teitelbaum, modular moog and micromoog synthesizer</td></tr>
<tr><td>ADO Rating</td><td>black dot</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=A5bkvu3xjan1k">AMG Rating</a></td><td>unrated</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/silence-time-zones-mw0000595735">AMG Rating</a></td><td>4 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Charles Gayle</td></tr>
<tr><td>CD</td><td>Time Zones</td></tr>
@@ -168,7 +173,7 @@
<tr><td>Total Time</td><td>49:06</td></tr>
<tr><td>Personnel</td><td>Charles Gayle, piano</td></tr>
<tr><td>ADO Rating</td><td>1 star</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=10:13rc28vw054a">AMG Rating</a></td><td>4.5 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/time-zones-mw0000349642">AMG Rating</a></td><td>4.5 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>The Get Up Kids</td></tr>
<tr><td>CD</td><td>Eudora</td></tr>
@@ -177,7 +182,7 @@
<tr><td>ID</td><td>357</td></tr>
<tr><td>Total Time</td><td>65:12</td></tr>
<tr><td>Notes</td><td>Includes the song "Central Standard Time." Thanks to Colin Bowern for this information.</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=10:7ddovwvla9xk">AMG Rating</a></td><td>2.5 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/eudora-mw0000592063">AMG Rating</a></td><td>2.5 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Coldplay</td></tr>
@@ -195,7 +200,7 @@
<tr><td>Artist</td><td>Irving Kahal and Harry Richman</td></tr>
<tr><td>Song</td><td>There Ought to be a Moonlight Saving Time</td></tr>
<tr><td>Copyright Date</td><td>1931</td>
-<tr><td>Notes</td><td>This musical standard was a #1 hit for Guy Lombardo
+<tr><td>Notes</td><td>This musical standard was a No. 1 hit for Guy Lombardo
in 1931, and was also performed by Maurice Chevalier, Blossom Dearie
and many others. The phrase "Moonlight saving time" also appears in
the 1995 country song "Not Enough Hours in the Night" written by Aaron
@@ -210,18 +215,18 @@
<tr><td>ID</td><td>272</td></tr>
<tr><td>Total Time</td><td>73:05</td></tr>
<tr><td>Notes</td><td>Includes the song "Twilight Time Zone."</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=10:w9fpxzykldje">AMG Rating</a></td><td>3.5 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/lobster-leaps-in-mw0000794929">AMG Rating</a></td><td>3.5 stars</td></tr>
<tr><td>ADO Rating</td><td>2 stars</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Bob Dylan</td></tr>
-<tr><td>CD</td><td>The Time They Are A-Changin'</td></tr>
+<tr><td>CD</td><td>The Times They Are a-Changin'</td></tr>
<tr><td>Copyright Date</td><td>1964</td></tr>
<tr><td>Label</td><td>Columbia</td></tr>
<tr><td>ID</td><td>CK-8905</td></tr>
<tr><td>Total Time</td><td>45:36</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=10:gifqxqt5ld0e">AMG Rating</a></td><td>4.5 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/the-times-they-a-changin-mw0000202344">AMG Rating</a></td><td>4.5 stars</td></tr>
<tr><td>ADO Rating</td><td>1.5 stars</td></tr>
<tr><td>Notes<td>The title song is also available on "Bob Dylan's Greatest Hits" and "The Essential Bob Dylan."</td></tr>
<tr><td> </td></tr>
@@ -232,10 +237,10 @@
<tr><td>Label</td><td>Universal Jazz France</td></tr>
<tr><td>ID</td><td>B0012688-02</td></tr>
<tr><td>Total Time</td><td>42:31</td></tr>
-<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=10:3bftxzw0ldhe">AMG Rating</a></td><td>3.5 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/tide-mw0000815692">AMG Rating</a></td><td>3.5 stars</td></tr>
<tr><td>ADO Rating</td><td>2.5 stars</td></tr>
<tr><td>Notes<td>Includes the song "Fire and Wood" with the lyric
-"The clocks were turned back you remeber/Think it's still November."
+"The clocks were turned back you remember/Think it's still November."
</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Ken Nordine</td></tr>
@@ -245,11 +250,83 @@
<tr><td>ID</td><td>B0005171-02</td></tr>
<tr><td>Total Time</td><td>156:22</td></tr>
<tr><td>ADO Rating</td><td>1 star</td></tr>
-<tr><td><a href="http://www.allmusic.com/album/youre-getting-better-the-word-jazz-dot-masters+r105931">AMG Rating</a></td><td>4.5 stars</td></tr>
+<tr><td><a href="http://www.allmusic.com/album/youre-getting-better-the-word-jazz-dot-masters-mw0000736197">AMG Rating</a></td><td>4.5 stars</td></tr>
<tr><td>Notes</td><td>Includes the piece "What Time Is It"
("He knew what time it was everywhere...that counted").</td></tr>
-<tr><td> </td></tr>
+</table>
+<h2>TV episodes</h2>
+
+<ul>
+<li>
+An episode of <em>The Adventures of Superman</em> entitled "The Mysterious
+Cube," first aired 1958-02-24, had Superman convincing the controllers
+of the Arlington Time Signal to broadcast ahead of actual time;
+doing so got a crook trying to be declared dead to
+emerge a bit too early from the titular enclosure.
+</li>
+<li>
+The 1960s ITC television series <em>The Prisoner</em> included an episode
+entitled "The Chimes of Big Ben" in which our protagonist tumbled to
+the fraudulent nature of a Poland-to-England escape upon hearing "Big
+Ben" chiming on Polish local time.
+</li>
+<li>
+The series <em>Seinfeld</em> included an episode entitled "The Susie," first
+broadcast 1997-02-13, in which Kramer decides that daylight saving time
+isn't coming fast enough, so he sets his watch ahead an hour.
+</li>
+<li>
+The "20 Hours in America" episode of <em>The West Wing</em>,
+first aired 2002-09-25,
+saw White House staffers stranded in Indiana; they thought they had time to
+catch Air Force One but were done in by intra-Indiana local time changes.
+</li>
+<li>
+"In what time zone would you find New York City?" was a $200 question on
+the 1999-11-13 United States airing of <em>Who Wants to Be a Millionaire?</em>,
+and "In 1883, what industry led the movement to divide the U.S. into four time
+zones?" was a $32,000 question on the 2001-05-23 United States airing of
+the same show. At this rate, the million-dollar time-zone
+question should have been asked 2002-06-04.
+</li>
+<li>
+A private jet's mid-flight change of time zones distorts Alison Dubois'
+premonition in the "We Had a Dream" episode of <em>Medium</em>
+(originally aired 2007-02-28).
+</li>
+<li>
+In the <em>30 Rock</em> episode "Anna Howard Shaw Day"
+(first broadcast 2010-02-11),
+Jack Donaghy's date realizes that a Geneva-to-New-York business phone call
+received in the evening must be fake given the difference in local times.
+</li>
+<li>
+In the "Run by the Monkeys" episode of <em>Da Vinci's Inquest</em>
+(first broadcast 2002-11-17),
+a witness in a five-year-old fire case realizes they may not have set
+their clock back when daylight saving ended on the day of the fire,
+introducing the possibility of an hour when arson might have occurred.
+</li>
+<li>
+In "The Todd Couple" episode of <em>Outsourced</em> (first aired 2011-02-10),
+Manmeet sets up Valentine's Day teledates for 6:00 and 9:00pm;
+since one is with a New Yorker and the other with a San Franciscan,
+hilarity ensues.
+(Never mind that this should be 7:30am in Mumbai, yet for some reason the show
+proceeds as though it's also mid-evening there.)
+</li>
+<li>
+In the "14 Days to Go"/"T Minus..." episode of
+<em>You, Me and the Apocalypse</em>
+(first aired 2015-11-11 in the UK, 2016-03-10 in the US),
+the success of a mission to deal with a comet
+hinges on whether or not Russia observes daylight saving time.
+(In the US, the episode first aired in the week before the switch to DST.)
+</li>
+</ul>
+
+<table>
<tr><td>TV episode title</td><td>The Lost Hour</td>
<tr><td>TV series</td><td><em>Eerie, Indiana</em></td>
<tr><td>TV episode number</td><td>10</td>
@@ -276,9 +353,21 @@
savings days. Lousy farmers."</td></tr>
<tr><td> </td></tr>
+<tr><td>TV episode title</td><td>Tracks</td></tr>
+<tr><td>TV series</td><td><em>The Good Wife</em></td></tr>
+<tr><td>TV episode number</td><td>12, season 7</td></tr>
+<tr><td>Network</td><td>CBS</td></tr>
+<tr><td>Air date</td><td>2016-01-17</td></tr>
+<tr><td>Notes</td><td>The applicability of a contract hinges on the
+time zone associated with a video time stamp.</td></tr>
+</table>
+
+<h2>Books, plays, and magazines</h2>
+
+<table>
<tr><td>Artist</td><td>Jules Verne</td></tr>
-<tr><td>Book</td><td>Le Tour du Monde en Quatre-Vingts Jours
-(Around the World in Eighty Days)</td></tr>
+<tr><td>Book</td><td><em>Around the World in Eighty Days</em>
+(<em>Le tour du monde en quatre-vingts jours</em>)</td></tr>
<tr><td>Notes</td><td>Wall-clock time plays a central role in the plot.
European readers of the 1870s clearly held the U.S. press in
deep contempt; the protagonists cross the U.S. without once
@@ -291,9 +380,17 @@
<a href="http://www.literature.org/Works/Jules-Verne/eighty">http://www.literature.org/Works/Jules-Verne/eighty</a></td></tr>
<tr><td> </td></tr>
+<tr><td>Artist</td><td>Nick Enright</td></tr>
+<tr><td>Play</td><td><em>Daylight Saving</em></td></tr>
+<tr><td>Copyright Date</td><td>1989</td></tr>
+<tr><td>Notes</td><td>
+A fast-paced comedy about love and loneliness as the clocks turn back.
+</td></tr>
+
+<tr><td> </td></tr>
<tr><td>Artist</td><td>Umberto Eco</td></tr>
-<tr><td>Book</td><td>The Island of the Day Before
-(L'isola del giorno prima)</td></tr>
+<tr><td>Book</td><td><em>The Island of the Day Before</em>
+(<em>L'isola del giorno prima</em>)</td></tr>
<tr><td>Copyright Date</td><td>1994</td></tr>
<tr><td>Notes</td><td>
"...the story of a 17th century Italian nobleman trapped near an island
@@ -301,86 +398,32 @@
part in the novel." (Paul Eggert, 2006-04-22)
</td></tr>
<tr><td> </td></tr>
-<tr><td>Artist</td><td>David Jebb</td></tr>
-<tr><td>Book</td><td><a href="http://www.thethirteenthtimezone.com">
-The Thirteenth Time Zone</a></td></tr>
-<tr><td>Notes</td><td>
-"It's fiction, but it's based on his experiences and travels." (Paul Eggert, 2006-04-22)
-</td></tr>
-<tr><td> </td></tr>
<tr><td>Artist</td><td>John Dunning</td></tr>
<tr><td>Book</td><td><a
-href="http://www.simonsays.com/content/book.cfm?sid=33&pid=479719">Two
-O'Clock, Eastern Wartime</a></td></tr>
+href="http://books.simonandschuster.com/Two-OClock-Eastern-Wartime/John-Dunning/9781439171530"><em>Two
+O'Clock, Eastern Wartime</em></a></td></tr>
<tr><td>Copyright Date</td><td>2001</td></tr>
<tr><td>Notes</td><td>
Mystery, history, daylight saving time, and old-time radio.
</td></tr>
-<tr><td> </td></tr>
-<tr><td>Film</td><td>Bell Science - About Time</td></tr>
-<tr><td>Notes</td><td>The Frank Baxter/Richard Deacon extravaganza.
-Information is available at
-<a href="http://www.videoflicks.com/titles/1035/1035893.htm">http://www.videoflicks.com/titles/1035/1035893.htm</a></td></tr>
</table>
<hr>
<ul>
<li>
-An episode of "The Adventures of Superman" entitled "The Mysterious
-Cube," first aired 1958-02-24, had Superman convincing the controllers
-of WWV to broadcast time signals five minutes ahead of actual time;
-doing so got a crook trying to beat the statute of limitations to
-emerge a bit too early from the titular enclosure.
-</li>
-<li>
-The 1960s ITC television series "The Prisoner" included an episode
-entitled "The Chimes of Big Ben" in which our protagonist tumbled to
-the fraudulent nature of a Poland-to-England escape upon hearing "Big
-Ben" chiming on Polish local time.
-</li>
-<li>
-The series "Seinfeld" included an episode entitled "The Susie," first
-broadcast 1997-02-13, in which Kramer decides that daylight saving time
-isn't coming fast enough, so he sets his watch ahead an hour.
-</li>
-<li>
-The syndicated comic strip "Dilbert" featured an all-too-rare example of
-time zone humor on 1998-03-14.
-</li>
-<li>
Surrealist artist Guy Billout's work "Date Line" appeared on page 103
-of the 1999-11 Atlantic Monthly.
+of the 1999-11 <em>Atlantic Monthly</em>.
</li>
<li>
-"Gloom, Gloom, Go Away" by Walter Kirn appeared on page 106 of Time
-Magazine's 2002-11-11 issue; among other things, it proposed
+"Gloom, Gloom, Go Away" by Walter Kirn appeared on page 106 of <em>Time</em>
+magazine's 2002-11-11 issue; among other things, it proposed
year-round DST as a way of lessening wintertime despair.
</li>
+</ul>
+<h2>Movies</h2>
+<ul>
<li>
-The "20 Hours in America" episode of "The West Wing," first aired 2002-09-25,
-saw White House staffers stranded in Indiana; they thought they had time to
-catch Air Force One but were done in by intra-Indiana local time changes.
-</li>
-<li>
-"In what time zone would you find New York City?" was a $200 question on
-the 1999-11-13 United States airing of "Who Wants to Be a Millionaire?"
-"In 1883, what industry led the movement to divide the U.S. into four time
-zones?" was a $32,000 question on the 2001-05-23 United States airing of
-"Who Wants to Be a Millionaire?" At this rate, the million-dollar time-zone
-question should have been asked 2002-06-04.
-</li>
-<li>
-A private jet's mid-flight change of time zones distorts Alison Dubois'
-premonition in the "We Had a Dream" episode of "Medium"
-(originally aired 2007-02-28).
-</li>
-<li>
-In the "30 Rock" episode "Anna Howard Shaw Day" (first broadcast 2010-02-11),
-Jack Donaghy's date realizes that a Geneva-to-New-York business phone call
-received in the evening must be fake given the difference in local times.
-</li>
-<li>
-In the 1946 movie "A Matter of Life and Death"
-(U.S. title "Stairway to Heaven")
+In the 1946 movie <em>A Matter of Life and Death</em>
+(U.S. title <em>Stairway to Heaven</em>)
there is a reference to British Double Summer Time.
The time does not play a large part in the plot;
it's just a passing reference to the time when one of the
@@ -390,17 +433,17 @@
http://us.imdb.com/title/tt0038733/
</a>. (Dave Cantor)
<li>
-The 1953 railway comedy movie "The Titfield Thunderbolt" includes a
+The 1953 railway comedy movie <em>The Titfield Thunderbolt</em> includes a
play on words on British Double Summer Time. Valentine's wife wants
him to leave the pub and asks him, "Do you know what time it is?"
And he, happy where he is, replies: "Yes, my love. Summer double time."
-IMDB page:
+IMDb page:
<a href="http://us.imdb.com/title/tt0046436/">
http://us.imdb.com/title/tt0046436/
</a>. (Mark Brader, 2009-10-02)
</li>
<li>
-The premise of the 1999 caper movie "Entrapment" involves computers
+The premise of the 1999 caper movie <em>Entrapment</em> involves computers
in an international banking network being shut down briefly at
midnight in each time zone to avoid any problems at the transition
from the year 1999 to 2000 in that zone. (Hmmmm.) If this shutdown
@@ -408,36 +451,61 @@
a gigantic computerized theft. To achieve this, at one location the
crooks interfere with the microwave system supplying time signals to
the computer, advancing the time by 0.1 second each minute over the
-last hour of 1999. (So this movie teaches us that 0.1 x 60 = 10.)
-IMDB page:
+last hour of 1999. (So this movie teaches us that 0.1 × 60 = 10.)
+IMDb page:
<a href="http://us.imdb.com/title/tt0137494/">
http://us.imdb.com/title/tt0137494/
</a>. (Mark Brader, 2009-10-02)
</li>
<li>
-In "The Todd Couple" episode of "Outsourced" (first aired 2011-02-10),
-Manmeet sets up teledates for 6:00 and 9:00;
-since one is with a New Yorker and the other with a San Franciscan,
-hilarity ensues.
+One mustn't forget the
+<a href="https://www.youtube.com/watch?v=k4EUTMPuvHo">trailer</a>
+(2014; 2:23) for the movie <em>Daylight Saving</em>.
</li>
</ul>
-<hr>
+<h2>Comics</h2>
<ul>
<li>
-"We're been using the five-cent nickle in this country since 1492.
-Now that's pretty near 100 years, daylight savings [sic]."
-(Groucho Marx as Captain Spaulding in "Animal Crackers", 1930,
-as noted by Will Fitzerald)
+The webcomic <em>xkcd</em> has the strip
+"<a href='http://xkcd.com/673/'>The Sun</a>" (2009-12-09) and the panels
+"<a href='http://xkcd.com/1017/'>Backward in Time</a>" (2012-02-14),
+"<a href='http://xkcd.com/1061/'>EST</a>" (2012-05-28), and
+"<a href='http://xkcd.com/1335/'>Now</a>" (2014-02-26), and
+"<a href='http://xkcd.com/1655/'>Doomsday Clock</a>" (2016-03-14).
+The related book <em>What If?</em> has an entry
+"<a href='http://what-if.xkcd.com/26/'>Leap Seconds</a>" (2012-12-31).
</li>
<li>
-Brady: "...[Bishop Usher] determined that the Lord began the Creation
-on the 23rd of October in the Year 4004 B.C. at -- uh, at 9 A.M.!"
+The syndicated comic strip <em>Dilbert</em> featured an
+<a href='http://dilbert.com/strip/1998-03-14'>example of
+time zone humor</a> on 1998-03-14.
+</li>
+<li>
+Peppermint Patty: "What if the world comes to an end tonight, Marcie?"
<br>
-Drummond: "That Eastern Standard Time? (Laughter) Or Rocky Mountain
-Time? (More laughter) It wasn't daylight-saving time, was it? Because
-the Lord didn't make the sun until the fourth day!"
+Marcie: "I promise there'll be a tomorrow, sir ... in fact,
+it's already tomorrow in Australia!"
<br>
-(From the play "Inherit the Wind" by Jerome Lawrence and Robert E. Lee,
+(Charles M. Schulz, <a href='http://www.gocomics.com/peanuts/1980/06/13'><em>Peanuts</em>, 1980-06-13</a>)
+</li>
+</ul>
+<h2>Jokes</h2>
+<ul>
+<li>
+"We've been using the five-cent nickel in this country since 1492.
+Now that's pretty near 100 years, daylight saving."
+(Groucho Marx as Captain Spaulding in <em>Animal Crackers</em>, 1930,
+as noted by Will Fitzgerald)
+</li>
+<li>
+BRADY. ...[Bishop Usher] determined that the Lord began the Creation
+on the 23rd of October in the Year 4,004 B.C. at – uh, 9 A.M.!
+<br>
+DRUMMOND. That Eastern Standard Time? (<em>Laughter.</em>) Or Rocky Mountain
+Time? (<em>More laughter.</em>) It wasn't daylight-saving time, was it? Because
+the Lord didn't make the sun until the fourth day!
+<br>
+(From the play <em>Inherit the Wind</em> by Jerome Lawrence and Robert E. Lee,
filmed in 1960 with Spencer Tracy as Drummond and Fredric March as
Brady, and several other times. Thanks to Mark Brader.)
</li>
@@ -445,13 +513,13 @@
"Good news."
"What did they do? Extend Daylight Saving Time year round?"
(Professional tanner George Hamilton, in dialog from a
-May, 1999 episode of the syndicated television series "Baywatch")
+May, 1999 episode of the syndicated television series <em>Baywatch</em>)
</li>
<li>
"A fundamental belief held by Americans is that if you are on land, you
cannot be killed by a fish...So most Americans remain on land, believing
-they're safe. Unfortunately, this belief—like so many myths, such as that
-there's a reason for 'Daylight Saving Time'—is false."
+they're safe. Unfortunately, this belief – like so many myths, such as that
+there's a reason for 'Daylight Saving Time' – is false."
(Dave Barry column, 2000-07-02)
</li>
<li>
@@ -461,32 +529,46 @@
</li>
<li>
"Would it impress you if I told you I invented Daylight Savings Time?"
-("Sahjhan" to "Lilah" in dialog from the "Loyalty" episode of "Angel,"
+("Sahjhan" to "Lilah" in dialog from the "Loyalty" episode of <em>Angel</em>,
originally aired 2002-02-25)
</li>
<li>
-"I thought you said Tulsa was a three hour flight."
+"I thought you said Tulsa was a three-hour flight."
"Well, you're forgetting about the time difference."
-("Chandler" and "Joey" in dialog from the episode of "Friends" first
-aired 2002-12-05)
+("Joey" and "Chandler" in dialog from the episode of <em>Friends</em>
+entitled "The One With Rachel's Phone Number," originally aired 2002-12-05)
</li>
<li>
"Is that a pertinent fact,
-or are you trying to dazzle me with your command of time zones?"
-(Kelsey Grammer as "Frasier Crane")
+or are you just trying to dazzle me with your command of time zones?"
+(Kelsey Grammer as "Frasier Crane" to "Roz" from the episode of <em>Frasier</em>
+entitled "The Kid," originally aired 1997-11-04)
</li>
<li>
-"Don't worry about the world coming to an end today.
-It is already tomorrow in Australia."
-(Charles M. Schulz, provided by Steve Summit)
-</li>
-<li>
"I put myself and my staff through this crazy, huge ordeal, all because
I refused to go on at midnight, okay? And so I work, you know, and
then I get this job at eleven, supposed to be a big deal. Then
yesterday daylight [saving] time ended. Right now it's basically
-midnight." (Conan O'Brien on the 2010-11-08 premier of "Conan.")
+midnight." (Conan O'Brien on the 2010-11-08 premiere of <em>Conan</em>.)
</li>
+<li>
+"Well, in my time zone that's all the time I have,
+but maybe in your time zone I haven't finished yet. So stay tuned!"
+(Goldie Hawn, <em>Rowan & Martin's Laugh-In</em> No. 65, 1970-03-09)
+</li>
</ul>
+<h2>See also</h2>
+<ul>
+<li><a href="tz-link.htm">Sources for Time Zone and Daylight Saving
+Time Data</a></li>
+</ul>
+<hr>
+<address>
+This web page is in the public domain, so clarified as of
+2009-05-17 by Arthur David Olson.
+<br>
+Please send corrections to this web page to the
+<a href="mailto:tz at iana.org">time zone mailing list</a>.
+</address>
</body>
</html>
Added: vendor/tzcode/dist/tz-how-to.html
===================================================================
--- vendor/tzcode/dist/tz-how-to.html (rev 0)
+++ vendor/tzcode/dist/tz-how-to.html 2016-08-15 01:50:22 UTC (rev 7736)
@@ -0,0 +1,680 @@
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head><title>How to Read the tz Database</title></head>
+<body>
+<h2>How to Read the <a href="https://en.wikipedia.org/wiki/Tz_database">tz
+Database</a> Source Files</h2>
+<h3>by Bill Seymour</h3>
+<p>This page uses the <code>America/Chicago</code> and
+<code>Pacific/Honolulu</code> zones as examples of how to infer
+times of day from the <a href="tz-link.htm">tz database</a>
+source files. It might be helpful, but not absolutely necessary,
+for the reader to have already downloaded the
+<a href="http://www.iana.org/time-zones/repository/tzdata-latest.tar.gz">latest
+release of the database</a> and become familiar with the basic layout
+of the data files. The format is explained in the “man
+page” for the zic compiler, <code>zic.8.txt</code>, in
+the <code>code</code> subdirectory.</p>
+
+<p>We’ll begin by talking about the rules for changing between standard
+and daylight saving time since we’ll need that information when we talk
+about the zones.</p>
+
+<p>First, let’s consider the special daylight saving time rules
+for Chicago (from the <code>northamerica</code> file in
+the <code>data</code> subdirectory):</p>
+
+<table border="1">
+<tr>
+ <th colspan="6">From the Source File</th>
+</tr>
+<tr>
+ <td colspan="6" align="center"><table><tr><td>
+<pre>
+#Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+Rule Chicago 1920 only - Jun 13 2:00 1:00 D
+Rule Chicago 1920 1921 - Oct lastSun 2:00 0 S
+Rule Chicago 1921 only - Mar lastSun 2:00 1:00 D
+Rule Chicago 1922 1966 - Apr lastSun 2:00 1:00 D
+Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S
+Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S
+</pre>
+ </td></tr></table></td>
+</tr>
+<tr>
+ <th colspan="6">Reformatted a Bit</th>
+</tr>
+<tr>
+ <th>From</th>
+ <th>To</th>
+ <th colspan="2">On</th>
+ <th>At</th>
+ <th>Action</th>
+</tr>
+<tr align="center">
+ <td colspan="2">1920 only</td>
+ <td colspan="2">June 13<small><sup>th</sup></small></td>
+ <td rowspan="6">02:00 local</td>
+ <td>go to daylight saving time</td>
+</tr>
+<tr align="center">
+ <td>1920</td>
+ <td>1921</td>
+ <td rowspan="5">last Sunday</td>
+ <td>in October</td>
+ <td>return to standard time</td>
+</tr>
+<tr align="center">
+ <td colspan="2">1921 only</td>
+ <td>in March</td>
+ <td rowspan="2">go to daylight saving time</td>
+</tr>
+<tr align="center">
+ <td rowspan="2">1922</td>
+ <td>1966</td>
+ <td>in April</td>
+</tr>
+<tr align="center">
+ <td>1954</td>
+ <td>in September</td>
+ <td rowspan="2">return to standard time</td>
+</tr>
+<tr align="center">
+ <td>1955</td>
+ <td>1966</td>
+ <td>in October</td>
+</tr>
+</table>
+
+<p>We’ll basically just ignore the <code>TYPE</code> column.
+In the 2007j release, the most recent as of this writing, the
+<code>TYPE</code> column never contains anything but a hyphen,
+a kind of null value. (From the description in <code>zic.8.txt</code>,
+this appears to be a mechanism for removing years from a set
+in some localizable way. It’s used in the file, <code>pacificnew</code>,
+to determine whether a given year will have a US presidential election;
+but everything related to that use is commented out.)
+
+<p>The <code>SAVE</code> column contains the wall clock offset from
+local standard time.
+This is usually either zero for standard time or one hour for daylight
+saving time; but there’s no reason, in principle, why it can’t
+take on other values.
+
+<p>The <code>LETTER</code> (sometimes called <code>LETTER/S</code>)
+column can contain a variable
+part of the usual abbreviation of the time zone’s name, or it can just
+be a hyphen if there’s no variable part. For example, the abbreviation
+used in the central time zone will be either “CST” or
+“CDT”. The variable part is ‘S’ or ‘D’;
+and, sure enough, that’s just what we find in
+the <code>LETTER</code> column
+in the <code>Chicago</code> rules. More about this when we talk about
+“Zone” lines.
+
+<p>One important thing to notice is that “Rule” lines
+want at once to be both <i>transitions</i> and <i>steady states</i>:
+<ul>
+<li>On the one hand, they represent transitions between standard and
+daylight saving time; and any number of Rule lines can be in effect
+during a given period (which will always be a non-empty set of
+contiguous calendar years).</li>
+<li>On the other hand, the <code>SAVE</code> and <code>LETTER</code>
+columns contain state that exists between transitions. More about this
+when we talk about the US rules.</li>
+</ul>
+
+<p>In the example above, the transition to daylight saving time
+happened on the 13<small><sup>th</sup></small> of June in 1920, and on
+the last Sunday in March in 1921; but the return to standard time
+happened on the last Sunday in October in both of those
+years. Similarly, the rule for changing to daylight saving time was
+the same from 1922 to 1966; but the rule for returning to standard
+time changed in 1955. Got it?</p>
+
+<p>OK, now for the somewhat more interesting “US” rules:</p>
+
+<table border="1">
+<tr>
+ <th colspan="6">From the Source File</th>
+</tr>
+<tr>
+ <td colspan="6" align="center"><table><tr><td>
+<pre>
+#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 - Aug 14 23:00u 1:00 P # Peace
+Rule US 1945 only - Sep 30 2:00 0 S
+Rule US 1967 2006 - Oct lastSun 2:00 0 S
+Rule US 1967 1973 - Apr lastSun 2:00 1:00 D
+Rule US 1974 only - Jan 6 2:00 1:00 D
+Rule US 1975 only - Feb 23 2:00 1:00 D
+Rule US 1976 1986 - Apr lastSun 2:00 1:00 D
+Rule US 1987 2006 - Apr Sun>=1 2:00 1:00 D
+Rule US 2007 max - Mar Sun>=8 2:00 1:00 D
+Rule US 2007 max - Nov Sun>=1 2:00 0 S
+</pre>
+ </td></tr></table></td>
+</tr>
+<tr>
+ <th colspan="6">Reformatted a Bit</th>
+</tr>
+<tr>
+ <th>From</th>
+ <th>To</th>
+ <th colspan="2">On</th>
+ <th>At</th>
+ <th>Action</th>
+</tr>
+<tr align="center">
+ <td rowspan="2">1918</td>
+ <td rowspan="2">1919</td>
+ <td rowspan="2">last Sunday</td>
+ <td>in March</td>
+ <td rowspan="3">02:00 local</td>
+ <td>go to daylight saving time</td>
+</tr>
+<tr align="center">
+ <td>in October</td>
+ <td>return to standard time</td>
+</tr>
+<tr align="center">
+ <td colspan="2">1942 only</td>
+ <td colspan="2">February 9<small><sup>th</sup></small></td>
+ <td>go to “war time”</td>
+</tr>
+<tr align="center">
+ <td colspan="2" rowspan="2">1945 only</td>
+ <td colspan="2">August 14<small><sup>th</sup></small></td>
+ <td>23:00 <a href="https://en.wikipedia.org/wiki/Universal_Time">UT</a></td>
+ <td>
+ rename “war time” to “peace<br>time;”
+ clocks don’t change
+ </td>
+</tr>
+<tr align="center">
+ <td colspan="2">September 30<small><sup>th</sup></small></td>
+ <td rowspan="9">02:00 local</td>
+ <td rowspan="2">return to standard time</td>
+</tr>
+<tr align="center">
+ <td rowspan="2">1967</td>
+ <td>2006</td>
+ <td rowspan="2">last Sunday</td>
+ <td>in October</td>
+</tr>
+<tr align="center">
+ <td>1973</td>
+ <td>in April</td>
+ <td rowspan="6">go to daylight saving time</td>
+</tr>
+<tr align="center">
+ <td colspan="2">1974 only</td>
+ <td colspan="2">January 6<small><sup>th</sup></small></td>
+</tr>
+<tr align="center">
+ <td colspan="2">1975 only</td>
+ <td colspan="2">February 23<small><sup>rd</sup></small></td>
+</tr>
+<tr align="center">
+ <td>1976</td>
+ <td>1986</td>
+ <td>last Sunday</td>
+ <td rowspan="2">in April</td>
+</tr>
+<tr align="center">
+ <td>1987</td>
+ <td>2006</td>
+ <td>first Sunday</td>
+</tr>
+<tr align="center">
+ <td rowspan="2">2007</td>
+ <td rowspan="2">present</td>
+ <td colspan="2">second Sunday in March</td>
+</tr>
+<tr align="center">
+ <td colspan="2">first Sunday in November</td>
+ <td>return to standard time</td>
+</tr>
+</table>
+
+<p>There are two interesting things to note here.</p>
+
+<p>First, the time that something happens (in the <code>AT</code>
+column) is not necessarily the local wall clock time. The time can be
+suffixed with ‘s’ (for “standard”) to mean
+local standard time (different from wall clock time when observing
+daylight saving time); or it can be suffixed with ‘g’,
+‘u’, or ‘z’, all three of which mean the
+standard time at the
+<a href="https://en.wikipedia.org/wiki/Prime_Meridian">prime meridan</a>.
+‘g’ stands for “<a
+href="https://en.wikipedia.org/wiki/Greenwich_Mean_Time">GMT</a>”;
+‘u’ stands for “<a
+href="https://en.wikipedia.org/wiki/Universal_Time">UT</a>” or “<a
+href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a>”
+(whichever was official at the time); ‘z’ stands for the
+<a href="https://en.wikipedia.org/wiki/Nautical_time">nautical time zone</a>
+Z (a.k.a. “Zulu” which, in turn, stands for ‘Z’).
+The time can also be suffixed with ‘w’ meaning “wall
+clock time;” but it usually isn’t because that’s the
+default.</p>
+
+<p>Second, the day in the <code>ON</code> column, in addition to
+“<code>lastSun</code>” or a particular day of the month,
+can have the form, “<code>Sun>=</code><i>x</i>” or
+“<code>Sun<=</code><i>x</i>,” where <i>x</i> is a day
+of the month. For example, “<code>Sun>=8</code>” means
+“the first Sunday on or after the eighth of the month,” in
+other words, the second Sunday of the month. Furthermore, although
+there are no examples above, the weekday needn’t be
+“<code>Sun</code>” in either form, but can be the usual
+three-character English abbreviation for any day of the week.</p>
+
+<p>And the US rules give us more examples of a couple of things
+already mentioned:</p>
+
+<ul>
+<li>The rules for changing to and from daylight saving time are
+actually <i>different sets</i> of rules; and the two sets can change
+independently. Consider, for example, that the rule for the return to
+standard time stayed the same from 1967 to 2006; but the rule for the
+transition to daylight saving time changed several times in the same
+period. There can also be periods, 1946 to 1966 for example, when no
+rule from this group is in effect, and so either no transition
+happened in those years, or some other rule is in effect (perhaps a
+state or other more local rule).</li>
+
+<li>The <code>SAVE</code> and <code>LETTER</code> columns
+contain <i>steady state</i>, not transitions. Consider, for example,
+the transition from “war time” to “peace time”
+that happened on August 14, 1945. The “1:00” in
+the <code>SAVE</code> column is <i>not</i> an instruction to advance
+the clock an hour. It means that clocks should <i>be</i> one hour
+ahead of standard time, which they already are because of the previous
+rule, so there should be no change.</li>
+
+</ul>
+
+<p>OK, now let’s look at a Zone record:</p>
+
+<table border="1">
+<tr>
+ <th colspan="5">From the Source File</th>
+</tr>
+<tr>
+ <td colspan="6" align="center"><table><tr><td>
+<pre>
+#Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
+ -6:00 US C%sT 1920
+ -6:00 Chicago C%sT 1936 Mar 1 2:00
+ -5:00 - EST 1936 Nov 15 2:00
+ -6:00 Chicago C%sT 1942
+ -6:00 US C%sT 1946
+ -6:00 Chicago C%sT 1967
+ -6:00 US C%sT
+</pre>
+ </td></tr></table></td>
+</tr>
+<tr>
+ <th colspan="5">Columns Renamed</th>
+</tr>
+<tr>
+ <th rowspan="2">Standard Offset<br>
+ from <a href="https://en.wikipedia.org/wiki/Prime_Meridian">Prime
+ Meridian</a></th>
+ <th rowspan="2">Daylight<br>Saving Time</th>
+ <th rowspan="2">Abbreviation(s)</th>
+ <th colspan="2">Ending at Local Time</th>
+</tr>
+<tr>
+ <th>Date</th>
+ <th>Time</th>
+</tr>
+<tr align="center">
+ <td>−5:50:36</td>
+ <td>not observed</td>
+ <td>LMT</td>
+ <td>1883-11-18</td>
+ <td>12:09:24</td>
+</tr>
+<tr align="center">
+ <td rowspan="2">−6:00:00</td>
+ <td>US rules</td>
+ <td rowspan="2">CST or CDT</td>
+ <td>1920-01-01</td>
+ <td>00:00:00</td>
+</tr>
+<tr align="center">
+ <td>Chicago rules</td>
+ <td>1936-03-01</td>
+ <td rowspan="2">02:00:00</td>
+</tr>
+<tr align="center">
+ <td>−5:00:00</td>
+ <td>not observed</td>
+ <td>EST</td>
+ <td>1936-11-15</td>
+</tr>
+<tr align="center">
+ <td rowspan="4">−6:00:00</td>
+ <td>Chicago rules</td>
+ <td>CST or CDT</td>
+ <td>1942-01-01</td>
+ <td rowspan="3">00:00:00</td>
+</tr>
+<tr align="center">
+ <td>US rules</td>
+ <td>CST, CWT or CPT</td>
+ <td>1946-01-01</td>
+</tr>
+<tr align="center">
+ <td>Chicago rules</td>
+ <td rowspan="2">CST or CDT</td>
+ <td>1967-01-01</td>
+</tr>
+<tr align="center">
+ <td>US rules</td>
+ <td colspan="2">—</td>
+</tr>
+</table>
+
+<p>There are a couple of interesting differences between Zones and Rules.</p>
+
+<p>First, and somewhat trivially, whereas Rules are considered to
+contain one or more records, a Zone is considered to be a single
+record with zero or more <i>continuation lines</i>. Thus, the keyword,
+“<code>Zone</code>,” and the zone name are not
+repeated. The last line is the one without anything in
+the <code>[UNTIL]</code> column.</p>
+
+<p>Second, and more fundamentally, each line of a Zone represents a
+steady state, not a transition between states. The state exists from
+the date and time in the previous line’s <code>[UNTIL]</code>
+column up to the date and time in the current
+line’s <code>[UNTIL]</code> column. In other words, the date and
+time in the <code>[UNTIL]</code> column is the instant that separates
+this state from the next. Where that would be ambiguous because
+we’re setting our clocks back, the <code>[UNTIL]</code> column
+specifies the first occurrence of the instant. The state specified by
+the last line, the one without anything in the <code>[UNTIL]</code>
+column, continues to the present.</p>
+
+<p>The first line typically specifies the mean solar time observed
+before the introduction of standard time. Since there’s no line before
+that, it has no beginning. <code>8-) </code> For some places near the <a
+href="https://en.wikipedia.org/wiki/International_Date_Line">International
+Date Line</a>, the first <i>two</i> lines will show solar times
+differing by 24 hours; this corresponds to a movement of the Date
+Line. For example:</p>
+
+<pre>
+#Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone America/Juneau 15:02:19 - LMT 1867 Oct 18
+ -8:57:41 - LMT ...
+</pre>
+
+<p>When Alaska was purchased from Russia in 1867, the Date Line moved
+from the Alaska/Canada border to the Bering Strait; and the time in
+Alaska was then 24 hours earlier than it had
+been. <code><aside></code>(6 October in the Julian calendar,
+which Russia was still using then for religious reasons, was followed
+by <i>a second instance of the same day with a different name</i>, 18
+October in the Gregorian calendar. Isn’t civil time
+wonderful? <code>8-)</code>)<code></aside></code></p>
+
+<p>The abbreviation, “LMT” stands for “local mean
+time”, which is an invention of
+the <a href="https://en.wikipedia.org/wiki/Tz_database">tz
+database</a> and was probably never actually used during the
+period. Furthermore, the value is almost certainly wrong except in the
+archetypal place after which the zone is named. (The tz database
+usually doesn’t provide a separate Zone record for places where
+nothing significant happened after 1970.)</p>
+
+<p>The <code>RULES</code> column tells us whether daylight saving time is being observed:
+<ul>
+<li>A hyphen, a kind of null value, means that we have not set our
+clocks ahead of standard time.</li>
+
+<li>An amount of time (usually but not necessarily “1:00”
+meaning one hour) means that we have set our clocks ahead by that
+amount.</li>
+
+<li>Some alphabetic string means that we <i>might have</i> set our
+clocks ahead; and we need to check the rule the name of which is the
+given alphabetic string.</li>
+</ul>
+
+<p>An example of a specific amount of time is:</p>
+<pre>
+#Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone Pacific/Honolulu ... 1933 Apr 30 2:00
+ -10:30 1:00 HDT 1933 May 21 2:00
+ ...
+</pre>
+
+<p>Hawaii tried daylight saving time for three weeks in 1933 and
+decided they didn’t like it. <code>8-) </code>Note that
+the <code>GMTOFF</code> column always contains the standard time
+offset, so the wall clock time during this period was GMT −
+10:30 + 1:00 = GMT − 9:30.</p>
+
+<p>The <code>FORMAT</code> column specifies the usual abbreviation of
+the time zone name. It can have one of three forms:</p>
+<ul>
+
+<li>a string of three or more characters that are either ASCII alphanumerics,
+“<code>+</code>”, or “<code>-</code>”,
+in which case that’s the abbreviation</li>
+
+<li>a pair of strings separated by a slash
+(‘<code>/</code>’), in which case the first string is the
+abbreviation for the standard time name and the second string is the
+abbreviation for the daylight saving time name</li>
+
+<li>a string containing “<code>%s</code>,” in which case
+the “<code>%s</code>” will be replaced by the text in the
+appropriate Rule’s <code>LETTER</code> column</li>
+</ul>
+
+<p>The last two make sense only if there’s a named rule in effect.</p>
+
+<p>An example of a slash is:</p>
+<pre>
+#Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone Europe/London ... 1996
+ 0:00 EU GMT/BST
+</pre>
+
+<p>The current time in the UK is called either Greenwich mean time or
+British summer time.</p>
+
+<p>One wrinkle, not fully explained in <code>zic.8.txt</code>, is what
+happens when switching to a named rule. To what values should
+the <code>SAVE</code> and <code>LETTER</code> data be initialized?</p>
+
+<ul>
+<li>If at least one transition has happened, use
+the <code>SAVE</code> and <code>LETTER</code> data from the most
+recent.</li>
+
+<li>If switching to a named rule before any transition has happened,
+assume standard time (<code>SAVE</code> zero), and use
+the <code>LETTER</code> data from the earliest transition with
+a <code>SAVE</code> of zero.
+
+</ul>
+
+<p>And three last things about the <code>FORMAT</code> column:</p>
+<ul>
+
+<li>The <a href="https://en.wikipedia.org/wiki/Tz_database">tz
+database</a> gives abbreviations for time zone names in <i>popular
+usage</i>, which is not necessarily “correct” by law. For
+example, the last line in
+<code>Zone</code> <code>Pacific/Honolulu</code> (shown below) gives
+“HST” for “Hawaii standard time” even though the
+<a href="http://www.law.cornell.edu/uscode/html/uscode15/usc_sec_15_00000263----000-.html">legal</a>
+name for that time zone is “Hawaii-Aleutian standard time.”
+This author has read that there are also some places in Australia where
+popular time zone names differ from the legal ones.
+
+<li>No attempt is made to <a
+href="https://en.wikipedia.org/wiki/Internationalization_and_localization">localize</a>
+the abbreviations. They are intended to be the values returned through the
+<code>"%Z"</code> format specifier to
+<a href="https://en.wikipedia.org/wiki/C_(programming_language)">C</a>’s
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html"><code>strftime</code></a>
+function in the
+<a href="http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_19.html#SEC324">“C” locale</a>.
+
+<li>If there is no generally-accepted abbreviation for a time zone,
+a numeric offset is used instead, e.g., <code>+07</code> for 7 hours
+ahead of Greenwich. By convention, <code>-00</code> is used in a
+zone while uninhabited, where the offset is zero but in some sense
+the true offset is undefined.
+</ul>
+
+<p>As a final example, here’s the complete history for Hawaii:</p>
+
+<table border="1">
+<tr>
+ <th colspan="6">Relevant Excerpts from the US Rules</th>
+</tr>
+<tr>
+ <td colspan="6" align="center"><table><tr><td>
+<pre>
+#Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+Rule US 1918 1919 - Oct lastSun 2:00 0 S
+Rule US 1942 only - Feb 9 2:00 1:00 W # War
+Rule US 1945 only - Aug 14 23:00u 1:00 P # Peace
+Rule US 1945 only - Sep 30 2:00 0 S
+</pre>
+ </td></tr></table></td>
+</tr>
+<tr>
+ <th colspan="6">The Zone Record</th>
+</tr>
+<tr>
+ <td colspan="6" align="center"><table><tr><td>
+<pre>
+#Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone Pacific/Honolulu -10:31:26 - LMT 1900 Jan 1 12:00
+ -10:30 - HST 1933 Apr 30 2:00
+ -10:30 1:00 HDT 1933 May 21 2:00
+ -10:30 US H%sT 1947 Jun 8 2:00
+ -10:00 - HST
+</pre>
+ </td></tr></table></td>
+</tr>
+<tr>
+ <th colspan="6">What We Infer</th>
+</tr>
+<tr>
+ <th rowspan="2">Wall-Clock<br>Offset from<br>Prime Meridian</th>
+ <th rowspan="2">Adjust<br>Clocks</th>
+ <th colspan="2">Time Zone</th>
+ <th colspan="2">Ending at Local Time</th>
+</tr>
+<tr>
+ <th>Abbrv.</th>
+ <th>Name</th>
+ <th>Date</th>
+ <th>Time</th>
+</tr>
+<tr align="center">
+ <td>−10:31:26</td>
+ <td>—</td>
+ <td>LMT</td>
+ <td>local mean time</td>
+ <td>1900-01-01</td>
+ <td>12:00</td>
+</tr>
+<tr align="center">
+ <td>−10:30</td>
+ <td>+0:01:26</td>
+ <td>HST</td>
+ <td>Hawaii standard time</td>
+ <td>1933-04-30</td>
+ <td rowspan="3">02:00</td>
+</tr>
+<tr align="center">
+ <td>−9:30</td>
+ <td>+1:00</td>
+ <td>HDT</td>
+ <td>Hawaii daylight time</td>
+ <td>1933-05-21</td>
+</tr>
+<tr align="center">
+ <td>−10:30¹</td>
+ <td>−1:00¹</td>
+ <td>HST¹</td>
+ <td>Hawaii standard time</td>
+ <td>1942-02-09</td>
+</tr>
+<tr align="center">
+ <td rowspan="2">−9:30</td>
+ <td>+1:00</td>
+ <td>HWT</td>
+ <td>Hawaii war time</td>
+ <td>1945-08-14</td>
+ <td>13:30²</td>
+</tr>
+<tr align="center">
+ <td>0</td>
+ <td>HPT</td>
+ <td>Hawaii peace time</td>
+ <td>1945-09-30</td>
+ <td rowspan="2">02:00</td>
+</tr>
+<tr align="center">
+ <td>−10:30</td>
+ <td>−1:00</td>
+ <td rowspan="2">HST</td>
+ <td rowspan="2">Hawaii standard time</td>
+ <td>1947-06-08</td>
+</tr>
+<tr align="center">
+ <td>−10:00³</td>
+ <td>+0:30³</td>
+ <td colspan="2">—</td>
+</tr>
+<tr>
+ <td colspan="6">
+ ¹Switching to US rules…most recent transition (in 1919) was to standard time
+ </td>
+</tr>
+<tr>
+ <td colspan="6">
+ ²23:00 <a href="https://en.wikipedia.org/wiki/Universal_Time">UT</a>
+ + (−9:30) = 13:30 local
+ </td>
+</tr>
+<tr>
+ <td colspan="6">
+ ³Since <a href="https://en.wikipedia.org/wiki/ISO_8601">1947–06–08T12:30Z</a>,
+ the civil time in Hawaii has been
+ <a href="https://en.wikipedia.org/wiki/Universal_Time">UT</a>/<a href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a>
+ − 10:00 year-round.
+ </td>
+</tr>
+</table>
+
+<p>There will be a short quiz later. <code>8-)</code></p>
+
+<hr>
+<address>
+This web page is in the public domain, so clarified as of
+2015-10-20 by Bill Seymour.
+<br>
+All suggestions and corrections will be welcome; all flames will be amusing.
+Mail to was at pobox dot com.
+</address>
+</body>
+</html>
Modified: vendor/tzcode/dist/tz-link.htm
===================================================================
--- vendor/tzcode/dist/tz-link.htm 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/tz-link.htm 2016-08-15 01:50:22 UTC (rev 7736)
@@ -2,13 +2,15 @@
PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
-<head>
-<title>Sources for Time Zone and Daylight Saving Time Data</title>
+<head profile="http://dublincore.org/documents/2008/08/04/dc-html/">
+<title>Sources for time zone and daylight saving time data</title>
<link rel="schema.DC" href="http://purl.org/DC/elements/1.1/">
-<meta http-equiv="Content-type" content='text/html; charset="US-ASCII"'>
+<meta http-equiv="Content-type" content='text/html; charset="UTF-8"'>
+<meta name="DC.Title"
+ content="Sources for time zone and daylight saving time data">
<meta name="DC.Creator" content="Eggert, Paul">
<meta name="DC.Contributor" content="Olson, Arthur David">
-<meta name="DC.Date" content="2012-11-13">
+<meta name="DC.Date" content="2016-06-14">
<meta name="DC.Description"
content="Sources of information about time zones and daylight saving time">
<meta name="DC.Identifier"
@@ -17,44 +19,61 @@
content="database,daylight saving,DST,time zone,timezone,tz,zoneinfo">
</head>
<body>
-<h1>Sources for Time Zone and Daylight Saving Time Data</h1>
-<h2>The <code>tz</code> database</h2>
+<h1>Sources for time zone and daylight saving time data</h1>
<p>
-The <a href="http://en.wikipedia.org/wiki/Public_domain">public-domain</a>
+Time zone and daylight saving rules are controlled by individual
+governments. They are sometimes changed with little notice, and their
+histories and planned futures are often recorded only fitfully. Here
+is a summary of attempts to organize and record relevant data in this
+area.
+</p>
+<h2>The <code><abbr title="time zone">tz</abbr></code> database</h2>
+<p>
+The <a href="https://en.wikipedia.org/wiki/Public_domain">public-domain</a>
time zone database contains code and data
that represent the history of local time
for many representative locations around the globe.
It is updated periodically to reflect changes made by political bodies
-to <a href="http://en.wikipedia.org/wiki/Time_zone">time zone</a>
-boundaries, <a
-href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time"><abbr
-title="Coordinated Universal Time">UTC</abbr></a> offsets, and
-<a href="http://en.wikipedia.org/wiki/Daylight_saving">daylight-saving</a>
+to <a href="https://en.wikipedia.org/wiki/Time_zone">time zone</a>
+boundaries and
+<a href="https://en.wikipedia.org/wiki/Daylight_saving_time">daylight-saving</a>
rules.
-This database (often called <code>zoneinfo</code> or <a
-href="http://en.wikipedia.org/wiki/Tz_database"><code>tz</code></a>)
+This database (often called <code>zoneinfo</code> or
+<code><abbr>tz</abbr></code>)
is used by several implementations,
including
<a href="http://www.gnu.org/software/libc/">the
<abbr title="GNU's Not Unix">GNU</abbr>
-C Library</a> used in
-<a href="http://www.linux.org/"><abbr>GNU</abbr>/Linux</a>,
-<a href="http://www.android.com/">Android</a>,
-<a href="http://www.freebsd.org/">FreeBSD</a>,
-<a href="http://netbsd.org/">NetBSD</a>,
-<a href="http://openbsd.org/">OpenBSD</a>,
-<a href="http://cygwin.com/">Cygwin</a>,
+C Library</a> (used in
+<a href="https://en.wikipedia.org/wiki/Linux"><abbr>GNU</abbr>/Linux</a>),
+<a href="https://www.android.com">Android</a>,
+<a href="https://developer.mozilla.org/en-US/docs/Mozilla/B2G_OS">B2G
+<abbr title="Operating System">OS</abbr></a>,
+<a href="https://www.freebsd.org">Free<abbr
+title="Berkeley Software Distribution">BSD</abbr></a>,
+<a href="http://netbsd.org">Net<abbr>BSD</abbr></a>,
+<a href="http://www.openbsd.org">Open<abbr>BSD</abbr></a>,
+<a href="http://www.chromium.org/chromium-os">Chromium OS</a>,
+<a href="https://cygwin.com">Cygwin</a>,
<a href="http://www.delorie.com/djgpp/"><abbr
title="DJ's GNU Programming Platform">DJGPP</abbr></a>,
-<a href="http://ibm.com/aix">AIX</a>,
-<a href="http://h71000.www7.hp.com/">OpenVMS</a>,
-<a href="http://oracle.com/database">Oracle Database</a>,
-<a href="http://www.apple.com/osx/">OS X</a>,
-<a href="http://sun.com/software/solaris">Solaris</a>,
-<a href="http://h30097.www3.hp.com/">Tru64</a>, and
-<a href="http://sco.com/products/unixware">UnixWare</a>.</p>
+<a href="https://en.wikipedia.org/wiki/MINIX">MINIX</a>,
+<a href="https://en.wikipedia.org/wiki/WebOS"><abbr
+title="Web Operating System">webOS</abbr></a>,
+<a href="http://ibm.com/aix"><abbr
+title="Advanced Interactive eXecutive">AIX</abbr></a>,
+<a href="https://en.wikipedia.org/wiki/BlackBerry_10">BlackBerry 10</a>,
+<a href="http://www.apple.com/ios/"><abbr
+title="iPhone OS">iOS</abbr></a>,
+<a href="http://windows.microsoft.com">Microsoft Windows</a>,
+<a href="http://www.hp.com/go/openvms/">Open<abbr
+title="Virtual Memory System">VMS</abbr></a>,
+<a href="https://www.oracle.com/database/index.html">Oracle Database</a>,
+<a href="http://oracle.com/solaris">Oracle Solaris</a>, and
+<a href="http://www.apple.com/osx/"><abbr title="Operating System Ten">OS
+X</abbr></a>.</p>
<p>
-Each location in the database represents a national region where all
+Each location in the database represents a region where all
clocks keeping local time have agreed since 1970.
Locations are identified by continent or ocean and then by the name of
the location, which is typically the largest city within the region.
@@ -69,20 +88,35 @@
Indiana, which switched from central to eastern time in 1991
and switched back in 2006.
To use the database on an extended <a
-href="http://en.wikipedia.org/wiki/POSIX"><abbr
+href="https://en.wikipedia.org/wiki/POSIX"><abbr
title="Portable Operating System Interface">POSIX</abbr></a>
-implementation set the <code>TZ</code> environment variable to
-the location's full name, e.g., <code>TZ="America/New_York"</code>.</p>
+implementation set the <code><abbr>TZ</abbr></code>
+environment variable to the location's full name,
+e.g., <code><abbr>TZ</abbr>="America/New_York"</code>.</p>
<p>
-In the <code>tz</code> database's
+Associated with each region is a history of offsets from
+<a href="https://en.wikipedia.org/wiki/Universal_Time">Universal
+Time</a> (<abbr>UT</abbr>), which is <a
+href="https://en.wikipedia.org/wiki/Greenwich_Mean_Time">Greenwich Mean
+Time</a> (<abbr>GMT</abbr>) with days beginning at midnight;
+for time stamps after 1960 this is more precisely <a
+href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">Coordinated
+Universal Time</a> (<abbr>UTC</abbr>).
+The database also records when daylight saving time was in use,
+along with alphabetic time zone abbreviations such as <abbr>EST</abbr>
+for Eastern Standard Time in the <abbr>US</abbr>.</p>
+<p>
+In the <code><abbr>tz</abbr></code> database's
<a href="ftp://ftp.iana.org/tz/releases/"><abbr
title="File Transfer Protocol">FTP</abbr> releases</a>
the code is in the file <code>tzcode<var>C</var>.tar.gz</code>,
where <code><var>C</var></code> is the code's version;
-similarly, the data are in <code>tzdata<var>D</var>.tar.gz</code>,
+similarly, the data entries are in <code>tzdata<var>D</var>.tar.gz</code>,
where <code><var>D</var></code> is the data's version.
-Each version is a four-digit year followed by lower-case letters
-(a through z, then za through zz, then zza through zzz, and so on).
+Since 1996, each version has been a four-digit year followed by
+lower-case letter (<samp>a</samp> through <samp>z</samp>,
+then <samp>za</samp> through <samp>zz</samp>, then <samp>zza</samp>
+through <samp>zzz</samp>, and so on).
Convenience links to
the <a href="ftp://ftp.iana.org/tz/tzcode-latest.tar.gz">latest
code</a> and
@@ -89,7 +123,7 @@
<a href="ftp://ftp.iana.org/tz/tzdata-latest.tar.gz">latest data</a> revisions
are also available.
The following <a
-href="http://en.wikipedia.org/wiki/Unix_shell">shell</a> commands download
+href="https://en.wikipedia.org/wiki/Unix_shell">shell</a> commands download
these files to a <abbr>GNU</abbr>/Linux or similar host;
see the downloaded
<code>README</code> file for what to do next.</p>
@@ -101,21 +135,23 @@
</code></pre>
<p>
The code and data files can also be obtained from the
-<a href="http://www.iana.org/time-zones">timezone web page</a>
+<a href="http://www.iana.org/time-zones">Time Zone Database website</a>
of the <a href="http://www.iana.org">Internet Assigned Numbers
Authority (IANA)</a>.
An <a href="https://github.com/eggert/tz">unofficial development
repository</a> of the code and data is available
-in <a href="http://git-scm.com/">Git</a> form
-from <a href="https://github.com/">GitHub</a>; be careful, as this
+in <a href="http://git-scm.com">Git</a> form
+from <a href="https://github.com">GitHub</a>; be careful, as this
repository is less well tested and probably contains more errors.
<p>
-The code lets you compile the <code>tz</code> source files into
+The code lets you compile the <code><abbr>tz</abbr></code> source files into
machine-readable binary files, one for each location. It also lets
-you read a <code>tz</code> binary file and interpret time stamps for that
+you read a <code><abbr>tz</abbr></code> binary file and interpret time stamps for that
location.</p>
+<h2>Changes to the <code><abbr>tz</abbr></code> database</h2>
<p>
-The data are by no means authoritative. If you find errors, please
+The <code><abbr>tz</abbr></code> code and data
+are by no means authoritative. If you find errors, please
send changes to the <a href="mailto:tz at iana.org">time zone
mailing list</a>. You can also <a
href="http://news.gmane.org/gmane.comp.time.tz">browse recent
@@ -125,64 +161,121 @@
href="http://mm.icann.org/pipermail/tz/">archive of old
messages</a>.</p>
<p>
-The Web has several other sources for time zone and daylight saving time data.
-Here are some links that may be of interest.
+If your government plans to change its time zone boundaries or
+daylight saving rules, let the mailing list know well in advance. With
+less than a year's notice there is a good chance that some
+computer-based clocks will operate incorrectly after the change, due
+to delays in propagating updates to software and data. The shorter
+the notice, the more likely clock problems will arise.
</p>
-<h2>Web pages using recent versions of the <code>tz</code> database</h2>
+<p>Sources for the <code><abbr>tz</abbr></code> database are
+<a href="https://en.wikipedia.org/wiki/UTF-8"><abbr
+title="Unicode Transformation Format 8-bit">UTF-8</abbr></a>
+<a href="https://en.wikipedia.org/wiki/Text_file">text files</a>
+with lines terminated by <a href="https://en.wikipedia.org/wiki/Newline"><abbr
+title="linefeed">LF</abbr></a>,
+which can be modified by common text editors such
+as <a href="https://www.gnu.org/software/emacs/">GNU Emacs</a>,
+<a href="https://wiki.gnome.org/Apps/Gedit">gedit</a>, and
+<a href="http://www.vim.org">vim</a>. One
+editor has a package to simplify editing further:</p>
+<ul>
+<li><a href="https://packagecontrol.io/packages/zoneinfo">Sublime
+zoneinfo</a> is a <a href="http://www.sublimetext.com">Sublime
+Text</a> package for syntax highlighting <code><abbr>tz</abbr></code>
+source files.</li>
+</ul>
<p>
+For further information about updates, please see
+<a href="https://tools.ietf.org/html/rfc6557">Procedures for
+Maintaining the Time Zone Database</a> (Internet <abbr
+title="Request For Comments">RFC</abbr> 6557).</p>
+<h2>Commentary on the <code><abbr>tz</abbr></code> database</h2>
+<ul>
+<li>The article
+<a href="https://en.wikipedia.org/wiki/Tz_database">tz database</a> is
+an encyclopedic summary.</li>
+<li><a href="tz-how-to.html">How to Read the
+tz Database Source Files</a> explains the <code><abbr>tz</abbr></code>
+database format.</li>
+<li><a
+href="http://codeofmatt.com/2016/04/23/on-the-timing-of-time-zone-changes/">On
+the Timing of Time Zone Changes</a> gives examples of problems caused
+by inadequate notice by governments of time zone and daylight saving
+rule changes.</li>
+<li><a
+href="http://blog.jonudell.net/2009/10/23/a-literary-appreciation-of-the-olsonzoneinfotz-database/">A
+literary appreciation of the Olson/Zoneinfo/tz database</a> comments on the
+database's style.</li>
+</ul>
+<h2>Web sites using recent versions of the <code><abbr>tz</abbr></code> database</h2>
+<p>
These are listed roughly in ascending order of complexity and fanciness.
</p>
<ul>
-<li><a href="http://twiki.org/cgi-bin/xtra/tzdatepick.html">Date and Time Gateway</a>
-lets you see the <code>TZ</code> values directly.</li>
+<li><a href="http://time.is">Time.is</a> shows locations'
+time and zones in a simple format.</li>
+<li><a href="https://www.timejones.com">TimeJones.com</a> is a simple
+time zone converter.</li>
<li><a
-href="http://convertit.com/Go/ConvertIt/World_Time/Current_Time.ASP">Current
+href="http://twiki.org/cgi-bin/xtra/tzdatepick.html">Date and Time Gateway</a>
+lets you see the <code><abbr>TZ</abbr></code> values directly.</li>
+<li><a
+href="http://www.convertit.com/Go/ConvertIt/World_Time/Current_Time.ASP">Current
Time in 1000 Places</a> uses descriptions of the values.</li>
-<li><a href="http://www.timezoneconverter.com/">Time Zone Converter</a>
+<li><a href="http://www.timezoneconverter.com/cgi-bin/tzc.tzc">Time Zone
+Converter</a>
uses a pulldown menu.</li>
-<li><a href="http://home.tiscali.nl/~t876506/TZworld.html">Complete
+<li><a href="http://home.kpn.nl/vanadovv/time/TZworld.html">Complete
timezone information for all countries</a> displays tables of DST rules.
-<li><a href="http://timeanddate.com/worldclock/">The World Clock –
-Time Zones</a> lets you sort zone names and convert times.</li>
-<li><a href="http://permatime.com/">Permatime</a> generates and views
-links that refer to a particular point in time and can be displayed in
-multiple timezones.</li>
-<li><a href="http://daylight-savings-time.info/">Daylight Saving Time info</a>
-shows a graph of time
-difference versus time for any pair of locations.</li>
-<li>The <a href="http://worldtimeengine.com/">World Time Engine</a>
+<li><a href="http://www.timeanddate.com/worldclock/">The World Clock –
+Worldwide</a> lets you sort zone names and convert times.</li>
+<li><a href="http://www.zeitverschiebung.net/en/">Time Difference</a>
+calculates the current time difference between locations.</li>
+<li><a href="http://www.wx-now.com">Weather Now</a> lists the weather too.</li>
+<li><a href="http://www.thetimenow.com">The Time Now</a> also lists weather.</li>
+<li><a href="https://worldtime.io">worldtime.io</a>
also contains data about time zone boundaries; it supports queries via place
names and shows location maps.</li>
-<li><a href="http://simpletimerclocks.mozdev.org/">Simple Timer + Clocks</a>
-is a Firefox add-on which uses a timezone data file generated from the
-tz data files.</li>
</ul>
-<h2>Other time zone database formats</h2>
+<h2>Network protocols for <code><abbr>tz</abbr></code> data</h2>
<ul>
-<li>The <a href="ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt">
+<li>The <a href="http://www.ietf.org">Internet Engineering Task Force</a>'s
+<a href="https://datatracker.ietf.org/wg/tzdist/charter/">Time Zone Data
+Distribution Service (tzdist) working group</a> defined <a
+href="https://tools.ietf.org/html/rfc7808">TZDIST</a>
+(Internet <abbr>RFC</abbr> 7808), a time zone data distribution service,
+along with a <a href="https://tools.ietf.org/html/rfc7809">calendar access
+protocol for transferring time zone data by reference</a>
+(Internet <abbr>RFC</abbr> 7809). This work was based
+on the iCalendar and CalConnect efforts described below.</li>
+<li>The <a href="https://tools.ietf.org/html/rfc5545">
Internet Calendaring and Scheduling Core Object Specification
-(iCalendar)</a>, Internet <abbr title="Request For
-Comments">RFC</abbr> 2445, published by the (now-concluded) <a
-href="http://ietf.org/html.charters/OLD/calsch-charter.html"><abbr
-title="Internet Engineering Task Force">IETF</abbr>
-Calendaring and Scheduling Working Group (<abbr
-title="Calendaring and Scheduling Working Group">calsch</abbr>)</a>
+(iCalendar)</a> (Internet <abbr>RFC</abbr> 5445)
covers time zone
data; see its VTIMEZONE calendar component.
-<a href="http://calconnect.org/">CalConnect, The Calendaring and Scheduling
+The iCalendar format requires specialized parsers and generators; a
+variant <a href="https://tools.ietf.org/html/rfc6321">xCal</a>
+(Internet <abbr>RFC</abbr> 6321) uses
+<a href="http://www.w3.org/XML/"><abbr
+title="Extensible Markup Language">XML</abbr></a> format, and a variant
+<a href="https://tools.ietf.org/html/rfc7265">jCal</a>
+(Internet <abbr>RFC</abbr> 7265)
+uses <a href="http://www.json.org"><abbr
+title="JavaScript Object Notation">JSON</abbr></a> format.
+<a href="https://www.calconnect.org">CalConnect, The Calendaring and Scheduling
Consortium</a> is promoting further work in this area. <a
href="http://calconnect.org/publications/icalendartimezoneproblemsandrecommendationsv1.0.pdf">iCalendar
TIMEZONE Problems and Recommendations</a> offers guidelines and
-recommendations for the use of VTIMEZONE and <code>tz</code>.</li>
-<li><a href="http://calconnect.org/dstlinks.shtml">Extended Daylight
-Saving Time Links, Advisories and Changes</a> lists vendor material on recent
-daylight saving time changes.</li>
-<li><a
+recommendations for the use of VTIMEZONE and <code><abbr>tz</abbr></code>.</li>
+<li>The <a
href="http://calconnect.org/publications/timezoneregistryandservicerecommendationsv1.0.pdf">Timezone
-Registry and Service Recommendations</a> discusses a
+Registry and Service Recommendations</a> of CalConnect's
+<a href="https://www.calconnect.org/about/technical-committees/tc-timezone">TIMEZONE
+Technical Committee</a> discusses a
strategy for defining and deploying a time zone
registration process that would establish unique names for each
-version of each <code>tz</code> zone, along with a polygonal
+version of each <code><abbr>tz</abbr></code> zone, along with a polygonal
representation of the geographical area corresponding to the
zone.</li>
<li>The <a
@@ -192,116 +285,204 @@
title="Resource Description Framework">RDF</abbr></a>-based calendar
and group scheduling systems, and has a <a
href="http://www.w3.org/2002/12/cal/#tzd">workspace on time zone
-data</a> converted from <code>tz</code>. An earlier <a
-href="http://www.w3.org/2000/01/foo">schema</a> was sketched out.</li>
+data</a> converted from <code><abbr>tz</abbr></code>.</li>
</ul>
-<h2>Other <code>tz</code> compilers</h2>
+<h2>Other <code><abbr>tz</abbr></code> compilers</h2>
<ul>
-<li><a href="http://sourceforge.net/projects/vzic/">Vzic iCalendar
-Timezone Converter</a> describes a <a
-href="http://en.wikipedia.org/wiki/C_%28programming_language%29">C</a>
+<li><a href="https://sourceforge.net/projects/vzic/">Vzic</a> is a <a
+href="https://en.wikipedia.org/wiki/C_%28programming_language%29">C</a>
program that compiles
-<code>tz</code> source into iCalendar-compatible VTIMEZONE files.
+<code><abbr>tz</abbr></code> source into iCalendar-compatible VTIMEZONE files.
Vzic is freely
available under the <a
href="http://www.gnu.org/copyleft/gpl.html"><abbr>GNU</abbr>
General Public License (<abbr
title="General Public License">GPL</abbr>)</a>.</li>
-<li><a href="http://sourceforge.net/projects/tzical">tziCal - tz
+<li><a href="https://sourceforge.net/projects/tzical/">tziCal – tz
database conversion utility</a> is like Vzic, except for the <a
-href="http://msdn.microsoft.com/netframework">.NET framework</a>.</li>
+href="https://www.microsoft.com/net">.NET framework</a>
+and with a <abbr>BSD</abbr>-style license.</li>
<li><a
href="http://search.cpan.org/dist/DateTime-TimeZone/">DateTime::TimeZone</a>
contains a script <code>parse_olson</code> that compiles
-<code>tz</code> source into <a href="http://www.perl.org/">Perl</a>
+<code><abbr>tz</abbr></code> source into <a href="https://www.perl.org">Perl</a>
modules. It is part of the Perl <a
-href="http://datetime.perl.org/">DateTime Project</a>, which is freely
+href="http://datetime.perl.org">DateTime Project</a>, which is freely
available under both the <abbr>GPL</abbr> and the Perl Artistic
License. DateTime::TimeZone also contains a script
<code>tests_from_zdump</code> that generates test cases for each clock
-transition in the <code>tz</code> database.</li>
-<li><a href="http://icu-project.org/">International Components for
+transition in the <code><abbr>tz</abbr></code> database.</li>
+<li>The <a href="https://howardhinnant.github.io/date/tz.html">Time Zone
+Database Parser</a> is a
+<a href="https://en.wikipedia.org/wiki/C%2B%2B">C++</a> parser and
+runtime library. It is freely available under the
+<a href="http://creativecommons.org/licenses/by/4.0/">Creative Commons
+Attribution 4.0 International Public License</a>.</li>
+<li><a href="http://site.icu-project.org">International Components for
Unicode (<abbr>ICU</abbr>)</a> contains C/C++ and <a
-href="http://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a>
+href="https://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a>
libraries for internationalization that
-has a compiler from <code>tz</code> source
+has a compiler from <code><abbr>tz</abbr></code> source
+and from <abbr title="Common Locale Data Repository">CLDR</abbr> data
+(mentioned below)
into an <abbr>ICU</abbr>-specific format.
<abbr>ICU</abbr> is freely available under a
-<abbr title="Berkeley Software Distribution">BSD</abbr>-style license.</li>
-<li><a href="http://joda-time.sourceforge.net/">Joda Time - Java date
-and time <abbr title="Application Program Interface">API</abbr></a>
-contains a class
+<abbr>BSD</abbr>-style license.</li>
+<li>The <a href="https://github.com/lau/tzdata">Tzdata</a> package for
+the <a href="http://elixir-lang.org">Elixir</a> language downloads
+and compiles tz source and exposes <abbr
+title="Application Program Interface">API</abbr>s for use. It is
+freely available under the <abbr
+title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
+<li>The <a
+href="http://www.oracle.com/technetwork/java/javase/tzupdater-readme-136440.html">TZUpdater
+tool</a> compiles <code><abbr>tz</abbr></code> source into the format used by
+Oracle Java.</li>
+<li><a href="http://www.joda.org/joda-time/">Joda-Time – Java date
+and time <abbr>API</abbr></a> contains a class
<code>org.joda.time.tz.ZoneInfoCompiler</code> that compiles
-<code>tz</code> source into a Joda-specific binary format. Joda Time
+<code><abbr>tz</abbr></code> source into a Joda-specific binary format. Joda Time
is freely available under a <abbr>BSD</abbr>-style license.</li>
-<li><a href="http://pytz.sourceforge.net">PyTZ - Python Time
-Zone Library</a> compiles <code>tz</code> source into
-<a href="http://python.org/">Python</a>.
+<li><a href="http://nodatime.org">Noda Time – Date and
+time <abbr>API</abbr> for .NET</a>
+and <a href="http://www.babiej.demon.nl/Tz4Net/main.htm">TZ4Net</a>
+are similar to Joda Time, but for the .NET framework instead of
+Java. They are freely available under the
+<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License</a>
+and a <abbr>BSD</abbr>-style license, respectively.</li>
+<li><a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a>-based
+compilers and libraries include:
+<ul>
+<li><a href="http://momentjs.com/timezone/">Moment Timezone</a> is a
+plugin for the <a href="http://momentjs.com">Moment.js</a> date
+manipulation library. It is freely available under the <abbr>MIT</abbr>
+license.</li>
+<li><a href="https://github.com/mde/timezone-js">TimezoneJS.Date</a>'s
+<abbr>API</abbr> is upward compatible with standard JavaScript
+Dates. It is freely available under the Apache License.</li>
+<li><a href="https://github.com/sproutsocial/walltime-js">Walltime-js</a>
+translates <abbr>UT</abbr> to local time. It is freely available under
+the <abbr>MIT</abbr> license.</li>
+</ul>
+<li><a href="http://pytz.sourceforge.net">pytz – World Timezone
+Definitions for Python</a> compiles <code><abbr>tz</abbr></code> source into
+<a href="https://www.python.org">Python</a>.
It is freely available under a <abbr>BSD</abbr>-style license.</li>
-<li><a href="http://tzinfo.rubyforge.org/">TZInfo - Ruby Timezone Library</a>
-compiles <code>tz</code> source into
-<a href="http://ruby-lang.org">Ruby</a>.
-It is freely available under the <abbr
-title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
-<li>The <a href="http://chronos-st.org/">Chronos Date/Time
+<li><a href="http://tzinfo.github.io">TZInfo –
+Ruby Timezone Library</a>
+compiles <code><abbr>tz</abbr></code> source into
+<a href="https://www.ruby-lang.org/en/">Ruby</a>.
+It is freely available under the <abbr>MIT</abbr> license.</li>
+<li>The <a href="http://www.squeaksource.com/Chronos/">Chronos Date/Time
Library</a> is
-a <a href="http://en.wikipedia.org/wiki/Smalltalk">Smalltalk</a> class
-library that compiles <code>tz</code> source into a time zone repository whose format
-is either proprietary or an <a href="http://www.w3.org/XML/"><abbr
-title="Extensible Markup Language">XML</abbr></a>-encoded
+a <a href="https://en.wikipedia.org/wiki/Smalltalk">Smalltalk</a> class
+library that compiles <code><abbr>tz</abbr></code> source into a time
+zone repository whose format
+is either proprietary or an <abbr>XML</abbr>-encoded
representation.</li>
-<li>Starting with version 8.5, <a href="http://tcl.tk/">Tcl</a>
-contains a developer-oriented parser that compiles <samp>tz</samp>
+<li><a href="http://tcl.tk">Tcl</a>
+contains a developer-oriented parser that compiles <code><abbr>tz</abbr></code>
source into text files, along with a runtime that can read those
files. Tcl is freely available under a <abbr>BSD</abbr>-style
license.</li>
</ul>
-<h2>Other <code>tz</code> binary file readers</h2>
+<h2>Other <code><abbr>tz</abbr></code> binary file readers</h2>
<ul>
<li>The <a
href="http://www.gnu.org/software/libc/"><abbr>GNU</abbr> C
Library</a>
has an independent, thread-safe implementation of
-a <code>tz</code> binary file reader.
+a <code><abbr>tz</abbr></code> binary file reader.
This library is freely available under the
<a href="http://www.gnu.org/copyleft/lesser.html">
<abbr>GNU</abbr> Lesser General Public License
(<abbr title="Lesser General Public License">LGPL</abbr>)</a>,
and is widely used in <abbr>GNU</abbr>/Linux systems.</li>
+<li><a href="https://www.gnome.org">GNOME</a>'s Glib has
+a <code><abbr>tz</abbr></code> binary file reader written in C that
+creates a <code>GTimeZone</code> object representing sets
+of <abbr>UT</abbr> offsets.
+It is freely available under the <abbr>LGPL</abbr>.</li>
+<li>The
+<a href="https://github.com/bloomberg/bde/wiki">BDE Standard Library</a>'s
+<code>baltzo::TimeZoneUtil</code> component contains a C++
+implementation of a binary file reader. It is freely available under
+the Apache License.</li>
+<li><a href="https://github.com/google/cctz">CCTZ</a> is a simple C++
+library that translates between UTC and civil time and can read binary
+files. It is freely available under the Apache License.</li>
<li><a href="http://bmsi.com/java/#TZ">ZoneInfo.java</a>
-is a <code>tz</code> binary file reader written in Java.
+is a <code><abbr>tz</abbr></code> binary file reader written in Java.
It is freely available under the <abbr>LGPL</abbr>.</li>
+<li><a href="https://github.com/bigeasy/timezone">Timezone</a> is a
+JavaScript library that supports date arithmetic that is time zone
+aware. It is freely available under the <abbr>MIT</abbr> license.</li>
<li>Tcl, mentioned above, also contains a
-<code>tz</code> binary file reader.</li>
+<code><abbr>tz</abbr></code> binary file reader.</li>
<li><a href="http://search.cpan.org/perldoc?DateTime::TimeZone::Tzfile">
DateTime::TimeZone::Tzfile</a>
-is a <code>tz</code> binary file reader written in Perl.
+is a <code><abbr>tz</abbr></code> binary file reader written in Perl.
It is freely available under the same terms as Perl
(dual <abbr>GPL</abbr> and Artistic license).</li>
+<li>The
+public-domain <a href="https://github.com/dbaron/tz.js">tz.js</a>
+library contains a Python tool that
+converts <code><abbr>tz</abbr></code> binary data into
+<abbr>JSON</abbr>-format data suitable for use
+in its JavaScript library for time zone conversion. Dates before 1970
+are not supported.</li>
+<li>The <a
+href="http://hackage.haskell.org/package/timezone-olson">timezone-olson</a>
+package contains <a href="https://www.haskell.org">Haskell</a> code that
+parses and uses <code><abbr>tz</abbr></code> binary data. It is freely
+available under a <abbr>BSD</abbr>-style license.</li>
</ul>
-<h2>Other <code>tz</code>-based time zone software</h2>
+<h2>Other <code><abbr>tz</abbr></code>-based time zone software</h2>
<ul>
-<li><a href="http://foxclocks.org/">FoxClocks</a>
-is an extension for <a href="http://google.com/chrome">Google
+<li><a href="https://foxclocks.org">FoxClocks</a>
+is an extension for <a href="https://www.google.com/chrome/">Google
Chrome</a> and for <a
-href="http://developer.mozilla.org/en/docs/Toolkit_API">Mozilla
+href="https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Toolkit_API">Mozilla
Toolkit</a> applications like <a
-href="http://mozilla.com/firefox">Firefox</a> and <a
-href="http://mozilla.com/thunderbird">Thunderbird</a>.
+href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a> and <a
+href="https://www.mozilla.org/en-US/thunderbird/">Thunderbird</a>.
It displays multiple clocks in the application window, and has a mapping
-interface to <a href="http://earth.google.com/">Google Earth</a>.
+interface to <a href="https://www.google.com/earth/">Google Earth</a>.
It is freely available under the <abbr>GPL</abbr>.</li>
+<li><a href="https://golang.org">Go programming language</a>
+implementations contain a copy of a 32-bit subset of a recent
+<code><abbr>tz</abbr></code> database in a
+Go-specific format.</li>
<li><a
href="http://users.skynet.be/Peter.Verthez/projects/intclock/">International
-clock (intclock)</a> is a multi-timezone clock for
+clock (intclock)</a> is a clock that displays multiple time zones on
<abbr>GNU</abbr>/Linux and similar systems. It is freely available
under the <abbr>GPL</abbr>.</li>
-<li><a href="http://www.oracle.com/us/technologies/java/overview/index.html">Oracle
-Java</a> releases since 1.4
-contain a copy of a subset of a recent <code>tz</code> database in a
+<li>Microsoft Windows 8.1
+and later has <code><abbr>tz</abbr></code> data and <abbr>CLDR</abbr>
+data (mentioned below) used by
+<a href="https://en.wikipedia.org/wiki/Windows_Runtime">Windows Runtime</a>
+classes such as <a
+href="https://msdn.microsoft.com/en-us/library/windows/apps/windows.globalization.datetimeformatting.datetimeformatter.aspx"><code>DateTimeFormatter</code></a>.
+<a
+href="https://blogs.msdn.microsoft.com/bclteam/2007/06/07/exploring-windows-time-zones-with-system-timezoneinfo-josh-free/">Exploring
+Windows Time Zones with <code>System.TimeZoneInfo</code></a> describes
+the older, proprietary method of Microsoft Windows 2000 and later,
+which stores time zone data in the
+<a href="https://en.wikipedia.org/wiki/Windows_Registry">Windows Registry</a>. The
+<a
+href="http://www.unicode.org/cldr/charts/latest/supplemental/zone_tzid.html">Zone →
+Tzid table</a> or <a
+href="http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml"><abbr>XML</abbr>
+file</a> of the <abbr>CLDR</abbr> data maps proprietary zone IDs
+to <code><abbr>tz</abbr></code> names.
+<li><a
+href="https://www.oracle.com/java/index.html">Oracle
+Java</a> contains a copy of a subset of a recent
+<code><abbr>tz</abbr></code> database in a
Java-specific format.</li>
-<li><a href="http://kimmo.suominen.com/sw/timezone/">Time Zone</a> is
-a <a href="http://wordpress.org/">WordPress</a> plugin. It is freely
+<li><a href="https://kimmo.suominen.com/sw/timezone/">Time Zone</a> is
+a <a href="https://wordpress.org">WordPress</a> plugin. It is freely
available under a <abbr>BSD</abbr>-style license.</li>
<li><a href="http://www.relativedata.com/time-zone-master">Time Zone
Master</a> is a Microsoft Windows clock program that can automatically
@@ -309,57 +490,47 @@
files as they are released. The Basic version is free.</li>
<li><a
href="http://veladg.com/velaterra.html">VelaTerra</a> is
-a Mac OS X program. Its developers
+an <abbr>OS X</abbr> program. Its developers
<a href="http://veladg.com/tzoffer.html">offer free
-licenses</a> to <code>tz</code> contributors.</li>
-<li><a
-href="http://worldtimeexplorer.com/">World Time Explorer</a> is a
-Microsoft Windows program.</li>
+licenses</a> to <code><abbr>tz</abbr></code> contributors.</li>
</ul>
<h2>Other time zone databases</h2>
<ul>
-<li><a href="http://www.astro.com/cgi/aq.cgi">Atlas Query</a>
+<li><a href="http://www.astro.com/atlas">Time-zone Atlas</a>
is Astrodienst's Web version of Shanks and Pottenger's
time zone history atlases published in both <a
href="http://astrocom.com/astrology-products/software/acs-atlas-software">computer</a>
and book form (<a
href="http://www.astrocom.com/astrology/books/american-atlas">one volume
-for the USA</a>, and <a
+for the <abbr>US</abbr></a>, and <a
href="http://www.astrocom.com/astrology/books/international-atlas">one for
other locations</a>) by <a
-href="http://astrocom.com/">Astro Computing Services</a>.</li>
-<li><a href="http://worldtime.com/">WORLDTIME: interactive atlas,
-time info, public holidays</a>
-contains information on local time, sunrise and sunset,
-and public holidays in several hundred cities around the world.</li>
-<li><a href="http://worldtimeserver.com/">World Time Server</a>
+href="http://astrocom.com">Astro Computing Services</a>.
+These atlases are extensive but unreliable, as Shanks appears to have
+guessed many <abbr>UT</abbr> offsets and transitions. The atlases cite no
+sources and do not indicate which entries are guesswork.</li>
+<li><a href="https://en.wikipedia.org/wiki/HP-UX">HP-UX</a> has a database in
+its own <code>tztab</code>(4) format.</li>
+<li>Microsoft Windows has proprietary data mentioned above.</li>
+<li><a href="http://www.worldtimeserver.com">World Time Server</a>
is another time zone database.</li>
<li><a href="http://tycho.usno.navy.mil/tzones.html">World Time Zones</a>
contains data from the Time Service Department of the
-<abbr>US</abbr> Naval Observatory, used as the source
-for the <code>usno*</code> files in the <code>tz</code> distribution.</li>
-<li>The <a href="http://iata.org/ps/publications/SSIM.htm">Standard
+<abbr>US</abbr> Naval Observatory.</li>
+<li>The <a href="http://www.iata.org/publications/Pages/ssim.aspx">Standard
Schedules Information Manual</a> of the
-<a href="http://iata.org/index.htm">International Air Transport
-Association</a>
+International Air Transport Association
gives current time zone rules for airports served by commercial aviation.</li>
-<li>Some Microsoft Windows versions contain time zone information in
-an undocumented format, with IDs that can be mapped to <code>TZ</code>
-values using the <a
-href="http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html">Zone
-→ Tzid table</a> maintained by the <abbr
-title="Common Locale Data Repository">CLDR</abbr> data mentioned
-below.</li>
</ul>
<h2>Maps</h2>
<ul>
-<li>The <a href="https://www.cia.gov/">United States Central
+<li>The <a href="https://www.cia.gov/index.html">United States Central
Intelligence Agency (<abbr
title="Central Intelligence Agency">CIA</abbr>)</a> publishes a <a
href="https://www.cia.gov/library/publications/the-world-factbook/graphics/ref_maps/physical/pdf/standard_time_zones_of_the_world.pdf">time
zone map</a>; the
<a
-href="http://www.lib.utexas.edu/maps/world.html">Perry-Castañeda
+href="http://www.lib.utexas.edu/maps/world.html">Perry–Castañeda
Library Map Collection</a>
of the University of Texas at Austin has copies of
recent editions.
@@ -366,22 +537,34 @@
The pictorial quality is good,
but the maps do not indicate summer time,
and parts of the data are a few years out of date.</li>
-<li><a href="http://worldtimezone.com/">Current time around the world
+<li><a href="http://www.worldtimezone.com">Current time around the world
and standard time zones map of the world</a>
has several fancy time zone maps; it covers Russia particularly well.
The maps' pictorial quality is not quite as good as the
<abbr>CIA</abbr>'s
but the maps are more up to date.</li>
+<li><a
+href="http://blog.poormansmath.net/how-much-is-time-wrong-around-the-world/">How
+much is time wrong around the world?</a> maps the difference between
+mean solar and standard time, highlighting areas such as western China
+where the two differ greatly. It's a bit out of date, unfortunately.</li>
</ul>
<h2>Time zone boundaries</h2>
<ul>
-<li><a href="http://efele.net/maps/tz/">TZ timezone maps</a> contains a <a
-href="http://en.wikipedia.org/wiki/Shapefile">shapefile</a> of the
-<code>tz</code> regions in the world.</li>
-<li><a href="http://statoids.com/statoids.html">Administrative Divisions
-of Countries ("Statoids")</a> contains detailed lists of
-<code>tz</code>-related zone subdivision data.</li>
-<li><a href="http://home.tiscali.nl/~t876506/Multizones.html">Time
+<li><a href="http://efele.net/maps/tz/"><abbr>TZ</abbr> timezones
+maps</a> contains <a
+href="https://en.wikipedia.org/wiki/Shapefile">shapefiles</a> of
+sets of <code><abbr>tz</abbr></code> regions.</li>
+<li>The <a href="https://github.com/bradfitz/latlong">latlong package</a>
+maps geographical coordinates to a <code><abbr>tz</abbr></code> region.
+It is written in Go and is freely available under the Apache License.</li>
+<li><a href="https://derickrethans.nl/what-time-is-it.html">What Time
+is It Here?</a> applies <a href="https://www.mongodb.com">MongoDB</a>
+geospatial query operators to shapefiles' data.</li>
+<li><a href="http://statoids.com/statoids.html">Administrative
+Divisions of Countries ("Statoids")</a> contains lists of
+political subdivision data related to time zones.</li>
+<li><a href="http://home.kpn.nl/vanadovv/time/Multizones.html">Time
zone boundaries for multizone countries</a> summarizes legal
boundaries between time zones within countries.</li>
<li>Manifold.net's <a
@@ -389,18 +572,15 @@
Manifold System Users</a> includes a Manifold-format map of
world time zone boundaries distributed under the
<abbr>GPL</abbr>.</li>
-<li>The <abbr>US</abbr> Geological Survey's National Atlas of
-the United States
-publishes the <a href="http://nationalatlas.gov/mld/timeznp.html">Time
-Zones of the United States</a> in the public domain.</li>
<li>The GeoCommunity lists several commercial sources for <a
href="http://spatialnews.geocomm.com/features/timezones/">International
Time Zones and Time Zone Data</a>.</li>
<li>A ship within the <a
-href="http://en.wikipedia.org/wiki/Territorial_waters">territorial
+href="https://en.wikipedia.org/wiki/Territorial_waters">territorial
waters</a> of any nation uses that nation's time. In international
waters, time zone boundaries are meridians 15° apart, except that
-UTC−12 and UTC+12 are each 7.5° wide and are separated by
+<abbr>UTC</abbr>−12 and <abbr>UTC</abbr>+12 are each 7.5°
+wide and are separated by
the 180° meridian (not by the International Date Line, which is
for land and territorial waters only). A captain can change ship's
clocks any time after entering a new time zone; midnight changes are
@@ -408,22 +588,20 @@
</ul>
<h2>Civil time concepts and history</h2>
<ul>
-<li><a href="http://physics.nist.gov/GenInt/Time/time.html">A
+<li><a href="http://www.nist.gov/pml/general/time/index.cfm">A
Walk through Time</a>
surveys the evolution of timekeeping.</li>
-<li><a href="http://webexhibits.org/daylightsaving/">About Daylight
-Saving Time - History, rationale, laws & dates</a>
+<li><a href="http://www.webexhibits.org/daylightsaving/">About Daylight
+Saving Time – History, rationale, laws & dates</a>
is an overall history of <abbr>DST</abbr>.</li>
+<li><a href="https://www.w3.org/TR/timezone/">Working with Time Zones</a>
+contains guidelines and best practices for software applications that
+deal with civil time.</li>
<li><a href="http://energy.ca.gov/daylightsaving.html">Saving Time,
Saving Energy</a> discusses a primary justification for <abbr>DST</abbr>.</li>
<li><a href="http://seizethedaylight.com/dst/">A Brief
History of Daylight Saving Time</a> summarizes some of the contentious
history of <abbr>DST</abbr>.</li>
-<li><a href="http://toi.inrim.it/uk/toi.html">The
-Time of Internet</a>
-describes time zones and daylight saving time,
-with diagrams.
-The time zone map is out of date, however.</li>
<li><a href="http://www.staff.science.uu.nl/~gent0113/idl/idl.htm">A History of
the International Date Line</a> tells the story of the most important
time zone boundary.</li>
@@ -433,11 +611,12 @@
<h2>National histories of legal time</h2>
<dl>
<dt>Australia</dt>
-<dd>The Parliamentary Library has commissioned <a
-href="http://www.aph.gov.au/binaries/library/pubs/rn/2006-07/07rn13.pdf">research
-note on daylight saving time in Australia</a>.
-The Bureau of Meteorology publishes a list of
-<a href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">Implementation Dates of Daylight Savings Time within Australia</a>.</dd>
+<dd>The Parliamentary Library has commissioned a <a
+href="http://www.aph.gov.au/binaries/library/pubs/rp/2009-10/10rp10.pdf">research
+paper on daylight saving time in Australia</a>.
+The Bureau of Meteorology publishes a list of <a
+href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">Implementation
+Dates of Daylight Savings Time within Australia</a>.</dd>
<dt>Belgium</dt>
<dd>The Royal Observatory of Belgium maintains a table of <a
href="http://www.astro.oma.be/GENERAL/INFO/nli001a.html"
@@ -453,13 +632,13 @@
href="http://www.nrc-cnrc.gc.ca/eng/services/time/time_zones.html">time
zones & daylight saving time</a>.</dd>
<dt>Chile</dt>
-<dd>The Chilean Hydrographic and Oceanographic Service publishes a <a
-href="http://www.horaoficial.cl/horaof.htm" hreflang="es"> history of
-official time (in Spanish)</a>.</dd>
+<dd>The Hydrographic and Oceanographic Service of the Chilean Navy publishes a
+<a href="http://www.horaoficial.cl/historia_hora.html" hreflang="es">history of
+Chile's official time (in Spanish)</a>.</dd>
<dt>Germany</dt>
<dd>The National Institute for Science and Technology maintains the <a
-href="http://www.ptb.de/cms/en/fachabteilungen/abt4/fb-44/ag-441/realisation-of-legal-time-in-germany.html">Realisation of
-Legal Time in Germany</a>.</dd>
+href="http://www.ptb.de/cms/en/fachabteilungen/abt4/fb-44/ag-441/realisation-of-legal-time-in-germany.html">Realisation
+of Legal Time in Germany</a>.</dd>
<dt>Israel</dt>
<dd>The Interior Ministry periodically issues <a
href="ftp://ftp.cs.huji.ac.il/pub/tz/announcements"
@@ -467,7 +646,7 @@
<dt>Mexico</dt>
<dd>The Investigation and Analysis Service of the Mexican Library of
Congress has published a <a
-href="http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/"
+href="http://www.diputados.gob.mx/bibliot/publica/inveyana/polisoc/horver/index.htm"
hreflang="es">history of Mexican local time (in Spanish)</a>.</dd>
<dt>Malaysia</dt>
<dd>See Singapore below.</dd>
@@ -488,12 +667,16 @@
history of legal time in Singapore and Malaysia.</dd>
<dt>United Kingdom</dt>
<dd><a
-href="http://www.polyomino.org.uk/british-time/">History of
+href="https://www.polyomino.org.uk/british-time/">History of
legal time in Britain</a> discusses in detail the country
with perhaps the best-documented history of clock adjustments.
The National Physical Laboratory also maintains an <a
-href="http://www.npl.co.uk/educate-explore/what-is-the-time/archive-of-summer-time-dates-1916-2006">Archive
+href="http://www.npl.co.uk/educate-explore/what-is-time/archive-of-summer-time-dates-1916-2006">Archive
of Summer time dates</a>.</dd>
+<dt>United States</dt>
+<dd>The Department of Transportation's <a
+href="https://www.transportation.gov/regulations/recent-time-zone-proceedings">Recent
+Time Zone Proceedings</a> lists changes to time zone boundaries.</dd>
</dl>
<h2>Precision timekeeping</h2>
<ul>
@@ -501,22 +684,25 @@
href="http://literature.agilent.com/litweb/pdf/5965-7984E.pdf">The
Science of Timekeeping</a> is a thorough introduction
to the theory and practice of precision timekeeping.</li>
-<li><a href="http://www.ntp.org/"><abbr
+<li><a href="http://www.ntp.org"><abbr
title="Network Time Protocol">NTP</abbr>: The Network
Time Protocol</a>
discusses how to synchronize clocks of
Internet hosts.</li>
+<li>The <a href="http://www.nist.gov/el/isd/ieee/ieee1588.cfm">Precision
+Time Protocol</a> (<abbr
+title="Institute of Electrical and Electronics Engineers">IEEE</abbr> 1588)
+can achieve submicrosecond clock accuracy on a local area network.</li>
<li><a
-href="ftp://ftp.rfc-editor.org/in-notes/rfc4833.txt">Timezone
+href="https://tools.ietf.org/html/rfc4833">Timezone
Options for <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr></a>
(Internet <abbr>RFC</abbr> 4833)
specifies a <a
-href="http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol">DHCP</a>
+href="https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol"><abbr>DHCP</abbr></a>
option for a server to configure
a client's time zone and daylight saving settings automatically.</li>
-<li><a href="http://gauss.gge.unb.ca/GMT.UT.and.the.RGO.html">A Few
-Facts Concerning <abbr title="Greenwich Mean Time">GMT</abbr>, <abbr
-title="Universal Time">UT</abbr>, and
+<li><a href="http://gauss.gge.unb.ca/GMT.UT.and.the.RGO.html">A Few Facts
+Concerning <abbr>GMT</abbr>, <abbr>UT</abbr>, and
the <abbr title="Royal Greenwich Observatory">RGO</abbr></a>
answers questions like "What is the
difference between <abbr>GMT</abbr> and <abbr>UTC</abbr>?"</li>
@@ -528,17 +714,18 @@
<abbr title="Barycentric Dynamic Time">TDB</abbr>.
<a href="http://www.ucolick.org/~sla/leapsecs/timescales.html">Time
Scales</a> goes into more detail, particularly for historical variants.</li>
-<li>The <a href="http://iau.org/"><abbr
+<li>The <a href="http://iau.org"><abbr
title="International Astronomical Union">IAU</abbr></a>'s <a
-href="http://www.iau-sofa.rl.ac.uk/"><abbr
+href="http://www.iausofa.org"><abbr
title="Standards Of Fundamental Astronomy">SOFA</abbr></a>
-initiative publishes Fortran
+collection contains C and <a
+href="https://en.wikipedia.org/wiki/Fortran">Fortran</a>
code for converting among time scales like
<abbr title="International Atomic Time">TAI</abbr>,
<abbr>TDB</abbr>, <abbr>TDT</abbr> and
<abbr>UTC</abbr>.</li>
-<li><a href="http://www2.jpl.nasa.gov/basics/bsf2-3.php">Basics of
-Space Flight - Reference Systems - Time Conventions</a>
+<li><a href="http://solarsystem.nasa.gov/basics/bsf2-3.php">Basics of
+Space Flight – Reference Systems – Time Conventions</a>
briefly explains interplanetary space flight timekeeping.</li>
<li><a
href="http://www.giss.nasa.gov/tools/mars24/help/notes.html">Technical
@@ -547,17 +734,18 @@
title="Mars Coordinated Time">MTC</abbr>) and the
diverse local time
scales used by each landed mission on Mars.</li>
-<li><a href="http://leapsecond.com/">LeapSecond.com</a> is
+<li><a href="http://leapsecond.com">LeapSecond.com</a> is
dedicated not only to leap seconds but to precise time and frequency
in general. It covers the state of the art in amateur timekeeping, and
how the art has progressed over the past few decades.</li>
<li><a
-href="http://www.iers.org/IERS/EN/Publications/Bulletins/bulletins.html">IERS
+href="https://www.iers.org/IERS/EN/Publications/Bulletins/bulletins.html"><abbr
+title="International Earth Rotation and Reference Systems Service">IERS</abbr>
Bulletins</a> contains official publications of the International
Earth Rotation and Reference Systems Service, which decides
when leap seconds occur.</li>
<li>The <a
-href="http://six.pairlist.net/mailman/listinfo/leapsecs">Leap
+href="https://pairlist6.pair.net/mailman/listinfo/leapsecs">Leap
Second Discussion List</a> covers <a
href="http://gauss.gge.unb.ca/papers.pdf/gpsworld.november99.pdf">McCarthy
and Klepczynski's proposal to discontinue leap seconds</a>,
@@ -564,39 +752,50 @@
discussed further in
<a href="http://www.cl.cam.ac.uk/~mgk25/time/metrologia-leapsecond.pdf">The
leap second: its history and possible future</a>.
-<a href="http://www.ucolick.org/~sla/leapsecs/">UTC might be redefined
+<a href="http://www.ucolick.org/~sla/leapsecs/"><abbr>UTC</abbr>
+might be redefined
without Leap Seconds</a> gives pointers on this
contentious issue.</li>
</ul>
<h2>Time notation</h2>
<ul>
+<li>The <a href="http://cldr.unicode.org">Unicode Common Locale Data
+Repository (<abbr>CLDR</abbr>) Project</a> has localizations for time
+zone names, abbreviations, identifiers, and formats. For example, it
+contains French translations for "Eastern European Summer Time",
+"<abbr title="Eastern European Summer Time">EEST</abbr>", and
+"Bucharest". Its
+<a href="http://unicode.org/cldr/charts/by_type/index.html">by-type
+charts</a> show these values for many locales. Data values are available in
+both <abbr title="Locale Data Markup Language">LDML</abbr>
+(an <abbr>XML</abbr> format) and <abbr>JSON</abbr>.
<li>
-<a href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">A Summary of
-the International Standard Date and Time Notation</a> is a good
+<a href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">A summary of
+the international standard date and time notation</a> is a good
summary of
<a
href="http://www.iso.org/iso/catalogue_detail?csnumber=40874"><abbr
title="International Organization for Standardization">ISO</abbr>
-8601:2004 -- Data elements and interchange formats -- Information
-interchange -- Representation of dates and times</a>.</li>
+8601:2004 – Data elements and interchange formats – Information
+interchange – Representation of dates and times</a>.</li>
<li>
-<a href="http://www.w3.org/TR/xmlschema-2/#dateTime"><abbr>XML</abbr>
-Schema: Datatypes - dateTime</a> specifies a format inspired by
-<abbr>ISO</abbr> 8601 that is in common use in XML data.</li>
+<a href="https://www.w3.org/TR/xmlschema-2/#dateTime"><abbr>XML</abbr>
+Schema: Datatypes – dateTime</a> specifies a format inspired by
+<abbr>ISO</abbr> 8601 that is in common use in <abbr>XML</abbr> data.</li>
<li>
-<a href="ftp://ftp.rfc-editor.org/in-notes/rfc2822.txt">Internet
-Message Format</a> (Internet <abbr>RFC</abbr> 2822) §3.3
+<a href="https://tools.ietf.org/html/rfc5322">Internet
+Message Format</a> (Internet <abbr>RFC</abbr> 5322) §3.3
specifies the time notation used in email and <a
-href="ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt"><abbr>HTTP</abbr></a>
+href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"><abbr>HTTP</abbr></a>
headers.</li>
<li>
-<a href="ftp://ftp.rfc-editor.org/in-notes/rfc3339.txt">Date and Time
+<a href="https://tools.ietf.org/html/rfc3339">Date and Time
on the Internet: Timestamps</a> (Internet <abbr>RFC</abbr> 3339)
specifies an <abbr>ISO</abbr> 8601
profile for use in new Internet
protocols.</li>
<li>
-<a href="http://www.hackcraft.net/web/datetime/">Date & Time
+<a href="https://www.hackcraft.net/web/datetime/">Date & Time
Formats on the Web</a> surveys web- and Internet-oriented date and time
formats.</li>
<li>
@@ -603,54 +802,42 @@
<a href="http://exit109.com/~ghealton/y2k/yrexamples.html">The
Best of Dates, the Worst of Dates</a> covers many problems encountered
by software developers when handling dates and time stamps.</li>
-<li>The <a
-href="http://unicode.org/cldr/">Unicode Common Locale Data Repository
-(<abbr>CLDR</abbr>) Project</a> has localizations for time zone names,
-abbreviations, identifiers, and formats. For example, it contains
-French translations for "Eastern European Summer Time", "<abbr
-title="Eastern European Summer Time">EEST</abbr>", and
-"Bucharest". <a
-href="http://unicode.org/cldr/charts/by_type/index.html">By-Type
-Chart</a> shows these values for many locales.
-<abbr>ICU</abbr> contains a mechanism for using this data.</li>
<li>Alphabetic time zone abbreviations should not be used as unique
identifiers for <abbr>UTC</abbr> offsets as they are ambiguous in
-practice. For example, "<abbr>EST</abbr>" denotes 5 hours behind
-<abbr>UTC</abbr> in English-speaking North America, but it denotes 10
-or 11 hours ahead of <abbr>UTC</abbr> in Australia; and
-French-speaking North Americans prefer
-"<abbr title="Heure Normale de l'Est">HNE</abbr>" to
-"<abbr>EST</abbr>". For <abbr>POSIX</abbr> the <code>tz</code>
+practice. For example, in English-speaking North America
+"<abbr>CST</abbr>" denotes 6 hours behind <abbr>UTC</abbr>,
+but in China it denotes 8 hours ahead of <abbr>UTC</abbr>,
+and French-speaking North Americans prefer
+"<abbr title="Heure Normale du Centre">HNC</abbr>" to
+"<abbr>CST</abbr>". For <abbr>POSIX</abbr> the <code><abbr>tz</abbr></code>
database contains English abbreviations for all time stamps but in
many cases these are merely inventions of the database
maintainers.</li>
<li>Numeric time zone abbreviations typically count hours east of
-<abbr>UTC</abbr>, e.g., <code>+09</code> for Japan and
-<code>-10</code> for Hawaii. However, the <abbr>POSIX</abbr>
-<code>TZ</code> environment variable uses the opposite convention. For
-example, one might use <code>TZ="JST-9"</code> and
-<code>TZ="HST10"</code> for Japan and Hawaii, respectively. If the
-<code>tz</code> database is available, it is usually better to use
-settings like <code>TZ="Asia/Tokyo"</code> and
-<code>TZ="Pacific/Honolulu"</code> instead, as this should avoid
+<abbr>UTC</abbr>, e.g., +09 for Japan and
+−10 for Hawaii. However, the <abbr>POSIX</abbr>
+<code><abbr>TZ</abbr></code> environment variable uses the opposite convention.
+For example, one might use <code><abbr>TZ</abbr>="<abbr
+title="Japan Standard Time">JST</abbr>-9"</code> and
+<code><abbr>TZ</abbr>="<abbr title="Hawaii Standard Time">HST</abbr>10"</code>
+for Japan and Hawaii, respectively. If the
+<code><abbr>tz</abbr></code> database is available, it is usually better to use
+settings like <code><abbr>TZ</abbr>="Asia/Tokyo"</code> and
+<code><abbr>TZ</abbr>="Pacific/Honolulu"</code> instead, as this should avoid
confusion, handle old time stamps better, and insulate you better from
any future changes to the rules. One should never set
-<abbr>POSIX</abbr> <code>TZ</code> to a value like
+<abbr>POSIX</abbr> <code><abbr>TZ</abbr></code> to a value like
<code>"GMT-9"</code>, though, since this would falsely claim that
local time is nine hours ahead of <abbr>UTC</abbr> and the time zone
is called "<abbr>GMT</abbr>".</li>
</ul>
-<h2>Related indexes</h2>
+<h2>See also</h2>
<ul>
<li><a href="tz-art.htm">Time and the Arts</a></li>
-<li><a href="http://www.dmoz.org/Reference/Time/">Open Directory -
-Reference: Time</a></li>
-<li><a href="http://dir.yahoo.com/Science/Measurements_and_Units/Time">Yahoo!
-Directory > Science > Measurements and Units > Time</a></li>
</ul>
<hr>
<address>
-This file is in the public domain, so clarified as of
+This web page is in the public domain, so clarified as of
2009-05-17 by Arthur David Olson.
<br>
Please send corrections to this web page to the
Modified: vendor/tzcode/dist/tzfile.5
===================================================================
--- vendor/tzcode/dist/tzfile.5 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/tzfile.5 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,9 +1,6 @@
.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)
@@ -10,51 +7,48 @@
begin with the magic characters "TZif" to identify them as
time zone information files,
followed by a character identifying the version of the file's format
-(as of 2005, either an ASCII NUL or a '2')
+(as of 2013, either an ASCII NUL, or '2', or '3')
followed by fifteen bytes containing zeroes reserved for future use,
-followed by six four-byte values of type
-.BR long ,
-written in a ``standard'' byte order
+followed by six four-byte integer values
+written in a standard byte order
(the high-order byte of the value is written first).
These values are,
in order:
.TP
.I tzh_ttisgmtcnt
-The number of UTC/local indicators stored in the file.
+The number of UT/local indicators stored in the file.
.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.
+The number of leap seconds for which data entries are stored in the file.
.TP
.I tzh_timecnt
-The number of "transition times" for which data is stored
+The number of transition times for which data entries are stored
in the file.
.TP
.I tzh_typecnt
-The number of "local time types" for which data is stored
+The number of local time types for which data entries are stored
in the file (must not be zero).
.TP
.I tzh_charcnt
-The number of characters of "time zone abbreviation strings"
+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.
+four-byte signed integer values 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.
+one-byte unsigned integer values;
+each one tells which of the different types of local time types
+described in the file is associated with the time period
+starting with the same-indexed transition time.
These values serve as indices into an array of
.I ttinfo
structures (with
@@ -64,19 +58,17 @@
.in +.5i
.sp
.nf
-.ta .5i +\w'unsigned int\0\0'u
+.ta .5i +\w'unsigned char\0\0'u
struct ttinfo {
- long tt_gmtoff;
- int tt_isdst;
- unsigned int tt_abbrind;
+ int32_t tt_gmtoff;
+ unsigned char tt_isdst;
+ unsigned char tt_abbrind;
};
.in -.5i
.fi
.sp
-Each structure is written as a four-byte value for
-.I tt_gmtoff
-of type
-.BR long ,
+Each structure is written as a four-byte signed integer value for
+.IR tt_gmtoff ,
in a standard byte order, followed by a one-byte value for
.I tt_isdst
and a one-byte value for
@@ -83,7 +75,7 @@
.IR tt_abbrind .
In each structure,
.I tt_gmtoff
-gives the number of seconds to be added to UTC,
+gives the number of seconds to be added to UT,
.I tt_isdst
tells whether
.I tm_isdst
@@ -105,7 +97,8 @@
at which a leap second occurs;
the second gives the
.I total
-number of leap seconds to be applied after the given time.
+number of leap seconds to be applied during the time period
+starting at the given time.
The pairs of values are sorted in ascending order by time.
.PP
Then there are
@@ -118,9 +111,9 @@
.PP
Finally there are
.I tzh_ttisgmtcnt
-UTC/local indicators, each stored as a one-byte value;
+UT/local indicators, each stored as a one-byte value;
they tell whether the transition times associated with local time types
-were specified as UTC or local time,
+were specified as UT or local time,
and are used when a time zone file is used in handling POSIX-style
time zone environment variables.
.PP
@@ -145,7 +138,18 @@
after the last transition time stored in the file
(with nothing between the newlines if there is no POSIX representation for
such instants).
+.PP
+For version-3-format time zone files, the POSIX-TZ-style string may
+use two minor extensions to the POSIX TZ format, as described in
+.IR newtzset (3).
+First, the hours part of its transition times may be signed and range from
+\-167 through 167 instead of the POSIX-required unsigned values
+from 0 through 24. Second, DST is in effect all year if it starts
+January 1 at 00:00 and ends December 31 at 24:00 plus the difference
+between daylight saving and standard time.
+.PP
+Future changes to the format may append more data.
.SH SEE ALSO
-newctime(3)
+newctime(3), newtzset(3), zdump(8), zic(8)
.\" This file is in the public domain, so clarified as of
.\" 1996-06-05 by Arthur David Olson.
Modified: vendor/tzcode/dist/tzfile.5.txt
===================================================================
--- vendor/tzcode/dist/tzfile.5.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/tzfile.5.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,71 +1,70 @@
-TZFILE(5) TZFILE(5)
+TZFILE(5) File Formats Manual TZFILE(5)
NAME
tzfile - time zone information
-SYNOPSIS
- #include <tzfile.h>
-
DESCRIPTION
The time zone information files used by tzset(3) begin with the magic
characters "TZif" to identify them as time zone information files,
followed by a character identifying the version of the file's format
- (as of 2005, either an ASCII NUL or a '2') followed by fifteen bytes
- containing zeroes reserved for future use, followed by six four-byte
- values of type long, written in a ``standard'' byte order (the high-
- order byte of the value is written first). These values are, in order:
+ (as of 2013, either an ASCII NUL, or '2', or '3') followed by fifteen
+ bytes containing zeroes reserved for future use, followed by six four-
+ byte integer values written in a standard byte order (the high-order
+ byte of the value is written first). These values are, in order:
tzh_ttisgmtcnt
- The number of UTC/local indicators stored in the file.
+ The number of UT/local indicators stored in the file.
tzh_ttisstdcnt
The number of standard/wall indicators stored in the file.
tzh_leapcnt
- The number of leap seconds for which data is stored in the file.
+ The number of leap seconds for which data entries are stored in
+ the file.
tzh_timecnt
- The number of "transition times" for which data is stored in the
- file.
+ The number of transition times for which data entries are stored
+ in the file.
tzh_typecnt
- The number of "local time types" for which data is stored in the
- file (must not be zero).
+ The number of local time types for which data entries are stored
+ in the file (must not be zero).
tzh_charcnt
- The number of characters of "time zone abbreviation strings"
+ The number of characters of time zone abbreviation strings
stored in the file.
- The above header is followed by tzh_timecnt four-byte values of type
- long, sorted in ascending order. These values are written in
- ``standard'' byte order. Each is used as a transition time (as
- returned by time(2)) at which the rules for computing local time
- change. Next come tzh_timecnt one-byte values of type 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 ttinfo structures
- (with tzh_typecnt entries) that appears next in the file; these
- structures are defined as follows:
+ The above header is followed by tzh_timecnt four-byte signed integer
+ values sorted in ascending order. These values are written in standard
+ byte order. Each is used as a transition time (as returned by time(2))
+ at which the rules for computing local time change. Next come
+ tzh_timecnt one-byte unsigned integer values; each one tells which of
+ the different types of local time types described in the file is
+ associated with the time period starting with the same-indexed
+ transition time. These values serve as indices into an array of ttinfo
+ structures (with tzh_typecnt entries) that appears next in the file;
+ these structures are defined as follows:
struct ttinfo {
- long tt_gmtoff;
- int tt_isdst;
- unsigned int tt_abbrind;
+ int32_t tt_gmtoff;
+ unsigned char tt_isdst;
+ unsigned char tt_abbrind;
};
- Each structure is written as a four-byte value for tt_gmtoff of type
- long, in a standard byte order, followed by a one-byte value for
+ Each structure is written as a four-byte signed integer value for
+ tt_gmtoff, in a standard byte order, followed by a one-byte value for
tt_isdst and a one-byte value for tt_abbrind. In each structure,
- tt_gmtoff gives the number of seconds to be added to UTC, tt_isdst
- tells whether tm_isdst should be set by localtime (3) and tt_abbrind
- serves as an index into the array of time zone abbreviation characters
- that follow the ttinfo structure(s) in the file.
+ tt_gmtoff gives the number of seconds to be added to UT, tt_isdst tells
+ whether tm_isdst should be set by localtime (3) and tt_abbrind serves
+ as an index into the array of time zone abbreviation characters that
+ follow the ttinfo structure(s) in the file.
Then there are tzh_leapcnt pairs of four-byte values, written in
standard byte order; the first value of each pair gives the time (as
returned by time(2)) at which a leap second occurs; the second gives
- the total number of leap seconds to be applied after the given time.
- The pairs of values are sorted in ascending order by time.
+ the total number of leap seconds to be applied during the time period
+ starting at the given time. The pairs of values are sorted in
+ ascending order by time.
Then there are tzh_ttisstdcnt standard/wall indicators, each stored as
a one-byte value; they tell whether the transition times associated
@@ -73,9 +72,9 @@
time, and are used when a time zone file is used in handling POSIX-
style time zone environment variables.
- Finally there are tzh_ttisgmtcnt UTC/local indicators, each stored as a
+ Finally there are tzh_ttisgmtcnt UT/local indicators, each stored as a
one-byte value; they tell whether the transition times associated with
- local time types were specified as UTC or local time, and are used when
+ local time types were specified as UT or local time, and are used when
a time zone file is used in handling POSIX-style time zone environment
variables.
@@ -92,7 +91,17 @@
the last transition time stored in the file (with nothing between the
newlines if there is no POSIX representation for such instants).
+ For version-3-format time zone files, the POSIX-TZ-style string may use
+ two minor extensions to the POSIX TZ format, as described in
+ newtzset(3). First, the hours part of its transition times may be
+ signed and range from -167 through 167 instead of the POSIX-required
+ unsigned values from 0 through 24. Second, DST is in effect all year
+ if it starts January 1 at 00:00 and ends December 31 at 24:00 plus the
+ difference between daylight saving and standard time.
+
+ Future changes to the format may append more data.
+
SEE ALSO
- newctime(3)
+ newctime(3), newtzset(3), zdump(8), zic(8)
TZFILE(5)
Modified: vendor/tzcode/dist/tzfile.h
===================================================================
--- vendor/tzcode/dist/tzfile.h 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/tzfile.h 2016-08-15 01:50:22 UTC (rev 7736)
@@ -39,8 +39,8 @@
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
- char tzh_version[1]; /* '\0' or '2' as of 2005 */
- char tzh_reserved[15]; /* reserved--must be zero */
+ char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */
+ char tzh_reserved[15]; /* reserved; must be zero */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
@@ -55,7 +55,7 @@
** tzh_timecnt (char [4])s coded transition times a la time(2)
** tzh_timecnt (unsigned char)s types of local time starting at above
** tzh_typecnt repetitions of
-** one (char [4]) coded UTC offset in seconds
+** one (char [4]) coded UT offset in seconds
** one (unsigned char) used to set tm_isdst
** one (unsigned char) that's an abbreviation list index
** tzh_charcnt (char)s '\0'-terminated zone abbreviations
@@ -62,13 +62,13 @@
** 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,
+** tzh_ttisstdcnt (char)s indexed by type; if 1, transition
+** time is standard time, if 0,
** transition time is wall clock time
** if absent, transition times are
** assumed to be wall clock time
-** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
-** time is UTC, if FALSE,
+** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition
+** time is UT, if 0,
** transition time is local time
** if absent, transition times are
** assumed to be local time
@@ -82,6 +82,13 @@
** instants after the last transition time stored in the file
** (with nothing between the newlines if there is no POSIX representation for
** such instants).
+**
+** If tz_version is '3' or greater, the above is extended as follows.
+** First, the POSIX TZ string's hour offset may range from -167
+** through 167 as compared to the POSIX-required 0 through 24.
+** Second, its DST start time may be January 1 at 00:00 and its stop
+** time December 31 at 24:00 plus the difference between DST and
+** standard time, indicating DST all year.
*/
/*
@@ -90,20 +97,12 @@
*/
#ifndef TZ_MAX_TIMES
-#define TZ_MAX_TIMES 1200
+#define TZ_MAX_TIMES 2000
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
-#ifndef NOSOLAR
+/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
-#endif /* !defined NOSOLAR */
-#ifdef NOSOLAR
-/*
-** Must be at least 14 for Europe/Riga as of Jan 12 1995,
-** as noted by Earl Chew.
-*/
-#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
-#endif /* !defined NOSOLAR */
#endif /* !defined TZ_MAX_TYPES */
#ifndef TZ_MAX_CHARS
@@ -122,7 +121,7 @@
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
+#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
#define TM_SUNDAY 0
Modified: vendor/tzcode/dist/tzselect.8
===================================================================
--- vendor/tzcode/dist/tzselect.8 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/tzselect.8 2016-08-15 01:50:22 UTC (rev 7736)
@@ -2,7 +2,20 @@
.SH NAME
tzselect \- select a time zone
.SH SYNOPSIS
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
.B tzselect
+[
+.B \*-c
+.I coord
+] [
+.B \*-n
+.I limit
+] [
+.B \*-\*-help
+] [
+.B \*-\*-version
+]
.SH DESCRIPTION
The
.B tzselect
@@ -11,6 +24,60 @@
The output is suitable as a value for the TZ environment variable.
.PP
All interaction with the user is done via standard input and standard error.
+.SH OPTIONS
+.TP
+.BI "\*-c " coord
+Instead of asking for continent and then country and then city,
+ask for selection from time zones whose largest cities
+are closest to the location with geographical coordinates
+.I coord.
+Use ISO 6709 notation for
+.I coord,
+that is, a latitude immediately followed by a longitude. The latitude
+and longitude should be signed integers followed by an optional
+decimal point and fraction: positive numbers represent north and east,
+negative south and west. Latitudes with two and longitudes with three
+integer digits are treated as degrees; latitudes with four or six and
+longitudes with five or seven integer digits are treated as
+.I "DDMM, DDDMM, DDMMSS,"
+or
+.I DDDMMSS
+representing
+.I DD
+or
+.I DDD
+degrees,
+.I MM
+minutes,
+and zero or
+.I SS
+seconds, with any trailing fractions represent fractional minutes or
+(if
+.I SS
+is present) seconds. The decimal point is that of the current locale.
+For example, in the (default) C locale,
+.B "\*-c\ +40.689\*-074.045"
+specifies 40.689\(de\|N, 74.045\(de\|W,
+.B "\*-c\ +4041.4\*-07402.7"
+specifies 40\(de\|41.4\(fm\|N, 74\(de\|2.7\(fm\|W, and
+.B "\*-c\ +404121\*-0740240"
+specifies 40\(de\|41\(fm\|21\(sd\|N, 74\(de\|2\(fm\|40\(sd\|W.
+If
+.I coord
+is not one of the documented forms, the resulting behavior is unspecified.
+.TP
+.BI "\*-n " limit
+When
+.B \*-c
+is used, display the closest
+.I limit
+locations (default 10).
+.TP
+.B "\*-\*-help"
+Output help information and exit.
+.TP
+.B "\*-\*-version"
+Output version information and exit.
.SH "ENVIRONMENT VARIABLES"
.TP
\f3AWK\fP
@@ -27,8 +94,8 @@
\f2TZDIR\fP\f3/iso3166.tab\fP
Table of ISO 3166 2-letter country codes and country names.
.TP
-\f2TZDIR\fP\f3/zone.tab\fP
-Table of country codes, latitude and longitude, TZ values, and
+\f2TZDIR\fP\f3/zone1970.tab\fP
+Table of country codes, latitude and longitude, zone names, and
descriptive comments.
.TP
\f2TZDIR\fP\f3/\fP\f2TZ\fP
@@ -38,5 +105,9 @@
nonzero otherwise.
.SH "SEE ALSO"
newctime(3), tzfile(5), zdump(8), zic(8)
+.SH NOTES
+Applications should not assume that
+.BR tzselect 's
+output matches the user's political preferences.
.\" This file is in the public domain, so clarified as of
.\" 2009-05-17 by Arthur David Olson.
Modified: vendor/tzcode/dist/tzselect.8.txt
===================================================================
--- vendor/tzcode/dist/tzselect.8.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/tzselect.8.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,10 +1,10 @@
-TZSELECT(8) TZSELECT(8)
+TZSELECT(8) System Manager's Manual TZSELECT(8)
NAME
tzselect - select a time zone
SYNOPSIS
- tzselect
+ tzselect [ -c coord ] [ -n limit ] [ --help ] [ --version ]
DESCRIPTION
The tzselect program asks the user for information about the current
@@ -15,6 +15,37 @@
All interaction with the user is done via standard input and standard
error.
+OPTIONS
+ -c coord
+ Instead of asking for continent and then country and then city,
+ ask for selection from time zones whose largest cities are
+ closest to the location with geographical coordinates coord.
+ Use ISO 6709 notation for coord, that is, a latitude immediately
+ followed by a longitude. The latitude and longitude should be
+ signed integers followed by an optional decimal point and
+ fraction: positive numbers represent north and east, negative
+ south and west. Latitudes with two and longitudes with three
+ integer digits are treated as degrees; latitudes with four or
+ six and longitudes with five or seven integer digits are treated
+ as DDMM, DDDMM, DDMMSS, or DDDMMSS representing DD or DDD
+ degrees, MM minutes, and zero or SS seconds, with any trailing
+ fractions represent fractional minutes or (if SS is present)
+ seconds. The decimal point is that of the current locale. For
+ example, in the (default) C locale, -c +40.689-074.045 specifies
+ 40.689oN, 74.045oW, -c +4041.4-07402.7 specifies 40o41.4'N,
+ 74o2.7'W, and -c +404121-0740240 specifies 40o41'21''N,
+ 74o2'40''W. If coord is not one of the documented forms, the
+ resulting behavior is unspecified.
+
+ -n limit
+ When -c is used, display the closest limit locations (default
+ 10).
+
+ --help Output help information and exit.
+
+ --version
+ Output version information and exit.
+
ENVIRONMENT VARIABLES
AWK Name of a Posix-compliant awk program (default: awk).
@@ -25,8 +56,8 @@
TZDIR/iso3166.tab
Table of ISO 3166 2-letter country codes and country names.
- TZDIR/zone.tab
- Table of country codes, latitude and longitude, TZ values, and
+ TZDIR/zone1970.tab
+ Table of country codes, latitude and longitude, zone names, and
descriptive comments.
TZDIR/TZ
@@ -39,4 +70,8 @@
SEE ALSO
newctime(3), tzfile(5), zdump(8), zic(8)
+NOTES
+ Applications should not assume that tzselect's output matches the
+ user's political preferences.
+
TZSELECT(8)
Modified: vendor/tzcode/dist/tzselect.ksh
===================================================================
--- vendor/tzcode/dist/tzselect.ksh 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/tzselect.ksh 2016-08-15 01:50:22 UTC (rev 7736)
@@ -2,15 +2,16 @@
PKGVERSION='(tzcode) '
TZVERSION=see_Makefile
+REPORT_BUGS_TO=tz at iana.org
# Ask the user about the time zone, and output the resulting TZ value to stdout.
# Interact with the user via stderr and stdin.
-# Contributed by Paul Eggert.
+# Contributed by Paul Eggert. This file is in the public domain.
# Porting notes:
#
-# This script requires a Posix-like shell with the extension of a
+# This script requires a Posix-like shell and prefers the extension of a
# 'select' statement. The 'select' statement was introduced in the
# Korn shell and is available in Bash and other shell implementations.
# If your host lacks both Bash and the Korn shell, you can get their
@@ -20,6 +21,10 @@
# Korn Shell <http://www.kornshell.com/>
# Public Domain Korn Shell <http://www.cs.mun.ca/~michael/pdksh/>
#
+# For portability to Solaris 9 /bin/sh this script avoids some POSIX
+# features and common extensions, such as $(...) (which works sometimes
+# but not others), $((...)), and $10.
+#
# This script also uses several features of modern awk programs.
# If your host lacks awk, or has an old awk that does not conform to Posix,
# you can use either of the following free programs instead:
@@ -30,52 +35,259 @@
# Specify default values for environment variables if they are unset.
: ${AWK=awk}
-: ${TZDIR=$(pwd)}
+: ${TZDIR=`pwd`}
+# Output one argument as-is to standard output.
+# Safer than 'echo', which can mishandle '\' or leading '-'.
+say() {
+ printf '%s\n' "$1"
+}
+
# Check for awk Posix compliance.
($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
[ $? = 123 ] || {
- echo >&2 "$0: Sorry, your \`$AWK' program is not Posix compatible."
+ say >&2 "$0: Sorry, your '$AWK' program is not Posix compatible."
exit 1
}
-if [ "$1" = "--help" ]; then
- cat <<EOF
-Usage: tzselect
+coord=
+location_limit=10
+zonetabtype=zone1970
+
+usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT]
Select a time zone interactively.
-Report bugs to tz at iana.org.
-EOF
- exit
-elif [ "$1" = "--version" ]; then
- cat <<EOF
-tzselect $PKGVERSION$TZVERSION
-EOF
- exit
+Options:
+
+ -c COORD
+ Instead of asking for continent and then country and then city,
+ ask for selection from time zones whose largest cities
+ are closest to the location with geographical coordinates COORD.
+ COORD should use ISO 6709 notation, for example, '-c +4852+00220'
+ for Paris (in degrees and minutes, North and East), or
+ '-c -35-058' for Buenos Aires (in degrees, South and West).
+
+ -n LIMIT
+ Display at most LIMIT locations when -c is used (default $location_limit).
+
+ --version
+ Output version information.
+
+ --help
+ Output this help.
+
+Report bugs to $REPORT_BUGS_TO."
+
+# Ask the user to select from the function's arguments,
+# and assign the selected argument to the variable 'select_result'.
+# Exit on EOF or I/O error. Use the shell's 'select' builtin if available,
+# falling back on a less-nice but portable substitute otherwise.
+if
+ case $BASH_VERSION in
+ ?*) : ;;
+ '')
+ # '; exit' should be redundant, but Dash doesn't properly fail without it.
+ (eval 'set --; select x; do break; done; exit') </dev/null 2>/dev/null
+ esac
+then
+ # Do this inside 'eval', as otherwise the shell might exit when parsing it
+ # even though it is never executed.
+ eval '
+ doselect() {
+ select select_result
+ do
+ case $select_result in
+ "") echo >&2 "Please enter a number in range." ;;
+ ?*) break
+ esac
+ done || exit
+ }
+
+ # Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
+ case $BASH_VERSION in
+ [01].*)
+ case `echo 1 | (select x in x; do break; done) 2>/dev/null` in
+ ?*) PS3=
+ esac
+ esac
+ '
+else
+ doselect() {
+ # Field width of the prompt numbers.
+ select_width=`expr $# : '.*'`
+
+ select_i=
+
+ while :
+ do
+ case $select_i in
+ '')
+ select_i=0
+ for select_word
+ do
+ select_i=`expr $select_i + 1`
+ printf >&2 "%${select_width}d) %s\\n" $select_i "$select_word"
+ done ;;
+ *[!0-9]*)
+ echo >&2 'Please enter a number in range.' ;;
+ *)
+ if test 1 -le $select_i && test $select_i -le $#; then
+ shift `expr $select_i - 1`
+ select_result=$1
+ break
+ fi
+ echo >&2 'Please enter a number in range.'
+ esac
+
+ # Prompt and read input.
+ printf >&2 %s "${PS3-#? }"
+ read select_i || exit
+ done
+ }
fi
+while getopts c:n:t:-: opt
+do
+ case $opt$OPTARG in
+ c*)
+ coord=$OPTARG ;;
+ n*)
+ location_limit=$OPTARG ;;
+ t*) # Undocumented option, used for developer testing.
+ zonetabtype=$OPTARG ;;
+ -help)
+ exec echo "$usage" ;;
+ -version)
+ exec echo "tzselect $PKGVERSION$TZVERSION" ;;
+ -*)
+ say >&2 "$0: -$opt$OPTARG: unknown option; try '$0 --help'"; exit 1 ;;
+ *)
+ say >&2 "$0: try '$0 --help'"; exit 1 ;;
+ esac
+done
+
+shift `expr $OPTIND - 1`
+case $# in
+0) ;;
+*) say >&2 "$0: $1: unknown argument"; exit 1 ;;
+esac
+
# Make sure the tables are readable.
TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab
-TZ_ZONE_TABLE=$TZDIR/zone.tab
+TZ_ZONE_TABLE=$TZDIR/$zonetabtype.tab
for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
do
- <$f || {
- echo >&2 "$0: time zone files are not set up correctly"
+ <"$f" || {
+ say >&2 "$0: time zone files are not set up correctly"
exit 1
}
done
+# If the current locale does not support UTF-8, convert data to current
+# locale's format if possible, as the shell aligns columns better that way.
+# Check the UTF-8 of U+12345 CUNEIFORM SIGN URU TIMES KI.
+! $AWK 'BEGIN { u12345 = "\360\222\215\205"; exit length(u12345) != 1 }' &&
+ { tmp=`(mktemp -d) 2>/dev/null` || {
+ tmp=${TMPDIR-/tmp}/tzselect.$$ &&
+ (umask 77 && mkdir -- "$tmp")
+ };} &&
+ trap 'status=$?; rm -fr -- "$tmp"; exit $status' 0 HUP INT PIPE TERM &&
+ (iconv -f UTF-8 -t //TRANSLIT <"$TZ_COUNTRY_TABLE" >$tmp/iso3166.tab) \
+ 2>/dev/null &&
+ TZ_COUNTRY_TABLE=$tmp/iso3166.tab &&
+ iconv -f UTF-8 -t //TRANSLIT <"$TZ_ZONE_TABLE" >$tmp/$zonetabtype.tab &&
+ TZ_ZONE_TABLE=$tmp/$zonetabtype.tab
+
newline='
'
IFS=$newline
-# Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
-case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in
-?*) PS3=
-esac
+# Awk script to read a time zone table and output the same table,
+# with each column preceded by its distance from 'here'.
+output_distances='
+ BEGIN {
+ FS = "\t"
+ while (getline <TZ_COUNTRY_TABLE)
+ if ($0 ~ /^[^#]/)
+ country[$1] = $2
+ country["US"] = "US" # Otherwise the strings get too long.
+ }
+ function abs(x) {
+ return x < 0 ? -x : x;
+ }
+ function min(x, y) {
+ return x < y ? x : y;
+ }
+ function convert_coord(coord, deg, minute, ilen, sign, sec) {
+ if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9][0-9][0-9]([^0-9]|$)/) {
+ degminsec = coord
+ intdeg = degminsec < 0 ? -int(-degminsec / 10000) : int(degminsec / 10000)
+ minsec = degminsec - intdeg * 10000
+ intmin = minsec < 0 ? -int(-minsec / 100) : int(minsec / 100)
+ sec = minsec - intmin * 100
+ deg = (intdeg * 3600 + intmin * 60 + sec) / 3600
+ } else if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9]([^0-9]|$)/) {
+ degmin = coord
+ intdeg = degmin < 0 ? -int(-degmin / 100) : int(degmin / 100)
+ minute = degmin - intdeg * 100
+ deg = (intdeg * 60 + minute) / 60
+ } else
+ deg = coord
+ return deg * 0.017453292519943296
+ }
+ function convert_latitude(coord) {
+ match(coord, /..*[-+]/)
+ return convert_coord(substr(coord, 1, RLENGTH - 1))
+ }
+ function convert_longitude(coord) {
+ match(coord, /..*[-+]/)
+ return convert_coord(substr(coord, RLENGTH))
+ }
+ # Great-circle distance between points with given latitude and longitude.
+ # Inputs and output are in radians. This uses the great-circle special
+ # case of the Vicenty formula for distances on ellipsoids.
+ function gcdist(lat1, long1, lat2, long2, dlong, x, y, num, denom) {
+ dlong = long2 - long1
+ x = cos(lat2) * sin(dlong)
+ y = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlong)
+ num = sqrt(x * x + y * y)
+ denom = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(dlong)
+ return atan2(num, denom)
+ }
+ # Parallel distance between points with given latitude and longitude.
+ # This is the product of the longitude difference and the cosine
+ # of the latitude of the point that is further from the equator.
+ # I.e., it considers longitudes to be further apart if they are
+ # nearer the equator.
+ function pardist(lat1, long1, lat2, long2) {
+ return abs(long1 - long2) * min(cos(lat1), cos(lat2))
+ }
+ # The distance function is the sum of the great-circle distance and
+ # the parallel distance. It could be weighted.
+ function dist(lat1, long1, lat2, long2) {
+ return gcdist(lat1, long1, lat2, long2) + pardist(lat1, long1, lat2, long2)
+ }
+ BEGIN {
+ coord_lat = convert_latitude(coord)
+ coord_long = convert_longitude(coord)
+ }
+ /^[^#]/ {
+ here_lat = convert_latitude($2)
+ here_long = convert_longitude($2)
+ line = $1 "\t" $2 "\t" $3
+ sep = "\t"
+ ncc = split($1, cc, /,/)
+ for (i = 1; i <= ncc; i++) {
+ line = line sep country[cc[i]]
+ sep = ", "
+ }
+ if (NF == 4)
+ line = line " - " $4
+ printf "%g\t%s\n", dist(coord_lat, coord_long, here_lat, here_long), line
+ }
+'
-
# Begin the main loop. We come back here if the user wants to retry.
while
@@ -86,39 +298,46 @@
country=
region=
+ case $coord in
+ ?*)
+ continent=coord;;
+ '')
# Ask the user for continent or ocean.
- echo >&2 'Please select a continent or ocean.'
+ echo >&2 'Please select a continent, ocean, "coord", or "TZ".'
- select continent in \
- Africa \
- Americas \
- Antarctica \
- 'Arctic Ocean' \
- Asia \
- 'Atlantic Ocean' \
- Australia \
- Europe \
- 'Indian Ocean' \
- 'Pacific Ocean' \
- 'none - I want to specify the time zone using the Posix TZ format.'
- do
+ quoted_continents=`
+ $AWK '
+ BEGIN { FS = "\t" }
+ /^[^#]/ {
+ entry = substr($3, 1, index($3, "/") - 1)
+ if (entry == "America")
+ entry = entry "s"
+ if (entry ~ /^(Arctic|Atlantic|Indian|Pacific)$/)
+ entry = entry " Ocean"
+ printf "'\''%s'\''\n", entry
+ }
+ ' <"$TZ_ZONE_TABLE" |
+ sort -u |
+ tr '\n' ' '
+ echo ''
+ `
+
+ eval '
+ doselect '"$quoted_continents"' \
+ "coord - I want to use geographical coordinates." \
+ "TZ - I want to specify the time zone using the Posix TZ format."
+ continent=$select_result
case $continent in
- '')
- echo >&2 'Please enter a number in range.';;
- ?*)
- case $continent in
- Americas) continent=America;;
- *' '*) continent=$(expr "$continent" : '\([^ ]*\)')
- esac
- break
+ Americas) continent=America;;
+ *" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''`
esac
- done
+ '
+ esac
+
case $continent in
- '')
- exit 1;;
- none)
+ TZ)
# Ask the user for a Posix TZ string. Check that it conforms.
while
echo >&2 'Please enter the desired value' \
@@ -127,11 +346,14 @@
'that is 10 hours ahead (east) of UTC.'
read TZ
$AWK -v TZ="$TZ" 'BEGIN {
- tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+"
- time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?"
+ tzname = "(<[[:alnum:]+-]{3,}>|[[:alpha:]]{3,})"
+ time = "(2[0-4]|[0-1]?[0-9])" \
+ "(:[0-5][0-9](:[0-5][0-9])?)?"
offset = "[-+]?" time
- date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)"
- datetime = "," date "(/" time ")?"
+ mdate = "M([1-9]|1[0-2])\\.[1-5]\\.[0-6]"
+ jdate = "((J[1-9]|[0-9]|J?[1-9][0-9]" \
+ "|J?[1-2][0-9][0-9])|J?3[0-5][0-9]|J?36[0-5])"
+ datetime = ",(" mdate "|" jdate ")(/" time ")?"
tzpattern = "^(:.*|" tzname offset "(" tzname \
"(" offset ")?(" datetime datetime ")?)?)$"
if (TZ ~ tzpattern) exit 1
@@ -138,19 +360,55 @@
exit 0
}'
do
- echo >&2 "\`$TZ' is not a conforming" \
- 'Posix time zone string.'
+ say >&2 "'$TZ' is not a conforming Posix time zone string."
done
TZ_for_date=$TZ;;
*)
+ case $continent in
+ coord)
+ case $coord in
+ '')
+ echo >&2 'Please enter coordinates' \
+ 'in ISO 6709 notation.'
+ echo >&2 'For example, +4042-07403 stands for'
+ echo >&2 '40 degrees 42 minutes north,' \
+ '74 degrees 3 minutes west.'
+ read coord;;
+ esac
+ distance_table=`$AWK \
+ -v coord="$coord" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ "$output_distances" <"$TZ_ZONE_TABLE" |
+ sort -n |
+ sed "${location_limit}q"
+ `
+ regions=`say "$distance_table" | $AWK '
+ BEGIN { FS = "\t" }
+ { print $NF }
+ '`
+ echo >&2 'Please select one of the following' \
+ 'time zone regions,'
+ echo >&2 'listed roughly in increasing order' \
+ "of distance from $coord".
+ doselect $regions
+ region=$select_result
+ TZ=`say "$distance_table" | $AWK -v region="$region" '
+ BEGIN { FS="\t" }
+ $NF == region { print $4 }
+ '`
+ ;;
+ *)
# Get list of names of countries in the continent or ocean.
- countries=$($AWK -F'\t' \
+ countries=`$AWK \
-v continent="$continent" \
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
'
+ BEGIN { FS = "\t" }
/^#/ { next }
$3 ~ ("^" continent "/") {
- if (!cc_seen[$1]++) cc_list[++ccs] = $1
+ ncc = split($1, cc, /,/)
+ for (i = 1; i <= ncc; i++)
+ if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i]
}
END {
while (getline <TZ_COUNTRY_TABLE) {
@@ -164,24 +422,16 @@
print country
}
}
- ' <$TZ_ZONE_TABLE | sort -f)
+ ' <"$TZ_ZONE_TABLE" | sort -f`
# If there's more than one country, ask the user which one.
case $countries in
*"$newline"*)
- echo >&2 'Please select a country.'
- select country in $countries
- do
- case $country in
- '') echo >&2 'Please enter a number in range.';;
- ?*) break
- esac
- done
-
- case $country in
- '') exit 1
- esac;;
+ echo >&2 'Please select a country' \
+ 'whose clocks agree with yours.'
+ doselect $countries
+ country=$select_result;;
*)
country=$countries
esac
@@ -188,11 +438,12 @@
# Get list of names of time zone rule regions in the country.
- regions=$($AWK -F'\t' \
+ regions=`$AWK \
-v country="$country" \
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
'
BEGIN {
+ FS = "\t"
cc = country
while (getline <TZ_COUNTRY_TABLE) {
if ($0 !~ /^#/ && country == $2) {
@@ -201,8 +452,9 @@
}
}
}
- $1 == cc { print $4 }
- ' <$TZ_ZONE_TABLE)
+ /^#/ { next }
+ $1 ~ cc { print $4 }
+ ' <"$TZ_ZONE_TABLE"`
# If there's more than one region, ask the user which one.
@@ -210,27 +462,20 @@
*"$newline"*)
echo >&2 'Please select one of the following' \
'time zone regions.'
- select region in $regions
- do
- case $region in
- '') echo >&2 'Please enter a number in range.';;
- ?*) break
- esac
- done
- case $region in
- '') exit 1
- esac;;
+ doselect $regions
+ region=$select_result;;
*)
region=$regions
esac
# Determine TZ from country and region.
- TZ=$($AWK -F'\t' \
+ TZ=`$AWK \
-v country="$country" \
-v region="$region" \
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
'
BEGIN {
+ FS = "\t"
cc = country
while (getline <TZ_COUNTRY_TABLE) {
if ($0 !~ /^#/ && country == $2) {
@@ -239,13 +484,15 @@
}
}
}
- $1 == cc && $4 == region { print $3 }
- ' <$TZ_ZONE_TABLE)
+ /^#/ { next }
+ $1 ~ cc && $4 == region { print $3 }
+ ' <"$TZ_ZONE_TABLE"`
+ esac
# Make sure the corresponding zoneinfo file exists.
TZ_for_date=$TZDIR/$TZ
- <$TZ_for_date || {
- echo >&2 "$0: time zone files are not set up correctly"
+ <"$TZ_for_date" || {
+ say >&2 "$0: time zone files are not set up correctly"
exit 1
}
esac
@@ -258,14 +505,14 @@
extra_info=
for i in 1 2 3 4 5 6 7 8
do
- TZdate=$(LANG=C TZ="$TZ_for_date" date)
- UTdate=$(LANG=C TZ=UTC0 date)
- TZsec=$(expr "$TZdate" : '.*:\([0-5][0-9]\)')
- UTsec=$(expr "$UTdate" : '.*:\([0-5][0-9]\)')
+ TZdate=`LANG=C TZ="$TZ_for_date" date`
+ UTdate=`LANG=C TZ=UTC0 date`
+ TZsec=`expr "$TZdate" : '.*:\([0-5][0-9]\)'`
+ UTsec=`expr "$UTdate" : '.*:\([0-5][0-9]\)'`
case $TZsec in
$UTsec)
extra_info="
-Local time is now: $TZdate.
+Selected time is now: $TZdate.
Universal Time is now: $UTdate."
break
esac
@@ -277,28 +524,23 @@
echo >&2 ""
echo >&2 "The following information has been given:"
echo >&2 ""
- case $country+$region in
- ?*+?*) echo >&2 " $country$newline $region";;
- ?*+) echo >&2 " $country";;
- +) echo >&2 " TZ='$TZ'"
+ case $country%$region%$coord in
+ ?*%?*%) say >&2 " $country$newline $region";;
+ ?*%%) say >&2 " $country";;
+ %?*%?*) say >&2 " coord $coord$newline $region";;
+ %%?*) say >&2 " coord $coord";;
+ *) say >&2 " TZ='$TZ'"
esac
- echo >&2 ""
- echo >&2 "Therefore TZ='$TZ' will be used.$extra_info"
- echo >&2 "Is the above information OK?"
+ say >&2 ""
+ say >&2 "Therefore TZ='$TZ' will be used.$extra_info"
+ say >&2 "Is the above information OK?"
- ok=
- select ok in Yes No
- do
- case $ok in
- '') echo >&2 'Please enter 1 for Yes, or 2 for No.';;
- ?*) break
- esac
- done
+ doselect Yes No
+ ok=$select_result
case $ok in
- '') exit 1;;
Yes) break
esac
-do :
+do coord=
done
case $SHELL in
@@ -306,7 +548,7 @@
*) file=.profile line="TZ='$TZ'; export TZ"
esac
-echo >&2 "
+test -t 1 && say >&2 "
You can make this change permanent for yourself by appending the line
$line
to the file '$file' in your home directory; then log out and log in again.
@@ -314,4 +556,4 @@
Here is that TZ value again, this time on standard output so that you
can use the $0 command in shell scripts:"
-echo "$TZ"
+say "$TZ"
Modified: vendor/tzcode/dist/workman.sh
===================================================================
--- vendor/tzcode/dist/workman.sh 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/workman.sh 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,6 +1,5 @@
#! /bin/sh
-# <pre>
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
@@ -14,6 +13,8 @@
..
.rm }H
.rm }F" | nroff -man - ${1+"$@"} | perl -ne '
+ binmode STDIN, '\'':encoding(utf8)'\'';
+ binmode STDOUT, '\'':encoding(utf8)'\'';
chomp;
s/.\010//g;
s/\s*$//;
Modified: vendor/tzcode/dist/zdump.8
===================================================================
--- vendor/tzcode/dist/zdump.8 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/zdump.8 2016-08-15 01:50:22 UTC (rev 7736)
@@ -4,14 +4,13 @@
.SH SYNOPSIS
.B zdump
[
-.B \-\-version
-]
-[
-.B \-v
-] [
-.B \-c
-[loyear,]hiyear ] [ zonename ... ]
+.I option
+\&... ] [
+.I zonename
+\&... ]
.SH DESCRIPTION
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
.I Zdump
prints the current time in each
.I zonename
@@ -19,10 +18,10 @@
.PP
These options are available:
.TP
-.BI "\-\-version"
+.BI "\*-\*-version"
Output version information and exit.
.TP
-.B \-v
+.B \*-v
For each
.I zonename
on the command line,
@@ -31,27 +30,62 @@
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.
+and the time at the highest possible time value.
+Each line is followed by
+.BI isdst= D
+where
+.I D
+is positive, zero, or negative depending on whether
+the given time is daylight saving time, standard time,
+or an unknown time type, respectively.
+Each line is also followed by
+.BI gmtoff= N
+if the given local time is known to be
+.I N
+seconds east of Greenwich.
.TP
-.BI "\-c " [loyear,]hiyear
-Cut off verbose output near the start of the given year(s).
-By default,
-the program cuts off verbose output near the starts of the years -500 and 2500.
+.B \*-V
+Like
+.BR \*-v ,
+except omit the times relative to the extreme time values.
+This generates output that is easier to compare to that of
+implementations with different time representations.
+.TP
+.BI "\*-c " [loyear,]hiyear
+Cut off verbose output at the given year(s).
+Cutoff times are computed using the proleptic Gregorian calendar with year 0
+and with Universal Time (UT) ignoring leap seconds.
+The lower bound is exclusive and the upper is inclusive; for example, a
+.I loyear
+of 1970 excludes a transition occurring at 1970-01-01 00:00:00 UTC but a
+.I hiyear
+of 1970 includes the transition.
+The default cutoff is
+.BR \*-500,2500 .
+.TP
+.BI "\*-t " [lotime,]hitime
+Cut off verbose output at the given time(s),
+given in decimal seconds since 1970-01-01 00:00:00
+Coordinated Universal Time (UTC).
+The
+.I zonename
+determines whether the count includes leap seconds.
+As with
+.BR \*-c ,
+the cutoff's lower bound is exclusive and its upper bound is inclusive.
.SH LIMITATIONS
-The
-.B \-v
-option may not be used on systems with floating-point time_t values
-that are neither float nor double.
-.PP
Time discontinuities are found by sampling the results returned by localtime
at twelve-hour intervals.
This works in all real-world cases;
one can construct artificial time zones for which this fails.
+.PP
+In the output, "UT" denotes the value returned by
+.IR gmtime (3),
+which uses UTC for modern time stamps and some other UT flavor for
+time stamps that predate the introduction of UTC.
+No attempt is currently made to have the output use "UTC" for newer
+and "UT" for older time stamps,
+partly because the exact date of the introduction of UTC is problematic.
.SH "SEE ALSO"
newctime(3), tzfile(5), zic(8)
.\" This file is in the public domain, so clarified as of
Modified: vendor/tzcode/dist/zdump.8.txt
===================================================================
--- vendor/tzcode/dist/zdump.8.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/zdump.8.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,10 +1,10 @@
-ZDUMP(8) ZDUMP(8)
+ZDUMP(8) System Manager's Manual ZDUMP(8)
NAME
zdump - time zone dumper
SYNOPSIS
- zdump [ --version ] [ -v ] [ -c [loyear,]hiyear ] [ zonename ... ]
+ zdump [ option ... ] [ zonename ... ]
DESCRIPTION
Zdump prints the current time in each zonename named on the command
@@ -20,22 +20,45 @@
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 isdst=1 if the
- given time is Daylight Saving Time or isdst=0 otherwise.
+ highest possible time value. Each line is followed by isdst=D
+ where D is positive, zero, or negative depending on whether the
+ given time is daylight saving time, standard time, or an unknown
+ time type, respectively. Each line is also followed by gmtoff=N
+ if the given local time is known to be N seconds east of
+ Greenwich.
+ -V Like -v, except omit the times relative to the extreme time
+ values. This generates output that is easier to compare to that
+ of implementations with different time representations.
+
-c [loyear,]hiyear
- Cut off verbose output near the start of the given year(s). By
- default, the program cuts off verbose output near the starts of
- the years -500 and 2500.
+ Cut off verbose output at the given year(s). Cutoff times are
+ computed using the proleptic Gregorian calendar with year 0 and
+ with Universal Time (UT) ignoring leap seconds. The lower bound
+ is exclusive and the upper is inclusive; for example, a loyear
+ of 1970 excludes a transition occurring at 1970-01-01 00:00:00
+ UTC but a hiyear of 1970 includes the transition. The default
+ cutoff is -500,2500.
+ -t [lotime,]hitime
+ Cut off verbose output at the given time(s), given in decimal
+ seconds since 1970-01-01 00:00:00 Coordinated Universal Time
+ (UTC). The zonename determines whether the count includes leap
+ seconds. As with -c, the cutoff's lower bound is exclusive and
+ its upper bound is inclusive.
+
LIMITATIONS
- The -v option may not be used on systems with floating-point time_t
- values that are neither float nor double.
-
Time discontinuities are found by sampling the results returned by
localtime at twelve-hour intervals. This works in all real-world
cases; one can construct artificial time zones for which this fails.
+ In the output, "UT" denotes the value returned by gmtime(3), which uses
+ UTC for modern time stamps and some other UT flavor for time stamps
+ that predate the introduction of UTC. No attempt is currently made to
+ have the output use "UTC" for newer and "UT" for older time stamps,
+ partly because the exact date of the introduction of UTC is
+ problematic.
+
SEE ALSO
newctime(3), tzfile(5), zic(8)
Modified: vendor/tzcode/dist/zdump.c
===================================================================
--- vendor/tzcode/dist/zdump.c 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/zdump.c 2016-08-15 01:50:22 UTC (rev 7736)
@@ -9,20 +9,116 @@
** 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.
+** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
*/
+#ifndef NETBSD_INSPIRED
+# define NETBSD_INSPIRED 1
+#endif
+#ifndef USE_LTZ
+# define USE_LTZ 1
+#endif
+
+#if USE_LTZ
+# include "private.h"
+#endif
+
+/* Enable tm_gmtoff and tm_zone on GNUish systems. */
+#define _GNU_SOURCE 1
+/* Enable strtoimax on Solaris 10. */
+#define __EXTENSIONS__ 1
+
#include "stdio.h" /* for stdout, stderr, perror */
#include "string.h" /* for strcpy */
#include "sys/types.h" /* for time_t */
#include "time.h" /* for struct tm */
#include "stdlib.h" /* for exit, malloc, atoi */
-#include "float.h" /* for FLT_MAX and DBL_MAX */
#include "limits.h" /* for CHAR_BIT, LLONG_MAX */
-#include "ctype.h" /* for isalpha et al. */
-#ifndef isascii
-#define isascii(x) 1
-#endif /* !defined isascii */
+#include <errno.h>
+/*
+** Substitutes for pre-C99 compilers.
+** Much of this section of code is stolen from private.h.
+*/
+
+#ifndef HAVE_STDINT_H
+# define HAVE_STDINT_H \
+ (199901 <= __STDC_VERSION__ \
+ || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
+ || __CYGWIN__)
+#endif
+#if HAVE_STDINT_H
+# include "stdint.h"
+#endif
+#ifndef HAVE_INTTYPES_H
+# define HAVE_INTTYPES_H HAVE_STDINT_H
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+#ifndef INT_FAST32_MAX
+# if INT_MAX >> 31 == 0
+typedef long int_fast32_t;
+# else
+typedef int int_fast32_t;
+# endif
+#endif
+
+/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
+#if !defined LLONG_MAX && defined __LONG_LONG_MAX__
+# define LLONG_MAX __LONG_LONG_MAX__
+#endif
+
+#ifndef INTMAX_MAX
+# ifdef LLONG_MAX
+typedef long long intmax_t;
+# define strtoimax strtoll
+# define INTMAX_MAX LLONG_MAX
+# else
+typedef long intmax_t;
+# define strtoimax strtol
+# define INTMAX_MAX LONG_MAX
+# endif
+#endif
+
+#ifndef PRIdMAX
+# if INTMAX_MAX == LLONG_MAX
+# define PRIdMAX "lld"
+# else
+# define PRIdMAX "ld"
+# endif
+#endif
+
+/* Infer TM_ZONE on systems where this information is known, but suppress
+ guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
+#if (defined __GLIBC__ \
+ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
+ || (defined __APPLE__ && defined __MACH__))
+# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
+# define TM_GMTOFF tm_gmtoff
+# endif
+# if !defined TM_ZONE && !defined NO_TM_ZONE
+# define TM_ZONE tm_zone
+# endif
+#endif
+
+#ifndef HAVE_LOCALTIME_R
+# define HAVE_LOCALTIME_R 1
+#endif
+
+#ifndef HAVE_LOCALTIME_RZ
+# ifdef TM_ZONE
+# define HAVE_LOCALTIME_RZ (NETBSD_INSPIRED && USE_LTZ)
+# else
+# define HAVE_LOCALTIME_RZ 0
+# endif
+#endif
+
+#ifndef HAVE_TZSET
+# define HAVE_TZSET 1
+#endif
+
#ifndef ZDUMP_LO_YEAR
#define ZDUMP_LO_YEAR (-500)
#endif /* !defined ZDUMP_LO_YEAR */
@@ -35,14 +131,14 @@
#define MAX_STRING_LENGTH 1024
#endif /* !defined MAX_STRING_LENGTH */
-#ifndef TRUE
-#define TRUE 1
-#endif /* !defined TRUE */
+#if __STDC_VERSION__ < 199901
+# define true 1
+# define false 0
+# define bool int
+#else
+# include <stdbool.h>
+#endif
-#ifndef FALSE
-#define FALSE 0
-#endif /* !defined FALSE */
-
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif /* !defined EXIT_SUCCESS */
@@ -90,10 +186,21 @@
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
#endif /* !defined isleap_sum */
-#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
+#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR)
#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY)
+#define SECSPER400YEARS (SECSPERNYEAR * (intmax_t) (300 + 3) \
+ + SECSPERLYEAR * (intmax_t) (100 - 3))
+/*
+** True if SECSPER400YEARS is known to be representable as an
+** intmax_t. It's OK that SECSPER400YEARS_FITS can in theory be false
+** even if SECSPER400YEARS is representable, because when that happens
+** the code merely runs a bit more slowly, and this slowness doesn't
+** occur on any practical platform.
+*/
+enum { SECSPER400YEARS_FITS = SECSPERLYEAR <= INTMAX_MAX / 400 };
+
#ifndef HAVE_GETTEXT
#define HAVE_GETTEXT 0
#endif
@@ -102,24 +209,6 @@
#include "libintl.h"
#endif /* HAVE_GETTEXT */
-#ifndef GNUC_or_lint
-#ifdef lint
-#define GNUC_or_lint
-#else /* !defined lint */
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined lint */
-#endif /* !defined GNUC_or_lint */
-
-#ifndef INITIALIZE
-#ifdef GNUC_or_lint
-#define INITIALIZE(x) ((x) = 0)
-#else /* !defined GNUC_or_lint */
-#define INITIALIZE(x)
-#endif /* !defined GNUC_or_lint */
-#endif /* !defined INITIALIZE */
-
#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
#else
@@ -128,7 +217,7 @@
/*
** For the benefit of GNU folk...
-** `_(MSGID)' uses the current locale's message library string for MSGID.
+** '_(MSGID)' uses the current locale's message library string for MSGID.
** The default is to use gettext if available, and use MSGID otherwise.
*/
@@ -140,90 +229,252 @@
#endif /* !HAVE_GETTEXT */
#endif /* !defined _ */
-#ifndef TZ_DOMAIN
-#define TZ_DOMAIN "tz"
-#endif /* !defined TZ_DOMAIN */
+#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
+# define TZ_DOMAIN "tz"
+#endif
+#if ! HAVE_LOCALTIME_RZ
+# undef timezone_t
+# define timezone_t char **
+#endif
+
+#if !HAVE_POSIX_DECLS
extern char ** environ;
extern int getopt(int argc, char * const argv[],
const char * options);
extern char * optarg;
extern int optind;
-extern char * tzname[2];
+extern char * tzname[];
+#endif
-/* The minimum and maximum finite time values. Shift 'long long' or
- 'long' instead of 'time_t'; this avoids compile-time errors when
- time_t is floating-point. In practice, 'long long' is wide enough. */
+/* The minimum and maximum finite time values. */
+enum { atime_shift = CHAR_BIT * sizeof (time_t) - 2 };
static time_t const absolute_min_time =
- ((time_t) 0.5 == 0.5
- ? (sizeof (time_t) == sizeof (float) ? (time_t) -FLT_MAX
- : sizeof (time_t) == sizeof (double) ? (time_t) -DBL_MAX
- : sizeof (time_t) == sizeof (long double) ? (time_t) -LDBL_MAX
- : 0)
- : (time_t) -1 < 0
-#ifdef LLONG_MAX
- ? (time_t) ((long long) -1 << (CHAR_BIT * sizeof (time_t) - 1))
-#else
- ? (time_t) ((long) -1 << (CHAR_BIT * sizeof (time_t) - 1))
-#endif
+ ((time_t) -1 < 0
+ ? (- ((time_t) ~ (time_t) 0 < 0)
+ - (((time_t) 1 << atime_shift) - 1 + ((time_t) 1 << atime_shift)))
: 0);
static time_t const absolute_max_time =
- ((time_t) 0.5 == 0.5
- ? (sizeof (time_t) == sizeof (float) ? (time_t) FLT_MAX
- : sizeof (time_t) == sizeof (double) ? (time_t) DBL_MAX
- : sizeof (time_t) == sizeof (long double) ? (time_t) LDBL_MAX
- : -1)
- : (time_t) -1 < 0
-#ifdef LLONG_MAX
- ? (time_t) (- (~ 0 < 0) - ((long long) -1 << (CHAR_BIT * sizeof (time_t) - 1)))
+ ((time_t) -1 < 0
+ ? (((time_t) 1 << atime_shift) - 1 + ((time_t) 1 << atime_shift))
+ : -1);
+static int longest;
+static char * progname;
+static bool warned;
+static bool errout;
+
+static char const *abbr(struct tm const *);
+static intmax_t delta(struct tm *, struct tm *) ATTRIBUTE_PURE;
+static void dumptime(struct tm const *);
+static time_t hunt(timezone_t, char *, time_t, time_t);
+static void show(timezone_t, char *, time_t, bool);
+static const char *tformat(void);
+static time_t yeartot(intmax_t) ATTRIBUTE_PURE;
+
+/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
+#define is_digit(c) ((unsigned)(c) - '0' <= 9)
+
+/* Is A an alphabetic character in the C locale? */
+static bool
+is_alpha(char a)
+{
+ switch (a) {
+ default:
+ return false;
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+ case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+ case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+ case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z':
+ return true;
+ }
+}
+
+/* Return A + B, exiting if the result would overflow. */
+static size_t
+sumsize(size_t a, size_t b)
+{
+ size_t sum = a + b;
+ if (sum < a) {
+ fprintf(stderr, "%s: size overflow\n", progname);
+ exit(EXIT_FAILURE);
+ }
+ return sum;
+}
+
+#if ! HAVE_TZSET
+# undef tzset
+# define tzset zdump_tzset
+static void tzset(void) { }
+#endif
+
+/* Assume gmtime_r works if localtime_r does.
+ A replacement localtime_r is defined below if needed. */
+#if ! HAVE_LOCALTIME_R
+
+# undef gmtime_r
+# define gmtime_r zdump_gmtime_r
+
+static struct tm *
+gmtime_r(time_t *tp, struct tm *tmp)
+{
+ struct tm *r = gmtime(tp);
+ if (r) {
+ *tmp = *r;
+ r = tmp;
+ }
+ return r;
+}
+
+#endif
+
+/* Platforms with TM_ZONE don't need tzname, so they can use the
+ faster localtime_rz or localtime_r if available. */
+
+#if defined TM_ZONE && HAVE_LOCALTIME_RZ
+# define USE_LOCALTIME_RZ true
#else
- ? (time_t) (- (~ 0 < 0) - ((long) -1 << (CHAR_BIT * sizeof (time_t) - 1)))
+# define USE_LOCALTIME_RZ false
#endif
- : (time_t) -1);
-static size_t longest;
-static char * progname;
-static int warned;
-static char * abbr(struct tm * tmp);
-static void abbrok(const char * abbrp, const char * zone);
-static long delta(struct tm * newp, struct tm * oldp) ATTRIBUTE_PURE;
-static void dumptime(const struct tm * tmp);
-static time_t hunt(char * name, time_t lot, time_t hit);
-static void checkabsolutes(void);
-static void show(char * zone, time_t t, int v);
-static const char * tformat(void);
-static time_t yeartot(long y) ATTRIBUTE_PURE;
+#if ! USE_LOCALTIME_RZ
+# if !defined TM_ZONE || ! HAVE_LOCALTIME_R || ! HAVE_TZSET
+# undef localtime_r
+# define localtime_r zdump_localtime_r
+static struct tm *
+localtime_r(time_t *tp, struct tm *tmp)
+{
+ struct tm *r = localtime(tp);
+ if (r) {
+ *tmp = *r;
+ r = tmp;
+ }
+ return r;
+}
+# endif
+
+# undef localtime_rz
+# define localtime_rz zdump_localtime_rz
+static struct tm *
+localtime_rz(timezone_t rz, time_t *tp, struct tm *tmp)
+{
+ return localtime_r(tp, tmp);
+}
+
+# ifdef TYPECHECK
+# undef mktime_z
+# define mktime_z zdump_mktime_z
+static time_t
+mktime_z(timezone_t tz, struct tm *tmp)
+{
+ return mktime(tmp);
+}
+# endif
+
+# undef tzalloc
+# undef tzfree
+# define tzalloc zdump_tzalloc
+# define tzfree zdump_tzfree
+
+static timezone_t
+tzalloc(char const *val)
+{
+ static char **fakeenv;
+ char **env = fakeenv;
+ char *env0;
+ if (! env) {
+ char **e = environ;
+ int to;
+
+ while (*e++)
+ continue;
+ env = malloc(sumsize(sizeof *environ,
+ (e - environ) * sizeof *environ));
+ if (! env) {
+ perror(progname);
+ exit(EXIT_FAILURE);
+ }
+ to = 1;
+ for (e = environ; (env[to] = *e); e++)
+ to += strncmp(*e, "TZ=", 3) != 0;
+ }
+ env0 = malloc(sumsize(sizeof "TZ=", strlen(val)));
+ if (! env0) {
+ perror(progname);
+ exit(EXIT_FAILURE);
+ }
+ env[0] = strcat(strcpy(env0, "TZ="), val);
+ environ = fakeenv = env;
+ tzset();
+ return env;
+}
+
+static void
+tzfree(timezone_t env)
+{
+ environ = env + 1;
+ free(env[0]);
+}
+#endif /* ! USE_LOCALTIME_RZ */
+
+/* A UTC time zone, and its initializer. */
+static timezone_t gmtz;
+static void
+gmtzinit(void)
+{
+ if (USE_LOCALTIME_RZ) {
+ static char const utc[] = "UTC0";
+ gmtz = tzalloc(utc);
+ if (!gmtz) {
+ perror(utc);
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
+/* Convert *TP to UTC, storing the broken-down time into *TMP.
+ Return TMP if successful, NULL otherwise. This is like gmtime_r(TP, TMP),
+ except typically faster if USE_LOCALTIME_RZ. */
+static struct tm *
+my_gmtime_r(time_t *tp, struct tm *tmp)
+{
+ return USE_LOCALTIME_RZ ? localtime_rz(gmtz, tp, tmp) : gmtime_r(tp, tmp);
+}
+
#ifndef TYPECHECK
-#define my_localtime localtime
+# define my_localtime_rz localtime_rz
#else /* !defined TYPECHECK */
+
static struct tm *
-my_localtime(time_t *tp)
+my_localtime_rz(timezone_t tz, time_t *tp, struct tm *tmp)
{
- register struct tm * tmp;
-
- tmp = localtime(tp);
- if (tp != NULL && tmp != NULL) {
+ tmp = localtime_rz(tz, tp, tmp);
+ if (tmp) {
struct tm tm;
register time_t t;
tm = *tmp;
- t = mktime(&tm);
- if (t - *tp >= 1 || *tp - t >= 1) {
- (void) fflush(stdout);
- (void) fprintf(stderr, "\n%s: ", progname);
- (void) fprintf(stderr, tformat(), *tp);
- (void) fprintf(stderr, " ->");
- (void) fprintf(stderr, " year=%d", tmp->tm_year);
- (void) fprintf(stderr, " mon=%d", tmp->tm_mon);
- (void) fprintf(stderr, " mday=%d", tmp->tm_mday);
- (void) fprintf(stderr, " hour=%d", tmp->tm_hour);
- (void) fprintf(stderr, " min=%d", tmp->tm_min);
- (void) fprintf(stderr, " sec=%d", tmp->tm_sec);
- (void) fprintf(stderr, " isdst=%d", tmp->tm_isdst);
- (void) fprintf(stderr, " -> ");
- (void) fprintf(stderr, tformat(), t);
- (void) fprintf(stderr, "\n");
+ t = mktime_z(tz, &tm);
+ if (t != *tp) {
+ fflush(stdout);
+ fprintf(stderr, "\n%s: ", progname);
+ fprintf(stderr, tformat(), *tp);
+ fprintf(stderr, " ->");
+ fprintf(stderr, " year=%d", tmp->tm_year);
+ fprintf(stderr, " mon=%d", tmp->tm_mon);
+ fprintf(stderr, " mday=%d", tmp->tm_mday);
+ fprintf(stderr, " hour=%d", tmp->tm_hour);
+ fprintf(stderr, " min=%d", tmp->tm_min);
+ fprintf(stderr, " sec=%d", tmp->tm_sec);
+ fprintf(stderr, " isdst=%d", tmp->tm_isdst);
+ fprintf(stderr, " -> ");
+ fprintf(stderr, tformat(), t);
+ fprintf(stderr, "\n");
+ errout = true;
}
}
return tmp;
@@ -239,41 +490,74 @@
if (warned)
return;
cp = abbrp;
- wp = NULL;
- while (isascii((unsigned char) *cp) && isalpha((unsigned char) *cp))
+ while (is_alpha(*cp) || is_digit(*cp) || *cp == '-' || *cp == '+')
++cp;
- if (cp - abbrp == 0)
- wp = _("lacks alphabetic at start");
- else if (cp - abbrp < 3)
- wp = _("has fewer than 3 alphabetics");
+ if (cp - abbrp < 3)
+ wp = _("has fewer than 3 characters");
else if (cp - abbrp > 6)
- wp = _("has more than 6 alphabetics");
- if (wp == NULL && (*cp == '+' || *cp == '-')) {
- ++cp;
- if (isascii((unsigned char) *cp) &&
- isdigit((unsigned char) *cp))
- if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
- ++cp;
- if (*cp != '\0')
- wp = _("differs from POSIX standard");
- }
- if (wp == NULL)
- return;
- (void) fflush(stdout);
- (void) fprintf(stderr,
+ wp = _("has more than 6 characters");
+ else if (*cp)
+ wp = _("has characters other than ASCII alphanumerics, '-' or '+'");
+ else
+ return;
+ fflush(stdout);
+ fprintf(stderr,
_("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"),
progname, zone, abbrp, wp);
- warned = TRUE;
+ warned = errout = true;
}
+/* Return a time zone abbreviation. If the abbreviation needs to be
+ saved, use *BUF (of size *BUFALLOC) to save it, and return the
+ abbreviation in the possibly-reallocated *BUF. Otherwise, just
+ return the abbreviation. Get the abbreviation from TMP.
+ Exit on memory allocation failure. */
+static char const *
+saveabbr(char **buf, size_t *bufalloc, struct tm const *tmp)
+{
+ char const *ab = abbr(tmp);
+ if (HAVE_LOCALTIME_RZ)
+ return ab;
+ else {
+ size_t ablen = strlen(ab);
+ if (*bufalloc <= ablen) {
+ free(*buf);
+
+ /* Make the new buffer at least twice as long as the old,
+ to avoid O(N**2) behavior on repeated calls. */
+ *bufalloc = sumsize(*bufalloc, ablen + 1);
+
+ *buf = malloc(*bufalloc);
+ if (! *buf) {
+ perror(progname);
+ exit(EXIT_FAILURE);
+ }
+ }
+ return strcpy(*buf, ab);
+ }
+}
+
static void
+close_file(FILE *stream)
+{
+ char const *e = (ferror(stream) ? _("I/O error")
+ : fclose(stream) != 0 ? strerror(errno) : NULL);
+ if (e) {
+ fprintf(stderr, "%s: %s\n", progname, e);
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void
usage(FILE * const stream, const int status)
{
- (void) fprintf(stream,
-_("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n\
-\n\
-Report bugs to tz at iana.org.\n"),
- progname, progname);
+ fprintf(stream,
+_("%s: usage: %s [--version] [--help] [-{vV}] [-{ct} [lo,]hi] zonename ...\n"
+ "\n"
+ "Report bugs to %s.\n"),
+ progname, progname, REPORT_BUGS_TO);
+ if (status == EXIT_SUCCESS)
+ close_file(stream);
exit(status);
}
@@ -280,217 +564,243 @@
int
main(int argc, char *argv[])
{
+ /* These are static so that they're initially zero. */
+ static char * abbrev;
+ static size_t abbrevsize;
+ static struct tm newtm;
+
register int i;
- register int c;
- register int vflag;
+ register bool vflag;
+ register bool Vflag;
register char * cutarg;
- register long cutloyear = ZDUMP_LO_YEAR;
- register long cuthiyear = ZDUMP_HI_YEAR;
+ register char * cuttimes;
register time_t cutlotime;
register time_t cuthitime;
- register char ** fakeenv;
time_t now;
time_t t;
time_t newt;
struct tm tm;
- struct tm newtm;
register struct tm * tmp;
register struct tm * newtmp;
- INITIALIZE(cutlotime);
- INITIALIZE(cuthitime);
+ cutlotime = absolute_min_time;
+ cuthitime = absolute_max_time;
#if HAVE_GETTEXT
- (void) setlocale(LC_ALL, "");
+ setlocale(LC_ALL, "");
#ifdef TZ_DOMAINDIR
- (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
+ bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined TEXTDOMAINDIR */
- (void) textdomain(TZ_DOMAIN);
+ textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT */
progname = argv[0];
for (i = 1; i < argc; ++i)
if (strcmp(argv[i], "--version") == 0) {
- (void) printf("zdump %s%s\n", PKGVERSION, TZVERSION);
- exit(EXIT_SUCCESS);
+ printf("zdump %s%s\n", PKGVERSION, TZVERSION);
+ return EXIT_SUCCESS;
} else if (strcmp(argv[i], "--help") == 0) {
usage(stdout, EXIT_SUCCESS);
}
- vflag = 0;
- cutarg = NULL;
- while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
- if (c == 'v')
- vflag = 1;
- else cutarg = optarg;
- if ((c != EOF && c != -1) ||
- (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
- usage(stderr, EXIT_FAILURE);
- }
- if (vflag) {
+ vflag = Vflag = false;
+ cutarg = cuttimes = NULL;
+ for (;;)
+ switch (getopt(argc, argv, "c:t:vV")) {
+ case 'c': cutarg = optarg; break;
+ case 't': cuttimes = optarg; break;
+ case 'v': vflag = true; break;
+ case 'V': Vflag = true; break;
+ case -1:
+ if (! (optind == argc - 1 && strcmp(argv[optind], "=") == 0))
+ goto arg_processing_done;
+ /* Fall through. */
+ default:
+ usage(stderr, EXIT_FAILURE);
+ }
+ arg_processing_done:;
+
+ if (vflag | Vflag) {
+ intmax_t lo;
+ intmax_t hi;
+ char *loend, *hiend;
+ register intmax_t cutloyear = ZDUMP_LO_YEAR;
+ register intmax_t cuthiyear = ZDUMP_HI_YEAR;
if (cutarg != NULL) {
- long lo;
- long hi;
- char dummy;
-
- if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) {
+ lo = strtoimax(cutarg, &loend, 10);
+ if (cutarg != loend && !*loend) {
+ hi = lo;
cuthiyear = hi;
- } else if (sscanf(cutarg, "%ld,%ld%c",
- &lo, &hi, &dummy) == 2) {
- cutloyear = lo;
- cuthiyear = hi;
+ } else if (cutarg != loend && *loend == ','
+ && (hi = strtoimax(loend + 1, &hiend, 10),
+ loend + 1 != hiend && !*hiend)) {
+ cutloyear = lo;
+ cuthiyear = hi;
} else {
-(void) fprintf(stderr, _("%s: wild -c argument %s\n"),
+ fprintf(stderr, _("%s: wild -c argument %s\n"),
progname, cutarg);
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
}
- checkabsolutes();
- cutlotime = yeartot(cutloyear);
- cuthitime = yeartot(cuthiyear);
+ if (cutarg != NULL || cuttimes == NULL) {
+ cutlotime = yeartot(cutloyear);
+ cuthitime = yeartot(cuthiyear);
+ }
+ if (cuttimes != NULL) {
+ lo = strtoimax(cuttimes, &loend, 10);
+ if (cuttimes != loend && !*loend) {
+ hi = lo;
+ if (hi < cuthitime) {
+ if (hi < absolute_min_time)
+ hi = absolute_min_time;
+ cuthitime = hi;
+ }
+ } else if (cuttimes != loend && *loend == ','
+ && (hi = strtoimax(loend + 1, &hiend, 10),
+ loend + 1 != hiend && !*hiend)) {
+ if (cutlotime < lo) {
+ if (absolute_max_time < lo)
+ lo = absolute_max_time;
+ cutlotime = lo;
+ }
+ if (hi < cuthitime) {
+ if (hi < absolute_min_time)
+ hi = absolute_min_time;
+ cuthitime = hi;
+ }
+ } else {
+ fprintf(stderr,
+ _("%s: wild -t argument %s\n"),
+ progname, cuttimes);
+ return EXIT_FAILURE;
+ }
+ }
}
- (void) time(&now);
+ gmtzinit();
+ now = time(NULL);
longest = 0;
- for (i = optind; i < argc; ++i)
- if (strlen(argv[i]) > longest)
- longest = strlen(argv[i]);
- {
- register int from;
- register int to;
+ for (i = optind; i < argc; i++) {
+ size_t arglen = strlen(argv[i]);
+ if (longest < arglen)
+ longest = arglen < INT_MAX ? arglen : INT_MAX;
+ }
- for (i = 0; environ[i] != NULL; ++i)
- continue;
- fakeenv = malloc((i + 2) * sizeof *fakeenv);
- if (fakeenv == NULL
- || (fakeenv[0] = malloc(longest + 4)) == NULL) {
- (void) perror(progname);
- exit(EXIT_FAILURE);
+ for (i = optind; i < argc; ++i) {
+ timezone_t tz = tzalloc(argv[i]);
+ char const *ab;
+ if (!tz) {
+ perror(argv[i]);
+ return 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]);
- if (!vflag) {
- show(argv[i], now, FALSE);
+ if (! (vflag | Vflag)) {
+ show(tz, argv[i], now, false);
+ tzfree(tz);
continue;
}
- warned = FALSE;
+ warned = false;
t = absolute_min_time;
- show(argv[i], t, TRUE);
- t += SECSPERHOUR * HOURSPERDAY;
- show(argv[i], t, TRUE);
+ if (!Vflag) {
+ show(tz, argv[i], t, true);
+ t += SECSPERDAY;
+ show(tz, argv[i], t, true);
+ }
if (t < cutlotime)
t = cutlotime;
- tmp = my_localtime(&t);
- if (tmp != NULL) {
- tm = *tmp;
- (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
- }
- for ( ; ; ) {
- if (t >= cuthitime || t >= cuthitime - SECSPERHOUR * 12)
- break;
- newt = t + SECSPERHOUR * 12;
- newtmp = localtime(&newt);
- if (newtmp != NULL)
- newtm = *newtmp;
+ tmp = my_localtime_rz(tz, &t, &tm);
+ if (tmp)
+ ab = saveabbr(&abbrev, &abbrevsize, &tm);
+ while (t < cuthitime) {
+ newt = ((t < absolute_max_time - SECSPERDAY / 2
+ && t + SECSPERDAY / 2 < cuthitime)
+ ? t + SECSPERDAY / 2
+ : cuthitime);
+ newtmp = localtime_rz(tz, &newt, &newtm);
if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
(delta(&newtm, &tm) != (newt - t) ||
newtm.tm_isdst != tm.tm_isdst ||
- strcmp(abbr(&newtm), buf) != 0)) {
- newt = hunt(argv[i], t, newt);
- newtmp = localtime(&newt);
- if (newtmp != NULL) {
- newtm = *newtmp;
- (void) strncpy(buf,
- abbr(&newtm),
- (sizeof buf) - 1);
- }
+ strcmp(abbr(&newtm), ab) != 0)) {
+ newt = hunt(tz, argv[i], t, newt);
+ newtmp = localtime_rz(tz, &newt, &newtm);
+ if (newtmp)
+ ab = saveabbr(&abbrev, &abbrevsize,
+ &newtm);
}
t = newt;
tm = newtm;
tmp = newtmp;
}
- t = absolute_max_time;
- t -= SECSPERHOUR * HOURSPERDAY;
- show(argv[i], t, TRUE);
- t += SECSPERHOUR * HOURSPERDAY;
- show(argv[i], t, TRUE);
+ if (!Vflag) {
+ t = absolute_max_time;
+ t -= SECSPERDAY;
+ show(tz, argv[i], t, true);
+ t += SECSPERDAY;
+ show(tz, argv[i], t, true);
+ }
+ tzfree(tz);
}
- if (fflush(stdout) || ferror(stdout)) {
- (void) fprintf(stderr, "%s: ", progname);
- (void) perror(_("Error writing to standard output"));
- exit(EXIT_FAILURE);
- }
- exit(EXIT_SUCCESS);
- /* If exit fails to exit... */
- return EXIT_FAILURE;
+ close_file(stdout);
+ if (errout && (ferror(stderr) || fclose(stderr) != 0))
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
}
-static void
-checkabsolutes(void)
-{
- if (absolute_max_time < absolute_min_time) {
- (void) fprintf(stderr,
-_("%s: use of -v on system with floating time_t other than float or double\n"),
- progname);
- exit(EXIT_FAILURE);
- }
-}
-
static time_t
-yeartot(const long y)
+yeartot(intmax_t y)
{
- register long myy;
- register long seconds;
- register time_t t;
+ register intmax_t myy, seconds, years;
+ register time_t t;
myy = EPOCH_YEAR;
t = 0;
- while (myy != y) {
- if (myy < y) {
+ while (myy < y) {
+ if (SECSPER400YEARS_FITS && 400 <= y - myy) {
+ intmax_t diff400 = (y - myy) / 400;
+ if (INTMAX_MAX / SECSPER400YEARS < diff400)
+ return absolute_max_time;
+ seconds = diff400 * SECSPER400YEARS;
+ years = diff400 * 400;
+ } else {
seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
- ++myy;
- if (t > absolute_max_time - seconds) {
- t = absolute_max_time;
- break;
- }
- t += seconds;
+ years = 1;
+ }
+ myy += years;
+ if (t > absolute_max_time - seconds)
+ return absolute_max_time;
+ t += seconds;
+ }
+ while (y < myy) {
+ if (SECSPER400YEARS_FITS && y + 400 <= myy && myy < 0) {
+ intmax_t diff400 = (myy - y) / 400;
+ if (INTMAX_MAX / SECSPER400YEARS < diff400)
+ return absolute_min_time;
+ seconds = diff400 * SECSPER400YEARS;
+ years = diff400 * 400;
} else {
- --myy;
- seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
- if (t < absolute_min_time + seconds) {
- t = absolute_min_time;
- break;
- }
- t -= seconds;
+ seconds = isleap(myy - 1) ? SECSPERLYEAR : SECSPERNYEAR;
+ years = 1;
}
+ myy -= years;
+ if (t < absolute_min_time + seconds)
+ return absolute_min_time;
+ t -= seconds;
}
return t;
}
static time_t
-hunt(char *name, time_t lot, time_t hit)
+hunt(timezone_t tz, char *name, time_t lot, time_t hit)
{
+ static char * loab;
+ static size_t loabsize;
+ char const * ab;
time_t t;
- long diff;
struct tm lotm;
register struct tm * lotmp;
struct tm tm;
register struct tm * tmp;
- char loab[MAX_STRING_LENGTH];
- lotmp = my_localtime(&lot);
- if (lotmp != NULL) {
- lotm = *lotmp;
- (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
- }
+ lotmp = my_localtime_rz(tz, &lot, &lotm);
+ if (lotmp)
+ ab = saveabbr(&loab, &loabsize, &lotm);
for ( ; ; ) {
- diff = (long) (hit - lot);
+ time_t diff = hit - lot;
if (diff < 2)
break;
t = lot;
@@ -499,20 +809,18 @@
++t;
else if (t >= hit)
--t;
- tmp = my_localtime(&t);
- if (tmp != NULL)
- tm = *tmp;
+ tmp = my_localtime_rz(tz, &t, &tm);
if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) :
(delta(&tm, &lotm) == (t - lot) &&
tm.tm_isdst == lotm.tm_isdst &&
- strcmp(abbr(&tm), loab) == 0)) {
+ strcmp(abbr(&tm), ab) == 0)) {
lot = t;
lotm = tm;
lotmp = tmp;
} else hit = t;
}
- show(name, lot, TRUE);
- show(name, hit, TRUE);
+ show(tz, name, lot, true);
+ show(tz, name, hit, true);
return hit;
}
@@ -520,11 +828,11 @@
** Thanks to Paul Eggert for logic used in delta.
*/
-static long
+static intmax_t
delta(struct tm * newp, struct tm *oldp)
{
- register long result;
- register int tmy;
+ register intmax_t result;
+ register int tmy;
if (newp->tm_year < oldp->tm_year)
return -delta(oldp, newp);
@@ -541,49 +849,87 @@
return result;
}
+#ifndef TM_GMTOFF
+/* Return A->tm_yday, adjusted to compare it fairly to B->tm_yday.
+ Assume A and B differ by at most one year. */
+static int
+adjusted_yday(struct tm const *a, struct tm const *b)
+{
+ int yday = a->tm_yday;
+ if (b->tm_year < a->tm_year)
+ yday += 365 + isleap_sum(b->tm_year, TM_YEAR_BASE);
+ return yday;
+}
+#endif
+
+/* If A is the broken-down local time and B the broken-down UTC for
+ the same instant, return A's UTC offset in seconds, where positive
+ offsets are east of Greenwich. On failure, return LONG_MIN. */
+static long
+gmtoff(struct tm const *a, struct tm const *b)
+{
+#ifdef TM_GMTOFF
+ return a->TM_GMTOFF;
+#else
+ if (! b)
+ return LONG_MIN;
+ else {
+ int ayday = adjusted_yday(a, b);
+ int byday = adjusted_yday(b, a);
+ int days = ayday - byday;
+ long hours = a->tm_hour - b->tm_hour + 24 * days;
+ long minutes = a->tm_min - b->tm_min + 60 * hours;
+ long seconds = a->tm_sec - b->tm_sec + 60 * minutes;
+ return seconds;
+ }
+#endif
+}
+
static void
-show(char *zone, time_t t, int v)
+show(timezone_t tz, char *zone, time_t t, bool v)
{
register struct tm * tmp;
+ register struct tm * gmtmp;
+ struct tm tm, gmtm;
- (void) printf("%-*s ", (int) longest, zone);
+ printf("%-*s ", longest, zone);
if (v) {
- tmp = gmtime(&t);
- if (tmp == NULL) {
- (void) printf(tformat(), t);
+ gmtmp = my_gmtime_r(&t, &gmtm);
+ if (gmtmp == NULL) {
+ printf(tformat(), t);
} else {
- dumptime(tmp);
- (void) printf(" UTC");
+ dumptime(gmtmp);
+ printf(" UT");
}
- (void) printf(" = ");
+ printf(" = ");
}
- tmp = my_localtime(&t);
+ tmp = my_localtime_rz(tz, &t, &tm);
dumptime(tmp);
if (tmp != NULL) {
if (*abbr(tmp) != '\0')
- (void) printf(" %s", abbr(tmp));
+ 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 */
+ long off = gmtoff(tmp, gmtmp);
+ printf(" isdst=%d", tmp->tm_isdst);
+ if (off != LONG_MIN)
+ printf(" gmtoff=%ld", off);
}
}
- (void) printf("\n");
+ printf("\n");
if (tmp != NULL && *abbr(tmp) != '\0')
abbrok(abbr(tmp), zone);
}
-static char *
-abbr(struct tm *tmp)
+static char const *
+abbr(struct tm const *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;
+#ifdef TM_ZONE
+ return tmp->TM_ZONE;
+#else
+ return (0 <= tmp->tm_isdst && tzname[0 < tmp->tm_isdst]
+ ? tzname[0 < tmp->tm_isdst]
+ : "");
+#endif
}
/*
@@ -594,12 +940,9 @@
static const char *
tformat(void)
{
- if (0.5 == (time_t) 0.5) { /* floating */
- if (sizeof (time_t) > sizeof (double))
- return "%Lg";
- return "%g";
- }
if (0 > (time_t) -1) { /* signed */
+ if (sizeof (time_t) == sizeof (intmax_t))
+ return "%"PRIdMAX;
if (sizeof (time_t) > sizeof (long))
return "%lld";
if (sizeof (time_t) > sizeof (int))
@@ -606,6 +949,10 @@
return "%ld";
return "%d";
}
+#ifdef PRIuMAX
+ if (sizeof (time_t) == sizeof (uintmax_t))
+ return "%"PRIuMAX;
+#endif
if (sizeof (time_t) > sizeof (unsigned long))
return "%llu";
if (sizeof (time_t) > sizeof (unsigned int))
@@ -629,11 +976,11 @@
register int trail;
if (timeptr == NULL) {
- (void) printf("NULL");
+ printf("NULL");
return;
}
/*
- ** The packaged versions of localtime and gmtime never put out-of-range
+ ** The packaged localtime_rz and gmtime_r never put out-of-range
** values in tm_wday or tm_mon, but since this code might be compiled
** with other (perhaps experimental) versions, paranoia is in order.
*/
@@ -645,7 +992,7 @@
(int) (sizeof mon_name / sizeof mon_name[0]))
mn = "???";
else mn = mon_name[timeptr->tm_mon];
- (void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d ",
+ printf("%.3s %.3s%3d %.2d:%.2d:%.2d ",
wn, mn,
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec);
@@ -662,6 +1009,6 @@
++lead;
}
if (lead == 0)
- (void) printf("%d", trail);
- else (void) printf("%d%d", lead, ((trail < 0) ? -trail : trail));
+ printf("%d", trail);
+ else printf("%d%d", lead, ((trail < 0) ? -trail : trail));
}
Modified: vendor/tzcode/dist/zic.8
===================================================================
--- vendor/tzcode/dist/zic.8 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/zic.8 2016-08-15 01:50:22 UTC (rev 7736)
@@ -4,38 +4,30 @@
.SH SYNOPSIS
.B zic
[
-.B \-\-version
-]
-[
-.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 option
+\&... ] [
.I filename
\&... ]
.SH DESCRIPTION
-.if t .ds lq ``
-.if t .ds rq ''
-.if n .ds lq \&"\"
-.if n .ds rq \&"\"
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
.de q
\\$3\*(lq\\$1\*(rq\\$2
..
+.ie '\(la'' .ds < <
+.el .ds < \(la
+.ie '\(ra'' .ds > >
+.el .ds > \(ra
+.ie \n(.g \{\
+. ds : \:
+. ds - \f(CW-\fP
+.\}
+.el \{\
+. ds :
+. ds - \-
+.\}
.I Zic
reads text from the file(s) named on the command line
and creates the time conversion information files specified in this input.
@@ -42,19 +34,19 @@
If a
.I filename
is
-.BR \- ,
+.q "\*-" ,
the standard input is read.
.PP
These options are available:
.TP
-.BI "\-\-version"
+.BI "\*-\*-version"
Output version information and exit.
.TP
-.BI "\-d " directory
+.BI "\*-d " directory
Create time conversion information files in the named directory rather than
in the standard directory named below.
.TP
-.BI "\-l " timezone
+.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
@@ -62,7 +54,7 @@
.ti +.5i
Link \fItimezone\fP localtime
.TP
-.BI "\-p " timezone
+.BI "\*-p " timezone
Use the given time zone's rules when handling POSIX-format
time zone environment variables.
.I Zic
@@ -71,35 +63,81 @@
.ti +.5i
Link \fItimezone\fP posixrules
.TP
-.BI "\-L " leapsecondfilename
+.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
+.B \*-v
+Be more verbose, and complain about the following situations:
+.RS
+.PP
+The input specifies a link to a link.
+.PP
+A year that appears in a data file is outside the range
of years representable by
.IR time (2)
values.
-Also complain if a time of 24:00
-(which cannot be handled by pre-1998 versions of
-.IR zic )
-appears in the input.
+.PP
+A time of 24:00 or more appears in the input.
+Pre-1998 versions of
+.I zic
+prohibit 24:00, and pre-2007 versions prohibit times greater than 24:00.
+.PP
+A rule goes past the start or end of the month.
+Pre-2004 versions of
+.I zic
+prohibit this.
+.PP
+The output file does not contain all the information about the
+long-term future of a zone, because the future cannot be summarized as
+an extended POSIX TZ string. For example, as of 2013 this problem
+occurs for Iran's daylight-saving rules for the predicted future, as
+these rules are based on the Iranian calendar, which cannot be
+represented.
+.PP
+The output contains data that may not be handled properly by client
+code designed for older
+.I zic
+output formats. These compatibility issues affect only time stamps
+before 1970 or after the start of 2038.
+.PP
+A time zone abbreviation has fewer than 3 characters.
+POSIX requires at least 3.
+.PP
+An output file name contains a byte that is not an ASCII letter,
+.q "\*-" ,
+.q "/" ,
+or
+.q "_" ;
+or it contains a file name component that contains more than 14 bytes
+or that starts with
+.q "\*-" .
+.RE
.TP
-.B \-s
+.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 files should be text files, that is, they should be a series of
+zero or more lines, each ending in a newline byte and containing at
+most 511 bytes, and without any NUL bytes. The input text's encoding
+is typically UTF-8 or ASCII; it should have a unibyte representation
+for the POSIX Portable Character Set (PPCS)
+\*<http://pubs\*:.opengroup\*:.org/\*:onlinepubs/\*:9699919799/\*:basedefs/\*:V1_chap06\*:.html\*>
+and the encoding's non-unibyte characters should consist entirely of
+non-PPCS bytes. Non-PPCS characters typically occur only in comments:
+although output file names and time zone abbreviations can contain
+nearly any character, other software will work better if these are
+limited to the restricted syntax described under the
+.B \*-v
+option.
+.PP
Input lines are made up of fields.
-Fields are separated from one another by any number of white space characters.
+Fields are separated from one another by one or more white space characters.
+The white space characters are space, form feed, carriage return, newline,
+tab, and vertical tab.
Leading and trailing white space on input lines is ignored.
An unquoted sharp character (#) in the input introduces a comment which extends
to the end of the line the sharp character appears on.
@@ -122,7 +160,7 @@
For example:
.ti +.5i
.sp
-Rule US 1967 1973 \- Apr lastSun 2:00 1:00 D
+Rule US 1967 1973 \*- Apr lastSun 2:00 1:00 D
.sp
.fi
The fields that make up a rule line are:
@@ -132,7 +170,7 @@
.TP
.B FROM
Gives the first year in which the rule applies.
-Any integer year can be supplied; the Gregorian calendar is assumed.
+Any integer year can be supplied; the proleptic Gregorian calendar is assumed.
The word
.B minimum
(or an abbreviation) means the minimum year representable as an integer.
@@ -158,27 +196,11 @@
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
+should be
+.q \*-
+and is present for compatibility with older versions of
.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.
+in which it could contain year types.
.TP
.B IN
Names the month in which the rule takes effect.
@@ -215,7 +237,7 @@
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
-\- equivalent to 0
+\*- equivalent to 0
.fi
.in -.5i
.sp
@@ -228,7 +250,7 @@
time,
.B s
if the given time is local
-.q standard
+.q "standard"
time, or
.B u
(or
@@ -238,6 +260,10 @@
if the given time is universal time;
in the absence of an indicator,
wall clock time is assumed.
+The intent is that a rule line describes the instants when a
+clock/calendar set to the type of time specified in the
+.B AT
+field would show the specified date and time of day.
.TP
.B SAVE
Gives the amount of time to be added to local standard time when the rule is in
@@ -250,21 +276,27 @@
and
.B s
suffixes are not used).
+Only the sum of standard time and this amount matters; for example,
+.I zic
+does not distinguish a 10:30 standard time plus an 0:30
+.B SAVE
+from a 10:00 standard time plus a 1:00
+.BR SAVE .
.TP
.B LETTER/S
Gives the
.q "variable part"
(for example, the
-.q S
+.q "S"
or
-.q D
+.q "D"
in
-.q EST
+.q "EST"
or
-.q EDT )
+.q "EDT" )
of time zone abbreviations to be used when this rule is in effect.
If this field is
-.BR \- ,
+.q \*- ,
the variable part is null.
.PP
A zone line has the form
@@ -277,7 +309,7 @@
For example:
.sp
.ti +.5i
-Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00
+Zone Australia/Adelaide 9:30 Aus AC%sT 1971 Oct 31 2:00
.sp
.fi
The fields that make up a zone line are:
@@ -286,22 +318,30 @@
The name of the time zone.
This is the name used in creating the time conversion information file for the
zone.
+It should not contain a file name component
+.q ".\&"
+or
+.q ".." ;
+a file name component is a maximal substring that does not contain
+.q "/" .
.TP
.B GMTOFF
-The amount of time to add to UTC to get standard time in this zone.
+The amount of time to add to UT 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 UTC.
+begin the field with a minus sign if time must be subtracted from UT.
.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 \-
+.B \*-
then standard time always applies in the time zone.
+When an amount of time is given, only the sum of standard time and
+this amount matters.
.TP
.B FORMAT
The format for time zone abbreviations in this time zone.
@@ -310,40 +350,61 @@
is used to show where the
.q "variable part"
of the time zone abbreviation goes.
+Alternately, a format can use the pair of characters
+.B %z
+to stand for the UTC offset in the form
+.RI \(+- hh ,
+.RI \(+- hhmm ,
+or
+.RI \(+- hhmmss ,
+using the shortest form that does not lose information, where
+.IR hh ,
+.IR mm ,
+and
+.I ss
+are the hours, minutes, and seconds east (+) or west (\(mi) of UTC.
Alternately,
a slash (/)
separates standard and daylight abbreviations.
+To conform to POSIX, a time zone abbreviation should contain only
+alphanumeric ASCII characters, "+" and "\*-".
.TP
.B UNTILYEAR [MONTH [DAY [TIME]]]
-The time at which the UTC offset or the rule(s) change for a location.
+The time at which the UT offset or the rule(s) change for a location.
It is specified as a year, a month, a day, and a time of day.
If this is specified,
-the time zone information is generated from the given UTC offset
-and rule change until the time specified.
+the time zone information is generated from the given UT offset
+and rule change until the time specified, which is interpreted using
+the rules in effect just before the transition.
The month, day, and time of day have the same format as the IN, ON, and AT
fields of a rule; trailing fields can be omitted, and default to the
earliest possible value for the missing fields.
.IP
The next line must be a
-.q continuation
+.q "continuation"
line; this has the same form as a zone line except that the
string
-.q Zone
+.q "Zone"
and the name are omitted, as the continuation line will
place information starting at the time specified as the
-.q until
+.q "until"
information in the previous line in the file used by the previous line.
Continuation lines may contain
-.q until
+.q "until"
information, just as zone lines do, indicating that the next line is a further
continuation.
.PP
+If a zone changes at the same instant that a rule would otherwise take
+effect in the earlier zone or continuation line, the rule is ignored.
+In a single zone it is an error if two rules take effect at the same
+instant, or if two zone changes take effect at the same instant.
+.PP
A link line has the form
.sp
.nf
.ti +.5i
.ta \w'Link\0\0'u +\w'Europe/Istanbul\0\0'u
-Link LINK-FROM LINK-TO
+Link TARGET LINK-NAME
.sp
For example:
.sp
@@ -352,16 +413,22 @@
.sp
.fi
The
-.B LINK-FROM
+.B TARGET
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.
+field in some zone line.
+The
+.B LINK-NAME
+field is used as an alternate name for that zone;
+it has the same syntax as a zone line's
+.B NAME
+field.
.PP
Except for continuation lines,
lines may appear in any order in the input.
+However, the behavior is unspecified if multiple zone or link lines
+define the same name, or if the source of one link line is the target
+of another.
.PP
Lines in the file that describes leap seconds have the following form:
.nf
@@ -387,10 +454,10 @@
.B CORR
field
should be
-.q +
+.q "+"
if a second was added
or
-.q -
+.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.
@@ -407,11 +474,11 @@
.B R/S
field
should be (an abbreviation of)
-.q Stationary
+.q "Stationary"
if the leap second time given by the other fields should be interpreted as UTC
or
(an abbreviation of)
-.q Rolling
+.q "Rolling"
if the leap second time given by the other fields should be interpreted as
local wall clock time.
.SH "EXTENDED EXAMPLE"
@@ -425,22 +492,20 @@
.ta \w'# Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u
.sp
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule Swiss 1940 only - Nov 2 0:00 1:00 S
-Rule Swiss 1940 only - Dec 31 0:00 0 -
-Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S
-Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0
+Rule Swiss 1941 1942 \*- May Mon>=1 1:00 1:00 S
+Rule Swiss 1941 1942 \*- Oct Mon>=1 2:00 0 \*-
.sp .5
-Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
-Rule EU 1977 only - Sep lastSun 1:00u 0 -
-Rule EU 1978 only - Oct 1 1:00u 0 -
-Rule EU 1979 1995 - Sep lastSun 1:00u 0 -
-Rule EU 1981 max - Mar lastSun 1:00u 1:00 S
-Rule EU 1996 max - Oct lastSun 1:00u 0 -
+Rule EU 1977 1980 \*- Apr Sun>=1 1:00u 1:00 S
+Rule EU 1977 only \*- Sep lastSun 1:00u 0 \*-
+Rule EU 1978 only \*- Oct 1 1:00u 0 \*-
+Rule EU 1979 1995 \*- Sep lastSun 1:00u 0 \*-
+Rule EU 1981 max \*- Mar lastSun 1:00u 1:00 S
+Rule EU 1996 max \*- Oct lastSun 1:00u 0 \*-
.sp
-.ta \w'# Zone\0\0'u +\w'Europe/Zurich\0\0'u +\w'0:34:08\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u
-# Zone NAME GMTOFF RULES FORMAT UNTIL
-Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12
- 0:29:44 - BMT 1894 Jun
+.ta \w'# Zone\0\0'u +\w'Europe/Zurich\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
+Zone Europe/Zurich 0:34:08 \*- LMT 1853 Jul 16
+ 0:29:46 \*- BMT 1894 Jun
1:00 Swiss CE%sT 1981
1:00 EU CE%sT
.sp
@@ -449,17 +514,17 @@
.in
.fi
In this example, the zone is named Europe/Zurich but it has an alias
-as Switzerland. Zurich was 34 minutes and 8 seconds west of GMT until
-1848-09-12 at 00:00, when the offset changed to 29 minutes and 44
-seconds. After 1894-06-01 at 00:00 Swiss daylight saving rules (defined
-with lines beginning with "Rule Swiss") apply, and the GMT offset
+as Switzerland. This example says that Zurich was 34 minutes and 8
+seconds west of UT until 1853-07-16 at 00:00, when the legal offset
+was changed to 7\(de\|26\(fm\|22.50\(sd; although this works out to
+0:29:45.50, the input format cannot represent fractional seconds so it
+is rounded here. After 1894-06-01 at 00:00 Swiss daylight saving rules
+(defined with lines beginning with "Rule Swiss") apply, and the UT offset
became one hour. From 1981 to the present, EU daylight saving rules have
applied, and the UTC offset has remained at one hour.
.PP
-In 1940, daylight saving time applied from November 2 at 00:00 to
-December 31 at 00:00. In 1941 and 1942, daylight saving time applied
-from the first Sunday in May at 02:00 to the first Sunday in October
-at 00:00.
+In 1941 and 1942, daylight saving time applied from the first Monday
+in May at 01:00 to the first Monday in October at 02:00.
The pre-1981 EU daylight-saving rules have no effect
here, but are included for completeness. Since 1981, daylight
saving has begun on the last Sunday in March at 01:00 UTC.
@@ -469,7 +534,7 @@
For purposes of
display, "LMT" and "BMT" were initially used, respectively. Since
Swiss rules and later EU rules were applied, the display name for the
-timezone has been CET for standard time and CEST for daylight saving
+time zone has been CET for standard time and CEST for daylight saving
time.
.SH NOTES
For areas with more than two types of local time,
@@ -482,13 +547,19 @@
for a particular zone,
a clock advance caused by the start of daylight saving
coincides with and is equal to
-a clock retreat caused by a change in UTC offset,
+a clock retreat caused by a change in UT offset,
.IR zic
-produces a single transition to daylight saving at the new UTC offset
+produces a single transition to daylight saving at the new UT offset
(without any change in wall clock time).
To get separate transitions
use multiple zone continuation lines
specifying transition instants using universal time.
+.PP
+Time stamps well before the Big Bang are silently omitted from the output.
+This works around bugs in software that mishandles large negative time
+stamps. Call it sour grapes, but pre-Big-Bang time stamps are
+physically suspect anyway. The pre-Big-Bang cutoff time is
+approximate and may change in future versions.
.SH FILE
/usr/local/etc/zoneinfo standard directory used for created files
.SH "SEE ALSO"
Modified: vendor/tzcode/dist/zic.8.txt
===================================================================
--- vendor/tzcode/dist/zic.8.txt 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/zic.8.txt 2016-08-15 01:50:22 UTC (rev 7736)
@@ -1,17 +1,15 @@
-ZIC(8) ZIC(8)
+ZIC(8) System Manager's Manual ZIC(8)
NAME
zic - time zone compiler
SYNOPSIS
- zic [ --version ] [ -v ] [ -d directory ] [ -l localtime ] [ -p
- posixrules ] [ -L leapsecondfilename ] [ -s ] [ -y command ] [ filename
- ... ]
+ zic [ option ... ] [ filename ... ]
DESCRIPTION
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
- filename is -, the standard input is read.
+ filename is "-", the standard input is read.
These options are available:
@@ -40,28 +38,66 @@
If this option is not used, no leap second information appears
in output files.
- -v Complain if a year that appears in a data file is outside the
- range of years representable by time(2) values. Also complain
- if a time of 24:00 (which cannot be handled by pre-1998 versions
- of zic) appears in the input.
+ -v Be more verbose, and complain about the following situations:
+ The input specifies a link to a link.
+
+ A year that appears in a data file is outside the range of years
+ representable by time(2) values.
+
+ A time of 24:00 or more appears in the input. Pre-1998 versions
+ of zic prohibit 24:00, and pre-2007 versions prohibit times
+ greater than 24:00.
+
+ A rule goes past the start or end of the month. Pre-2004
+ versions of zic prohibit this.
+
+ The output file does not contain all the information about the
+ long-term future of a zone, because the future cannot be
+ summarized as an extended POSIX TZ string. For example, as of
+ 2013 this problem occurs for Iran's daylight-saving rules for
+ the predicted future, as these rules are based on the Iranian
+ calendar, which cannot be represented.
+
+ The output contains data that may not be handled properly by
+ client code designed for older zic output formats. These
+ compatibility issues affect only time stamps before 1970 or
+ after the start of 2038.
+
+ A time zone abbreviation has fewer than 3 characters. POSIX
+ requires at least 3.
+
+ An output file name contains a byte that is not an ASCII letter,
+ "-", "/", or "_"; or it contains a file name component that
+ contains more than 14 bytes or that starts with "-".
+
-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.
- -y command
- Use the given command rather than yearistype when checking year
- types (see below).
+ Input files should be text files, that is, they should be a series of
+ zero or more lines, each ending in a newline byte and containing at
+ most 511 bytes, and without any NUL bytes. The input text's encoding
+ is typically UTF-8 or ASCII; it should have a unibyte representation
+ for the POSIX Portable Character Set (PPCS) <http://pubs.opengroup.org/
+ onlinepubs/9699919799/basedefs/V1_chap06.html> and the encoding's non-
+ unibyte characters should consist entirely of non-PPCS bytes. Non-PPCS
+ characters typically occur only in comments: although output file names
+ and time zone abbreviations can contain nearly any character, other
+ software will work better if these are limited to the restricted syntax
+ described under the -v option.
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.
+ another by one or more white space characters. The white space
+ characters are space, form feed, carriage return, newline, tab, and
+ vertical tab. Leading and trailing white space on input lines is
+ ignored. An unquoted sharp character (#) 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.
Names (such as month names) must be in English and are case
insensitive. Abbreviations, if used, must be unambiguous in context.
@@ -80,10 +116,10 @@
part of.
FROM Gives the first year in which the rule applies. Any integer
- year can be supplied; the Gregorian calendar is assumed. The
- word minimum (or an abbreviation) means the minimum year
- representable as an integer. The word maximum (or an
- abbreviation) means the maximum year representable as an
+ year can be supplied; the proleptic Gregorian calendar is
+ assumed. The word minimum (or an abbreviation) means the
+ minimum year representable as an integer. The word 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
@@ -94,14 +130,8 @@
abbreviation) may be used to repeat the value of the FROM
field.
- TYPE Gives the type of year in which the rule applies. If TYPE is -
- then the rule applies in all years between FROM and TO
- inclusive. If TYPE is something else, then zic executes the
- command
- yearistype year type
- to check the type of a year: an exit status of zero is taken to
- mean that the year is of the given type; an exit status of one
- is taken to mean that the year is not of the given type.
+ TYPE should be "-" and is present for compatibility with older
+ versions of zic in which it could contain year types.
IN Names the month in which the rule takes effect. Month names
may be abbreviated.
@@ -132,17 +162,22 @@
followed by the letter w if the given time is local "wall
clock" time, s if the given time is local "standard" time, or u
(or g or z) if the given time is universal time; in the absence
- of an indicator, wall clock time is assumed.
+ of an indicator, wall clock time is assumed. The intent is
+ that a rule line describes the instants when a clock/calendar
+ set to the type of time specified in the AT field would show
+ the specified date and time of day.
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 AT field (although, of course, the w and s suffixes are not
- used).
+ used). Only the sum of standard time and this amount matters;
+ for example, zic does not distinguish a 10:30 standard time
+ plus an 0:30 SAVE from a 10:00 standard time plus a 1:00 SAVE.
LETTER/S
Gives the "variable part" (for example, the "S" or "D" in "EST"
or "EDT") of time zone abbreviations to be used when this rule
- is in effect. If this field is -, the variable part is null.
+ is in effect. If this field is "-", the variable part is null.
A zone line has the form
@@ -150,40 +185,50 @@
For example:
- Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00
+ Zone Australia/Adelaide 9:30 Aus AC%sT 1971 Oct 31 2:00
The fields that make up a zone line are:
NAME The name of the time zone. This is the name used in creating the
- time conversion information file for the zone.
+ time conversion information file for the zone. It should not
+ contain a file name component "." or ".."; a file name component
+ is a maximal substring that does not contain "/".
GMTOFF
- The amount of time to add to UTC to get standard time in this
+ The amount of time to add to UT to get standard time in this
zone. This field has the same format as the AT and SAVE fields
of rule lines; begin the field with a minus sign if time must be
- subtracted from UTC.
+ subtracted from UT.
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 - then standard time always applies in the time
- zone.
+ zone. When an amount of time is given, only the sum of standard
+ time and this amount matters.
FORMAT
The format for time zone abbreviations in this time zone. The
pair of characters %s is used to show where the "variable part"
- of the time zone abbreviation goes. Alternately, a slash (/)
- separates standard and daylight abbreviations.
+ of the time zone abbreviation goes. Alternately, a format can
+ use the pair of characters %z to stand for the UTC offset in the
+ form +-hh, +-hhmm, or +-hhmmss, using the shortest form that does
+ not lose information, where hh, mm, and ss are the hours,
+ minutes, and seconds east (+) or west (-) of UTC. Alternately, a
+ slash (/) separates standard and daylight abbreviations. To
+ conform to POSIX, a time zone abbreviation should contain only
+ alphanumeric ASCII characters, "+" and "-".
UNTILYEAR [MONTH [DAY [TIME]]]
- The time at which the UTC offset or the rule(s) change for a
+ The time at which the UT offset or the rule(s) change for a
location. It is specified as a year, a month, a day, and a time
of day. If this is specified, the time zone information is
- generated from the given UTC offset and rule change until the
- time specified. The month, day, and time of day have the same
- format as the IN, ON, and AT fields of a rule; trailing fields
- can be omitted, and default to the earliest possible value for
- the missing fields.
+ generated from the given UT offset and rule change until the time
+ specified, which is interpreted using the rules in effect just
+ before the transition. The month, day, and time of day have the
+ same format as the IN, ON, and AT fields of a rule; trailing
+ fields can be omitted, and default to the earliest possible value
+ for the missing fields.
The next line must be a "continuation" line; this has the same
form as a zone line except that the string "Zone" and the name
@@ -194,19 +239,27 @@
lines do, indicating that the next line is a further
continuation.
+ If a zone changes at the same instant that a rule would otherwise take
+ effect in the earlier zone or continuation line, the rule is ignored.
+ In a single zone it is an error if two rules take effect at the same
+ instant, or if two zone changes take effect at the same instant.
+
A link line has the form
- Link LINK-FROM LINK-TO
+ Link TARGET LINK-NAME
For example:
Link Europe/Istanbul Asia/Istanbul
- The LINK-FROM field should appear as the NAME field in some zone line;
- the LINK-TO field is used as an alternate name for that zone.
+ The TARGET field should appear as the NAME field in some zone line.
+ The LINK-NAME field is used as an alternate name for that zone; it has
+ the same syntax as a zone line's NAME field.
Except for continuation lines, lines may appear in any order in the
- input.
+ input. However, the behavior is unspecified if multiple zone or link
+ lines define the same name, or if the source of one link line is the
+ target of another.
Lines in the file that describes leap seconds have the following form:
@@ -229,10 +282,8 @@
of its features.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
- Rule Swiss 1940 only - Nov 2 0:00 1:00 S
- Rule Swiss 1940 only - Dec 31 0:00 0 -
- Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S
- Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0
+ Rule Swiss 1941 1942 - May Mon>=1 1:00 1:00 S
+ Rule Swiss 1941 1942 - Oct Mon>=1 2:00 0 -
Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
Rule EU 1977 only - Sep lastSun 1:00u 0 -
Rule EU 1978 only - Oct 1 1:00u 0 -
@@ -240,34 +291,35 @@
Rule EU 1981 max - Mar lastSun 1:00u 1:00 S
Rule EU 1996 max - Oct lastSun 1:00u 0 -
- # Zone NAME GMTOFF RULES FORMAT UNTIL
- Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12
- 0:29:44 - BMT 1894 Jun
- 1:00 Swiss CE%sT 1981
- 1:00 EU CE%sT
+ # Zone NAME GMTOFF RULES/SAVE FORMAT UNTIL
+ Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16
+ 0:29:46 - BMT 1894 Jun
+ 1:00 Swiss CE%sT 1981
+ 1:00 EU CE%sT
Link Europe/Zurich Switzerland
In this example, the zone is named Europe/Zurich but it has an alias as
- Switzerland. Zurich was 34 minutes and 8 seconds west of GMT until
- 1848-09-12 at 00:00, when the offset changed to 29 minutes and 44
- seconds. After 1894-06-01 at 00:00 Swiss daylight saving rules
- (defined with lines beginning with "Rule Swiss") apply, and the GMT
- offset became one hour. From 1981 to the present, EU daylight saving
- rules have applied, and the UTC offset has remained at one hour.
+ Switzerland. This example says that Zurich was 34 minutes and 8
+ seconds west of UT until 1853-07-16 at 00:00, when the legal offset was
+ changed to 7o26'22.50''; although this works out to 0:29:45.50, the
+ input format cannot represent fractional seconds so it is rounded here.
+ After 1894-06-01 at 00:00 Swiss daylight saving rules (defined with
+ lines beginning with "Rule Swiss") apply, and the UT offset became one
+ hour. From 1981 to the present, EU daylight saving rules have applied,
+ and the UTC offset has remained at one hour.
- In 1940, daylight saving time applied from November 2 at 00:00 to
- December 31 at 00:00. In 1941 and 1942, daylight saving time applied
- from the first Sunday in May at 02:00 to the first Sunday in October at
- 00:00. The pre-1981 EU daylight-saving rules have no effect here, but
- are included for completeness. Since 1981, daylight saving has begun
- on the last Sunday in March at 01:00 UTC. Until 1995 it ended the last
- Sunday in September at 01:00 UTC, but this changed to the last Sunday
- in October starting in 1996.
+ In 1941 and 1942, daylight saving time applied from the first Monday in
+ May at 01:00 to the first Monday in October at 02:00. The pre-1981 EU
+ daylight-saving rules have no effect here, but are included for
+ completeness. Since 1981, daylight saving has begun on the last Sunday
+ in March at 01:00 UTC. Until 1995 it ended the last Sunday in
+ September at 01:00 UTC, but this changed to the last Sunday in October
+ starting in 1996.
For purposes of display, "LMT" and "BMT" were initially used,
respectively. Since Swiss rules and later EU rules were applied, the
- display name for the timezone has been CET for standard time and CEST
+ display name for the time zone has been CET for standard time and CEST
for daylight saving time.
NOTES
@@ -278,13 +330,19 @@
If, for a particular zone, a clock advance caused by the start of
daylight saving coincides with and is equal to a clock retreat caused
- by a change in UTC offset, zic produces a single transition to daylight
- saving at the new UTC offset (without any change in wall clock time).
+ by a change in UT offset, zic produces a single transition to daylight
+ saving at the new UT offset (without any change in wall clock time).
To get separate transitions use multiple zone continuation lines
specifying transition instants using universal time.
+ Time stamps well before the Big Bang are silently omitted from the
+ output. This works around bugs in software that mishandles large
+ negative time stamps. Call it sour grapes, but pre-Big-Bang time
+ stamps are physically suspect anyway. The pre-Big-Bang cutoff time is
+ approximate and may change in future versions.
+
FILE
- /usr/local/etc/zoneinfo standard directory used for created
+ /usr/local/etc/zoneinfo standard directory used for created
files
SEE ALSO
Modified: vendor/tzcode/dist/zic.c
===================================================================
--- vendor/tzcode/dist/zic.c 2016-08-15 01:49:33 UTC (rev 7735)
+++ vendor/tzcode/dist/zic.c 2016-08-15 01:50:22 UTC (rev 7736)
@@ -8,16 +8,29 @@
#include "locale.h"
#include "tzfile.h"
-#define ZIC_VERSION '2'
+#include <stdarg.h>
+#define ZIC_VERSION_PRE_2013 '2'
+#define ZIC_VERSION '3'
+
typedef int_fast64_t zic_t;
+#define ZIC_MIN INT_FAST64_MIN
+#define ZIC_MAX INT_FAST64_MAX
+#define SCNdZIC SCNdFAST64
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
#define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+# include <io.h>
+# undef mkdir
+# define mkdir(name, mode) _mkdir(name)
+#endif
+
#if HAVE_SYS_STAT_H
-#include "sys/stat.h"
+#include <sys/stat.h>
#endif
#ifdef S_IRUSR
#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
@@ -25,34 +38,16 @@
#define MKDIR_UMASK 0755
#endif
-/*
-** On some ancient hosts, predicates like `isspace(C)' are defined
-** only if isascii(C) || C == EOF. Modern hosts obey the C Standard,
-** which says they are defined only if C == ((unsigned char) C) || C == EOF.
-** Neither the C Standard nor Posix require that `isascii' exist.
-** For portability, we check both ancient and modern requirements.
-** If isascii is not defined, the isascii check succeeds trivially.
-*/
-#include "ctype.h"
-#ifndef isascii
-#define isascii(x) 1
-#endif
-
-#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long))
-#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */
-
-#define end(cp) (strchr((cp), '\0'))
-
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 */
+ zic_t r_loyear; /* for example, 1986 */
+ zic_t r_hiyear; /* for example, 1986 */
const char * r_yrtype;
- int r_lowasnum;
- int r_hiwasnum;
+ bool r_lowasnum;
+ bool r_hiwasnum;
int r_month; /* 0..11 */
@@ -60,12 +55,12 @@
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_todisgmt; /* above is GMT if TRUE */
- /* or local time if FALSE */
- long r_stdoff; /* offset from standard time */
+ zic_t r_tod; /* time from midnight */
+ bool r_todisstd; /* above is standard time if 1 */
+ /* or wall clock time if 0 */
+ bool r_todisgmt; /* above is GMT if 1 */
+ /* or local time if 0 */
+ zic_t r_stdoff; /* offset from standard time */
const char * r_abbrvar; /* variable part of abbreviation */
int r_todo; /* a rule to do (used in outzone) */
@@ -85,11 +80,12 @@
int z_linenum;
const char * z_name;
- long z_gmtoff;
+ zic_t z_gmtoff;
const char * z_rule;
const char * z_format;
+ char z_format_specifier;
- long z_stdoff;
+ zic_t z_stdoff;
struct rule * z_rules;
int z_nrules;
@@ -98,61 +94,81 @@
zic_t z_untiltime;
};
+#if !HAVE_POSIX_DECLS
extern int getopt(int argc, char * const argv[],
const char * options);
extern int link(const char * fromname, const char * toname);
extern char * optarg;
extern int optind;
+#endif
+#if ! HAVE_LINK
+# define link(from, to) (errno = ENOTSUP, -1)
+#endif
+#if ! HAVE_SYMLINK
+# define symlink(from, to) (errno = ENOTSUP, -1)
+#endif
+
static void addtt(zic_t starttime, int type);
-static int addtype(long gmtoff, const char * abbr, int isdst,
- int ttisstd, int ttisgmt);
-static void leapadd(zic_t t, int positive, int rolling, int count);
+static int addtype(zic_t, char const *, bool, bool, bool);
+static void leapadd(zic_t, bool, int, int);
static void adjleap(void);
static void associate(void);
static void dolink(const char * fromfield, const char * tofield);
-static long eitol(int i);
static char ** getfields(char * buf);
-static long gethms(const char * string, const char * errstrng,
- int signable);
+static zic_t gethms(const char * string, const char * errstring,
+ bool);
static void infile(const char * filename);
static void inleap(char ** fields, int nfields);
static void inlink(char ** fields, int nfields);
static void inrule(char ** fields, int nfields);
-static int inzcont(char ** fields, int nfields);
-static int inzone(char ** fields, int nfields);
-static int inzsub(char ** fields, int nfields, int iscont);
+static bool inzcont(char ** fields, int nfields);
+static bool inzone(char ** fields, int nfields);
+static bool inzsub(char **, int, bool);
static int itsdir(const char * name);
-static int lowerit(int c);
-static int mkdirs(char * filename);
+static bool is_alpha(char a);
+static char lowerit(char);
+static bool mkdirs(char *);
static void newabbr(const char * abbr);
-static long oadd(long t1, long t2);
+static zic_t oadd(zic_t t1, zic_t t2);
static void outzone(const struct zone * zp, int ntzones);
-static zic_t rpytime(const struct rule * rp, int wantedy);
+static zic_t rpytime(const struct rule * rp, zic_t wantedy);
static void rulesub(struct rule * rp,
const char * loyearp, const char * hiyearp,
const char * typep, const char * monthp,
const char * dayp, const char * timep);
-static zic_t tadd(zic_t t1, long t2);
-static int yearistype(int year, const char * type);
+static zic_t tadd(zic_t t1, zic_t t2);
+static bool yearistype(int year, const char * type);
+/* Bound on length of what %z can expand to. */
+enum { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1 };
+
+/* If true, work around a bug in Qt 5.6.1 and earlier, which mishandles
+ tzdata binary files whose POSIX-TZ-style strings contain '<'; see
+ QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
+ workaround will no longer be needed when Qt 5.6.1 and earlier are
+ obsolete, say in the year 2021. */
+enum { WORK_AROUND_QTBUG_53071 = true };
+
static int charcnt;
-static int errors;
+static bool errors;
+static bool warnings;
static const char * filename;
static int leapcnt;
-static int leapseen;
-static int leapminyear;
-static int leapmaxyear;
+static bool leapseen;
+static zic_t leapminyear;
+static zic_t leapmaxyear;
static int linenum;
-static int max_abbrvar_len;
+static int max_abbrvar_len = PERCENT_Z_LEN_BOUND;
static int max_format_len;
-static int max_year;
-static int min_year;
-static int noise;
+static zic_t max_year;
+static zic_t min_year;
+static bool noise;
static const char * rfilename;
static int rlinenum;
static const char * progname;
static int timecnt;
+static int timecnt_alloc;
static int typecnt;
/*
@@ -238,9 +254,11 @@
static struct rule * rules;
static int nrules; /* number of rules */
+static int nrules_alloc;
static struct zone * zones;
static int nzones; /* number of zones */
+static int nzones_alloc;
struct link {
const char * l_filename;
@@ -251,6 +269,7 @@
static struct link * links;
static int nlinks;
+static int nlinks_alloc;
struct lookup {
const char * l_word;
@@ -320,8 +339,8 @@
};
static struct lookup const leap_types[] = {
- { "Rolling", TRUE },
- { "Stationary", FALSE },
+ { "Rolling", true },
+ { "Stationary", false },
{ NULL, 0 }
};
@@ -337,15 +356,15 @@
static struct attype {
zic_t at;
unsigned char type;
-} attypes[TZ_MAX_TIMES];
-static long gmtoffs[TZ_MAX_TYPES];
+} * attypes;
+static zic_t 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 ttisgmts[TZ_MAX_TYPES];
+static bool ttisstds[TZ_MAX_TYPES];
+static bool ttisgmts[TZ_MAX_TYPES];
static char chars[TZ_MAX_CHARS];
static zic_t trans[TZ_MAX_LEAPS];
-static long corr[TZ_MAX_LEAPS];
+static zic_t corr[TZ_MAX_LEAPS];
static char roll[TZ_MAX_LEAPS];
/*
@@ -352,24 +371,71 @@
** Memory allocation.
*/
+static _Noreturn void
+memory_exhausted(const char *msg)
+{
+ fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
+ exit(EXIT_FAILURE);
+}
+
+static ATTRIBUTE_PURE size_t
+size_product(size_t nitems, size_t itemsize)
+{
+ if (SIZE_MAX / itemsize < nitems)
+ memory_exhausted(_("size overflow"));
+ return nitems * itemsize;
+}
+
+#if !HAVE_STRDUP
+static char *
+strdup(char const *str)
+{
+ char *result = malloc(strlen(str) + 1);
+ return result ? strcpy(result, str) : result;
+}
+#endif
+
static ATTRIBUTE_PURE void *
-memcheck(void *const ptr)
+memcheck(void *ptr)
{
- if (ptr == NULL) {
- const char *e = strerror(errno);
+ if (ptr == NULL)
+ memory_exhausted(strerror(errno));
+ return ptr;
+}
- (void) fprintf(stderr, _("%s: Memory exhausted: %s\n"),
- progname, e);
- exit(EXIT_FAILURE);
+static void *
+emalloc(size_t size)
+{
+ return memcheck(malloc(size));
+}
+
+static void *
+erealloc(void *ptr, size_t size)
+{
+ return memcheck(realloc(ptr, size));
+}
+
+static char *
+ecpyalloc (char const *str)
+{
+ return memcheck(strdup(str));
+}
+
+static void *
+growalloc(void *ptr, size_t itemsize, int nitems, int *nitems_alloc)
+{
+ if (nitems < *nitems_alloc)
+ return ptr;
+ else {
+ int nitems_max = INT_MAX - WORK_AROUND_QTBUG_53071;
+ int amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
+ if ((amax - 1) / 3 * 2 < *nitems_alloc)
+ memory_exhausted(_("int overflow"));
+ *nitems_alloc = *nitems_alloc + (*nitems_alloc >> 1) + 1;
+ return erealloc(ptr, size_product(*nitems_alloc, itemsize));
}
- return ptr;
}
-#define emalloc(size) memcheck(malloc(size))
-#define erealloc(ptr, size) memcheck(realloc(ptr, size))
-#define ecpyalloc(ptr) memcheck(icpyalloc(ptr))
-#define ecatalloc(oldp, newp) memcheck(icatalloc((oldp), (newp)))
-
/*
** Error handling.
*/
@@ -390,8 +456,8 @@
eats(name, num, NULL, -1);
}
-static void
-error(const char *const string)
+static void ATTRIBUTE_FORMAT((printf, 1, 0))
+verror(const char *const string, va_list args)
{
/*
** Match the format of "cc" to allow sh users to
@@ -398,37 +464,62 @@
** zic ... 2>&1 | error -t "*" -v
** on BSD systems.
*/
- (void) fprintf(stderr, _("\"%s\", line %d: %s"),
- filename, linenum, string);
+ if (filename)
+ fprintf(stderr, _("\"%s\", line %d: "), filename, linenum);
+ vfprintf(stderr, string, args);
if (rfilename != NULL)
- (void) fprintf(stderr, _(" (rule from \"%s\", line %d)"),
+ fprintf(stderr, _(" (rule from \"%s\", line %d)"),
rfilename, rlinenum);
- (void) fprintf(stderr, "\n");
- ++errors;
+ fprintf(stderr, "\n");
}
-static void
-warning(const char *const string)
+static void ATTRIBUTE_FORMAT((printf, 1, 2))
+error(const char *const string, ...)
{
- char * cp;
+ va_list args;
+ va_start(args, string);
+ verror(string, args);
+ va_end(args);
+ errors = true;
+}
- cp = ecpyalloc(_("warning: "));
- cp = ecatalloc(cp, string);
- error(cp);
- free(cp);
- --errors;
+static void ATTRIBUTE_FORMAT((printf, 1, 2))
+warning(const char *const string, ...)
+{
+ va_list args;
+ fprintf(stderr, _("warning: "));
+ va_start(args, string);
+ verror(string, args);
+ va_end(args);
+ warnings = true;
}
static void
+close_file(FILE *stream, char const *name)
+{
+ char const *e = (ferror(stream) ? _("I/O error")
+ : fclose(stream) != 0 ? strerror(errno) : NULL);
+ if (e) {
+ fprintf(stderr, "%s: ", progname);
+ if (name)
+ fprintf(stderr, "%s: ", name);
+ fprintf(stderr, "%s\n", e);
+ exit(EXIT_FAILURE);
+ }
+}
+
+static _Noreturn void
usage(FILE *stream, int status)
{
- (void) fprintf(stream, _("%s: usage is %s \
-[ --version ] [ --help ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
-\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\
-\n\
-Report bugs to tz at iana.org.\n"),
- progname, progname);
- exit(status);
+ fprintf(stream,
+ _("%s: usage is %s [ --version ] [ --help ] [ -v ] \\\n"
+ "\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n"
+ "\t[ -L leapseconds ] [ filename ... ]\n\n"
+ "Report bugs to %s.\n"),
+ progname, progname, REPORT_BUGS_TO);
+ if (status == EXIT_SUCCESS)
+ close_file(stream, NULL);
+ exit(status);
}
static const char * psxrules;
@@ -444,26 +535,27 @@
register int j;
register int c;
-#ifdef unix
- (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
-#endif /* defined unix */
+#ifdef S_IWGRP
+ umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
+#endif
#if HAVE_GETTEXT
- (void) setlocale(LC_ALL, "");
+ setlocale(LC_ALL, "");
#ifdef TZ_DOMAINDIR
- (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
+ bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined TEXTDOMAINDIR */
- (void) textdomain(TZ_DOMAIN);
+ textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT */
progname = argv[0];
if (TYPE_BIT(zic_t) < 64) {
- (void) fprintf(stderr, "%s: %s\n", progname,
+ fprintf(stderr, "%s: %s\n", progname,
_("wild compilation-time specification of zic_t"));
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
for (i = 1; i < argc; ++i)
if (strcmp(argv[i], "--version") == 0) {
- (void) printf("zic %s%s\n", PKGVERSION, TZVERSION);
- exit(EXIT_SUCCESS);
+ printf("zic %s%s\n", PKGVERSION, TZVERSION);
+ close_file(stdout, NULL);
+ return EXIT_SUCCESS;
} else if (strcmp(argv[i], "--help") == 0) {
usage(stdout, EXIT_SUCCESS);
}
@@ -475,10 +567,10 @@
if (directory == NULL)
directory = optarg;
else {
- (void) fprintf(stderr,
+ fprintf(stderr,
_("%s: More than one -d option specified\n"),
progname);
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
break;
case 'l':
@@ -485,10 +577,10 @@
if (lcltime == NULL)
lcltime = optarg;
else {
- (void) fprintf(stderr,
+ fprintf(stderr,
_("%s: More than one -l option specified\n"),
progname);
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
break;
case 'p':
@@ -495,10 +587,10 @@
if (psxrules == NULL)
psxrules = optarg;
else {
- (void) fprintf(stderr,
+ fprintf(stderr,
_("%s: More than one -p option specified\n"),
progname);
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
break;
case 'y':
@@ -505,10 +597,10 @@
if (yitcommand == NULL)
yitcommand = optarg;
else {
- (void) fprintf(stderr,
+ fprintf(stderr,
_("%s: More than one -y option specified\n"),
progname);
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
break;
case 'L':
@@ -515,17 +607,17 @@
if (leapsec == NULL)
leapsec = optarg;
else {
- (void) fprintf(stderr,
+ fprintf(stderr,
_("%s: More than one -L option specified\n"),
progname);
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
break;
case 'v':
- noise = TRUE;
+ noise = true;
break;
case 's':
- (void) printf("%s: -s ignored\n", progname);
+ warning(_("-s ignored"));
break;
}
if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
@@ -543,7 +635,7 @@
for (i = optind; i < argc; ++i)
infile(argv[i]);
if (errors)
- exit(EXIT_FAILURE);
+ return EXIT_FAILURE;
associate();
for (i = 0; i < nzones; i = j) {
/*
@@ -566,78 +658,191 @@
warning(_("link to link"));
}
if (lcltime != NULL) {
- eat("command line", 1);
+ eat(_("command line"), 1);
dolink(lcltime, TZDEFAULT);
}
if (psxrules != NULL) {
- eat("command line", 1);
+ eat(_("command line"), 1);
dolink(psxrules, TZDEFRULES);
}
- return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+ if (warnings && (ferror(stderr) || fclose(stderr) != 0))
+ return EXIT_FAILURE;
+ return errors ? EXIT_FAILURE : EXIT_SUCCESS;
}
+static bool
+componentcheck(char const *name, char const *component,
+ char const *component_end)
+{
+ enum { component_len_max = 14 };
+ size_t component_len = component_end - component;
+ if (component_len == 0) {
+ if (!*name)
+ error (_("empty file name"));
+ else
+ error (_(component == name
+ ? "file name '%s' begins with '/'"
+ : *component_end
+ ? "file name '%s' contains '//'"
+ : "file name '%s' ends with '/'"),
+ name);
+ return false;
+ }
+ if (0 < component_len && component_len <= 2
+ && component[0] == '.' && component_end[-1] == '.') {
+ error(_("file name '%s' contains '%.*s' component"),
+ name, (int) component_len, component);
+ return false;
+ }
+ if (noise) {
+ if (0 < component_len && component[0] == '-')
+ warning(_("file name '%s' component contains leading '-'"),
+ name);
+ if (component_len_max < component_len)
+ warning(_("file name '%s' contains overlength component"
+ " '%.*s...'"),
+ name, component_len_max, component);
+ }
+ return true;
+}
+
+static bool
+namecheck(const char *name)
+{
+ register char const *cp;
+
+ /* Benign characters in a portable file name. */
+ static char const benign[] =
+ "-/_"
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ /* Non-control chars in the POSIX portable character set,
+ excluding the benign characters. */
+ static char const printable_and_not_benign[] =
+ " !\"#$%&'()*+,.0123456789:;<=>?@[\\]^`{|}~";
+
+ register char const *component = name;
+ for (cp = name; *cp; cp++) {
+ unsigned char c = *cp;
+ if (noise && !strchr(benign, c)) {
+ warning((strchr(printable_and_not_benign, c)
+ ? _("file name '%s' contains byte '%c'")
+ : _("file name '%s' contains byte '\\%o'")),
+ name, c);
+ }
+ if (c == '/') {
+ if (!componentcheck(name, component, cp))
+ return false;
+ component = cp + 1;
+ }
+ }
+ return componentcheck(name, component, cp);
+}
+
+static char *
+relname(char const *dir, char const *base)
+{
+ if (*base == '/')
+ return ecpyalloc(base);
+ else {
+ size_t dir_len = strlen(dir);
+ bool needs_slash = dir_len && dir[dir_len - 1] != '/';
+ char *result = emalloc(dir_len + needs_slash + strlen(base) + 1);
+ result[dir_len] = '/';
+ strcpy(result + dir_len + needs_slash, base);
+ return memcpy(result, dir, dir_len);
+ }
+}
+
static void
-dolink(const char *const fromfield, const char *const tofield)
+dolink(char const *fromfield, char const *tofield)
{
register char * fromname;
register char * toname;
+ register int fromisdir;
- if (fromfield[0] == '/')
- fromname = ecpyalloc(fromfield);
- else {
- fromname = ecpyalloc(directory);
- fromname = ecatalloc(fromname, "/");
- fromname = ecatalloc(fromname, fromfield);
- }
- if (tofield[0] == '/')
- toname = ecpyalloc(tofield);
- else {
- toname = ecpyalloc(directory);
- toname = ecatalloc(toname, "/");
- toname = ecatalloc(toname, tofield);
- }
+ fromname = relname(directory, fromfield);
+ toname = relname(directory, tofield);
/*
** We get to be careful here since
** there's a fair chance of root running us.
*/
- if (!itsdir(toname))
- (void) remove(toname);
+ fromisdir = itsdir(fromname);
+ if (fromisdir) {
+ char const *e = strerror(fromisdir < 0 ? errno : EPERM);
+ fprintf(stderr, _("%s: link from %s failed: %s"),
+ progname, fromname, e);
+ exit(EXIT_FAILURE);
+ }
if (link(fromname, toname) != 0) {
- int result;
+ int link_errno = errno;
+ bool retry_if_link_supported = false;
- if (mkdirs(toname) != 0)
- exit(EXIT_FAILURE);
+ if (link_errno == ENOENT || link_errno == ENOTSUP) {
+ if (! mkdirs(toname))
+ exit(EXIT_FAILURE);
+ retry_if_link_supported = true;
+ }
+ if ((link_errno == EEXIST || link_errno == ENOTSUP)
+ && itsdir(toname) == 0
+ && (remove(toname) == 0 || errno == ENOENT))
+ retry_if_link_supported = true;
+ if (retry_if_link_supported && link_errno != ENOTSUP)
+ link_errno = link(fromname, toname) == 0 ? 0 : errno;
+ if (link_errno != 0) {
+ const char *s = fromfield;
+ const char *t;
+ char *p;
+ size_t dotdots = 0;
+ char *symlinkcontents;
+ int symlink_result;
- result = link(fromname, toname);
-#if HAVE_SYMLINK
- if (result != 0 &&
- access(fromname, F_OK) == 0 &&
- !itsdir(fromname)) {
- const char *s = tofield;
- register char * symlinkcontents = NULL;
+ do
+ t = s;
+ while ((s = strchr(s, '/'))
+ && strncmp(fromfield, tofield, ++s - fromfield) == 0);
- while ((s = strchr(s+1, '/')) != NULL)
- symlinkcontents =
- ecatalloc(symlinkcontents,
- "../");
- symlinkcontents =
- ecatalloc(symlinkcontents,
- fromname);
- result = symlink(symlinkcontents,
- toname);
- if (result == 0)
-warning(_("hard link failed, symbolic link used"));
- free(symlinkcontents);
- }
-#endif /* HAVE_SYMLINK */
- if (result != 0) {
- const char *e = strerror(errno);
-
- (void) fprintf(stderr,
- _("%s: Can't link from %s to %s: %s\n"),
- progname, fromname, toname, e);
- exit(EXIT_FAILURE);
- }
+ for (s = tofield + (t - fromfield); *s; s++)
+ dotdots += *s == '/';
+ symlinkcontents = emalloc(3 * dotdots + strlen(t) + 1);
+ for (p = symlinkcontents; dotdots-- != 0; p += 3)
+ memcpy(p, "../", 3);
+ strcpy(p, t);
+ symlink_result = symlink(symlinkcontents, toname);
+ free(symlinkcontents);
+ if (symlink_result == 0) {
+ if (link_errno != ENOTSUP)
+ warning(_("symbolic link used because hard link failed: %s"),
+ strerror (link_errno));
+ } else {
+ FILE *fp, *tp;
+ int c;
+ fp = fopen(fromname, "rb");
+ if (!fp) {
+ const char *e = strerror(errno);
+ fprintf(stderr,
+ _("%s: Can't read %s: %s\n"),
+ progname, fromname, e);
+ exit(EXIT_FAILURE);
+ }
+ tp = fopen(toname, "wb");
+ if (!tp) {
+ const char *e = strerror(errno);
+ fprintf(stderr,
+ _("%s: Can't create %s: %s\n"),
+ progname, toname, e);
+ exit(EXIT_FAILURE);
+ }
+ while ((c = getc(fp)) != EOF)
+ putc(c, tp);
+ close_file(fp, fromname);
+ close_file(tp, toname);
+ if (link_errno != ENOTSUP)
+ warning(_("copy used because hard link failed: %s"),
+ strerror (link_errno));
+ }
+ }
}
free(fromname);
free(toname);
@@ -645,20 +850,64 @@
#define TIME_T_BITS_IN_FILE 64
-static const zic_t min_time = (zic_t) -1 << (TIME_T_BITS_IN_FILE - 1);
-static const zic_t max_time = -1 - ((zic_t) -1 << (TIME_T_BITS_IN_FILE - 1));
+static zic_t const min_time = MINVAL (zic_t, TIME_T_BITS_IN_FILE);
+static zic_t const max_time = MAXVAL (zic_t, TIME_T_BITS_IN_FILE);
+/* Estimated time of the Big Bang, in seconds since the POSIX epoch.
+ rounded downward to the negation of a power of two that is
+ comfortably outside the error bounds.
+
+ For the time of the Big Bang, see:
+
+ Ade PAR, Aghanim N, Armitage-Caplan C et al. Planck 2013 results.
+ I. Overview of products and scientific results.
+ arXiv:1303.5062 2013-03-20 20:10:01 UTC
+ <http://arxiv.org/pdf/1303.5062v1> [PDF]
+
+ Page 36, Table 9, row Age/Gyr, column Planck+WP+highL+BAO 68% limits
+ gives the value 13.798 plus-or-minus 0.037 billion years.
+ Multiplying this by 1000000000 and then by 31557600 (the number of
+ seconds in an astronomical year) gives a value that is comfortably
+ less than 2**59, so BIG_BANG is - 2**59.
+
+ BIG_BANG is approximate, and may change in future versions.
+ Please do not rely on its exact value. */
+
+#ifndef BIG_BANG
+#define BIG_BANG (- (1LL << 59))
+#endif
+
+/* If true, work around GNOME bug 730332
+ <https://bugzilla.gnome.org/show_bug.cgi?id=730332>
+ by refusing to output time stamps before BIG_BANG.
+ Such time stamps are physically suspect anyway.
+
+ The GNOME bug is scheduled to be fixed in GNOME 3.22, and if so
+ this workaround will no longer be needed when GNOME 3.21 and
+ earlier are obsolete, say in the year 2021. */
+enum { WORK_AROUND_GNOME_BUG_730332 = true };
+
+static const zic_t early_time = (WORK_AROUND_GNOME_BUG_730332
+ ? BIG_BANG
+ : MINVAL(zic_t, TIME_T_BITS_IN_FILE));
+
+/* Return 1 if NAME is a directory, 0 if it's something else, -1 if trouble. */
static int
-itsdir(const char *const name)
+itsdir(char const *name)
{
- register char * myname;
- register int accres;
-
- myname = ecpyalloc(name);
- myname = ecatalloc(myname, "/.");
- accres = access(myname, F_OK);
- free(myname);
- return accres == 0;
+ struct stat st;
+ int res = stat(name, &st);
+#ifdef S_ISDIR
+ if (res == 0)
+ return S_ISDIR(st.st_mode) != 0;
+#endif
+ if (res == 0 || errno == EOVERFLOW) {
+ char *nameslashdot = relname(name, ".");
+ bool dir = stat(nameslashdot, &st) == 0 || errno == EOVERFLOW;
+ free(nameslashdot);
+ return dir;
+ }
+ return -1;
}
/*
@@ -685,7 +934,7 @@
register int i, j;
if (nrules != 0) {
- (void) qsort(rules, nrules, sizeof *rules, rcomp);
+ qsort(rules, nrules, sizeof *rules, rcomp);
for (i = 0; i < nrules - 1; ++i) {
if (strcmp(rules[i].r_name,
rules[i + 1].r_name) != 0)
@@ -738,13 +987,13 @@
*/
eat(zp->z_filename, zp->z_linenum);
zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"),
- TRUE);
+ 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 (zp->z_format_specifier == 's')
+ error("%s", _("%s in ruleless zone"));
}
}
if (errors)
@@ -759,7 +1008,7 @@
register char * cp;
register const struct lookup * lp;
register int nfields;
- register int wantcont;
+ register bool wantcont;
register int num;
char buf[BUFSIZ];
@@ -769,11 +1018,11 @@
} else if ((fp = fopen(name, "r")) == NULL) {
const char *e = strerror(errno);
- (void) fprintf(stderr, _("%s: Can't open %s: %s\n"),
+ fprintf(stderr, _("%s: Can't open %s: %s\n"),
progname, name, e);
exit(EXIT_FAILURE);
}
- wantcont = FALSE;
+ wantcont = false;
for (num = 1; ; ++num) {
eat(name, num);
if (fgets(buf, sizeof buf, fp) != buf)
@@ -804,7 +1053,7 @@
else switch ((int) (lp->l_value)) {
case LC_RULE:
inrule(fields, nfields);
- wantcont = FALSE;
+ wantcont = false;
break;
case LC_ZONE:
wantcont = inzone(fields, nfields);
@@ -811,18 +1060,18 @@
break;
case LC_LINK:
inlink(fields, nfields);
- wantcont = FALSE;
+ wantcont = false;
break;
case LC_LEAP:
if (name != leapsec)
- (void) fprintf(stderr,
-_("%s: Leap line in non leap seconds file %s\n"),
- progname, name);
+ warning(_("%s: Leap line in non leap"
+ " seconds file %s"),
+ progname, name);
else inleap(fields, nfields);
- wantcont = FALSE;
+ wantcont = false;
break;
default: /* "cannot happen" */
- (void) fprintf(stderr,
+ fprintf(stderr,
_("%s: panic: Invalid l_value %d\n"),
progname, lp->l_value);
exit(EXIT_FAILURE);
@@ -830,18 +1079,7 @@
}
free(fields);
}
- if (ferror(fp)) {
- (void) fprintf(stderr, _("%s: Error reading %s\n"),
- progname, filename);
- exit(EXIT_FAILURE);
- }
- if (fp != stdin && fclose(fp)) {
- const char *e = strerror(errno);
-
- (void) fprintf(stderr, _("%s: Error closing %s: %s\n"),
- progname, filename, e);
- exit(EXIT_FAILURE);
- }
+ close_file(fp, filename);
if (wantcont)
error(_("expected continuation line not found"));
}
@@ -854,11 +1092,12 @@
** Call error with errstring and return zero on errors.
*/
-static long
-gethms(const char *string, const char *const errstring, const int signable)
+static zic_t
+gethms(char const *string, char const *errstring, bool signable)
{
- long hh;
+ zic_t hh;
int mm, ss, sign;
+ char xs;
if (string == NULL || *string == '\0')
return 0;
@@ -868,36 +1107,34 @@
sign = -1;
++string;
} else sign = 1;
- if (sscanf(string, scheck(string, "%ld"), &hh) == 1)
+ if (sscanf(string, "%"SCNdZIC"%c", &hh, &xs) == 1)
mm = ss = 0;
- else if (sscanf(string, scheck(string, "%ld:%d"), &hh, &mm) == 2)
+ else if (sscanf(string, "%"SCNdZIC":%d%c", &hh, &mm, &xs) == 2)
ss = 0;
- else if (sscanf(string, scheck(string, "%ld:%d:%d"),
- &hh, &mm, &ss) != 3) {
- error(errstring);
+ else if (sscanf(string, "%"SCNdZIC":%d:%d%c", &hh, &mm, &ss, &xs)
+ != 3) {
+ error("%s", errstring);
return 0;
}
if (hh < 0 ||
mm < 0 || mm >= MINSPERHOUR ||
ss < 0 || ss > SECSPERMIN) {
- error(errstring);
+ error("%s", errstring);
return 0;
}
- if (LONG_MAX / SECSPERHOUR < hh) {
+ if (ZIC_MAX / SECSPERHOUR < hh) {
error(_("time overflow"));
return 0;
}
- if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0)
- warning(_("24:00 not handled by pre-1998 versions of zic"));
if (noise && (hh > HOURSPERDAY ||
(hh == HOURSPERDAY && (mm != 0 || ss != 0))))
warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
- return oadd(eitol(sign) * hh * eitol(SECSPERHOUR),
- eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss)));
+ return oadd(sign * hh * SECSPERHOUR,
+ sign * (mm * SECSPERMIN + ss));
}
static void
-inrule(register char **const fields, const int nfields)
+inrule(char **fields, int nfields)
{
static struct rule r;
@@ -911,7 +1148,7 @@
}
r.r_filename = filename;
r.r_linenum = linenum;
- r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), TRUE);
+ 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]);
@@ -918,72 +1155,64 @@
r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
if (max_abbrvar_len < strlen(r.r_abbrvar))
max_abbrvar_len = strlen(r.r_abbrvar);
- rules = erealloc(rules, (nrules + 1) * sizeof *rules);
+ rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
rules[nrules++] = r;
}
-static int
-inzone(register char **const fields, const int nfields)
+static bool
+inzone(char **fields, 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;
+ return false;
}
if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) {
- buf = erealloc(buf, 132 + strlen(TZDEFAULT));
- (void) sprintf(buf,
+ error(
_("\"Zone %s\" line and -l option are mutually exclusive"),
TZDEFAULT);
- error(buf);
- return FALSE;
+ return false;
}
if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) {
- buf = erealloc(buf, 132 + strlen(TZDEFRULES));
- (void) sprintf(buf,
+ error(
_("\"Zone %s\" line and -p option are mutually exclusive"),
TZDEFRULES);
- error(buf);
- return FALSE;
+ 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,
- (132 + strlen(fields[ZF_NAME])
- + strlen(zones[i].z_filename)));
- (void) sprintf(buf,
+ error(
_("duplicate zone name %s (file \"%s\", line %d)"),
fields[ZF_NAME],
zones[i].z_filename,
zones[i].z_linenum);
- error(buf);
- return FALSE;
+ return false;
}
- return inzsub(fields, nfields, FALSE);
+ return inzsub(fields, nfields, false);
}
-static int
-inzcont(register char **const fields, const int nfields)
+static bool
+inzcont(char **fields, int nfields)
{
if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
error(_("wrong number of fields on Zone continuation line"));
- return FALSE;
+ return false;
}
- return inzsub(fields, nfields, TRUE);
+ return inzsub(fields, nfields, true);
}
-static int
-inzsub(register char **const fields, const int nfields, const int iscont)
+static bool
+inzsub(char **fields, int nfields, bool iscont)
{
register char * cp;
+ char * cp1;
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;
+ register bool hasuntil;
if (iscont) {
i_gmtoff = ZFC_GMTOFF;
@@ -994,7 +1223,9 @@
i_untilday = ZFC_TILDAY;
i_untiltime = ZFC_TILTIME;
z.z_name = NULL;
- } else {
+ } else if (!namecheck(fields[ZF_NAME]))
+ return false;
+ else {
i_gmtoff = ZF_GMTOFF;
i_rule = ZF_RULE;
i_format = ZF_FORMAT;
@@ -1006,15 +1237,23 @@
}
z.z_filename = filename;
z.z_linenum = linenum;
- z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UTC offset"), TRUE);
+ z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"), true);
if ((cp = strchr(fields[i_format], '%')) != 0) {
- if (*++cp != 's' || strchr(cp, '%') != 0) {
+ if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
+ || strchr(fields[i_format], '/')) {
error(_("invalid abbreviation format"));
- return FALSE;
+ return false;
}
}
z.z_rule = ecpyalloc(fields[i_rule]);
- z.z_format = ecpyalloc(fields[i_format]);
+ z.z_format = cp1 = ecpyalloc(fields[i_format]);
+ z.z_format_specifier = cp ? *cp : '\0';
+ if (z.z_format_specifier == 'z') {
+ if (noise)
+ warning(_("format '%s' not handled by pre-2015 versions of zic"),
+ z.z_format);
+ cp1[cp - fields[i_format]] = 's';
+ }
if (max_format_len < strlen(z.z_format))
max_format_len = strlen(z.z_format);
hasuntil = nfields > i_untilyear;
@@ -1040,10 +1279,10 @@
error(_(
"Zone continuation line end time is not after end time of previous line"
));
- return FALSE;
+ return false;
}
}
- zones = erealloc(zones, (nzones + 1) * sizeof *zones);
+ zones = growalloc(zones, sizeof *zones, nzones, &nzones_alloc);
zones[nzones++] = z;
/*
** If there was an UNTIL field on this line,
@@ -1053,14 +1292,16 @@
}
static void
-inleap(register char ** const fields, const int nfields)
+inleap(char **fields, int nfields)
{
register const char * cp;
register const struct lookup * lp;
register int i, j;
- int year, month, day;
- long dayoff, tod;
+ zic_t year;
+ int month, day;
+ zic_t dayoff, tod;
zic_t t;
+ char xs;
if (nfields != LEAP_FIELDS) {
error(_("wrong number of fields on Leap line"));
@@ -1068,7 +1309,7 @@
}
dayoff = 0;
cp = fields[LP_YEAR];
- if (sscanf(cp, scheck(cp, "%d"), &year) != 1) {
+ if (sscanf(cp, "%"SCNdZIC"%c", &year, &xs) != 1) {
/*
** Leapin' Lizards!
*/
@@ -1079,7 +1320,7 @@
leapmaxyear = year;
if (!leapseen || leapminyear > year)
leapminyear = year;
- leapseen = TRUE;
+ leapseen = true;
j = EPOCH_YEAR;
while (j != year) {
if (year > j) {
@@ -1089,7 +1330,7 @@
--j;
i = -len_years[isleap(j)];
}
- dayoff = oadd(dayoff, eitol(i));
+ dayoff = oadd(dayoff, i);
}
if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) {
error(_("invalid month name"));
@@ -1099,20 +1340,16 @@
j = TM_JANUARY;
while (j != month) {
i = len_months[isleap(year)][j];
- dayoff = oadd(dayoff, eitol(i));
+ dayoff = oadd(dayoff, i);
++j;
}
cp = fields[LP_DAY];
- if (sscanf(cp, scheck(cp, "%d"), &day) != 1 ||
+ if (sscanf(cp, "%d%c", &day, &xs) != 1 ||
day <= 0 || day > len_months[isleap(year)][month]) {
error(_("invalid day of month"));
return;
}
- dayoff = oadd(dayoff, eitol(day - 1));
- if (dayoff < 0 && !TYPE_SIGNED(zic_t)) {
- error(_("time before zero"));
- return;
- }
+ dayoff = oadd(dayoff, day - 1);
if (dayoff < min_time / SECSPERDAY) {
error(_("time too small"));
return;
@@ -1121,24 +1358,24 @@
error(_("time too large"));
return;
}
- t = (zic_t) dayoff * SECSPERDAY;
- tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
+ t = dayoff * SECSPERDAY;
+ tod = gethms(fields[LP_TIME], _("invalid time of day"), false);
cp = fields[LP_CORR];
{
- register int positive;
+ register bool positive;
int count;
if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
- positive = FALSE;
+ positive = false;
count = 1;
} else if (strcmp(cp, "--") == 0) {
- positive = FALSE;
+ positive = false;
count = 2;
} else if (strcmp(cp, "+") == 0) {
- positive = TRUE;
+ positive = true;
count = 1;
} else if (strcmp(cp, "++") == 0) {
- positive = TRUE;
+ positive = true;
count = 2;
} else {
error(_("illegal CORRECTION field on Leap line"));
@@ -1150,12 +1387,17 @@
));
return;
}
- leapadd(tadd(t, tod), positive, lp->l_value, count);
+ t = tadd(t, tod);
+ if (t < early_time) {
+ error(_("leap second precedes Big Bang"));
+ return;
+ }
+ leapadd(t, positive, lp->l_value, count);
}
}
static void
-inlink(register char **const fields, const int nfields)
+inlink(char **fields, int nfields)
{
struct link l;
@@ -1167,31 +1409,26 @@
error(_("blank FROM field on Link line"));
return;
}
- if (*fields[LF_TO] == '\0') {
- error(_("blank TO field on Link line"));
- return;
- }
+ if (! namecheck(fields[LF_TO]))
+ return;
l.l_filename = filename;
l.l_linenum = linenum;
l.l_from = ecpyalloc(fields[LF_FROM]);
l.l_to = ecpyalloc(fields[LF_TO]);
- links = erealloc(links, (nlinks + 1) * sizeof *links);
+ links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
links[nlinks++] = l;
}
static void
-rulesub(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)
+rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
+ const char *typep, const char *monthp, const char *dayp,
+ const char *timep)
{
register const struct lookup * lp;
register const char * cp;
register char * dp;
register char * ep;
+ char xs;
if ((lp = byword(monthp, mon_names)) == NULL) {
error(_("invalid month name"));
@@ -1198,32 +1435,32 @@
return;
}
rp->r_month = lp->l_value;
- rp->r_todisstd = FALSE;
- rp->r_todisgmt = FALSE;
+ rp->r_todisstd = false;
+ rp->r_todisgmt = false;
dp = ecpyalloc(timep);
if (*dp != '\0') {
ep = dp + strlen(dp) - 1;
switch (lowerit(*ep)) {
case 's': /* Standard */
- rp->r_todisstd = TRUE;
- rp->r_todisgmt = FALSE;
+ rp->r_todisstd = true;
+ rp->r_todisgmt = false;
*ep = '\0';
break;
case 'w': /* Wall */
- rp->r_todisstd = FALSE;
- rp->r_todisgmt = FALSE;
+ rp->r_todisstd = false;
+ rp->r_todisgmt = false;
*ep = '\0';
break;
case 'g': /* Greenwich */
case 'u': /* Universal */
case 'z': /* Zulu */
- rp->r_todisstd = TRUE;
- rp->r_todisgmt = TRUE;
+ rp->r_todisstd = true;
+ rp->r_todisgmt = true;
*ep = '\0';
break;
}
}
- rp->r_tod = gethms(dp, _("invalid time of day"), FALSE);
+ rp->r_tod = gethms(dp, _("invalid time of day"), false);
free(dp);
/*
** Year work.
@@ -1233,17 +1470,17 @@
rp->r_lowasnum = lp == NULL;
if (!rp->r_lowasnum) switch ((int) lp->l_value) {
case YR_MINIMUM:
- rp->r_loyear = INT_MIN;
+ rp->r_loyear = ZIC_MIN;
break;
case YR_MAXIMUM:
- rp->r_loyear = INT_MAX;
+ rp->r_loyear = ZIC_MAX;
break;
default: /* "cannot happen" */
- (void) fprintf(stderr,
+ fprintf(stderr,
_("%s: panic: Invalid l_value %d\n"),
progname, lp->l_value);
exit(EXIT_FAILURE);
- } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
+ } else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_loyear, &xs) != 1) {
error(_("invalid starting year"));
return;
}
@@ -1252,20 +1489,20 @@
rp->r_hiwasnum = lp == NULL;
if (!rp->r_hiwasnum) switch ((int) lp->l_value) {
case YR_MINIMUM:
- rp->r_hiyear = INT_MIN;
+ rp->r_hiyear = ZIC_MIN;
break;
case YR_MAXIMUM:
- rp->r_hiyear = INT_MAX;
+ rp->r_hiyear = ZIC_MAX;
break;
case YR_ONLY:
rp->r_hiyear = rp->r_loyear;
break;
default: /* "cannot happen" */
- (void) fprintf(stderr,
+ fprintf(stderr,
_("%s: panic: Invalid l_value %d\n"),
progname, lp->l_value);
exit(EXIT_FAILURE);
- } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) {
+ } else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_hiyear, &xs) != 1) {
error(_("invalid ending year"));
return;
}
@@ -1318,7 +1555,7 @@
}
rp->r_wday = lp->l_value;
}
- if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 ||
+ if (sscanf(ep, "%d%c", &rp->r_dayofmonth, &xs) != 1 ||
rp->r_dayofmonth <= 0 ||
(rp->r_dayofmonth > len_months[1][rp->r_month])) {
error(_("invalid day of month"));
@@ -1330,7 +1567,7 @@
}
static void
-convert(const long val, char *const buf)
+convert(const int_fast32_t val, char *const buf)
{
register int i;
register int shift;
@@ -1352,12 +1589,12 @@
}
static void
-puttzcode(const long val, FILE *const fp)
+puttzcode(const int_fast32_t val, FILE *const fp)
{
char buf[4];
convert(val, buf);
- (void) fwrite(buf, sizeof buf, 1, fp);
+ fwrite(buf, sizeof buf, 1, fp);
}
static void
@@ -1366,7 +1603,7 @@
char buf[8];
convert64(val, buf);
- (void) fwrite(buf, sizeof buf, 1, fp);
+ fwrite(buf, sizeof buf, 1, fp);
}
static int
@@ -1378,7 +1615,7 @@
return (a < b) ? -1 : (a > b);
}
-static int
+static bool
is32(const zic_t x)
{
return INT32_MIN <= x && x <= INT32_MAX;
@@ -1385,7 +1622,7 @@
}
static void
-writezone(const char *const name, const char *const string)
+writezone(const char *const name, const char *const string, char version)
{
register FILE * fp;
register int i, j;
@@ -1392,17 +1629,21 @@
register int leapcnt32, leapi32;
register int timecnt32, timei32;
register int pass;
- static char * fullname;
+ char * fullname;
static const struct tzhead tzh0;
static struct tzhead tzh;
- zic_t ats[TZ_MAX_TIMES];
- unsigned char types[TZ_MAX_TIMES];
+ zic_t one = 1;
+ zic_t y2038_boundary = one << 31;
+ int nats = timecnt + WORK_AROUND_QTBUG_53071;
+ zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1));
+ void *typesptr = ats + nats;
+ unsigned char *types = typesptr;
/*
** Sort.
*/
if (timecnt > 1)
- (void) qsort(attypes, timecnt, sizeof *attypes, atcomp);
+ qsort(attypes, timecnt, sizeof *attypes, atcomp);
/*
** Optimize.
*/
@@ -1412,16 +1653,13 @@
toi = 0;
fromi = 0;
- while (fromi < timecnt && attypes[fromi].at < min_time)
+ while (fromi < timecnt && attypes[fromi].at < early_time)
++fromi;
- if (isdsts[0] == 0)
- while (fromi < timecnt && attypes[fromi].type == 0)
- ++fromi; /* handled by default rule */
for ( ; fromi < timecnt; ++fromi) {
- if (toi != 0 && ((attypes[fromi].at +
+ if (toi > 1 && ((attypes[fromi].at +
gmtoffs[attypes[toi - 1].type]) <=
- (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0
- : attypes[toi - 2].type]))) {
+ (attypes[toi - 1].at +
+ gmtoffs[attypes[toi - 2].type]))) {
attypes[toi - 1].type =
attypes[fromi].type;
continue;
@@ -1432,6 +1670,9 @@
}
timecnt = toi;
}
+ if (noise && timecnt > 1200)
+ warning(_("pre-2014 clients may mishandle"
+ " more than 1200 transition times"));
/*
** Transfer.
*/
@@ -1439,6 +1680,19 @@
ats[i] = attypes[i].at;
types[i] = attypes[i].type;
}
+
+ /* Work around QTBUG-53071 for time stamps less than y2038_boundary - 1,
+ by inserting a no-op transition at time y2038_boundary - 1.
+ This works only for timestamps before the boundary, which
+ should be good enough in practice as QTBUG-53071 should be
+ long-dead by 2038. */
+ if (WORK_AROUND_QTBUG_53071 && timecnt != 0
+ && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) {
+ ats[timecnt] = y2038_boundary - 1;
+ types[timecnt] = types[timecnt - 1];
+ timecnt++;
+ }
+
/*
** Correct for leap seconds.
*/
@@ -1463,6 +1717,13 @@
--timecnt32;
++timei32;
}
+ /*
+ ** Output an INT32_MIN "transition" if appropriate; see below.
+ */
+ if (timei32 > 0 && ats[timei32] > INT32_MIN) {
+ --timei32;
+ ++timecnt32;
+ }
while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
--leapcnt32;
while (leapcnt32 > 0 && !is32(trans[leapi32])) {
@@ -1469,26 +1730,24 @@
--leapcnt32;
++leapi32;
}
- fullname = erealloc(fullname,
- strlen(directory) + 1 + strlen(name) + 1);
- (void) sprintf(fullname, "%s/%s", directory, name);
+ fullname = relname(directory, name);
/*
** Remove old file, if any, to snap links.
*/
- if (!itsdir(fullname) && remove(fullname) != 0 && errno != ENOENT) {
+ if (itsdir(fullname) == 0 && remove(fullname) != 0 && errno != ENOENT) {
const char *e = strerror(errno);
- (void) fprintf(stderr, _("%s: Can't remove %s: %s\n"),
+ fprintf(stderr, _("%s: Can't remove %s: %s\n"),
progname, fullname, e);
exit(EXIT_FAILURE);
}
if ((fp = fopen(fullname, "wb")) == NULL) {
- if (mkdirs(fullname) != 0)
+ if (! mkdirs(fullname))
exit(EXIT_FAILURE);
if ((fp = fopen(fullname, "wb")) == NULL) {
const char *e = strerror(errno);
- (void) fprintf(stderr, _("%s: Can't create %s: %s\n"),
+ fprintf(stderr, _("%s: Can't create %s: %s\n"),
progname, fullname, e);
exit(EXIT_FAILURE);
}
@@ -1497,12 +1756,12 @@
register int thistimei, thistimecnt;
register int thisleapi, thisleapcnt;
register int thistimelim, thisleaplim;
- int writetype[TZ_MAX_TIMES];
+ int writetype[TZ_MAX_TYPES];
int typemap[TZ_MAX_TYPES];
register int thistypecnt;
char thischars[TZ_MAX_CHARS];
char thischarcnt;
- int indmap[TZ_MAX_CHARS];
+ int indmap[TZ_MAX_CHARS];
if (pass == 1) {
thistimei = timei32;
@@ -1525,16 +1784,16 @@
** (32- or 64-bit) window.
*/
if (typecnt != 0)
- writetype[typecnt - 1] = TRUE;
+ writetype[typecnt - 1] = true;
} else {
for (i = thistimei - 1; i < thistimelim; ++i)
if (i >= 0)
- writetype[types[i]] = TRUE;
+ writetype[types[i]] = true;
/*
** For America/Godthab and Antarctica/Palmer
*/
if (thistimei == 0)
- writetype[0] = TRUE;
+ writetype[0] = true;
}
#ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
/*
@@ -1564,11 +1823,11 @@
isdsts[mrudst] = -1;
type = addtype(gmtoffs[mrudst],
&chars[abbrinds[mrudst]],
- TRUE,
+ true,
ttisstds[mrudst],
ttisgmts[mrudst]);
- isdsts[mrudst] = TRUE;
- writetype[type] = TRUE;
+ isdsts[mrudst] = 1;
+ writetype[type] = true;
}
if (histd >= 0 && mrustd >= 0 && histd != mrustd &&
gmtoffs[histd] != gmtoffs[mrustd]) {
@@ -1575,11 +1834,11 @@
isdsts[mrustd] = -1;
type = addtype(gmtoffs[mrustd],
&chars[abbrinds[mrustd]],
- FALSE,
+ false,
ttisstds[mrustd],
ttisgmts[mrustd]);
- isdsts[mrustd] = FALSE;
- writetype[type] = TRUE;
+ isdsts[mrustd] = 0;
+ writetype[type] = true;
}
}
#endif /* !defined LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */
@@ -1601,22 +1860,22 @@
if (strcmp(&thischars[j], thisabbr) == 0)
break;
if (j == thischarcnt) {
- (void) strcpy(&thischars[(int) thischarcnt],
+ strcpy(&thischars[(int) thischarcnt],
thisabbr);
thischarcnt += strlen(thisabbr) + 1;
}
indmap[abbrinds[i]] = j;
}
-#define DO(field) ((void) fwrite(tzh.field, sizeof tzh.field, 1, fp))
+#define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp)
tzh = tzh0;
- (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
- tzh.tzh_version[0] = ZIC_VERSION;
- convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt);
- convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt);
- convert(eitol(thisleapcnt), tzh.tzh_leapcnt);
- convert(eitol(thistimecnt), tzh.tzh_timecnt);
- convert(eitol(thistypecnt), tzh.tzh_typecnt);
- convert(eitol(thischarcnt), tzh.tzh_charcnt);
+ strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
+ tzh.tzh_version[0] = version;
+ convert(thistypecnt, tzh.tzh_ttisgmtcnt);
+ convert(thistypecnt, tzh.tzh_ttisstdcnt);
+ convert(thisleapcnt, tzh.tzh_leapcnt);
+ convert(thistimecnt, tzh.tzh_timecnt);
+ convert(thistypecnt, tzh.tzh_typecnt);
+ convert(thischarcnt, tzh.tzh_charcnt);
DO(tzh_magic);
DO(tzh_version);
DO(tzh_reserved);
@@ -1629,22 +1888,27 @@
#undef DO
for (i = thistimei; i < thistimelim; ++i)
if (pass == 1)
- puttzcode((long) ats[i], fp);
+ /*
+ ** Output an INT32_MIN "transition"
+ ** if appropriate; see above.
+ */
+ puttzcode(((ats[i] < INT32_MIN) ?
+ INT32_MIN : ats[i]), fp);
else puttzcode64(ats[i], fp);
for (i = thistimei; i < thistimelim; ++i) {
unsigned char uc;
uc = typemap[types[i]];
- (void) fwrite(&uc, sizeof uc, 1, fp);
+ fwrite(&uc, sizeof uc, 1, fp);
}
for (i = 0; i < typecnt; ++i)
if (writetype[i]) {
puttzcode(gmtoffs[i], fp);
- (void) putc(isdsts[i], fp);
- (void) putc((unsigned char) indmap[abbrinds[i]], fp);
+ putc(isdsts[i], fp);
+ putc((unsigned char) indmap[abbrinds[i]], fp);
}
if (thischarcnt != 0)
- (void) fwrite(thischars, sizeof thischars[0],
+ fwrite(thischars, sizeof thischars[0],
thischarcnt, fp);
for (i = thisleapi; i < thisleaplim; ++i) {
register zic_t todo;
@@ -1673,57 +1937,92 @@
}
for (i = 0; i < typecnt; ++i)
if (writetype[i])
- (void) putc(ttisstds[i], fp);
+ putc(ttisstds[i], fp);
for (i = 0; i < typecnt; ++i)
if (writetype[i])
- (void) putc(ttisgmts[i], fp);
+ putc(ttisgmts[i], fp);
}
- (void) fprintf(fp, "\n%s\n", string);
- if (ferror(fp) || fclose(fp)) {
- (void) fprintf(stderr, _("%s: Error writing %s\n"),
- progname, fullname);
- exit(EXIT_FAILURE);
- }
+ fprintf(fp, "\n%s\n", string);
+ close_file(fp, fullname);
+ free(ats);
+ free(fullname);
}
-static void
-doabbr(char *const abbr, const char *const format, const char *const letters,
- const int isdst, const int doquotes)
+static char const *
+abbroffset(char *buf, zic_t offset)
{
+ char sign = '+';
+ int seconds, minutes;
+
+ if (offset < 0) {
+ offset = -offset;
+ sign = '-';
+ }
+
+ seconds = offset % SECSPERMIN;
+ offset /= SECSPERMIN;
+ minutes = offset % MINSPERHOUR;
+ offset /= MINSPERHOUR;
+ if (100 <= offset) {
+ error(_("%%z UTC offset magnitude exceeds 99:59:59"));
+ return "%z";
+ } else {
+ char *p = buf;
+ *p++ = sign;
+ *p++ = '0' + offset / 10;
+ *p++ = '0' + offset % 10;
+ if (minutes | seconds) {
+ *p++ = '0' + minutes / 10;
+ *p++ = '0' + minutes % 10;
+ if (seconds) {
+ *p++ = '0' + seconds / 10;
+ *p++ = '0' + seconds % 10;
+ }
+ }
+ *p = '\0';
+ return buf;
+ }
+}
+
+static size_t
+doabbr(char *abbr, struct zone const *zp, char const *letters,
+ zic_t stdoff, bool doquotes)
+{
register char * cp;
register char * slashp;
- register int len;
+ register size_t len;
+ char const *format = zp->z_format;
slashp = strchr(format, '/');
if (slashp == NULL) {
- if (letters == NULL)
- (void) strcpy(abbr, format);
- else (void) sprintf(abbr, format, letters);
- } else if (isdst) {
- (void) strcpy(abbr, slashp + 1);
+ char letterbuf[PERCENT_Z_LEN_BOUND + 1];
+ if (zp->z_format_specifier == 'z')
+ letters = abbroffset(letterbuf, zp->z_gmtoff + stdoff);
+ else if (!letters)
+ letters = "%s";
+ sprintf(abbr, format, letters);
+ } else if (stdoff != 0) {
+ strcpy(abbr, slashp + 1);
} else {
- if (slashp > format)
- (void) strncpy(abbr, format, slashp - format);
+ memcpy(abbr, format, slashp - format);
abbr[slashp - format] = '\0';
}
+ len = strlen(abbr);
if (!doquotes)
- return;
- for (cp = abbr; *cp != '\0'; ++cp)
- if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL &&
- strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL)
- break;
- len = strlen(abbr);
+ return len;
+ for (cp = abbr; is_alpha(*cp); cp++)
+ continue;
if (len > 0 && *cp == '\0')
- return;
+ return len;
abbr[len + 2] = '\0';
abbr[len + 1] = '>';
- for ( ; len > 0; --len)
- abbr[len] = abbr[len - 1];
+ memmove(abbr + 1, abbr, len);
abbr[0] = '<';
+ return len + 2;
}
static void
-updateminmax(const int x)
+updateminmax(const zic_t x)
{
if (min_year > x)
min_year = x;
@@ -1732,16 +2031,17 @@
}
static int
-stringoffset(char *result, long offset)
+stringoffset(char *result, zic_t offset)
{
register int hours;
register int minutes;
register int seconds;
+ bool negative = offset < 0;
+ int len = negative;
- result[0] = '\0';
- if (offset < 0) {
- (void) strcpy(result, "-");
+ if (negative) {
offset = -offset;
+ result[0] = '-';
}
seconds = offset % SECSPERMIN;
offset /= SECSPERMIN;
@@ -1748,26 +2048,26 @@
minutes = offset % MINSPERHOUR;
offset /= MINSPERHOUR;
hours = offset;
- if (hours >= HOURSPERDAY) {
+ if (hours >= HOURSPERDAY * DAYSPERWEEK) {
result[0] = '\0';
- return -1;
+ return 0;
}
- (void) sprintf(end(result), "%d", hours);
+ len += sprintf(result + len, "%d", hours);
if (minutes != 0 || seconds != 0) {
- (void) sprintf(end(result), ":%02d", minutes);
+ len += sprintf(result + len, ":%02d", minutes);
if (seconds != 0)
- (void) sprintf(end(result), ":%02d", seconds);
+ len += sprintf(result + len, ":%02d", seconds);
}
- return 0;
+ return len;
}
static int
-stringrule(char *result, const struct rule *const rp, const long dstoff,
- const long gmtoff)
+stringrule(char *result, const struct rule *const rp, const zic_t dstoff,
+ const zic_t gmtoff)
{
- register long tod;
+ register zic_t tod = rp->r_tod;
+ register int compat = 0;
- result = end(result);
if (rp->r_dycode == DC_DOM) {
register int month, total;
@@ -1776,44 +2076,76 @@
total = 0;
for (month = 0; month < rp->r_month; ++month)
total += len_months[0][month];
- (void) sprintf(result, "J%d", total + rp->r_dayofmonth);
+ /* Omit the "J" in Jan and Feb, as that's shorter. */
+ if (rp->r_month <= 1)
+ result += sprintf(result, "%d", total + rp->r_dayofmonth - 1);
+ else
+ result += sprintf(result, "J%d", total + rp->r_dayofmonth);
} else {
register int week;
+ register int wday = rp->r_wday;
+ register int wdayoff;
if (rp->r_dycode == DC_DOWGEQ) {
- if ((rp->r_dayofmonth % DAYSPERWEEK) != 1)
- return -1;
- week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
+ wdayoff = (rp->r_dayofmonth - 1) % DAYSPERWEEK;
+ if (wdayoff)
+ compat = 2013;
+ wday -= wdayoff;
+ tod += wdayoff * SECSPERDAY;
+ week = 1 + (rp->r_dayofmonth - 1) / DAYSPERWEEK;
} else if (rp->r_dycode == DC_DOWLEQ) {
if (rp->r_dayofmonth == len_months[1][rp->r_month])
week = 5;
else {
- if ((rp->r_dayofmonth % DAYSPERWEEK) != 0)
- return -1;
+ wdayoff = rp->r_dayofmonth % DAYSPERWEEK;
+ if (wdayoff)
+ compat = 2013;
+ wday -= wdayoff;
+ tod += wdayoff * SECSPERDAY;
week = rp->r_dayofmonth / DAYSPERWEEK;
}
} else return -1; /* "cannot happen" */
- (void) sprintf(result, "M%d.%d.%d",
- rp->r_month + 1, week, rp->r_wday);
+ if (wday < 0)
+ wday += DAYSPERWEEK;
+ result += sprintf(result, "M%d.%d.%d",
+ rp->r_month + 1, week, wday);
}
- tod = rp->r_tod;
if (rp->r_todisgmt)
tod += gmtoff;
if (rp->r_todisstd && rp->r_stdoff == 0)
tod += dstoff;
- if (tod < 0) {
- result[0] = '\0';
- return -1;
- }
if (tod != 2 * SECSPERMIN * MINSPERHOUR) {
- (void) strcat(result, "/");
- if (stringoffset(end(result), tod) != 0)
+ *result++ = '/';
+ if (! stringoffset(result, tod))
return -1;
+ if (tod < 0) {
+ if (compat < 2013)
+ compat = 2013;
+ } else if (SECSPERDAY <= tod) {
+ if (compat < 1994)
+ compat = 1994;
+ }
}
- return 0;
+ return compat;
}
-static void
+static int
+rule_cmp(struct rule const *a, struct rule const *b)
+{
+ if (!a)
+ return -!!b;
+ if (!b)
+ return 1;
+ if (a->r_hiyear != b->r_hiyear)
+ return a->r_hiyear < b->r_hiyear ? -1 : 1;
+ if (a->r_month - b->r_month != 0)
+ return a->r_month - b->r_month;
+ return a->r_dayofmonth - b->r_dayofmonth;
+}
+
+enum { YEAR_BY_YEAR_ZONE = 1 };
+
+static int
stringzone(char *result, const struct zone *const zpfirst, const int zonecount)
{
register const struct zone * zp;
@@ -1822,6 +2154,11 @@
register struct rule * dstrp;
register int i;
register const char * abbrvar;
+ register int compat = 0;
+ register int c;
+ size_t len;
+ int offsetlen;
+ struct rule stdr, dstr;
result[0] = '\0';
zp = zpfirst + zonecount - 1;
@@ -1828,7 +2165,7 @@
stdrp = dstrp = NULL;
for (i = 0; i < zp->z_nrules; ++i) {
rp = &zp->z_rules[i];
- if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX)
+ if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
continue;
if (rp->r_yrtype != NULL)
continue;
@@ -1835,27 +2172,27 @@
if (rp->r_stdoff == 0) {
if (stdrp == NULL)
stdrp = rp;
- else return;
+ else return -1;
} else {
if (dstrp == NULL)
dstrp = rp;
- else return;
+ else return -1;
}
}
if (stdrp == NULL && dstrp == NULL) {
/*
** There are no rules running through "max".
- ** Let's find the latest rule.
+ ** Find the latest std rule in stdabbrrp
+ ** and latest rule of any type in stdrp.
*/
+ register struct rule *stdabbrrp = NULL;
for (i = 0; i < zp->z_nrules; ++i) {
rp = &zp->z_rules[i];
- if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear ||
- (rp->r_hiyear == stdrp->r_hiyear &&
- rp->r_month > stdrp->r_month))
- stdrp = rp;
+ if (rp->r_stdoff == 0 && rule_cmp(stdabbrrp, rp) < 0)
+ stdabbrrp = rp;
+ if (rule_cmp(stdrp, rp) < 0)
+ stdrp = rp;
}
- if (stdrp != NULL && stdrp->r_stdoff != 0)
- return; /* We end up in DST (a POSIX no-no). */
/*
** Horrid special case: if year is 2037,
** presume this is a zone handled on a year-by-year basis;
@@ -1862,51 +2199,85 @@
** do not try to apply a rule to the zone.
*/
if (stdrp != NULL && stdrp->r_hiyear == 2037)
- return;
+ return YEAR_BY_YEAR_ZONE;
+
+ if (stdrp != NULL && stdrp->r_stdoff != 0) {
+ /* Perpetual DST. */
+ dstr.r_month = TM_JANUARY;
+ dstr.r_dycode = DC_DOM;
+ dstr.r_dayofmonth = 1;
+ dstr.r_tod = 0;
+ dstr.r_todisstd = dstr.r_todisgmt = false;
+ dstr.r_stdoff = stdrp->r_stdoff;
+ dstr.r_abbrvar = stdrp->r_abbrvar;
+ stdr.r_month = TM_DECEMBER;
+ stdr.r_dycode = DC_DOM;
+ stdr.r_dayofmonth = 31;
+ stdr.r_tod = SECSPERDAY + stdrp->r_stdoff;
+ stdr.r_todisstd = stdr.r_todisgmt = false;
+ stdr.r_stdoff = 0;
+ stdr.r_abbrvar
+ = (stdabbrrp ? stdabbrrp->r_abbrvar : "");
+ dstrp = &dstr;
+ stdrp = &stdr;
+ }
}
if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_stdoff != 0))
- return;
+ return -1;
abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
- doabbr(result, zp->z_format, abbrvar, FALSE, TRUE);
- if (stringoffset(end(result), -zp->z_gmtoff) != 0) {
+ len = doabbr(result, zp, abbrvar, 0, true);
+ offsetlen = stringoffset(result + len, -zp->z_gmtoff);
+ if (! offsetlen) {
result[0] = '\0';
- return;
+ return -1;
}
+ len += offsetlen;
if (dstrp == NULL)
- return;
- doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE);
- if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR)
- if (stringoffset(end(result),
- -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) {
- result[0] = '\0';
- return;
- }
- (void) strcat(result, ",");
- if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
+ return compat;
+ len += doabbr(result + len, zp, dstrp->r_abbrvar, dstrp->r_stdoff, true);
+ if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) {
+ offsetlen = stringoffset(result + len,
+ -(zp->z_gmtoff + dstrp->r_stdoff));
+ if (! offsetlen) {
+ result[0] = '\0';
+ return -1;
+ }
+ len += offsetlen;
+ }
+ result[len++] = ',';
+ c = stringrule(result + len, dstrp, dstrp->r_stdoff, zp->z_gmtoff);
+ if (c < 0) {
result[0] = '\0';
- return;
+ return -1;
}
- (void) strcat(result, ",");
- if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
+ if (compat < c)
+ compat = c;
+ len += strlen(result + len);
+ result[len++] = ',';
+ c = stringrule(result + len, stdrp, dstrp->r_stdoff, zp->z_gmtoff);
+ if (c < 0) {
result[0] = '\0';
- return;
+ return -1;
}
+ if (compat < c)
+ compat = c;
+ return compat;
}
static void
-outzone(const struct zone * const zpfirst, const int zonecount)
+outzone(const struct zone *zpfirst, int zonecount)
{
register const struct zone * zp;
register struct rule * rp;
register int i, j;
- register int usestart, useuntil;
+ register bool usestart, useuntil;
register zic_t starttime, untiltime;
- register long gmtoff;
- register long stdoff;
- register int year;
- register long startoff;
- register int startttisstd;
- register int startttisgmt;
+ register zic_t gmtoff;
+ register zic_t stdoff;
+ register zic_t year;
+ register zic_t startoff;
+ register bool startttisstd;
+ register bool startttisgmt;
register int type;
register char * startbuf;
register char * ab;
@@ -1913,7 +2284,10 @@
register char * envvar;
register int max_abbr_len;
register int max_envvar_len;
- register int prodstic; /* all rules are min to max */
+ register bool prodstic; /* all rules are min to max */
+ register int compat;
+ register bool do_extend;
+ register char version;
max_abbr_len = 2 + max_format_len + max_abbrvar_len;
max_envvar_len = 2 * max_abbr_len + 5 * 9;
@@ -1933,12 +2307,12 @@
** Thanks to Earl Chew
** for noting the need to unconditionally initialize startttisstd.
*/
- startttisstd = FALSE;
- startttisgmt = FALSE;
+ startttisstd = false;
+ startttisgmt = false;
min_year = max_year = EPOCH_YEAR;
if (leapseen) {
updateminmax(leapminyear);
- updateminmax(leapmaxyear + (leapmaxyear < INT_MAX));
+ updateminmax(leapmaxyear + (leapmaxyear < ZIC_MAX));
}
for (i = 0; i < zonecount; ++i) {
zp = &zpfirst[i];
@@ -1951,30 +2325,52 @@
if (rp->r_hiwasnum)
updateminmax(rp->r_hiyear);
if (rp->r_lowasnum || rp->r_hiwasnum)
- prodstic = FALSE;
+ prodstic = false;
}
}
/*
** Generate lots of data if a rule can't cover all future times.
*/
- stringzone(envvar, zpfirst, zonecount);
- if (noise && envvar[0] == '\0') {
- register char * wp;
-
-wp = ecpyalloc(_("no POSIX environment variable for zone"));
- wp = ecatalloc(wp, " ");
- wp = ecatalloc(wp, zpfirst->z_name);
- warning(wp);
- free(wp);
+ compat = stringzone(envvar, zpfirst, zonecount);
+ version = compat < 2013 ? ZIC_VERSION_PRE_2013 : ZIC_VERSION;
+ do_extend = compat < 0 || compat == YEAR_BY_YEAR_ZONE;
+ if (noise) {
+ if (!*envvar)
+ warning("%s %s",
+ _("no POSIX environment variable for zone"),
+ zpfirst->z_name);
+ else if (compat != 0 && compat != YEAR_BY_YEAR_ZONE) {
+ /* Circa-COMPAT clients, and earlier clients, might
+ not work for this zone when given dates before
+ 1970 or after 2038. */
+ warning(_("%s: pre-%d clients may mishandle"
+ " distant timestamps"),
+ zpfirst->z_name, compat);
+ }
}
- if (envvar[0] == '\0') {
- if (min_year >= INT_MIN + YEARSPERREPEAT)
- min_year -= YEARSPERREPEAT;
- else min_year = INT_MIN;
- if (max_year <= INT_MAX - YEARSPERREPEAT)
- max_year += YEARSPERREPEAT;
- else max_year = INT_MAX;
+ if (do_extend) {
/*
+ ** Search through a couple of extra years past the obvious
+ ** 400, to avoid edge cases. For example, suppose a non-POSIX
+ ** rule applies from 2012 onwards and has transitions in March
+ ** and September, plus some one-off transitions in November
+ ** 2013. If zic looked only at the last 400 years, it would
+ ** set max_year=2413, with the intent that the 400 years 2014
+ ** through 2413 will be repeated. The last transition listed
+ ** in the tzfile would be in 2413-09, less than 400 years
+ ** after the last one-off transition in 2013-11. Two years
+ ** might be overkill, but with the kind of edge cases
+ ** available we're not sure that one year would suffice.
+ */
+ enum { years_of_observations = YEARSPERREPEAT + 2 };
+
+ if (min_year >= ZIC_MIN + years_of_observations)
+ min_year -= years_of_observations;
+ else min_year = ZIC_MIN;
+ if (max_year <= ZIC_MAX - years_of_observations)
+ max_year += years_of_observations;
+ else max_year = ZIC_MAX;
+ /*
** Regardless of any of the above,
** for a "proDSTic" zone which specifies that its rules
** always have and always will be in effect,
@@ -1982,7 +2378,7 @@
*/
if (prodstic) {
min_year = 1900;
- max_year = min_year + YEARSPERREPEAT;
+ max_year = min_year + years_of_observations;
}
}
/*
@@ -1999,9 +2395,9 @@
*/
stdoff = 0;
zp = &zpfirst[i];
- usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
+ usestart = i > 0 && (zp - 1)->z_untiltime > early_time;
useuntil = i < (zonecount - 1);
- if (useuntil && zp->z_untiltime <= min_time)
+ if (useuntil && zp->z_untiltime <= early_time)
continue;
gmtoff = zp->z_gmtoff;
eat(zp->z_filename, zp->z_linenum);
@@ -2009,16 +2405,14 @@
startoff = zp->z_gmtoff;
if (zp->z_nrules == 0) {
stdoff = zp->z_stdoff;
- doabbr(startbuf, zp->z_format,
- NULL, stdoff != 0, FALSE);
+ doabbr(startbuf, zp, NULL, stdoff, false);
type = addtype(oadd(zp->z_gmtoff, stdoff),
startbuf, stdoff != 0, startttisstd,
startttisgmt);
if (usestart) {
addtt(starttime, type);
- usestart = FALSE;
- } else if (stdoff != 0)
- addtt(min_time, type);
+ usestart = false;
+ } else addtt(early_time, type);
} else for (year = min_year; year <= max_year; ++year) {
if (useuntil && year > zp->z_untilrule.r_hiyear)
break;
@@ -2039,12 +2433,12 @@
for ( ; ; ) {
register int k;
register zic_t jtime, ktime;
- register long offset;
+ register zic_t offset;
INITIALIZE(ktime);
if (useuntil) {
/*
- ** Turn untiltime into UTC
+ ** Turn untiltime into UT
** assuming the current gmtoff and
** stdoff values.
*/
@@ -2078,25 +2472,35 @@
if (k < 0 || jtime < ktime) {
k = j;
ktime = jtime;
+ } else if (jtime == ktime) {
+ char const *dup_rules_msg =
+ _("two rules for same instant");
+ eats(zp->z_filename, zp->z_linenum,
+ rp->r_filename, rp->r_linenum);
+ warning("%s", dup_rules_msg);
+ rp = &zp->z_rules[k];
+ eats(zp->z_filename, zp->z_linenum,
+ rp->r_filename, rp->r_linenum);
+ error("%s", dup_rules_msg);
}
}
if (k < 0)
break; /* go on to next year */
rp = &zp->z_rules[k];
- rp->r_todo = FALSE;
+ rp->r_todo = false;
if (useuntil && ktime >= untiltime)
break;
stdoff = rp->r_stdoff;
if (usestart && ktime == starttime)
- usestart = FALSE;
+ usestart = false;
if (usestart) {
if (ktime < starttime) {
startoff = oadd(zp->z_gmtoff,
stdoff);
- doabbr(startbuf, zp->z_format,
+ doabbr(startbuf, zp,
rp->r_abbrvar,
- rp->r_stdoff != 0,
- FALSE);
+ rp->r_stdoff,
+ false);
continue;
}
if (*startbuf == '\0' &&
@@ -2103,17 +2507,16 @@
startoff == oadd(zp->z_gmtoff,
stdoff)) {
doabbr(startbuf,
- zp->z_format,
+ zp,
rp->r_abbrvar,
- rp->r_stdoff !=
- 0,
- FALSE);
+ rp->r_stdoff,
+ false);
}
}
eats(zp->z_filename, zp->z_linenum,
rp->r_filename, rp->r_linenum);
- doabbr(ab, zp->z_format, rp->r_abbrvar,
- rp->r_stdoff != 0, FALSE);
+ doabbr(ab, zp, rp->r_abbrvar,
+ rp->r_stdoff, false);
offset = oadd(zp->z_gmtoff, rp->r_stdoff);
type = addtype(offset, ab, rp->r_stdoff != 0,
rp->r_todisstd, rp->r_todisgmt);
@@ -2125,7 +2528,7 @@
zp->z_format != NULL &&
strchr(zp->z_format, '%') == NULL &&
strchr(zp->z_format, '/') == NULL)
- (void) strcpy(startbuf, zp->z_format);
+ strcpy(startbuf, zp->z_format);
eat(zp->z_filename, zp->z_linenum);
if (*startbuf == '\0')
error(_("can't determine time zone abbreviation to use just after until time"));
@@ -2148,7 +2551,45 @@
starttime = tadd(starttime, -gmtoff);
}
}
- writezone(zpfirst->z_name, envvar);
+ if (do_extend) {
+ /*
+ ** If we're extending the explicitly listed observations
+ ** for 400 years because we can't fill the POSIX-TZ field,
+ ** check whether we actually ended up explicitly listing
+ ** observations through that period. If there aren't any
+ ** near the end of the 400-year period, add a redundant
+ ** one at the end of the final year, to make it clear
+ ** that we are claiming to have definite knowledge of
+ ** the lack of transitions up to that point.
+ */
+ struct rule xr;
+ struct attype *lastat;
+ xr.r_month = TM_JANUARY;
+ xr.r_dycode = DC_DOM;
+ xr.r_dayofmonth = 1;
+ xr.r_tod = 0;
+ for (lastat = &attypes[0], i = 1; i < timecnt; i++)
+ if (attypes[i].at > lastat->at)
+ lastat = &attypes[i];
+ if (lastat->at < rpytime(&xr, max_year - 1)) {
+ /*
+ ** Create new type code for the redundant entry,
+ ** to prevent it being optimized away.
+ */
+ if (typecnt >= TZ_MAX_TYPES) {
+ error(_("too many local time types"));
+ exit(EXIT_FAILURE);
+ }
+ gmtoffs[typecnt] = gmtoffs[lastat->type];
+ isdsts[typecnt] = isdsts[lastat->type];
+ ttisstds[typecnt] = ttisstds[lastat->type];
+ ttisgmts[typecnt] = ttisgmts[lastat->type];
+ abbrinds[typecnt] = abbrinds[lastat->type];
+ ++typecnt;
+ addtt(rpytime(&xr, max_year + 1), typecnt-1);
+ }
+ }
+ writezone(zpfirst->z_name, envvar, version);
free(startbuf);
free(ab);
free(envvar);
@@ -2155,16 +2596,16 @@
}
static void
-addtt(const zic_t starttime, int type)
+addtt(zic_t starttime, int type)
{
- if (starttime <= min_time ||
- (timecnt == 1 && attypes[0].at < min_time)) {
+ if (starttime <= early_time
+ || (timecnt == 1 && attypes[0].at < early_time)) {
gmtoffs[0] = gmtoffs[type];
isdsts[0] = isdsts[type];
ttisstds[0] = ttisstds[type];
ttisgmts[0] = ttisgmts[type];
if (abbrinds[type] != 0)
- (void) strcpy(chars, &chars[abbrinds[type]]);
+ strcpy(chars, &chars[abbrinds[type]]);
abbrinds[0] = 0;
charcnt = strlen(chars) + 1;
typecnt = 1;
@@ -2171,10 +2612,7 @@
timecnt = 0;
type = 0;
}
- if (timecnt >= TZ_MAX_TIMES) {
- error(_("too many transitions?!"));
- exit(EXIT_FAILURE);
- }
+ attypes = growalloc(attypes, sizeof *attypes, timecnt, &timecnt_alloc);
attypes[timecnt].at = starttime;
attypes[timecnt].type = type;
++timecnt;
@@ -2181,23 +2619,10 @@
}
static int
-addtype(const long gmtoff, const char *const abbr, const int isdst,
- const int ttisstd, const int ttisgmt)
+addtype(zic_t gmtoff, char const *abbr, bool isdst, bool ttisstd, bool ttisgmt)
{
register int i, j;
- if (isdst != TRUE && isdst != FALSE) {
- error(_("internal error - addtype called with bad isdst"));
- exit(EXIT_FAILURE);
- }
- if (ttisstd != TRUE && ttisstd != FALSE) {
- error(_("internal error - addtype called with bad ttisstd"));
- exit(EXIT_FAILURE);
- }
- if (ttisgmt != TRUE && ttisgmt != FALSE) {
- error(_("internal error - addtype called with bad ttisgmt"));
- exit(EXIT_FAILURE);
- }
/*
** See if there's already an entry for this zone type.
** If so, just return its index.
@@ -2218,7 +2643,7 @@
exit(EXIT_FAILURE);
}
if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) {
- error(_("UTC offset out of range"));
+ error(_("UT offset out of range"));
exit(EXIT_FAILURE);
}
gmtoffs[i] = gmtoff;
@@ -2237,7 +2662,7 @@
}
static void
-leapadd(const zic_t t, const int positive, const int rolling, int count)
+leapadd(zic_t t, bool positive, int rolling, int count)
{
register int i, j;
@@ -2260,7 +2685,7 @@
roll[j] = roll[j - 1];
}
trans[i] = t;
- corr[i] = positive ? 1L : eitol(-count);
+ corr[i] = positive ? 1 : -count;
roll[i] = rolling;
++leapcnt;
} while (positive && --count != 0);
@@ -2270,7 +2695,7 @@
adjleap(void)
{
register int i;
- register long last = 0;
+ register zic_t last = 0;
/*
** propagate leap seconds forward
@@ -2281,64 +2706,106 @@
}
}
-static int
-yearistype(const int year, const char *const type)
+static bool
+yearistype(int year, const char *type)
{
static char * buf;
int result;
if (type == NULL || *type == '\0')
- return TRUE;
+ return true;
buf = erealloc(buf, 132 + strlen(yitcommand) + strlen(type));
- (void) sprintf(buf, "%s %d %s", yitcommand, year, type);
+ sprintf(buf, "%s %d %s", yitcommand, year, type);
result = system(buf);
if (WIFEXITED(result)) switch (WEXITSTATUS(result)) {
case 0:
- return TRUE;
+ return true;
case 1:
- return FALSE;
+ return false;
}
error(_("Wild result from command execution"));
- (void) fprintf(stderr, _("%s: command was '%s', result was %d\n"),
+ fprintf(stderr, _("%s: command was '%s', result was %d\n"),
progname, buf, result);
for ( ; ; )
exit(EXIT_FAILURE);
}
-static int
-lowerit(int a)
+/* Is A a space character in the C locale? */
+static bool
+is_space(char a)
{
- a = (unsigned char) a;
- return (isascii(a) && isupper(a)) ? tolower(a) : a;
+ switch (a) {
+ default:
+ return false;
+ case ' ': case '\f': case '\n': case '\r': case '\t': case '\v':
+ return true;
+ }
}
+/* Is A an alphabetic character in the C locale? */
+static bool
+is_alpha(char a)
+{
+ switch (a) {
+ default:
+ return false;
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+ case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+ case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+ case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z':
+ return true;
+ }
+}
+
+/* If A is an uppercase character in the C locale, return its lowercase
+ counterpart. Otherwise, return A. */
+static char
+lowerit(char a)
+{
+ switch (a) {
+ default: return a;
+ case 'A': return 'a'; case 'B': return 'b'; case 'C': return 'c';
+ case 'D': return 'd'; case 'E': return 'e'; case 'F': return 'f';
+ case 'G': return 'g'; case 'H': return 'h'; case 'I': return 'i';
+ case 'J': return 'j'; case 'K': return 'k'; case 'L': return 'l';
+ case 'M': return 'm'; case 'N': return 'n'; case 'O': return 'o';
+ case 'P': return 'p'; case 'Q': return 'q'; case 'R': return 'r';
+ case 'S': return 's'; case 'T': return 't'; case 'U': return 'u';
+ case 'V': return 'v'; case 'W': return 'w'; case 'X': return 'x';
+ case 'Y': return 'y'; case 'Z': return 'z';
+ }
+}
+
/* case-insensitive equality */
-static ATTRIBUTE_PURE int
+static ATTRIBUTE_PURE bool
ciequal(register const char *ap, register const char *bp)
{
while (lowerit(*ap) == lowerit(*bp++))
if (*ap++ == '\0')
- return TRUE;
- return FALSE;
+ return true;
+ return false;
}
-static ATTRIBUTE_PURE int
+static ATTRIBUTE_PURE bool
itsabbr(register const char *abbr, register const char *word)
{
if (lowerit(*abbr) != lowerit(*word))
- return FALSE;
+ return false;
++word;
while (*++abbr != '\0')
do {
if (*word == '\0')
- return FALSE;
+ return false;
} while (lowerit(*word++) != lowerit(*abbr));
- return TRUE;
+ return true;
}
static ATTRIBUTE_PURE const struct lookup *
-byword(register const char *const word,
- register const struct lookup *const table)
+byword(const char *word, const struct lookup *table)
{
register const struct lookup * foundlp;
register const struct lookup * lp;
@@ -2373,11 +2840,10 @@
if (cp == NULL)
return NULL;
- array = emalloc((strlen(cp) + 1) * sizeof *array);
+ array = emalloc(size_product(strlen(cp) + 1, sizeof *array));
nsubs = 0;
for ( ; ; ) {
- while (isascii((unsigned char) *cp) &&
- isspace((unsigned char) *cp))
+ while (is_space(*cp))
++cp;
if (*cp == '\0' || *cp == '#')
break;
@@ -2394,9 +2860,8 @@
));
exit(1);
}
- } while (*cp != '\0' && *cp != '#' &&
- (!isascii(*cp) || !isspace((unsigned char) *cp)));
- if (isascii(*cp) && isspace((unsigned char) *cp))
+ } while (*cp && *cp != '#' && !is_space(*cp));
+ if (is_space(*cp))
++cp;
*dp = '\0';
}
@@ -2404,45 +2869,55 @@
return array;
}
-static ATTRIBUTE_PURE long
-oadd(const long t1, const long t2)
+static _Noreturn void
+time_overflow(void)
{
- if (t1 < 0 ? t2 < LONG_MIN - t1 : LONG_MAX - t1 < t2) {
- error(_("time overflow"));
- exit(EXIT_FAILURE);
- }
- return t1 + t2;
+ error(_("time overflow"));
+ exit(EXIT_FAILURE);
}
static ATTRIBUTE_PURE zic_t
-tadd(const zic_t t1, const long t2)
+oadd(zic_t t1, zic_t t2)
{
- if (t1 == max_time && t2 > 0)
- return max_time;
- if (t1 == min_time && t2 < 0)
- return min_time;
- if (t1 < 0 ? t2 < min_time - t1 : max_time - t1 < t2) {
- error(_("time overflow"));
- exit(EXIT_FAILURE);
- }
+ if (t1 < 0 ? t2 < ZIC_MIN - t1 : ZIC_MAX - t1 < t2)
+ time_overflow();
return t1 + t2;
}
+static ATTRIBUTE_PURE zic_t
+tadd(zic_t t1, zic_t t2)
+{
+ if (t1 < 0) {
+ if (t2 < min_time - t1) {
+ if (t1 != min_time)
+ time_overflow();
+ return min_time;
+ }
+ } else {
+ if (max_time - t1 < t2) {
+ if (t1 != max_time)
+ time_overflow();
+ return max_time;
+ }
+ }
+ return t1 + t2;
+}
+
/*
-** 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.
+** 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 zic_t
-rpytime(register const struct rule *const rp, register const int wantedy)
+rpytime(const struct rule *rp, zic_t wantedy)
{
- register int y, m, i;
- register long dayoff; /* with a nod to Margaret O. */
- register zic_t t;
+ register int m, i;
+ register zic_t dayoff; /* with a nod to Margaret O. */
+ register zic_t t, y;
- if (wantedy == INT_MIN)
+ if (wantedy == ZIC_MIN)
return min_time;
- if (wantedy == INT_MAX)
+ if (wantedy == ZIC_MAX)
return max_time;
dayoff = 0;
m = TM_JANUARY;
@@ -2455,11 +2930,11 @@
--y;
i = -len_years[isleap(y)];
}
- dayoff = oadd(dayoff, eitol(i));
+ dayoff = oadd(dayoff, i);
}
while (m != rp->r_month) {
i = len_months[isleap(y)][m];
- dayoff = oadd(dayoff, eitol(i));
+ dayoff = oadd(dayoff, i);
++m;
}
i = rp->r_dayofmonth;
@@ -2472,12 +2947,12 @@
}
}
--i;
- dayoff = oadd(dayoff, eitol(i));
+ dayoff = oadd(dayoff, i);
if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
- register long wday;
+ register zic_t wday;
-#define LDAYSPERWEEK ((long) DAYSPERWEEK)
- wday = eitol(EPOCH_WDAY);
+#define LDAYSPERWEEK ((zic_t) DAYSPERWEEK)
+ wday = EPOCH_WDAY;
/*
** Don't trust mod of negative numbers.
*/
@@ -2488,7 +2963,7 @@
if (wday < 0)
wday += LDAYSPERWEEK;
}
- while (wday != eitol(rp->r_wday))
+ while (wday != rp->r_wday)
if (rp->r_dycode == DC_DOWGEQ) {
dayoff = oadd(dayoff, 1);
if (++wday >= LDAYSPERWEEK)
@@ -2502,7 +2977,7 @@
}
if (i < 0 || i >= len_months[isleap(y)][m]) {
if (noise)
- warning(_("rule goes past start/end of month--\
+ warning(_("rule goes past start/end of month; \
will not work with pre-2004 versions of zic"));
}
}
@@ -2515,7 +2990,7 @@
}
static void
-newabbr(const char *const string)
+newabbr(const char *string)
{
register int i;
@@ -2523,39 +2998,19 @@
register const char * cp;
const char * mp;
- /*
- ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics
- ** optionally followed by a + or - and a number from 1 to 14.
- */
cp = string;
mp = NULL;
- while (isascii((unsigned char) *cp) &&
- isalpha((unsigned char) *cp))
+ while (is_alpha(*cp) || ('0' <= *cp && *cp <= '9')
+ || *cp == '-' || *cp == '+')
++cp;
- if (cp - string == 0)
-mp = _("time zone abbreviation lacks alphabetic at start");
if (noise && cp - string < 3)
-mp = _("time zone abbreviation has fewer than 3 alphabetics");
+ mp = _("time zone abbreviation has fewer than 3 characters");
if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
-mp = _("time zone abbreviation has too many alphabetics");
- if (mp == NULL && (*cp == '+' || *cp == '-')) {
- ++cp;
- if (isascii((unsigned char) *cp) &&
- isdigit((unsigned char) *cp))
- if (*cp++ == '1' &&
- *cp >= '0' && *cp <= '4')
- ++cp;
- }
+ mp = _("time zone abbreviation has too many characters");
if (*cp != '\0')
mp = _("time zone abbreviation differs from POSIX standard");
- if (mp != NULL) {
- char *wp = ecpyalloc(mp);
- wp = ecatalloc(wp, " (");
- wp = ecatalloc(wp, string);
- wp = ecatalloc(wp, ")");
- warning(wp);
- free(wp);
- }
+ if (mp != NULL)
+ warning("%s (%s)", mp, string);
}
i = strlen(string) + 1;
if (charcnt + i > TZ_MAX_CHARS) {
@@ -2562,11 +3017,11 @@
error(_("too many, or too long, time zone abbreviations"));
exit(EXIT_FAILURE);
}
- (void) strcpy(&chars[charcnt], string);
- charcnt += eitol(i);
+ strcpy(&chars[charcnt], string);
+ charcnt += i;
}
-static int
+static bool
mkdirs(char *argname)
{
register char * name;
@@ -2573,60 +3028,37 @@
register char * cp;
if (argname == NULL || *argname == '\0')
- return 0;
+ return true;
cp = name = ecpyalloc(argname);
while ((cp = strchr(cp + 1, '/')) != 0) {
*cp = '\0';
-#ifndef unix
+#ifdef HAVE_DOS_FILE_NAMES
/*
** DOS drive specifier?
*/
- if (isalpha((unsigned char) name[0]) &&
- name[1] == ':' && name[2] == '\0') {
+ if (is_alpha(name[0]) && name[1] == ':' && name[2] == '\0') {
*cp = '/';
continue;
}
-#endif /* !defined unix */
- if (!itsdir(name)) {
- /*
- ** It doesn't seem to exist, so we try to create it.
- ** Creation may fail because of the directory being
- ** created by some other multiprocessor, so we get
- ** to do extra checking.
- */
- if (mkdir(name, MKDIR_UMASK) != 0) {
- const char *e = strerror(errno);
-
- if (errno != EEXIST || !itsdir(name)) {
- (void) fprintf(stderr,
-_("%s: Can't create directory %s: %s\n"),
- progname, name, e);
- free(name);
- return -1;
- }
+#endif
+ /*
+ ** Try to create it. It's OK if creation fails because
+ ** the directory already exists, perhaps because some
+ ** other process just created it.
+ */
+ if (mkdir(name, MKDIR_UMASK) != 0) {
+ int err = errno;
+ if (itsdir(name) <= 0) {
+ char const *e = strerror(err);
+ warning(_("%s: Can't create directory"
+ " %s: %s"),
+ progname, name, e);
+ free(name);
+ return false;
}
}
*cp = '/';
}
free(name);
- return 0;
+ return true;
}
-
-static ATTRIBUTE_PURE long
-eitol(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);
- exit(EXIT_FAILURE);
- }
- return l;
-}
-
-/*
-** UNIX was a registered trademark of The Open Group in 2003.
-*/
More information about the Midnightbsd-cvs
mailing list