" 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.
+
+Traditionally 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. Recent releases also come in an experimental format
+consisting of a single tarball tzdb-R.tar.lz with extra data.
+
+Release timestamps are taken from the release's commit (for newer,
+Git-based 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:
Index: vendor/tzdb/tzcode2018e/README
===================================================================
--- vendor/tzdb/tzcode2018e/README (nonexistent)
+++ vendor/tzdb/tzcode2018e/README (revision 337695)
@@ -0,0 +1,52 @@
+README for the tz distribution
+
+"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 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.
+
+See or the
+file tz-link.html for how to acquire the code and data. Once acquired,
+read the comments in the file 'Makefile' and make any changes needed
+to make things right for your system, especially if you are using some
+platform other than GNU/Linux. Then run the following commands,
+substituting your desired installation directory for "$HOME/tzdir":
+
+ make TOPDIR=$HOME/tzdir install
+ $HOME/tzdir/usr/bin/zdump -v America/Los_Angeles
+
+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 not 100% accurate;
+
+* give an idea of the variety of local time rules that have
+ existed in the past and thus an idea of the variety that may be
+ expected in the future;
+
+* provide a test of the generality of the local time rule description
+ system.
+
+The information in the time zone data files is by no means authoritative;
+fixes and enhancements are welcome. Please see the file CONTRIBUTING
+for details.
+
+Thanks to these Time Zone Caballeros who've made major contributions to the
+time conversion package: Keith Bostic; Bob Devine; Paul Eggert; Robert Elz;
+Guy Harris; Mark Horton; John Mackin; and Bradley White. Thanks also to
+Michael Bloom, Art Neilson, Stephen Prince, John Sovereign, and Frank Wales
+for testing work, and to Gwillim Law for checking local mean time data.
+Thanks in particular to Arthur David Olson, the project's founder and first
+maintainer, to whom the time zone community owes the greatest debt of all.
+None of them are responsible for remaining errors.
+
+-----
+
+This file is in the public domain, so clarified as of 2009-05-17 by
+Arthur David Olson. The other files in this distribution are either
+public domain or BSD licensed; see the file LICENSE for details.
Index: vendor/tzdb/tzcode2018e/asctime.c
===================================================================
--- vendor/tzdb/tzcode2018e/asctime.c (nonexistent)
+++ vendor/tzdb/tzcode2018e/asctime.c (revision 337695)
@@ -0,0 +1,122 @@
+/* asctime and asctime_r a la POSIX and ISO C, except pad years before 1000. */
+
+/*
+** This file is in the public domain, so clarified as of
+** 1996-06-05 by Arthur David Olson.
+*/
+
+/*
+** Avoid the temptation to punt entirely to strftime;
+** the output of strftime is supposed to be locale specific
+** whereas the output of asctime is supposed to be constant.
+*/
+
+/*LINTLIBRARY*/
+
+#include "private.h"
+#include
+
+/*
+** Some systems only handle "%.2d"; others only handle "%02d";
+** "%02.2d" makes (most) everybody happy.
+** At least some versions of gcc warn about the %02.2d;
+** we conditionalize below to avoid the warning.
+*/
+/*
+** All years associated with 32-bit time_t values are exactly four digits long;
+** some years associated with 64-bit time_t values are not.
+** Vintage programs are coded for years that are always four digits long
+** and may assume that the newline always lands in the same place.
+** For years that are less than four digits, we pad the output with
+** leading zeroes to get the newline in the traditional place.
+** The -4 ensures that we get four characters of output even if
+** we call a strftime variant that produces fewer characters for some years.
+** The ISO C and POSIX standards prohibit padding the year,
+** but many implementations pad anyway; most likely the standards are buggy.
+*/
+#ifdef __GNUC__
+#define ASCTIME_FMT "%s %s%3d %2.2d:%2.2d:%2.2d %-4s\n"
+#else /* !defined __GNUC__ */
+#define ASCTIME_FMT "%s %s%3d %02.2d:%02.2d:%02.2d %-4s\n"
+#endif /* !defined __GNUC__ */
+/*
+** For years that are more than four digits we put extra spaces before the year
+** so that code trying to overwrite the newline won't end up overwriting
+** a digit within a year and truncating the year (operating on the assumption
+** that no output is better than wrong output).
+*/
+#ifdef __GNUC__
+#define ASCTIME_FMT_B "%s %s%3d %2.2d:%2.2d:%2.2d %s\n"
+#else /* !defined __GNUC__ */
+#define ASCTIME_FMT_B "%s %s%3d %02.2d:%02.2d:%02.2d %s\n"
+#endif /* !defined __GNUC__ */
+
+#define STD_ASCTIME_BUF_SIZE 26
+/*
+** Big enough for something such as
+** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
+** (two three-character abbreviations, five strings denoting integers,
+** seven explicit spaces, two explicit colons, a newline,
+** and a trailing 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.
+*/
+#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
+
+static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
+
+char *
+asctime_r(register const struct tm *timeptr, char *buf)
+{
+ static const char wday_name[][4] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char mon_name[][4] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ register const char * wn;
+ register const char * mn;
+ char year[INT_STRLEN_MAXIMUM(int) + 2];
+ char result[MAX_ASCTIME_BUF_SIZE];
+
+ if (timeptr == NULL) {
+ errno = EINVAL;
+ return strcpy(buf, "??? ??? ?? ??:??:?? ????\n");
+ }
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
+ wn = "???";
+ else wn = wday_name[timeptr->tm_wday];
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
+ mn = "???";
+ else mn = mon_name[timeptr->tm_mon];
+ /*
+ ** Use strftime's %Y to generate the year, to avoid overflow problems
+ ** when computing timeptr->tm_year + TM_YEAR_BASE.
+ ** Assume that strftime is unaffected by other out-of-range members
+ ** (e.g., timeptr->tm_mday) when processing "%Y".
+ */
+ strftime(year, sizeof year, "%Y", timeptr);
+ /*
+ ** We avoid using snprintf since it's not available on all systems.
+ */
+ sprintf(result,
+ ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
+ wn, mn,
+ timeptr->tm_mday, timeptr->tm_hour,
+ timeptr->tm_min, timeptr->tm_sec,
+ year);
+ if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
+ return strcpy(buf, result);
+ else {
+ errno = EOVERFLOW;
+ return NULL;
+ }
+}
+
+char *
+asctime(register const struct tm *timeptr)
+{
+ return asctime_r(timeptr, buf_asctime);
+}
Property changes on: vendor/tzdb/tzcode2018e/asctime.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/calendars
===================================================================
--- vendor/tzdb/tzcode2018e/calendars (nonexistent)
+++ vendor/tzdb/tzcode2018e/calendars (revision 337695)
@@ -0,0 +1,173 @@
+----- Calendrical issues -----
+
+As mentioned in Theory.html, although calendrical issues are out of
+scope for tzdb, they indicate the sort of problems that we would run
+into if we extended tzdb further into the past. The following
+information and sources go beyond Theory.html's brief discussion.
+They sometimes disagree.
+
+
+France
+
+Gregorian calendar adopted 1582-12-20.
+French Revolutionary calendar used 1793-11-24 through 1805-12-31,
+and (in Paris only) 1871-05-06 through 1871-05-23.
+
+
+Russia
+
+From Chris Carrier (1996-12-02):
+On 1929-10-01 the Soviet Union instituted an "Eternal Calendar"
+with 30-day months plus 5 holidays, with a 5-day week.
+On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the
+Gregorian calendar while retaining the 6-day week; on 1940-06-27 it
+reverted to the 7-day week. With the 6-day week the usual days
+off were the 6th, 12th, 18th, 24th and 30th of the month.
+(Source: Evitiar Zerubavel, _The Seven Day Circle_)
+
+
+Mark Brader reported a similar story in "The Book of Calendars", edited
+by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But:
+
+From: Petteri Sulonen (via Usenet)
+Date: 14 Jan 1999 00:00:00 GMT
+...
+
+If your source is correct, how come documents between 1929 and 1940 were
+still dated using the conventional, Gregorian calendar?
+
+I can post a scan of a document dated December 1, 1934, signed by
+Yenukidze, the secretary, on behalf of Kalinin, the President of the
+Executive Committee of the Supreme Soviet, if you like.
+
+
+
+Sweden (and Finland)
+
+From: Mark Brader
+Subject: Re: Gregorian reform - a part of locale?
+
+Date: 1996-07-06
+
+In 1700, Denmark made the transition from Julian to Gregorian. Sweden
+decided to *start* a transition in 1700 as well, but rather than have one of
+those unsightly calendar gaps :-), they simply decreed that the next leap
+year after 1696 would be in 1744 - putting the whole country on a calendar
+different from both Julian and Gregorian for a period of 40 years.
+
+However, in 1704 something went wrong and the plan was not carried through;
+they did, after all, have a leap year that year. And one in 1708. In 1712
+they gave it up and went back to Julian, putting 30 days in February that
+year!...
+
+Then in 1753, Sweden made the transition to Gregorian in the usual manner,
+getting there only 13 years behind the original schedule.
+
+(A previous posting of this story was challenged, and Swedish readers
+produced the following references to support it: "Tideräkning och historia"
+by Natanael Beckman (1924) and "Tid, en bok om tideräkning och
+kalenderväsen" by Lars-Olof Lodén (1968).
+
+
+Grotefend's data
+
+From: "Michael Palmer" [with one obvious typo fixed]
+Subject: Re: Gregorian Calendar (was Re: Another FHC related question
+Newsgroups: soc.genealogy.german
+Date: Tue, 9 Feb 1999 02:32:48 -800
+...
+
+The following is a(n incomplete) listing, arranged chronologically, of
+European states, with the date they converted from the Julian to the
+Gregorian calendar:
+
+04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman
+ Catholics and Danzig only)
+09/20 Dec 1582 - France, Lorraine
+
+21 Dec 1582/
+ 01 Jan 1583 - Holland, Brabant, Flanders, Hennegau
+10/21 Feb 1583 - bishopric of Liege (Lüttich)
+13/24 Feb 1583 - bishopric of Augsburg
+04/15 Oct 1583 - electorate of Trier
+05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg,
+ Salzburg, Brixen
+13/24 Oct 1583 - Austrian Oberelsaß and Breisgau
+20/31 Oct 1583 - bishopric of Basel
+02/13 Nov 1583 - duchy of Jülich-Berg
+02/13 Nov 1583 - electorate and city of Köln
+04/15 Nov 1583 - bishopric of Würzburg
+11/22 Nov 1583 - electorate of Mainz
+16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden
+17/28 Nov 1583 - bishopric of Münster and duchy of Cleve
+14/25 Dec 1583 - Steiermark
+
+06/17 Jan 1584 - Austria and Bohemia
+11/22 Jan 1584 - Lucerne, Uri, Schwyz, Zug, Freiburg, Solothurn
+12/23 Jan 1584 - Silesia and the Lausitz
+22 Jan/
+ 02 Feb 1584 - Hungary (legally on 21 Oct 1587)
+ Jun 1584 - Unterwalden
+01/12 Jul 1584 - duchy of Westfalen
+
+16/27 Jun 1585 - bishopric of Paderborn
+
+14/25 Dec 1590 - Transylvania
+
+22 Aug/
+ 02 Sep 1612 - duchy of Prussia
+
+13/24 Dec 1614 - Pfalz-Neuburg
+
+ 1617 - duchy of Kurland (reverted to the Julian calendar in
+ 1796)
+
+ 1624 - bishopric of Osnabrück
+
+ 1630 - bishopric of Minden
+
+15/26 Mar 1631 - bishopric of Hildesheim
+
+ 1655 - Kanton Wallis
+
+05/16 Feb 1682 - city of Strassburg
+
+18 Feb/
+ 01 Mar 1700 - Protestant Germany (including Swedish possessions in
+ Germany), Denmark, Norway
+30 Jun/
+ 12 Jul 1700 - Gelderland, Zutphen
+10 Nov/
+ 12 Dec 1700 - Utrecht, Overijssel
+
+31 Dec 1700/
+ 12 Jan 1701 - Friesland, Groningen, Zürich, Bern, Basel, Geneva,
+ Turgau, and Schaffhausen
+
+ 1724 - Glarus, Appenzell, and the city of St. Gallen
+
+01 Jan 1750 - Pisa and Florence
+
+02/14 Sep 1752 - Great Britain
+
+17 Feb/
+ 01 Mar 1753 - Sweden
+
+1760-1812 - Graubünden
+
+The Russian empire (including Finland and the Baltic states) did not
+convert to the Gregorian calendar until the Soviet revolution of 1917.
+
+Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen
+Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend
+(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28.
+
+-----
+
+This file is in the public domain, so clarified as of 2009-05-17 by
+Arthur David Olson.
+
+-----
+Local Variables:
+coding: utf-8
+End:
Index: vendor/tzdb/tzcode2018e/date.1
===================================================================
--- vendor/tzdb/tzcode2018e/date.1 (nonexistent)
+++ vendor/tzdb/tzcode2018e/date.1 (revision 337695)
@@ -0,0 +1,165 @@
+.TH DATE 1
+.SH NAME
+date \- show and set date and time
+.SH SYNOPSIS
+.if n .nh
+.if n .na
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
+.B date
+[
+.B \*-u
+] [
+.B \*-c
+] [
+.B \*-r
+.I seconds
+] [
+.BI + format
+] [
+\fR[\fIyyyy\fR]\fImmddhhmm\fR[\fIyy\fR][\fB.\fIss\fR]
+]
+.SH DESCRIPTION
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
+.I Date
+without arguments writes the date and time to the standard output in
+the form
+.ce 1
+Wed Mar 8 14:54:40 EST 1989
+.br
+with
+.B EST
+replaced by the local time zone's abbreviation
+(or by the abbreviation for the time zone specified in the
+.B TZ
+environment variable if set).
+The exact output format depends on the locale.
+.PP
+If a command-line argument starts with a plus sign (\c
+.q "\fB+\fP" ),
+the rest of the argument is used as a
+.I format
+that controls what appears in the output.
+In the format, when a percent sign (\c
+.q "\fB%\fP"
+appears,
+it and the character after it are not output,
+but rather identify part of the date or time
+to be output in a particular way
+(or identify a special character to output):
+.nf
+.sp
+.if t .in +.5i
+.if n .in +2
+.ta \w'%M\0\0'u +\w'Wed Mar 8 14:54:40 EST 1989\0\0'u
+ Sample output Explanation
+%a Wed Abbreviated weekday name*
+%A Wednesday Full weekday name*
+%b Mar Abbreviated month name*
+%B March Full month name*
+%c Wed Mar 08 14:54:40 1989 Date and time*
+%C 19 Century
+%d 08 Day of month (always two digits)
+%D 03/08/89 Month/day/year (eight characters)
+%e 8 Day of month (leading zero blanked)
+%h Mar Abbreviated month name*
+%H 14 24-hour-clock hour (two digits)
+%I 02 12-hour-clock hour (two digits)
+%j 067 Julian day number (three digits)
+%k 2 12-hour-clock hour (leading zero blanked)
+%l 14 24-hour-clock hour (leading zero blanked)
+%m 03 Month number (two digits)
+%M 54 Minute (two digits)
+%n \\n newline character
+%p PM AM/PM designation
+%r 02:54:40 PM Hour:minute:second AM/PM designation
+%R 14:54 Hour:minute
+%S 40 Second (two digits)
+%t \\t tab character
+%T 14:54:40 Hour:minute:second
+%U 10 Sunday-based week number (two digits)
+%w 3 Day number (one digit, Sunday is 0)
+%W 10 Monday-based week number (two digits)
+%x 03/08/89 Date*
+%X 14:54:40 Time*
+%y 89 Last two digits of year
+%Y 1989 Year in full
+%z -0500 Numeric time zone
+%Z EST Time zone abbreviation
+%+ Wed Mar 8 14:54:40 EST 1989 Default output format*
+.if t .in -.5i
+.if n .in -2
+* The exact output depends on the locale.
+.sp
+.fi
+If a character other than one of those shown above appears after
+a percent sign in the format,
+that following character is output.
+All other characters in the format are copied unchanged to the output;
+a newline character is always added at the end of the output.
+.PP
+In Sunday-based week numbering,
+the first Sunday of the year begins week 1;
+days preceding it are part of
+.q "week 0" .
+In Monday-based week numbering,
+the first Monday of the year begins week 1.
+.PP
+To set the date, use a command line argument with one of the following forms:
+.nf
+.if t .in +.5i
+.if n .in +2
+.ta \w'198903081454\0'u
+1454 24-hour-clock hours (first two digits) and minutes
+081454 Month day (first two digits), hours, and minutes
+03081454 Month (two digits, January is 01), month day, hours, minutes
+8903081454 Year, month, month day, hours, minutes
+0308145489 Month, month day, hours, minutes, year
+ (on System V-compatible systems)
+030814541989 Month, month day, hours, minutes, four-digit year
+198903081454 Four-digit year, month, month day, hours, minutes
+.if t .in -.5i
+.if n .in -2
+.fi
+If the century, year, month, or month day is not given,
+the current value is used.
+Any of the above forms may be followed by a period and two digits that give
+the seconds part of the new time; if no seconds are given, zero is assumed.
+.PP
+These options are available:
+.TP
+.BR \*-u " or " \*-c
+Use Universal Time when setting and showing the date and time.
+.TP
+.BI "\*-r " seconds
+Output the date that corresponds to
+.I seconds
+past the epoch of 1970-01-01 00:00:00 UTC, where
+.I seconds
+should be an integer, either decimal, octal (leading 0), or
+hexadecimal (leading 0x), preceded by an optional sign.
+.SH FILES
+.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
+/etc/localtime local time zone file
+.br
+/usr/lib/locale/\f2L\fP/LC_TIME description of time locale \f2L\fP
+.br
+/usr/share/zoneinfo time zone information directory
+.br
+/usr/share/zoneinfo/posixrules used with POSIX-style TZ's
+.br
+/usr/share/zoneinfo/GMT for UTC leap seconds
+.sp
+If
+.B /usr/share/zoneinfo/GMT
+is absent,
+UTC leap seconds are loaded from
+.BR /usr/share/zoneinfo/posixrules .
+.\" This file is in the public domain, so clarified as of
+.\" 2009-05-17 by Arthur David Olson.
Property changes on: vendor/tzdb/tzcode2018e/date.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/date.1.txt
===================================================================
--- vendor/tzdb/tzcode2018e/date.1.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/date.1.txt (revision 337695)
@@ -0,0 +1,107 @@
+DATE(1) General Commands Manual DATE(1)
+
+NAME
+ date - show and set date and time
+
+SYNOPSIS
+ date [ -u ] [ -c ] [ -r seconds ] [ +format ] [ [yyyy]mmddhhmm[yy][.ss]
+ ]
+
+DESCRIPTION
+ Date without arguments writes the date and time to the standard output
+ in the form
+ Wed Mar 8 14:54:40 EST 1989
+ with EST replaced by the local time zone's abbreviation (or by the
+ 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
+ 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
+ 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):
+
+ Sample output Explanation
+ %a Wed Abbreviated weekday name*
+ %A Wednesday Full weekday name*
+ %b Mar Abbreviated month name*
+ %B March Full month name*
+ %c Wed Mar 08 14:54:40 1989 Date and time*
+ %C 19 Century
+ %d 08 Day of month (always two digits)
+ %D 03/08/89 Month/day/year (eight characters)
+ %e 8 Day of month (leading zero blanked)
+ %h Mar Abbreviated month name*
+ %H 14 24-hour-clock hour (two digits)
+ %I 02 12-hour-clock hour (two digits)
+ %j 067 Julian day number (three digits)
+ %k 2 12-hour-clock hour (leading zero blanked)
+ %l 14 24-hour-clock hour (leading zero blanked)
+ %m 03 Month number (two digits)
+ %M 54 Minute (two digits)
+ %n \n newline character
+ %p PM AM/PM designation
+ %r 02:54:40 PM Hour:minute:second AM/PM designation
+ %R 14:54 Hour:minute
+ %S 40 Second (two digits)
+ %t \t tab character
+ %T 14:54:40 Hour:minute:second
+ %U 10 Sunday-based week number (two digits)
+ %w 3 Day number (one digit, Sunday is 0)
+ %W 10 Monday-based week number (two digits)
+ %x 03/08/89 Date*
+ %X 14:54:40 Time*
+ %y 89 Last two digits of year
+ %Y 1989 Year in full
+ %z -0500 Numeric time zone
+ %Z EST Time zone abbreviation
+ %+ Wed Mar 8 14:54:40 EST 1989 Default output format*
+ * The exact output depends on the locale.
+
+ If a character other than one of those shown above appears after a
+ percent sign in the format, that following character is output. All
+ other characters in the format are copied unchanged to the output; a
+ newline character is always added at the end of the output.
+
+ In Sunday-based week numbering, the first Sunday of the year begins
+ week 1; days preceding it are part of "week 0". In Monday-based week
+ numbering, the first Monday of the year begins week 1.
+
+ To set the date, use a command line argument with one of the following
+ forms:
+ 1454 24-hour-clock hours (first two digits) and minutes
+ 081454 Month day (first two digits), hours, and minutes
+ 03081454 Month (two digits, January is 01), month day, hours, minutes
+ 8903081454 Year, month, month day, hours, minutes
+ 0308145489 Month, month day, hours, minutes, year
+ (on System V-compatible systems)
+ 030814541989 Month, month day, hours, minutes, four-digit year
+ 198903081454 Four-digit year, month, month day, hours, minutes
+ If the century, year, month, or month day is not given, the current
+ value is used. Any of the above forms may be followed by a period and
+ two digits that give the seconds part of the new time; if no seconds
+ are given, zero is assumed.
+
+ These options are available:
+
+ -u or -c
+ Use Universal Time when setting and showing the date and time.
+
+ -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.
+
+FILES
+ /etc/localtime local time zone file
+ /usr/lib/locale/L/LC_TIME description of time locale L
+ /usr/share/zoneinfo time zone information directory
+ /usr/share/zoneinfo/posixrules used with POSIX-style TZ's
+ /usr/share/zoneinfo/GMT for UTC leap seconds
+
+ If /usr/share/zoneinfo/GMT is absent, UTC leap seconds are loaded from
+ /usr/share/zoneinfo/posixrules.
+
+ DATE(1)
Property changes on: vendor/tzdb/tzcode2018e/date.1.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/date.c
===================================================================
--- vendor/tzdb/tzcode2018e/date.c (nonexistent)
+++ vendor/tzdb/tzcode2018e/date.c (revision 337695)
@@ -0,0 +1,237 @@
+/* Display or set the current time and date. */
+
+/* Copyright 1985, 1987, 1988 The Regents of the University of California.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE. */
+
+#include "private.h"
+#include
+#include
+
+/*
+** The two things date knows about time are. . .
+*/
+
+#ifndef TM_YEAR_BASE
+#define TM_YEAR_BASE 1900
+#endif /* !defined TM_YEAR_BASE */
+
+#ifndef SECSPERMIN
+#define SECSPERMIN 60
+#endif /* !defined SECSPERMIN */
+
+#if !HAVE_POSIX_DECLS
+extern char * optarg;
+extern int optind;
+#endif
+
+static int retval = EXIT_SUCCESS;
+
+static void display(const char *, time_t);
+static void dogmt(void);
+static void errensure(void);
+static void timeout(FILE *, const char *, const struct tm *);
+static _Noreturn void usage(void);
+
+int
+main(const int argc, char *argv[])
+{
+ register const char * format;
+ register const char * cp;
+ register int ch;
+ register bool rflag = false;
+ time_t t;
+ intmax_t secs;
+ char * endarg;
+
+#ifdef LC_ALL
+ setlocale(LC_ALL, "");
+#endif /* defined(LC_ALL) */
+#if HAVE_GETTEXT
+#ifdef TZ_DOMAINDIR
+ bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
+#endif /* defined(TEXTDOMAINDIR) */
+ textdomain(TZ_DOMAIN);
+#endif /* HAVE_GETTEXT */
+ t = time(NULL);
+ format = NULL;
+ while ((ch = getopt(argc, argv, "ucr:")) != EOF && ch != -1) {
+ switch (ch) {
+ default:
+ usage();
+ case 'u': /* do it in UT */
+ case 'c':
+ dogmt();
+ break;
+ case 'r': /* seconds since 1970 */
+ if (rflag) {
+ fprintf(stderr,
+ _("date: error: multiple -r's used"));
+ usage();
+ }
+ rflag = true;
+ errno = 0;
+ secs = strtoimax (optarg, &endarg, 0);
+ if (*endarg || optarg == endarg)
+ errno = EINVAL;
+ else if (! (TIME_T_MIN <= secs && secs <= TIME_T_MAX))
+ errno = ERANGE;
+ if (errno) {
+ perror(optarg);
+ errensure();
+ exit(retval);
+ }
+ t = secs;
+ break;
+ }
+ }
+ while (optind < argc) {
+ cp = argv[optind++];
+ if (*cp == '+')
+ if (format == NULL)
+ format = cp + 1;
+ else {
+ fprintf(stderr,
+_("date: error: multiple formats in command line\n"));
+ usage();
+ }
+ else {
+ fprintf(stderr, _("date: unknown operand: %s\n"), cp);
+ usage();
+ }
+ }
+
+ display(format, t);
+ return retval;
+}
+
+static void
+dogmt(void)
+{
+ static char ** fakeenv;
+
+ if (fakeenv == NULL) {
+ register int from;
+ register int to;
+ register int n;
+ static char tzegmt0[] = "TZ=GMT0";
+
+ for (n = 0; environ[n] != NULL; ++n)
+ continue;
+ fakeenv = malloc((n + 2) * sizeof *fakeenv);
+ if (fakeenv == NULL) {
+ perror(_("Memory exhausted"));
+ errensure();
+ exit(retval);
+ }
+ to = 0;
+ fakeenv[to++] = tzegmt0;
+ for (from = 1; environ[from] != NULL; ++from)
+ if (strncmp(environ[from], "TZ=", 3) != 0)
+ fakeenv[to++] = environ[from];
+ fakeenv[to] = NULL;
+ environ = fakeenv;
+ }
+}
+
+static void
+errensure(void)
+{
+ if (retval == EXIT_SUCCESS)
+ retval = EXIT_FAILURE;
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ _("date: usage: date [-u] [-c] [-r seconds]"
+ " [+format]\n"));
+ errensure();
+ exit(retval);
+}
+
+static void
+display(char const *format, time_t now)
+{
+ struct tm *tmp;
+
+ tmp = localtime(&now);
+ if (!tmp) {
+ fprintf(stderr,
+ _("date: error: time out of range\n"));
+ errensure();
+ return;
+ }
+ timeout(stdout, format ? format : "%+", tmp);
+ putchar('\n');
+ fflush(stdout);
+ fflush(stderr);
+ if (ferror(stdout) || ferror(stderr)) {
+ fprintf(stderr,
+ _("date: error: couldn't write results\n"));
+ errensure();
+ }
+}
+
+#define INCR 1024
+
+static void
+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) {
+ fprintf(stderr,
+ _("date: error: can't get memory\n"));
+ errensure();
+ exit(retval);
+ }
+ cp[0] = '\1';
+ result = strftime(cp, size, format, tmp);
+ if (result != 0 || cp[0] == '\0')
+ break;
+ size += INCR;
+ cp = realloc(cp, size);
+ }
+ fwrite(cp, 1, result, fp);
+ free(cp);
+}
Property changes on: vendor/tzdb/tzcode2018e/date.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/difftime.c
===================================================================
--- vendor/tzdb/tzcode2018e/difftime.c (nonexistent)
+++ vendor/tzdb/tzcode2018e/difftime.c (revision 337695)
@@ -0,0 +1,58 @@
+/*
+** This file is in the public domain, so clarified as of
+** 1996-06-05 by Arthur David Olson.
+*/
+
+/*LINTLIBRARY*/
+
+#include "private.h" /* for time_t and TYPE_SIGNED */
+
+/* Return -X as a double. Using this avoids casting to 'double'. */
+static double
+dminus(double x)
+{
+ return -x;
+}
+
+double
+difftime(time_t time1, time_t time0)
+{
+ /*
+ ** If double is large enough, simply convert and subtract
+ ** (assuming that the larger type has more precision).
+ */
+ if (sizeof (time_t) < sizeof (double)) {
+ double t1 = time1, t0 = time0;
+ return t1 - t0;
+ }
+
+ /*
+ ** The difference of two unsigned values can't overflow
+ ** if the minuend is greater than or equal to the subtrahend.
+ */
+ if (!TYPE_SIGNED(time_t))
+ return time0 <= time1 ? time1 - time0 : dminus(time0 - time1);
+
+ /* Use uintmax_t if wide enough. */
+ if (sizeof (time_t) <= sizeof (uintmax_t)) {
+ uintmax_t t1 = time1, t0 = time0;
+ return time0 <= time1 ? t1 - t0 : dminus(t0 - t1);
+ }
+
+ /*
+ ** Handle cases where both time1 and time0 have the same sign
+ ** (meaning that their difference cannot overflow).
+ */
+ if ((time1 < 0) == (time0 < 0))
+ return time1 - time0;
+
+ /*
+ ** The values have opposite signs and uintmax_t is too narrow.
+ ** This suffers from double rounding; attempt to lessen that
+ ** by using long double temporaries.
+ */
+ {
+ long double t1 = time1, t0 = time0;
+ return t1 - t0;
+ }
+}
Property changes on: vendor/tzdb/tzcode2018e/difftime.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/localtime.c
===================================================================
--- vendor/tzdb/tzcode2018e/localtime.c (nonexistent)
+++ vendor/tzdb/tzcode2018e/localtime.c (revision 337695)
@@ -0,0 +1,2342 @@
+/*
+** This file is in the public domain, so clarified as of
+** 1996-06-05 by Arthur David Olson.
+*/
+
+/*
+** Leap second handling from Bradley White.
+** POSIX-style TZ environment variable handling from Guy Harris.
+*/
+
+/*LINTLIBRARY*/
+
+#define LOCALTIME_IMPLEMENTATION
+#include "private.h"
+
+#include "tzfile.h"
+#include
+
+#if defined THREAD_SAFE && THREAD_SAFE
+# include
+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 */
+
+#ifndef TZ_ABBR_CHAR_SET
+#define TZ_ABBR_CHAR_SET \
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
+#endif /* !defined TZ_ABBR_CHAR_SET */
+
+#ifndef TZ_ABBR_ERR_CHAR
+#define TZ_ABBR_ERR_CHAR '_'
+#endif /* !defined TZ_ABBR_ERR_CHAR */
+
+/*
+** SunOS 4.1.1 headers lack O_BINARY.
+*/
+
+#ifdef O_BINARY
+#define OPEN_MODE (O_RDONLY | O_BINARY)
+#endif /* defined O_BINARY */
+#ifndef O_BINARY
+#define OPEN_MODE O_RDONLY
+#endif /* !defined O_BINARY */
+
+#ifndef WILDABBR
+/*
+** Someone might make incorrect use of a time zone abbreviation:
+** 1. They might reference tzname[0] before calling tzset (explicitly
+** or implicitly).
+** 2. They might reference tzname[1] before calling tzset (explicitly
+** or implicitly).
+** 3. They might reference tzname[1] after setting to a time zone
+** in which Daylight Saving Time is never observed.
+** 4. They might reference tzname[0] after setting to a time zone
+** in which Standard Time is never observed.
+** 5. They might reference tm.TM_ZONE after calling offtime.
+** What's best to do in the above cases is open to debate;
+** for now, we just set things up so that in any of the five cases
+** WILDABBR is used. Another possibility: initialize tzname[0] to the
+** string "tzname[0] used before set", and similarly for the other cases.
+** And another: initialize tzname[0] to "ERA", with an explanation in the
+** manual page of what this "time zone abbreviation" means (doing this so
+** that tzname[0] has the "normal" length of three characters).
+*/
+#define WILDABBR " "
+#endif /* !defined WILDABBR */
+
+static const char wildabbr[] = WILDABBR;
+
+static const char gmt[] = "GMT";
+
+/*
+** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
+** Default to US rules as of 2017-05-07.
+** POSIX does not specify the default DST rules;
+** for historical reasons, US rules are a common default.
+*/
+#ifndef TZDEFRULESTRING
+#define TZDEFRULESTRING ",M3.2.0,M11.1.0"
+#endif
+
+struct ttinfo { /* time type information */
+ int_fast32_t tt_gmtoff; /* UT offset in seconds */
+ bool tt_isdst; /* used to set tm_isdst */
+ int tt_abbrind; /* abbreviation list index */
+ bool tt_ttisstd; /* transition is std time */
+ bool tt_ttisgmt; /* transition is UT */
+};
+
+struct lsinfo { /* leap second information */
+ time_t ls_trans; /* transition time */
+ 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
+#define MY_TZNAME_MAX TZNAME_MAX
+#endif /* defined TZNAME_MAX */
+#ifndef TZNAME_MAX
+#define MY_TZNAME_MAX 255
+#endif /* !defined TZNAME_MAX */
+
+struct state {
+ int leapcnt;
+ int timecnt;
+ int typecnt;
+ int charcnt;
+ bool goback;
+ bool goahead;
+ time_t ats[TZ_MAX_TIMES];
+ unsigned char types[TZ_MAX_TIMES];
+ struct ttinfo ttis[TZ_MAX_TYPES];
+ char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
+ (2 * (MY_TZNAME_MAX + 1)))];
+ struct lsinfo lsis[TZ_MAX_LEAPS];
+ 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 {
+ 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 */
+ int_fast32_t r_time; /* transition time of rule */
+};
+
+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);
+
+#ifdef ALL_STATE
+static struct state * lclptr;
+static struct state * gmtptr;
+#endif /* defined ALL_STATE */
+
+#ifndef ALL_STATE
+static struct state lclmem;
+static struct state gmtmem;
+#define lclptr (&lclmem)
+#define gmtptr (&gmtmem)
+#endif /* State Farm */
+
+#ifndef TZ_STRLEN_MAX
+#define TZ_STRLEN_MAX 255
+#endif /* !defined TZ_STRLEN_MAX */
+
+static char lcl_TZname[TZ_STRLEN_MAX + 1];
+static int lcl_is_set;
+
+/*
+** Section 4.12.3 of X3.159-1989 requires that
+** Except for the strftime function, these functions [asctime,
+** ctime, gmtime, localtime] return values in one of two static
+** objects: a broken-down time structure and an array of char.
+** Thanks to Paul Eggert for noting this.
+*/
+
+static struct tm tm;
+
+#if !HAVE_POSIX_DECLS || TZ_TIME_T
+# if HAVE_TZNAME
+char * tzname[2] = {
+ (char *) wildabbr,
+ (char *) wildabbr
+};
+# endif
+# if USG_COMPAT
+long timezone;
+int daylight;
+# endif
+# ifdef ALTZONE
+long altzone;
+# endif
+#endif
+
+/* 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 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] & 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 int_fast64_t
+detzcode64(const char *const codep)
+{
+ 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] & 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)
+{
+#if HAVE_TZNAME
+ tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
+#endif
+#if 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;
+
+#if HAVE_TZNAME
+ tzname[0] = tzname[1] = (char *) (sp ? wildabbr : gmt);
+#endif
+#if USG_COMPAT
+ daylight = 0;
+ timezone = 0;
+#endif
+#ifdef ALTZONE
+ altzone = 0;
+#endif /* defined ALTZONE */
+ if (sp == NULL) {
+ return;
+ }
+ /*
+ ** 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]];
+ update_tzname_etc(sp, ttisp);
+#if USG_COMPAT
+ if (ttisp->tt_isdst)
+ daylight = 1;
+#endif
+ }
+}
+
+static void
+scrub_abbrs(struct state *sp)
+{
+ int i;
+ /*
+ ** First, replace bogus characters.
+ */
+ for (i = 0; i < sp->charcnt; ++i)
+ if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
+ sp->chars[i] = TZ_ABBR_ERR_CHAR;
+ /*
+ ** Second, truncate long abbreviations.
+ */
+ for (i = 0; i < sp->typecnt; ++i) {
+ register const struct ttinfo * const ttisp = &sp->ttis[i];
+ register char * cp = &sp->chars[ttisp->tt_abbrind];
+
+ if (strlen(cp) > TZ_ABBR_MAX_LEN &&
+ strcmp(cp, GRANDPARENTED) != 0)
+ *(cp + TZ_ABBR_MAX_LEN) = '\0';
+ }
+}
+
+static bool
+differ_by_repeat(const time_t t1, const time_t t0)
+{
+ 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];
+};
+
+/* TZDIR with a trailing '/' rather than a trailing '\0'. */
+static char const tzdirslash[sizeof TZDIR] = TZDIR "/";
+
+/* Local storage needed for 'tzloadbody'. */
+union local_storage {
+ /* The results of analyzing the file's contents after it is opened. */
+ struct file_analysis {
+ /* The input buffer. */
+ union input_buffer u;
+
+ /* A temporary state used for parsing a TZ string in the file. */
+ struct state st;
+ } u;
+
+ /* The file name to be opened. */
+ char fullname[BIGGEST(sizeof (struct file_analysis),
+ sizeof tzdirslash + 1024)];
+};
+
+/* 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
+tzloadbody(char const *name, struct state *sp, bool doextend,
+ union local_storage *lsp)
+{
+ register int i;
+ register int fid;
+ register int stored;
+ register ssize_t nread;
+ register bool doaccess;
+ register union input_buffer *up = &lsp->u.u;
+ register int tzheadsize = sizeof (struct tzhead);
+
+ sp->goback = sp->goahead = false;
+
+ if (! name) {
+ name = TZDEFAULT;
+ if (! name)
+ return EINVAL;
+ }
+
+ if (name[0] == ':')
+ ++name;
+#ifdef SUPPRESS_TZDIR
+ /* Do not prepend TZDIR. This is intended for specialized
+ applications only, due to its security implications. */
+ doaccess = true;
+#else
+ doaccess = name[0] == '/';
+#endif
+ if (!doaccess) {
+ size_t namelen = strlen(name);
+ if (sizeof lsp->fullname - sizeof tzdirslash <= namelen)
+ return ENAMETOOLONG;
+
+ /* Create a string "TZDIR/NAME". Using sprintf here
+ would pull in stdio (and would fail if the
+ resulting string length exceeded INT_MAX!). */
+ memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash);
+ strcpy(lsp->fullname + sizeof tzdirslash, name);
+
+ /* Set doaccess if '.' (as in "../") shows up in name. */
+ if (strchr(name, '.'))
+ doaccess = true;
+ name = lsp->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 (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_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
+ int_fast32_t ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
+ int_fast64_t prevtr = 0;
+ int_fast32_t prevcorr = 0;
+ 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;
+
+ /* 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) {
+ 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) {
+ 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;
+ 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) {
+ int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
+ int_fast32_t corr = detzcode(p + stored);
+ p += stored + 4;
+ /* Leap seconds cannot occur before the Epoch. */
+ if (tr < 0)
+ return EINVAL;
+ if (tr <= TIME_T_MAX) {
+ /* Leap seconds cannot occur more than once per UTC month,
+ and UTC months are at least 28 days long (minus 1
+ second for a negative leap second). Each leap second's
+ correction must differ from the previous one's by 1
+ second. */
+ if (tr - prevtr < 28 * SECSPERDAY - 1
+ || (corr != prevcorr - 1 && corr != prevcorr + 1))
+ return EINVAL;
+ sp->lsis[leapcnt].ls_trans = prevtr = tr;
+ sp->lsis[leapcnt].ls_corr = prevcorr = corr;
+ leapcnt++;
+ }
+ }
+ sp->leapcnt = leapcnt;
+
+ for (i = 0; i < sp->typecnt; ++i) {
+ register struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ if (ttisstdcnt == 0)
+ ttisp->tt_ttisstd = false;
+ else {
+ if (*p != true && *p != false)
+ return EINVAL;
+ ttisp->tt_ttisstd = *p++;
+ }
+ }
+ for (i = 0; i < sp->typecnt; ++i) {
+ register struct ttinfo * ttisp;
+
+ ttisp = &sp->ttis[i];
+ if (ttisgmtcnt == 0)
+ ttisp->tt_ttisgmt = false;
+ else {
+ if (*p != true && *p != false)
+ return EINVAL;
+ ttisp->tt_ttisgmt = *p++;
+ }
+ }
+ /*
+ ** If this is an old file, we're done.
+ */
+ if (up->tzhead.tzh_version[0] == '\0')
+ break;
+ nread -= p - up->buf;
+ 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 = &lsp->u.st;
+
+ up->buf[nread - 1] = '\0';
+ if (tzparse(&up->buf[1], ts, false)
+ && ts->typecnt == 2) {
+
+ /* Attempt to reuse existing abbreviations.
+ Without this, America/Anchorage would be right on
+ the edge after 2037 when TZ_MAX_CHARS is 50, as
+ sp->charcnt equals 40 (for LMT AST AWT APT AHST
+ AHDT YST AKDT AKST) and ts->charcnt equals 10
+ (for AKST AKDT). Reusing means sp->charcnt can
+ stay 40 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;
+
+ /* Ignore any trailing, no-op transitions generated
+ by zic as they don't help here and can run afoul
+ of bugs in zic 2016j or earlier. */
+ while (1 < sp->timecnt
+ && (sp->types[sp->timecnt - 1]
+ == sp->types[sp->timecnt - 2]))
+ sp->timecnt--;
+
+ 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) {
+ 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;
+ break;
+ }
+ for (i = sp->timecnt - 2; i >= 0; --i)
+ if (typesequiv(sp, sp->types[sp->timecnt - 1],
+ sp->types[i]) &&
+ differ_by_repeat(sp->ats[sp->timecnt - 1],
+ sp->ats[i])) {
+ sp->goahead = true;
+ break;
+ }
+ }
+ /*
+ ** If type 0 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;
+}
+
+/* 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
+tzload(char const *name, struct state *sp, bool doextend)
+{
+#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;
+ else {
+ register const struct ttinfo * ap = &sp->ttis[a];
+ register const struct ttinfo * bp = &sp->ttis[b];
+ result = ap->tt_gmtoff == bp->tt_gmtoff &&
+ ap->tt_isdst == bp->tt_isdst &&
+ ap->tt_ttisstd == bp->tt_ttisstd &&
+ ap->tt_ttisgmt == bp->tt_ttisgmt &&
+ strcmp(&sp->chars[ap->tt_abbrind],
+ &sp->chars[bp->tt_abbrind]) == 0;
+ }
+ return result;
+}
+
+static const int mon_lengths[2][MONSPERYEAR] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static const int year_lengths[2] = {
+ DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+/*
+** Given a pointer into a time zone string, scan until a character that is not
+** a valid character in a zone name is found. Return a pointer to that
+** character.
+*/
+
+static const char *
+getzname(register const char *strp)
+{
+ register char c;
+
+ while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
+ c != '+')
+ ++strp;
+ return strp;
+}
+
+/*
+** Given a pointer into an extended time zone string, scan until the ending
+** delimiter of the zone name is located. Return a pointer to the delimiter.
+**
+** As with getzname above, the legal character set is actually quite
+** restricted, with other characters producing undefined results.
+** We don't do any checking here; checking is done later in common-case code.
+*/
+
+static const char *
+getqzname(register const char *strp, const int delim)
+{
+ register int c;
+
+ while ((c = *strp) != '\0' && c != delim)
+ ++strp;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a number from that string.
+** Check that the number is within a specified range; if it is not, return
+** NULL.
+** Otherwise, return a pointer to the first character not part of the number.
+*/
+
+static const char *
+getnum(register const char *strp, int *const nump, const int min, const int max)
+{
+ register char c;
+ register int num;
+
+ if (strp == NULL || !is_digit(c = *strp))
+ return NULL;
+ num = 0;
+ do {
+ num = num * 10 + (c - '0');
+ if (num > max)
+ return NULL; /* illegal value */
+ c = *++strp;
+ } while (is_digit(c));
+ if (num < min)
+ return NULL; /* illegal value */
+ *nump = num;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a number of seconds,
+** in hh[:mm[:ss]] form, from the string.
+** If any error occurs, return NULL.
+** Otherwise, return a pointer to the first character not part of the number
+** of seconds.
+*/
+
+static const char *
+getsecs(register const char *strp, int_fast32_t *const secsp)
+{
+ int num;
+
+ /*
+ ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
+ ** "M10.4.6/26", which does not conform to Posix,
+ ** but which specifies the equivalent of
+ ** "02:00 on the first Sunday on or after 23 Oct".
+ */
+ strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp = num * (int_fast32_t) SECSPERHOUR;
+ if (*strp == ':') {
+ ++strp;
+ strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num * SECSPERMIN;
+ if (*strp == ':') {
+ ++strp;
+ /* 'SECSPERMIN' allows for leap seconds. */
+ strp = getnum(strp, &num, 0, SECSPERMIN);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num;
+ }
+ }
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract an offset, in
+** [+-]hh[:mm[:ss]] form, from the string.
+** If any error occurs, return NULL.
+** Otherwise, return a pointer to the first character not part of the time.
+*/
+
+static const char *
+getoffset(register const char *strp, int_fast32_t *const offsetp)
+{
+ register bool neg = false;
+
+ if (*strp == '-') {
+ neg = true;
+ ++strp;
+ } else if (*strp == '+')
+ ++strp;
+ strp = getsecs(strp, offsetp);
+ if (strp == NULL)
+ return NULL; /* illegal time */
+ if (neg)
+ *offsetp = -*offsetp;
+ return strp;
+}
+
+/*
+** Given a pointer into a time zone string, extract a rule in the form
+** date[/time]. See POSIX section 8 for the format of "date" and "time".
+** If a valid rule is not found, return NULL.
+** Otherwise, return a pointer to the first character not part of the rule.
+*/
+
+static const char *
+getrule(const char *strp, register struct rule *const rulep)
+{
+ if (*strp == 'J') {
+ /*
+ ** Julian day.
+ */
+ rulep->r_type = JULIAN_DAY;
+ ++strp;
+ strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
+ } else if (*strp == 'M') {
+ /*
+ ** Month, week, day.
+ */
+ rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
+ ++strp;
+ strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_week, 1, 5);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
+ } else if (is_digit(*strp)) {
+ /*
+ ** Day of year.
+ */
+ rulep->r_type = DAY_OF_YEAR;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
+ } else return NULL; /* invalid format */
+ if (strp == NULL)
+ return NULL;
+ if (*strp == '/') {
+ /*
+ ** Time specified.
+ */
+ ++strp;
+ strp = getoffset(strp, &rulep->r_time);
+ } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
+ return strp;
+}
+
+/*
+** 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 int_fast32_t
+transtime(const int year, register const struct rule *const rulep,
+ const int_fast32_t offset)
+{
+ register bool leapyear;
+ register int_fast32_t value;
+ register int i;
+ int d, m1, yy0, yy1, yy2, dow;
+
+ INITIALIZE(value);
+ leapyear = isleap(year);
+ switch (rulep->r_type) {
+
+ case JULIAN_DAY:
+ /*
+ ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
+ ** years.
+ ** In non-leap years, or if the day number is 59 or less, just
+ ** add SECSPERDAY times the day number-1 to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = (rulep->r_day - 1) * SECSPERDAY;
+ if (leapyear && rulep->r_day >= 60)
+ value += SECSPERDAY;
+ break;
+
+ case DAY_OF_YEAR:
+ /*
+ ** n - day of year.
+ ** Just add SECSPERDAY times the day number to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = rulep->r_day * SECSPERDAY;
+ break;
+
+ case MONTH_NTH_DAY_OF_WEEK:
+ /*
+ ** Mm.n.d - nth "dth day" of month m.
+ */
+
+ /*
+ ** Use Zeller's Congruence to get day-of-week of first day of
+ ** month.
+ */
+ m1 = (rulep->r_mon + 9) % 12 + 1;
+ yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
+ yy1 = yy0 / 100;
+ yy2 = yy0 % 100;
+ dow = ((26 * m1 - 2) / 10 +
+ 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
+ if (dow < 0)
+ dow += DAYSPERWEEK;
+
+ /*
+ ** "dow" is the day-of-week of the first day of the month. Get
+ ** the day-of-month (zero-origin) of the first "dow" day of the
+ ** month.
+ */
+ d = rulep->r_day - dow;
+ if (d < 0)
+ d += DAYSPERWEEK;
+ for (i = 1; i < rulep->r_week; ++i) {
+ if (d + DAYSPERWEEK >=
+ mon_lengths[leapyear][rulep->r_mon - 1])
+ break;
+ d += DAYSPERWEEK;
+ }
+
+ /*
+ ** "d" is the day-of-month (zero-origin) of the day we want.
+ */
+ value = d * SECSPERDAY;
+ for (i = 0; i < rulep->r_mon - 1; ++i)
+ value += mon_lengths[leapyear][i] * SECSPERDAY;
+ break;
+ }
+
+ /*
+ ** "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 UT.
+ */
+ return value + rulep->r_time + offset;
+}
+
+/*
+** Given a POSIX section 8-style TZ string, fill in the rule tables as
+** appropriate.
+*/
+
+static bool
+tzparse(const char *name, struct state *sp, bool lastditch)
+{
+ const char * stdname;
+ const char * dstname;
+ size_t stdlen;
+ size_t dstlen;
+ size_t charcnt;
+ int_fast32_t stdoffset;
+ int_fast32_t dstoffset;
+ register char * cp;
+ register bool load_ok;
+
+ stdname = name;
+ if (lastditch) {
+ stdlen = sizeof gmt - 1;
+ name += stdlen;
+ stdoffset = 0;
+ } else {
+ if (*name == '<') {
+ name++;
+ stdname = name;
+ name = getqzname(name, '>');
+ if (*name != '>')
+ return false;
+ stdlen = name - stdname;
+ name++;
+ } else {
+ name = getzname(name);
+ stdlen = name - stdname;
+ }
+ if (!stdlen)
+ return false;
+ name = getoffset(name, &stdoffset);
+ if (name == NULL)
+ return false;
+ }
+ 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 == '<') {
+ dstname = ++name;
+ name = getqzname(name, '>');
+ if (*name != '>')
+ return false;
+ dstlen = name - dstname;
+ name++;
+ } else {
+ dstname = name;
+ 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 false;
+ } else dstoffset = stdoffset - SECSPERHOUR;
+ if (*name == '\0' && !load_ok)
+ name = TZDEFRULESTRING;
+ if (*name == ',' || *name == ';') {
+ struct rule start;
+ struct rule end;
+ register int year;
+ register int yearlim;
+ register int timecnt;
+ time_t janfirst;
+ int_fast32_t janoffset = 0;
+ int yearbeg;
+
+ ++name;
+ if ((name = getrule(name, &start)) == NULL)
+ return false;
+ if (*name++ != ',')
+ return false;
+ if ((name = getrule(name, &end)) == NULL)
+ return false;
+ if (*name != '\0')
+ return false;
+ sp->typecnt = 2; /* standard time and DST */
+ /*
+ ** Two transitions per year, from EPOCH_YEAR forward.
+ */
+ init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
+ init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
+ sp->defaulttype = 0;
+ timecnt = 0;
+ janfirst = 0;
+ yearbeg = EPOCH_YEAR;
+
+ do {
+ int_fast32_t yearsecs
+ = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
+ yearbeg--;
+ if (increment_overflow_time(&janfirst, -yearsecs)) {
+ janoffset = -yearsecs;
+ break;
+ }
+ } while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
+
+ yearlim = yearbeg + YEARSPERREPEAT + 1;
+ for (year = yearbeg; 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;
+ }
+ if (reversed
+ || (starttime < endtime
+ && (endtime - starttime
+ < (yearsecs
+ + (stdoffset - dstoffset))))) {
+ if (TZ_MAX_TIMES - 2 < timecnt)
+ break;
+ sp->ats[timecnt] = janfirst;
+ if (! increment_overflow_time
+ (&sp->ats[timecnt],
+ janoffset + starttime))
+ sp->types[timecnt++] = reversed;
+ else if (janoffset)
+ sp->defaulttype = reversed;
+ sp->ats[timecnt] = janfirst;
+ if (! increment_overflow_time
+ (&sp->ats[timecnt],
+ janoffset + endtime)) {
+ sp->types[timecnt++] = !reversed;
+ yearlim = year + YEARSPERREPEAT + 1;
+ } else if (janoffset)
+ sp->defaulttype = !reversed;
+ }
+ if (increment_overflow_time
+ (&janfirst, janoffset + yearsecs))
+ break;
+ janoffset = 0;
+ }
+ sp->timecnt = timecnt;
+ if (! timecnt)
+ sp->typecnt = 1; /* Perpetual DST. */
+ else if (YEARSPERREPEAT < year - yearbeg)
+ sp->goback = sp->goahead = true;
+ } else {
+ 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 false;
+ /*
+ ** Initial values of theirstdoffset and theirdstoffset.
+ */
+ theirstdoffset = 0;
+ for (i = 0; i < sp->timecnt; ++i) {
+ j = sp->types[i];
+ if (!sp->ttis[j].tt_isdst) {
+ theirstdoffset =
+ -sp->ttis[j].tt_gmtoff;
+ break;
+ }
+ }
+ theirdstoffset = 0;
+ for (i = 0; i < sp->timecnt; ++i) {
+ j = sp->types[i];
+ if (sp->ttis[j].tt_isdst) {
+ theirdstoffset =
+ -sp->ttis[j].tt_gmtoff;
+ break;
+ }
+ }
+ /*
+ ** Initially we're assumed to be in standard time.
+ */
+ isdst = false;
+ theiroffset = theirstdoffset;
+ /*
+ ** Now juggle transition times and types
+ ** tracking offsets as you do.
+ */
+ for (i = 0; i < sp->timecnt; ++i) {
+ j = sp->types[i];
+ sp->types[i] = sp->ttis[j].tt_isdst;
+ if (sp->ttis[j].tt_ttisgmt) {
+ /* No adjustment to transition time */
+ } else {
+ /*
+ ** If daylight saving time is in
+ ** effect, and the transition time was
+ ** not specified as standard time, add
+ ** the daylight saving time offset to
+ ** the transition time; otherwise, add
+ ** the standard time offset to the
+ ** transition time.
+ */
+ /*
+ ** Transitions from DST to DDST
+ ** will effectively disappear since
+ ** POSIX provides for only one DST
+ ** offset.
+ */
+ if (isdst && !sp->ttis[j].tt_ttisstd) {
+ sp->ats[i] += dstoffset -
+ theirdstoffset;
+ } else {
+ sp->ats[i] += stdoffset -
+ theirstdoffset;
+ }
+ }
+ theiroffset = -sp->ttis[j].tt_gmtoff;
+ if (sp->ttis[j].tt_isdst)
+ theirdstoffset = theiroffset;
+ else theirstdoffset = theiroffset;
+ }
+ /*
+ ** Finally, fill in ttis.
+ */
+ 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;
+ init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
+ sp->defaulttype = 0;
+ }
+ sp->charcnt = charcnt;
+ cp = sp->chars;
+ memcpy(cp, stdname, stdlen);
+ cp += stdlen;
+ *cp++ = '\0';
+ if (dstlen != 0) {
+ memcpy(cp, dstname, dstlen);
+ *(cp + dstlen) = '\0';
+ }
+ return true;
+}
+
+static void
+gmtload(struct state *const sp)
+{
+ if (tzload(gmt, sp, true) != 0)
+ tzparse(gmt, sp, true);
+}
+
+/* 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 (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 (! sp)
+ lclptr = sp = malloc(sizeof *lclptr);
+#endif /* defined ALL_STATE */
+ 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
+tzsetwall(void)
+{
+ if (lock() != 0)
+ return;
+ tzsetlcl(NULL);
+ unlock();
+}
+#endif
+
+static void
+tzset_unlocked(void)
+{
+ tzsetlcl(getenv("TZ"));
+}
+
+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
+ 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,
+** but it *is* desirable.)
+**
+** 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(struct state const *sp, time_t const *timep, int_fast32_t setname,
+ struct tm *const tmp)
+{
+ register const struct ttinfo * ttisp;
+ register int i;
+ register struct tm * result;
+ const time_t t = *timep;
+
+ 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 years;
+
+ if (t < sp->ats[0])
+ seconds = sp->ats[0] - t;
+ else seconds = t - sp->ats[sp->timecnt - 1];
+ --seconds;
+ years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
+ seconds = years * AVGSECSPERYEAR;
+ if (t < sp->ats[0])
+ newt += seconds;
+ else newt -= seconds;
+ if (newt < sp->ats[0] ||
+ newt > sp->ats[sp->timecnt - 1])
+ return NULL; /* "cannot happen" */
+ result = localsub(sp, &newt, setname, tmp);
+ if (result) {
+ register int_fast64_t newy;
+
+ newy = result->tm_year;
+ if (t < sp->ats[0])
+ 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 = sp->defaulttype;
+ } else {
+ register int lo = 1;
+ register int hi = sp->timecnt;
+
+ while (lo < hi) {
+ register int mid = (lo + hi) >> 1;
+
+ if (t < sp->ats[mid])
+ hi = mid;
+ else lo = mid + 1;
+ }
+ i = (int) sp->types[lo - 1];
+ }
+ ttisp = &sp->ttis[i];
+ /*
+ ** To get (wrong) behavior that's compatible with System V Release 2.0
+ ** you'd replace the statement below with
+ ** t += ttisp->tt_gmtoff;
+ ** timesub(&t, 0L, sp, tmp);
+ */
+ result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
+ if (result) {
+ result->tm_isdst = ttisp->tt_isdst;
+#ifdef TM_ZONE
+ 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_rz(struct state *sp, time_t const *timep, struct tm *tmp)
+{
+ return localsub(sp, timep, 0, tmp);
+}
+
+#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(const time_t *timep)
+{
+ 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(struct state const *sp, time_t const *timep, int_fast32_t offset,
+ struct tm *tmp)
+{
+ register struct tm * result;
+
+ result = timesub(timep, offset, gmtptr, tmp);
+#ifdef TM_ZONE
+ /*
+ ** Could get fancy here and deliver something such as
+ ** "+xx" or "-xx" if offset is non-zero,
+ ** but this is no time for a treasure hunt.
+ */
+ tmp->TM_ZONE = ((char *)
+ (offset ? wildabbr : gmtptr ? gmtptr->chars : gmt));
+#endif /* defined TM_ZONE */
+ return result;
+}
+
+/*
+* Re-entrant version of gmtime.
+*/
+
+struct tm *
+gmtime_r(const time_t *timep, struct tm *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 *timep, long offset)
+{
+ gmtcheck();
+ return gmtsub(gmtptr, timep, offset, &tm);
+}
+
+#endif /* defined STD_INSPIRED */
+
+/*
+** Return the number of leap years through the end of the given year
+** where, to make the math easy, the answer for year zero is defined as zero.
+*/
+
+static int
+leaps_thru_end_of_nonneg(int y)
+{
+ return y / 4 - y / 100 + y / 400;
+}
+
+static int
+leaps_thru_end_of(register const int y)
+{
+ return (y < 0
+ ? -1 - leaps_thru_end_of_nonneg(-1 - y)
+ : leaps_thru_end_of_nonneg(y));
+}
+
+static struct tm *
+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 int_fast64_t rem;
+ int y;
+ register const int * ip;
+ register int_fast64_t corr;
+ register bool hit;
+ register int i;
+
+ corr = 0;
+ hit = false;
+ i = (sp == NULL) ? 0 : sp->leapcnt;
+ while (--i >= 0) {
+ lp = &sp->lsis[i];
+ if (*timep >= lp->ls_trans) {
+ corr = lp->ls_corr;
+ hit = (*timep == lp->ls_trans
+ && (i == 0 ? 0 : lp[-1].ls_corr) < corr);
+ break;
+ }
+ }
+ y = EPOCH_YEAR;
+ tdays = *timep / SECSPERDAY;
+ rem = *timep % SECSPERDAY;
+ while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
+ int newy;
+ register time_t tdelta;
+ register int idelta;
+ register int leapdays;
+
+ tdelta = tdays / DAYSPERLYEAR;
+ if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
+ && tdelta <= INT_MAX))
+ goto out_of_range;
+ idelta = tdelta;
+ if (idelta == 0)
+ idelta = (tdays < 0) ? -1 : 1;
+ newy = y;
+ if (increment_overflow(&newy, idelta))
+ goto out_of_range;
+ leapdays = leaps_thru_end_of(newy - 1) -
+ leaps_thru_end_of(y - 1);
+ tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
+ tdays -= leapdays;
+ y = newy;
+ }
+ /*
+ ** Given the range, we can now fearlessly cast...
+ */
+ idays = tdays;
+ rem += offset - corr;
+ while (rem < 0) {
+ rem += SECSPERDAY;
+ --idays;
+ }
+ while (rem >= SECSPERDAY) {
+ rem -= SECSPERDAY;
+ ++idays;
+ }
+ while (idays < 0) {
+ if (increment_overflow(&y, -1))
+ 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))
+ goto out_of_range;
+ }
+ tmp->tm_year = y;
+ if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
+ goto out_of_range;
+ tmp->tm_yday = idays;
+ /*
+ ** The "extra" mods below avoid overflow problems.
+ */
+ tmp->tm_wday = EPOCH_WDAY +
+ ((y - EPOCH_YEAR) % DAYSPERWEEK) *
+ (DAYSPERNYEAR % DAYSPERWEEK) +
+ leaps_thru_end_of(y - 1) -
+ leaps_thru_end_of(EPOCH_YEAR - 1) +
+ idays;
+ tmp->tm_wday %= DAYSPERWEEK;
+ if (tmp->tm_wday < 0)
+ tmp->tm_wday += DAYSPERWEEK;
+ tmp->tm_hour = (int) (rem / SECSPERHOUR);
+ rem %= SECSPERHOUR;
+ tmp->tm_min = (int) (rem / SECSPERMIN);
+ /*
+ ** A positive leap second requires a special
+ ** representation. This uses "... ??:59:60" et seq.
+ */
+ tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
+ ip = mon_lengths[isleap(y)];
+ for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
+ idays -= ip[tmp->tm_mon];
+ tmp->tm_mday = (int) (idays + 1);
+ tmp->tm_isdst = 0;
+#ifdef TM_GMTOFF
+ tmp->TM_GMTOFF = offset;
+#endif /* defined TM_GMTOFF */
+ return tmp;
+
+ out_of_range:
+ errno = EOVERFLOW;
+ return NULL;
+}
+
+char *
+ctime(const time_t *timep)
+{
+/*
+** Section 4.12.3.2 of X3.159-1989 requires that
+** The ctime function converts the calendar time pointed to by timer
+** to local time in the form of a string. It is equivalent to
+** asctime(localtime(timer))
+*/
+ struct tm *tmp = localtime(timep);
+ return tmp ? asctime(tmp) : NULL;
+}
+
+char *
+ctime_r(const time_t *timep, char *buf)
+{
+ struct tm mytm;
+ struct tm *tmp = localtime_r(timep, &mytm);
+ return tmp ? asctime_r(tmp, buf) : NULL;
+}
+
+/*
+** Adapted from code provided by Robert Elz, who writes:
+** The "best" way to do mktime I think is based on an idea of Bob
+** Kridle's (so its said...) from a long time ago.
+** It does a binary search of the time_t space. Since time_t's are
+** just 32 bits, its a max of 32 iterations (even at 64 bits it
+** would still be very reasonable).
+*/
+
+#ifndef WRONG
+#define WRONG (-1)
+#endif /* !defined WRONG */
+
+/*
+** Normalize logic courtesy Paul Eggert.
+*/
+
+static bool
+increment_overflow(int *ip, int j)
+{
+ register int const i = *ip;
+
+ /*
+ ** If i >= 0 there can only be overflow if i + j > INT_MAX
+ ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
+ ** If i < 0 there can only be overflow if i + j < INT_MIN
+ ** 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;
+ *ip += j;
+ return false;
+}
+
+static bool
+increment_overflow32(int_fast32_t *const lp, int const m)
+{
+ register int_fast32_t const l = *lp;
+
+ if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
+ return true;
+ *lp += m;
+ return false;
+}
+
+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;
+
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) :
+ (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return increment_overflow(tensptr, tensdelta);
+}
+
+static bool
+normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
+{
+ register int tensdelta;
+
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) :
+ (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return increment_overflow32(tensptr, tensdelta);
+}
+
+static int
+tmcomp(register const struct tm *const atmp,
+ register const struct tm *const btmp)
+{
+ register int result;
+
+ 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)
+ result = atmp->tm_sec - btmp->tm_sec;
+ return result;
+}
+
+static time_t
+time2sub(struct tm *const tmp,
+ 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 int dir;
+ register int i, j;
+ register int saved_seconds;
+ register int_fast32_t li;
+ register time_t lo;
+ register time_t hi;
+ int_fast32_t y;
+ time_t newt;
+ time_t t;
+ struct tm yourtm, mytm;
+
+ *okayp = false;
+ yourtm = *tmp;
+ if (do_norm_secs) {
+ if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
+ SECSPERMIN))
+ return WRONG;
+ }
+ if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
+ return WRONG;
+ if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
+ return WRONG;
+ y = yourtm.tm_year;
+ 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 (increment_overflow32(&y, TM_YEAR_BASE))
+ return WRONG;
+ while (yourtm.tm_mday <= 0) {
+ if (increment_overflow32(&y, -1))
+ return WRONG;
+ li = y + (1 < yourtm.tm_mon);
+ yourtm.tm_mday += year_lengths[isleap(li)];
+ }
+ while (yourtm.tm_mday > DAYSPERLYEAR) {
+ li = y + (1 < yourtm.tm_mon);
+ yourtm.tm_mday -= year_lengths[isleap(li)];
+ if (increment_overflow32(&y, 1))
+ return WRONG;
+ }
+ for ( ; ; ) {
+ i = mon_lengths[isleap(y)][yourtm.tm_mon];
+ if (yourtm.tm_mday <= i)
+ break;
+ yourtm.tm_mday -= i;
+ if (++yourtm.tm_mon >= MONSPERYEAR) {
+ yourtm.tm_mon = 0;
+ if (increment_overflow32(&y, 1))
+ return WRONG;
+ }
+ }
+ 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_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
+ saved_seconds = 0;
+ else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
+ /*
+ ** We can't set tm_sec to 0, because that might push the
+ ** time below the minimum representable time.
+ ** Set tm_sec to 59 instead.
+ ** This assumes that the minimum representable time is
+ ** not in the same minute that a leap second was deleted from,
+ ** which is a safer assumption than using 58 would be.
+ */
+ if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
+ return WRONG;
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = SECSPERMIN - 1;
+ } else {
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = 0;
+ }
+ /*
+ ** Do a binary search (this works whatever time_t's type is).
+ */
+ lo = TIME_T_MIN;
+ hi = TIME_T_MAX;
+ for ( ; ; ) {
+ t = lo / 2 + hi / 2;
+ if (t < lo)
+ t = lo;
+ else if (t > hi)
+ t = hi;
+ 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
+ ** extreme on the next pass.
+ */
+ dir = (t > 0) ? 1 : -1;
+ } else dir = tmcomp(&mytm, &yourtm);
+ if (dir != 0) {
+ if (t == lo) {
+ if (t == TIME_T_MAX)
+ return WRONG;
+ ++t;
+ ++lo;
+ } else if (t == hi) {
+ if (t == TIME_T_MIN)
+ return WRONG;
+ --t;
+ --hi;
+ }
+ if (lo > hi)
+ return WRONG;
+ if (dir > 0)
+ hi = t;
+ 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 UT 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;
+ /*
+ ** Right time, wrong type.
+ ** Hunt for right time, right type.
+ ** It's okay to guess wrong since the guess
+ ** gets checked.
+ */
+ if (sp == NULL)
+ return WRONG;
+ for (i = sp->typecnt - 1; i >= 0; --i) {
+ if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
+ continue;
+ for (j = sp->typecnt - 1; j >= 0; --j) {
+ if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
+ continue;
+ newt = t + sp->ttis[j].tt_gmtoff -
+ sp->ttis[i].tt_gmtoff;
+ if (! funcp(sp, &newt, offset, &mytm))
+ continue;
+ if (tmcomp(&mytm, &yourtm) != 0)
+ continue;
+ if (mytm.tm_isdst != yourtm.tm_isdst)
+ continue;
+ /*
+ ** We have a match.
+ */
+ t = newt;
+ goto label;
+ }
+ }
+ return WRONG;
+ }
+label:
+ newt = t + saved_seconds;
+ if ((newt < t) != (saved_seconds < 0))
+ return WRONG;
+ t = newt;
+ if (funcp(sp, &t, offset, tmp))
+ *okayp = true;
+ return t;
+}
+
+static time_t
+time2(struct tm * const tmp,
+ 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;
+
+ /*
+ ** First try without normalization of seconds
+ ** (in case tm_sec contains a value associated with a leap second).
+ ** If that fails, try with normalization of seconds.
+ */
+ 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 *(*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 int samei, otheri;
+ register int sameind, otherind;
+ register int i;
+ register int nseen;
+ char seen[TZ_MAX_TYPES];
+ unsigned char types[TZ_MAX_TYPES];
+ bool okay;
+
+ if (tmp == NULL) {
+ errno = EINVAL;
+ return WRONG;
+ }
+ if (tmp->tm_isdst > 1)
+ tmp->tm_isdst = 1;
+ 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 */
+#else
+ return t;
+#endif /* !defined PCTS */
+ /*
+ ** We're supposed to assume that somebody took a time of one type
+ ** and did some math on it that yielded a "struct tm" that's bad.
+ ** We try to divine the type they started from and adjust to the
+ ** type they need.
+ */
+ if (sp == NULL)
+ return WRONG;
+ for (i = 0; i < sp->typecnt; ++i)
+ seen[i] = false;
+ nseen = 0;
+ for (i = sp->timecnt - 1; i >= 0; --i)
+ if (!seen[sp->types[i]]) {
+ seen[sp->types[i]] = true;
+ types[nseen++] = sp->types[i];
+ }
+ for (sameind = 0; sameind < nseen; ++sameind) {
+ samei = types[sameind];
+ if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
+ continue;
+ for (otherind = 0; otherind < nseen; ++otherind) {
+ otheri = types[otherind];
+ if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
+ continue;
+ tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
+ sp->ttis[samei].tt_gmtoff;
+ tmp->tm_isdst = !tmp->tm_isdst;
+ t = time2(tmp, funcp, sp, offset, &okay);
+ if (okay)
+ return t;
+ tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
+ sp->ttis[samei].tt_gmtoff;
+ tmp->tm_isdst = !tmp->tm_isdst;
+ }
+ }
+ return WRONG;
+}
+
+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_z(struct state *sp, struct tm *tmp)
+{
+ 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 *tmp)
+{
+ if (tmp != NULL)
+ tmp->tm_isdst = -1; /* in case it wasn't initialized */
+ return mktime(tmp);
+}
+
+time_t
+timegm(struct tm *tmp)
+{
+ return timeoff(tmp, 0);
+}
+
+time_t
+timeoff(struct tm *tmp, long offset)
+{
+ if (tmp)
+ tmp->tm_isdst = 0;
+ gmtcheck();
+ return time1(tmp, gmtsub, gmtptr, offset);
+}
+
+#endif /* defined STD_INSPIRED */
+
+/*
+** XXX--is the below the right way to conditionalize??
+*/
+
+#ifdef STD_INSPIRED
+
+/*
+** IEEE Std 1003.1 (POSIX) says that 536457599
+** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
+** is not the case if we are accounting for leap seconds.
+** So, we provide the following conversion routines for use
+** when exchanging timestamps with POSIX conforming systems.
+*/
+
+static int_fast64_t
+leapcorr(struct state const *sp, time_t t)
+{
+ register struct lsinfo const * lp;
+ register int i;
+
+ i = sp->leapcnt;
+ while (--i >= 0) {
+ lp = &sp->lsis[i];
+ if (t >= lp->ls_trans)
+ return lp->ls_corr;
+ }
+ return 0;
+}
+
+NETBSD_INSPIRED_EXTERN time_t
+time2posix_z(struct state *sp, time_t t)
+{
+ return t - leapcorr(sp, t);
+}
+
+time_t
+time2posix(time_t 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;
+}
+
+NETBSD_INSPIRED_EXTERN time_t
+posix2time_z(struct state *sp, time_t t)
+{
+ time_t x;
+ time_t y;
+ /*
+ ** For a positive leap second hit, the result
+ ** is not unique. For a negative leap second
+ ** hit, the corresponding time doesn't exist,
+ ** so we return an adjacent second.
+ */
+ x = t + leapcorr(sp, t);
+ y = x - leapcorr(sp, x);
+ if (y < t) {
+ do {
+ x++;
+ y = x - leapcorr(sp, x);
+ } while (y < t);
+ x -= y != t;
+ } else if (y > t) {
+ do {
+ --x;
+ y = x - leapcorr(sp, x);
+ } while (y > t);
+ 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 */
+
+#if TZ_TIME_T
+
+# if !USG_COMPAT
+# define daylight 0
+# define timezone 0
+# endif
+# ifndef ALTZONE
+# define altzone 0
+# endif
+
+/* Convert from the underlying system's time_t to the ersatz time_tz,
+ which is called 'time_t' in this file. Typically, this merely
+ converts the time's integer width. On some platforms, the system
+ time is local time not UT, or uses some epoch other than the POSIX
+ epoch.
+
+ Although this code appears to define a function named 'time' that
+ returns time_t, the macros in private.h cause this code to actually
+ define a function named 'tz_time' that returns tz_time_t. The call
+ to sys_time invokes the underlying system's 'time' function. */
+
+time_t
+time(time_t *p)
+{
+ time_t r = sys_time(0);
+ if (r != (time_t) -1) {
+ int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0;
+ if (increment_overflow32(&offset, -EPOCH_OFFSET)
+ || increment_overflow_time (&r, offset)) {
+ errno = EOVERFLOW;
+ r = -1;
+ }
+ }
+ if (p)
+ *p = r;
+ return r;
+}
+
+#endif
Property changes on: vendor/tzdb/tzcode2018e/localtime.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/newctime.3
===================================================================
--- vendor/tzdb/tzcode2018e/newctime.3 (nonexistent)
+++ vendor/tzdb/tzcode2018e/newctime.3 (revision 337695)
@@ -0,0 +1,317 @@
+.TH NEWCTIME 3
+.SH NAME
+asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
+.SH SYNOPSIS
+.nf
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
+.B #include
+.PP
+.BR "extern char *tzname[];" " /\(** (optional) \(**/"
+.PP
+.B char *ctime(time_t const *clock);
+.PP
+.B char *ctime_r(time_t const *clock, char *buf);
+.PP
+.B double difftime(time_t time1, time_t time0);
+.PP
+.B char *asctime(struct tm const *tm);
+.PP
+.B "char *asctime_r(struct tm const *restrict tm,"
+.B " char *restrict result);"
+.PP
+.B struct tm *localtime(time_t const *clock);
+.PP
+.B "struct tm *localtime_r(time_t const *restrict clock,"
+.B " struct tm *restrict result);"
+.PP
+.B "struct tm *localtime_rz(timezone_t restrict zone,"
+.B " time_t const *restrict clock,"
+.B " struct tm *restrict result);"
+.PP
+.B struct tm *gmtime(time_t const *clock);
+.PP
+.B "struct tm *gmtime_r(time_t const *restrict clock,"
+.B " struct tm *restrict result);"
+.PP
+.B time_t mktime(struct tm *tm);
+.PP
+.B "time_t mktime_z(timezone_t restrict zone,"
+.B " struct tm *restrict tm);"
+.PP
+.B cc ... \*-ltz
+.fi
+.SH DESCRIPTION
+.ie '\(en'' .ds en \-
+.el .ds en \(en
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
+.I Ctime
+converts a long integer, pointed to by
+.IR clock ,
+and returns a pointer to a
+string of the form
+.br
+.ce
+.eo
+Thu Nov 24 18:22:48 1986\n\0
+.br
+.ec
+Years requiring fewer than four characters are padded with leading zeroes.
+For years longer than four characters, the string is of the form
+.br
+.ce
+.eo
+Thu Nov 24 18:22:48 81986\n\0
+.ec
+.br
+with five spaces before the year.
+These unusual formats are designed to make it less likely that older
+software that expects exactly 26 bytes of output will mistakenly output
+misleading values for out-of-range years.
+.PP
+The
+.BI * clock
+timestamp represents the time in seconds since 1970-01-01 00:00:00
+Coordinated Universal Time (UTC).
+The POSIX standard says that timestamps must be nonnegative
+and must ignore leap seconds.
+Many implementations extend POSIX by allowing negative timestamps,
+and can therefore represent timestamps that predate the
+introduction of UTC and are some other flavor of Universal Time (UT).
+Some implementations support leap seconds, in contradiction to POSIX.
+.PP
+.I Localtime
+and
+.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
+.q "tm"
+structure,
+.I localtime
+sets the
+.BR tm_isdst 'th
+element of
+.B tzname
+to a pointer to a string that's the time zone abbreviation to be used with
+.IR localtime 's
+return value.
+.PP
+.I Gmtime
+converts to Coordinated Universal Time.
+.PP
+.I Asctime
+converts a time value contained in a
+.q "tm"
+structure to a string,
+as shown in the above example,
+and returns a pointer to the string.
+.PP
+.I Mktime
+converts the broken-down time,
+expressed as local time,
+in the structure pointed to by
+.I tm
+into a calendar time value with the same encoding as that of the values
+returned by the
+.I time
+function.
+The original values of the
+.B tm_wday
+and
+.B tm_yday
+components of the structure are ignored,
+and the original values of the other components are not restricted
+to their normal ranges.
+(A positive or zero value for
+.B tm_isdst
+causes
+.I mktime
+to presume initially that daylight saving time
+respectively,
+is or is not in effect for the specified time.
+A negative value for
+.B tm_isdst
+causes the
+.I mktime
+function to attempt to divine whether daylight saving time is in effect
+for the specified time; in this case it does not use a consistent
+rule and may give a different answer when later
+presented with the same argument.)
+On successful completion, the values of the
+.B tm_wday
+and
+.B tm_yday
+components of the structure are set appropriately,
+and the other components are set to represent the specified calendar time,
+but with their values forced to their normal ranges; the final value of
+.B tm_mday
+is not set until
+.B tm_mon
+and
+.B tm_year
+are determined.
+.I Mktime
+returns the specified calendar time;
+If the calendar time cannot be represented,
+it returns \-1.
+.PP
+.I Difftime
+returns the difference between two calendar times,
+.RI ( time1
+\-
+.IR time0 ),
+expressed in seconds.
+.PP
+.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, UT 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
+header file.
+The structure (of type)
+.B struct tm
+includes the following fields:
+.RS
+.PP
+.nf
+.ta 2n +\w'long tm_gmtoff;nn'u
+ int tm_sec; /\(** seconds (0\*(en60) \(**/
+ int tm_min; /\(** minutes (0\*(en59) \(**/
+ int tm_hour; /\(** hours (0\*(en23) \(**/
+ int tm_mday; /\(** day of month (1\*(en31) \(**/
+ int tm_mon; /\(** month of year (0\*(en11) \(**/
+ int tm_year; /\(** year \- 1900 \(**/
+ int tm_wday; /\(** day of week (Sunday = 0) \(**/
+ int tm_yday; /\(** day of year (0\*(en365) \(**/
+ int tm_isdst; /\(** is daylight saving time in effect? \(**/
+ char \(**tm_zone; /\(** time zone abbreviation (optional) \(**/
+ long tm_gmtoff; /\(** offset from UT in seconds (optional) \(**/
+.fi
+.RE
+.PP
+.I Tm_isdst
+is non-zero if daylight saving time is in effect.
+.PP
+.I 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.
+.PP
+In
+.B struct tm
+the
+.I tm_zone
+and
+.I tm_gmtoff
+fields exist, and are filled in, only if arrangements to do
+so were made when the library containing these functions was
+created.
+Similarly, the
+.B tzname
+variable is optional.
+There is no guarantee that these fields and this variable will
+continue to exist in this form in future releases of this code.
+.SH FILES
+.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
+/usr/share/zoneinfo time zone information directory
+.br
+/usr/share/zoneinfo/localtime local time zone file
+.br
+/usr/share/zoneinfo/posixrules used with POSIX-style TZ's
+.br
+/usr/share/zoneinfo/GMT for UTC leap seconds
+.sp
+If
+.B /usr/share/zoneinfo/GMT
+is absent,
+UTC leap seconds are loaded from
+.BR /usr/share/zoneinfo/posixrules .
+.SH SEE ALSO
+getenv(3),
+newstrftime(3),
+newtzset(3),
+time(2),
+tzfile(5)
+.SH NOTES
+The return values of
+.IR asctime ,
+.IR ctime ,
+.IR gmtime ,
+and
+.I localtime
+point to static data
+overwritten by each call.
+The
+.B tzname
+variable (once set) and the
+.B tm_zone
+field of a returned
+.B "struct tm"
+both point to an array of characters that
+can be freed or overwritten by later calls to the functions
+.IR localtime ,
+.IR tzfree ,
+and
+.IR tzset ,
+if these functions affect the time zone information that specifies the
+abbreviation in question.
+The remaining functions and data are thread-safe.
+.PP
+.IR Asctime ,
+.IR asctime_r ,
+.IR ctime ,
+and
+.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
+instead.
+.\" This file is in the public domain, so clarified as of
+.\" 2009-05-17 by Arthur David Olson.
Property changes on: vendor/tzdb/tzcode2018e/newctime.3
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/newctime.3.txt
===================================================================
--- vendor/tzdb/tzcode2018e/newctime.3.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/newctime.3.txt (revision 337695)
@@ -0,0 +1,171 @@
+NEWCTIME(3) Library Functions Manual NEWCTIME(3)
+
+NAME
+ asctime, ctime, difftime, gmtime, localtime, mktime - convert date and
+ time
+
+SYNOPSIS
+ #include
+
+ extern char *tzname[]; /* (optional) */
+
+ char *ctime(time_t const *clock);
+
+ char *ctime_r(time_t const *clock, char *buf);
+
+ double difftime(time_t time1, time_t time0);
+
+ char *asctime(struct tm const *tm);
+
+ char *asctime_r(struct tm const *restrict tm,
+ char *restrict result);
+
+ struct tm *localtime(time_t const *clock);
+
+ struct tm *localtime_r(time_t const *restrict clock,
+ struct tm *restrict result);
+
+ struct tm *localtime_rz(timezone_t restrict zone,
+ time_t const *restrict clock,
+ struct tm *restrict result);
+
+ 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, 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
+ form
+ Thu Nov 24 18:22:48 81986\n\0
+ with five spaces before the year. These unusual formats are designed
+ to make it less likely that older software that expects exactly 26
+ bytes of output will mistakenly output misleading values for out-of-
+ range years.
+
+ The *clock timestamp represents the time in seconds since 1970-01-01
+ 00:00:00 Coordinated Universal Time (UTC). The POSIX standard says
+ that timestamps must be nonnegative and must ignore leap seconds. Many
+ implementations extend POSIX by allowing negative timestamps, and can
+ therefore represent timestamps that predate the introduction of UTC and
+ are some other flavor of Universal Time (UT). Some implementations
+ support leap seconds, in contradiction to POSIX.
+
+ 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 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
+ string, as shown in the above example, and returns a pointer to the
+ string.
+
+ Mktime converts the broken-down time, expressed as local time, in the
+ structure pointed to by tm into a calendar time value with the same
+ encoding as that of the values returned by the time function. The
+ original values of the tm_wday and tm_yday components of the structure
+ are ignored, and the original values of the other components are not
+ restricted to their normal ranges. (A positive or zero value for
+ tm_isdst causes mktime to presume initially that daylight saving time
+ respectively, is or is not in effect for the specified time. A
+ negative value for tm_isdst causes the mktime function to attempt to
+ divine whether daylight saving time is in effect for the specified
+ time; in this case it does not use a consistent rule and may give a
+ different answer when later presented with the same argument.) On
+ successful completion, the values of the tm_wday and tm_yday components
+ of the structure are set appropriately, and the other components are
+ set to represent the specified calendar time, but with their values
+ forced to their normal ranges; the final value of tm_mday is not set
+ until tm_mon and tm_year are determined. Mktime returns the specified
+ calendar time; If the calendar time cannot be represented, it returns
+ -1.
+
+ Difftime returns the difference between two calendar times, (time1 -
+ time0), expressed in seconds.
+
+ 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, UT 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 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_year; /* year - 1900 */
+ int tm_wday; /* day of week (Sunday = 0) */
+ int tm_yday; /* day of year (0-365) */
+ int tm_isdst; /* is daylight saving time in effect? */
+ char *tm_zone; /* time zone abbreviation (optional) */
+ long tm_gmtoff; /* offset from UT in seconds (optional) */
+
+ Tm_isdst is non-zero if daylight saving time is in effect.
+
+ 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.
+
+ In struct tm 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 functions was created. Similarly, the tzname variable is
+ optional. There is no guarantee that these fields and this variable
+ will continue to exist in this form in future releases of this code.
+
+FILES
+ /usr/share/zoneinfo time zone information directory
+ /usr/share/zoneinfo/localtime local time zone file
+ /usr/share/zoneinfo/posixrules used with POSIX-style TZ's
+ /usr/share/zoneinfo/GMT for UTC leap seconds
+
+ If /usr/share/zoneinfo/GMT is absent, UTC leap seconds are loaded from
+ /usr/share/zoneinfo/posixrules.
+
+SEE ALSO
+ getenv(3), newstrftime(3), newtzset(3), time(2), tzfile(5)
+
+NOTES
+ The return values of asctime, ctime, gmtime, and localtime point to
+ static data overwritten by each call. The tzname variable (once set)
+ and the tm_zone field of a returned struct tm both point to an array of
+ characters that can be freed or overwritten by later calls to the
+ functions localtime, tzfree, and tzset, if these functions affect the
+ time zone information that specifies the abbreviation in question. The
+ remaining functions and data are thread-safe.
+
+ 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.
+
+ NEWCTIME(3)
Property changes on: vendor/tzdb/tzcode2018e/newctime.3.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/newstrftime.3
===================================================================
--- vendor/tzdb/tzcode2018e/newstrftime.3 (nonexistent)
+++ vendor/tzdb/tzcode2018e/newstrftime.3 (revision 337695)
@@ -0,0 +1,238 @@
+.\" Based on the UCB file whose corrected copyright information appears below.
+.\" Copyright 1989, 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
+.\" $Id: strftime.3,v 1.4 1993/12/15 20:33:00 jtc Exp $
+.\"
+.TH NEWSTRFTIME 3
+.SH NAME
+strftime \- format date and time
+.SH SYNOPSIS
+.nf
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
+.B #include
+.PP
+.B "size_t strftime(char *restrict buf, size_t maxsize,"
+.B " char const *restrict format, struct tm const *restrict timeptr);"
+.PP
+.B cc ... \-ltz
+.fi
+.SH DESCRIPTION
+.ie '\(en'' .ds en \-
+.el .ds en \(en
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
+The
+.I strftime
+function formats the information from
+.I timeptr
+into the buffer
+.I buf
+according to the string pointed to by
+.IR format .
+.PP
+The
+.I format
+string consists of zero or more conversion specifications and
+ordinary characters.
+All ordinary characters are copied directly into the buffer.
+A conversion specification consists of a percent sign
+.Ql %
+and one other character.
+.PP
+No more than
+.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
+returns the number of characters in the array, not counting the
+terminating null.
+Otherwise, zero is returned.
+.PP
+Each conversion specification is replaced by the characters as
+follows which are then copied into the buffer.
+.TP
+%A
+is replaced by the locale's full weekday name.
+.TP
+%a
+is replaced by the locale's abbreviated weekday name.
+.TP
+%B
+is replaced by the locale's full month name.
+.TP
+%b or %h
+is replaced by the locale's abbreviated month name.
+.TP
+%C
+is replaced by the century (a year divided by 100 and truncated to an integer)
+as a decimal number (00\*(en99).
+.TP
+%c
+is replaced by the locale's appropriate date and time representation.
+.TP
+%D
+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\*(en31).
+.TP
+%e
+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.
+.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\*(en99).
+.TP
+%H
+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\*(en12).
+.TP
+%j
+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\*(en23);
+single digits are preceded by a blank.
+.TP
+%l
+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\*(en59).
+.TP
+%m
+is replaced by the month as a decimal number (01\*(en12).
+.TP
+%n
+is replaced by a newline.
+.TP
+%p
+is replaced by the locale's equivalent of either AM or PM.
+.TP
+%R
+is replaced by the time in the format %H:%M.
+.TP
+%r
+is replaced by the locale's representation of 12-hour clock time
+using AM/PM notation.
+.TP
+%S
+is replaced by the second as a decimal number (00\*(en60).
+.TP
+%s
+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.
+.TP
+%t
+is replaced by a tab.
+.TP
+%U
+is replaced by the week number of the year (Sunday as the first day of
+the week) as a decimal number (00\*(en53).
+.TP
+%u
+is replaced by the weekday (Monday as the first day of the week)
+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\*(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\*(en53).
+.TP
+%w
+is replaced by the weekday (Sunday as the first day of the week)
+as a decimal number (0\*(en6).
+.TP
+%X
+is replaced by the locale's appropriate time representation.
+.TP
+%x
+is replaced by the locale's appropriate date representation.
+.TP
+%Y
+is replaced by the year with century as a decimal number.
+.TP
+%y
+is replaced by the year without century as a decimal number (00\*(en99).
+.TP
+%Z
+is replaced by the time zone name,
+or by the empty string if this is not determinable.
+.TP
+%z
+is replaced by the offset from the Prime Meridian
+in the format +HHMM or \*-HHMM as appropriate,
+with positive values representing locations east of Greenwich,
+or by the empty string if this is not determinable.
+The numeric time zone \*-0000 is used when the time is Universal Time
+but local time is indeterminate; by convention this is used for
+locations while uninhabited, and corresponds to a zero offset when the
+time zone abbreviation begins with
+.q "\*-" .
+.TP
+%%
+is replaced by a single %.
+.TP
+%+
+is replaced by the date and time in date(1) format.
+.SH SEE ALSO
+date(1),
+getenv(3),
+newctime(3),
+newtzset(3),
+time(2),
+tzfile(5)
Property changes on: vendor/tzdb/tzcode2018e/newstrftime.3
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/newstrftime.3.txt
===================================================================
--- vendor/tzdb/tzcode2018e/newstrftime.3.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/newstrftime.3.txt (revision 337695)
@@ -0,0 +1,145 @@
+NEWSTRFTIME(3) Library Functions Manual NEWSTRFTIME(3)
+
+NAME
+ strftime - format date and time
+
+SYNOPSIS
+ #include
+
+ size_t strftime(char *restrict buf, size_t maxsize,
+ char const *restrict format, struct tm const *restrict timeptr);
+
+ cc ... -ltz
+
+DESCRIPTION
+ The strftime function formats the information from timeptr into the
+ buffer buf according to the string pointed to by format.
+
+ The format string consists of zero or more conversion specifications
+ and ordinary characters. All ordinary characters are copied directly
+ into the buffer. A conversion specification consists of a percent sign
+ and one other character.
+
+ 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,
+ zero is returned.
+
+ Each conversion specification is replaced by the characters as follows
+ which are then copied into the buffer.
+
+ %A is replaced by the locale's full weekday name.
+
+ %a is replaced by the locale's abbreviated weekday name.
+
+ %B is replaced by the locale's full month name.
+
+ %b or %h
+ is replaced by the locale's abbreviated month name.
+
+ %C is replaced by the century (a year divided by 100 and truncated
+ to an integer) as a decimal number (00-99).
+
+ %c is replaced by the locale's appropriate date and time
+ representation.
+
+ %D is replaced by the date in the format %m/%d/%y.
+
+ %d is replaced by the day of the month as a decimal number (01-31).
+
+ %e is replaced by the day of month as a decimal number (1-31);
+ single digits are preceded by a blank.
+
+ %F is replaced by the date in the format %Y-%m-%d.
+
+ %G is replaced by the ISO 8601 year with century as a decimal
+ number.
+
+ %g is replaced by the ISO 8601 year without century as a decimal
+ number (00-99).
+
+ %H is replaced by the hour (24-hour clock) as a decimal number
+ (00-23).
+
+ %I is replaced by the hour (12-hour clock) as a decimal number
+ (01-12).
+
+ %j is replaced by the day of the year as a decimal number
+ (001-366).
+
+ %k is replaced by the hour (24-hour clock) as a decimal number
+ (0-23); single digits are preceded by a blank.
+
+ %l is replaced by the hour (12-hour clock) as a decimal number
+ (1-12); single digits are preceded by a blank.
+
+ %M is replaced by the minute as a decimal number (00-59).
+
+ %m is replaced by the month as a decimal number (01-12).
+
+ %n is replaced by a newline.
+
+ %p is replaced by the locale's equivalent of either AM or PM.
+
+ %R is replaced by the time in the format %H:%M.
+
+ %r is replaced by the locale's representation of 12-hour clock time
+ using AM/PM notation.
+
+ %S is replaced by the second as a decimal number (00-60).
+
+ %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.
+
+ %t is replaced by a tab.
+
+ %U is replaced by the week number of the year (Sunday as the first
+ day of the week) as a decimal number (00-53).
+
+ %u is replaced by the weekday (Monday as the first day of the week)
+ as a decimal number (1-7).
+
+ %V is replaced by the week number of the year (Monday as the first
+ day of the week) as a decimal number (01-53). If the week
+ containing January 1 has four or more days in the new year, then
+ it is week 1; otherwise it is week 53 of the previous year, and
+ the next week is week 1.
+
+ %W is replaced by the week number of the year (Monday as the first
+ day of the week) as a decimal number (00-53).
+
+ %w is replaced by the weekday (Sunday as the first day of the week)
+ as a decimal number (0-6).
+
+ %X is replaced by the locale's appropriate time representation.
+
+ %x is replaced by the locale's appropriate date representation.
+
+ %Y is replaced by the year with century as a decimal number.
+
+ %y is replaced by the year without century as a decimal number
+ (00-99).
+
+ %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 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. The numeric time zone -0000 is used when the
+ time is Universal Time but local time is indeterminate; by
+ convention this is used for locations while uninhabited, and
+ corresponds to a zero offset when the time zone abbreviation
+ begins with "-".
+
+ %% is replaced by a single %.
+
+ %+ is replaced by the date and time in date(1) format.
+
+SEE ALSO
+ date(1), getenv(3), newctime(3), newtzset(3), time(2), tzfile(5)
+
+ NEWSTRFTIME(3)
Property changes on: vendor/tzdb/tzcode2018e/newstrftime.3.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/newtzset.3
===================================================================
--- vendor/tzdb/tzcode2018e/newtzset.3 (nonexistent)
+++ vendor/tzdb/tzcode2018e/newtzset.3 (revision 337695)
@@ -0,0 +1,344 @@
+.TH NEWTZSET 3
+.SH NAME
+tzset \- initialize time conversion information
+.SH SYNOPSIS
+.nf
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
+.B #include
+.PP
+.B timezone_t tzalloc(char const *TZ);
+.PP
+.B void tzfree(timezone_t tz);
+.PP
+.B void tzset(void);
+.PP
+.B cc ... \*-ltz
+.fi
+.SH DESCRIPTION
+.ie '\(en'' .ds en \-
+.el .ds en \(en
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
+.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
+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 Universal Time (UT).
+.PP
+If
+.B TZ
+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.
+If
+.B TZ
+is the empty string,
+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
+is nonnull and nonempty:
+.IP
+if the value begins with a colon, it is used as a pathname of a file
+from which to read the time conversion information;
+.IP
+if the value does not begin with a colon, it is first used as the
+pathname of a file from which to read the time conversion information,
+and, if that file cannot be read, is used directly as a specification of
+the time conversion information.
+.PP
+When
+.B TZ
+is used as a pathname, if it begins with a slash,
+it is used as an absolute pathname; otherwise,
+it is used as a pathname relative to a system time conversion information
+directory.
+The file must be in the format specified in
+.IR tzfile (5).
+.PP
+When
+.B TZ
+is used directly as a specification of the time conversion information,
+it must have the following syntax (spaces inserted for clarity):
+.IP
+\fIstd\|offset\fR[\fIdst\fR[\fIoffset\fR][\fB,\fIrule\fR]]
+.PP
+Where:
+.RS
+.TP 15
+.IR std " and " dst
+Three or more bytes that are the designation for the standard
+.RI ( std )
+or the alternative
+.RI ( dst ,
+such as daylight saving time)
+time zone. Only
+.I std
+is required; if
+.I dst
+is missing, then daylight saving time does not apply in this locale.
+Upper- and lowercase letters are explicitly allowed. Any characters
+except a leading colon
+.RB ( : ),
+digits, comma
+.RB ( , ),
+ASCII minus
+.RB ( \*- ),
+ASCII plus
+.RB ( + ),
+and NUL bytes are allowed.
+Alternatively, a designation can be surrounded by angle brackets
+.B <
+and
+.BR > ;
+in this case, the designation can contain any characters other than
+.B >
+and NUL.
+.TP
+.I offset
+Indicates the value one must add to the local time to arrive at
+Coordinated Universal Time. The
+.I offset
+has the form:
+.RS
+.IP
+\fIhh\fR[\fB:\fImm\fR[\fB:\fIss\fR]]
+.RE
+.IP
+The minutes
+.RI ( mm )
+and seconds
+.RI ( ss )
+are optional. The hour
+.RI ( hh )
+is required and may be a single digit. The
+.I offset
+following
+.I std
+is required. If no
+.I offset
+follows
+.IR dst ,
+daylight saving time is assumed to be one hour ahead of standard time. One or
+more digits may be used; the value is always interpreted as a decimal
+number. The hour must be between zero and 24, and the minutes (and
+seconds) \*(en if present \*(en between zero and 59. If preceded by a
+.q "\*-" ,
+the time zone shall be east of the Prime Meridian; otherwise it shall be
+west (which may be indicated by an optional preceding
+.q "+" .
+.TP
+.I rule
+Indicates when to change to and back from daylight saving time. The
+.I rule
+has the form:
+.RS
+.IP
+\fIdate\fB/\fItime\fB,\fIdate\fB/\fItime\fR
+.RE
+.IP
+where the first
+.I date
+describes when the change from standard to daylight saving time occurs and the
+second
+.I date
+describes when the change back happens. Each
+.I time
+field describes when, in current local time, the change to the other
+time is made.
+As an extension to POSIX, daylight saving is assumed to be in effect
+all year if it begins January 1 at 00:00 and ends December 31 at
+24:00 plus the difference between daylight saving and standard time,
+leaving no room for standard time in the calendar.
+.IP
+The format of
+.I date
+is one of the following:
+.RS
+.TP 10
+.BI J n
+The Julian day
+.I n
+.RI "(1\ \(<=" "\ n\ " "\(<=\ 365).
+Leap days are not counted; that is, in all years \*(en including leap
+years \*(en February 28 is day 59 and March 1 is day 60. It is
+impossible to explicitly refer to the occasional February 29.
+.TP
+.I n
+The zero-based Julian day
+.RI "(0\ \(<=" "\ n\ " "\(<=\ 365).
+Leap days are counted, and it is possible to refer to February 29.
+.TP
+.BI M m . n . d
+The
+.IR d' th
+day
+.RI "(0\ \(<=" "\ d\ " "\(<=\ 6)
+of week
+.I n
+of month
+.I m
+of the year
+.RI "(1\ \(<=" "\ n\ " "\(<=\ 5,
+.RI "1\ \(<=" "\ m\ " "\(<=\ 12,
+where week 5 means
+.q "the last \fId\fP day in month \fIm\fP"
+which may occur in either the fourth or the fifth week). Week 1 is the
+first week in which the
+.IR d' th
+day occurs. Day zero is Sunday.
+.RE
+.IP "" 15
+The
+.I time
+has the same format as
+.I offset
+except that POSIX does not allow a leading sign (\c
+.q "\*-"
+or
+.q "+" ).
+As an extension to POSIX, the hours part of
+.I time
+can range from \-167 through 167; this allows for unusual rules such
+as
+.q "the Saturday before the first Sunday of March" .
+The default, if
+.I time
+is not given, is
+.BR 02:00:00 .
+.RE
+.LP
+Here are some examples of
+.B TZ
+values that directly specify the time zone rules; they use some of the
+extensions to POSIX.
+.TP
+.B EST5
+stands for US Eastern Standard
+Time (EST), 5 hours behind UT, without daylight saving.
+.TP
+.B <+12>\*-12<+13>,M11.1.0,M1.2.1/147
+stands for Fiji time, 12 hours ahead
+of UT, springing forward on November's first Sunday at 02:00, and
+falling back on January's second Monday at 147:00 (i.e., 03:00 on the
+first Sunday on or after January 14). The abbreviations for standard
+and daylight saving time are
+.q "+12"
+and
+.q "+13".
+.TP
+.B IST\*-2IDT,M3.4.4/26,M10.5.0
+stands for Israel Standard Time (IST) and Israel Daylight Time (IDT),
+2 hours ahead of UT, springing forward on March's fourth
+Thursday at 26:00 (i.e., 02:00 on the first Friday on or after March
+23), and falling back on October's last Sunday at 02:00.
+.TP
+.B <\*-04>4<\*-03>,J1/0,J365/25
+stands for permanent daylight saving time, 3 hours behind UT with
+abbreviation
+.q "\*-03".
+There is a dummy fall-back transition on December 31 at 25:00 daylight
+saving time (i.e., 24:00 standard time, equivalent to January 1 at
+00:00 standard time), and a simultaneous spring-forward transition on
+January 1 at 00:00 standard time, so daylight saving time is in effect
+all year and the initial
+.B <\*-04>
+is a placeholder.
+.TP
+.B <\*-03>3<\*-02>,M3.5.0/\*-2,M10.5.0/\*-1
+stands for time in western Greenland, 3 hours behind UT, where clocks
+follow the EU rules of
+springing forward on March's last Sunday at 01:00 UT (\-02:00 local
+time, i.e., 22:00 the previous day) and falling back on October's last
+Sunday at 01:00 UT (\-01:00 local time, i.e., 23:00 the previous day).
+The abbreviations for standard and daylight saving time are
+.q "\*-03"
+and
+.q "\*-02".
+.PP
+If no
+.I rule
+is present in
+.BR TZ ,
+the rules specified
+by the
+.IR tzfile (5)-format
+file
+.B posixrules
+in the system time conversion information directory are used, with the
+standard and daylight saving time offsets from UT replaced by those specified by
+the
+.I offset
+values in
+.BR TZ .
+.PP
+For compatibility with System V Release 3.1, a semicolon
+.RB ( ; )
+may be used to separate the
+.I rule
+from the rest of the specification.
+.SH FILES
+.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
+/usr/share/zoneinfo time zone information directory
+.br
+/usr/share/zoneinfo/localtime local time zone file
+.br
+/usr/share/zoneinfo/posixrules used with POSIX-style TZ's
+.br
+/usr/share/zoneinfo/GMT for UTC leap seconds
+.sp
+If
+.B /usr/share/zoneinfo/GMT
+is absent,
+UTC leap seconds are loaded from
+.BR /usr/share/zoneinfo/posixrules .
+.SH SEE ALSO
+getenv(3),
+newctime(3),
+newstrftime(3),
+time(2),
+tzfile(5)
+.\" This file is in the public domain, so clarified as of
+.\" 2009-05-17 by Arthur David Olson.
Property changes on: vendor/tzdb/tzcode2018e/newtzset.3
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/newtzset.3.txt
===================================================================
--- vendor/tzdb/tzcode2018e/newtzset.3.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/newtzset.3.txt (revision 337695)
@@ -0,0 +1,199 @@
+NEWTZSET(3) Library Functions Manual NEWTZSET(3)
+
+NAME
+ tzset - initialize time conversion information
+
+SYNOPSIS
+ #include
+
+ timezone_t tzalloc(char const *TZ);
+
+ void tzfree(timezone_t tz);
+
+ void tzset(void);
+
+ cc ... -ltz
+
+DESCRIPTION
+ 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 Universal Time (UT).
+
+ 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, 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;
+
+ if the value does not begin with a colon, it is first used as
+ the pathname of a file from which to read the time conversion
+ information, and, if that file cannot be read, is used directly
+ as a specification of the time conversion information.
+
+ When TZ is used as a pathname, if it begins with a slash, it is used as
+ an absolute pathname; otherwise, it is used as a pathname relative to a
+ system time conversion information directory. The file must be in the
+ format specified in tzfile(5).
+
+ When TZ is used directly as a specification of the time conversion
+ information, it must have the following syntax (spaces inserted for
+ clarity):
+
+ stdoffset[dst[offset][,rule]]
+
+ Where:
+
+ std and dst Three or more bytes that are the designation for
+ the standard (std) or the alternative (dst, such
+ as daylight saving time) time zone. Only std is
+ required; if dst is missing, then daylight saving
+ time does not apply in this locale. Upper- and
+ lowercase letters are explicitly allowed. Any
+ characters except a leading colon (:), digits,
+ comma (,), ASCII minus (-), ASCII plus (+), and
+ NUL bytes are allowed. Alternatively, a
+ designation can be surrounded by angle brackets <
+ and >; in this case, the designation can contain
+ any characters other than > and NUL.
+
+ offset Indicates the value one must add to the local
+ time to arrive at Coordinated Universal Time.
+ The offset has the form:
+
+ hh[:mm[:ss]]
+
+ The minutes (mm) and seconds (ss) are optional.
+ The hour (hh) is required and may be a single
+ digit. The offset following std is required. If
+ no offset follows dst, daylight saving time is
+ assumed to be one hour ahead of standard time.
+ One or more digits may be used; the value is
+ always interpreted as a decimal number. The hour
+ must be between zero and 24, and the minutes (and
+ seconds) - 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
+ daylight saving time. The rule has the form:
+
+ date/time,date/time
+
+ where the first date describes when the change
+ from standard to daylight saving time occurs and
+ the 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. 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.
+
+ n The zero-based Julian day
+ (0 <= n <= 365). Leap days are
+ counted, and it is possible to refer to
+ February 29.
+
+ 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
+ in either the fourth or the fifth
+ week). Week 1 is the first week in
+ which the d'th day occurs. Day zero is
+ Sunday.
+
+ The time has the same format as offset except
+ 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 UT,
+ without daylight saving.
+
+ <+12>-12<+13>,M11.1.0,M1.2.1/147
+ stands for Fiji time, 12 hours ahead of UT, springing forward on
+ November's first Sunday at 02:00, and falling back on January's
+ second Monday at 147:00 (i.e., 03:00 on the first Sunday on or
+ after January 14). The abbreviations for standard and daylight
+ saving time are "+12" and "+13".
+
+ IST-2IDT,M3.4.4/26,M10.5.0
+ stands for Israel Standard Time (IST) and Israel Daylight Time
+ (IDT), 2 hours ahead of UT, springing forward on March's fourth
+ Thursday at 26:00 (i.e., 02:00 on the first Friday on or after
+ March 23), and falling back on October's last Sunday at 02:00.
+
+ <-04>4<-03>,J1/0,J365/25
+ stands for permanent daylight saving time, 3 hours behind UT
+ with abbreviation "-03". There is a dummy fall-back transition
+ on December 31 at 25:00 daylight saving time (i.e., 24:00
+ standard time, equivalent to January 1 at 00:00 standard time),
+ and a simultaneous spring-forward transition on January 1 at
+ 00:00 standard time, so daylight saving time is in effect all
+ year and the initial <-04> is a placeholder.
+
+ <-03>3<-02>,M3.5.0/-2,M10.5.0/-1
+ stands for time in western Greenland, 3 hours behind UT, where
+ clocks follow the EU rules of springing forward on March's last
+ Sunday at 01:00 UT (-02:00 local time, i.e., 22:00 the previous
+ day) and falling back on October's last Sunday at 01:00 UT
+ (-01:00 local time, i.e., 23:00 the previous day). The
+ abbreviations for standard and daylight saving time are "-03"
+ and "-02".
+
+ 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 daylight saving
+ time offsets from UT replaced by those specified by the offset values
+ in TZ.
+
+ For compatibility with System V Release 3.1, a semicolon (;) may be
+ used to separate the rule from the rest of the specification.
+
+FILES
+ /usr/share/zoneinfo time zone information directory
+ /usr/share/zoneinfo/localtime local time zone file
+ /usr/share/zoneinfo/posixrules used with POSIX-style TZ's
+ /usr/share/zoneinfo/GMT for UTC leap seconds
+
+ If /usr/share/zoneinfo/GMT is absent, UTC leap seconds are loaded from
+ /usr/share/zoneinfo/posixrules.
+
+SEE ALSO
+ getenv(3), newctime(3), newstrftime(3), time(2), tzfile(5)
+
+ NEWTZSET(3)
Property changes on: vendor/tzdb/tzcode2018e/newtzset.3.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/private.h
===================================================================
--- vendor/tzdb/tzcode2018e/private.h (nonexistent)
+++ vendor/tzdb/tzcode2018e/private.h (revision 337695)
@@ -0,0 +1,760 @@
+#ifndef PRIVATE_H
+
+#define PRIVATE_H
+
+/*
+** This file is in the public domain, so clarified as of
+** 1996-06-05 by Arthur David Olson.
+*/
+
+/*
+** This header is for use ONLY with the time conversion code.
+** There is no guarantee that it will remain unchanged,
+** or that it will remain at all.
+** Do NOT copy it to any system include directory.
+** Thank you!
+*/
+
+/*
+** zdump has been made independent of the rest of the time
+** conversion package to increase confidence in the verification it provides.
+** You can use zdump to help in verifying other implementations.
+** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
+*/
+#ifndef USE_LTZ
+# define USE_LTZ 1
+#endif
+
+/* This string was in the Factory zone through version 2016f. */
+#define GRANDPARENTED "Local time zone must be set--see zic manual page"
+
+/*
+** Defaults for preprocessor symbols.
+** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
+*/
+
+#ifndef HAVE_DECL_ASCTIME_R
+#define HAVE_DECL_ASCTIME_R 1
+#endif
+
+#if !defined HAVE_GENERIC && defined __has_extension
+# if __has_extension(c_generic_selections)
+# define HAVE_GENERIC 1
+# else
+# define HAVE_GENERIC 0
+# endif
+#endif
+/* _Generic is buggy in pre-4.9 GCC. */
+#if !defined HAVE_GENERIC && defined __GNUC__
+# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
+#endif
+#ifndef HAVE_GENERIC
+# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
+#endif
+
+#ifndef HAVE_GETTEXT
+#define HAVE_GETTEXT 0
+#endif /* !defined HAVE_GETTEXT */
+
+#ifndef HAVE_INCOMPATIBLE_CTIME_R
+#define HAVE_INCOMPATIBLE_CTIME_R 0
+#endif
+
+#ifndef HAVE_LINK
+#define HAVE_LINK 1
+#endif /* !defined HAVE_LINK */
+
+#ifndef HAVE_POSIX_DECLS
+#define HAVE_POSIX_DECLS 1
+#endif
+
+#ifndef HAVE_STDBOOL_H
+#define HAVE_STDBOOL_H (199901 <= __STDC_VERSION__)
+#endif
+
+#ifndef HAVE_STRDUP
+#define HAVE_STRDUP 1
+#endif
+
+#ifndef HAVE_STRTOLL
+#define HAVE_STRTOLL 1
+#endif
+
+#ifndef HAVE_SYMLINK
+#define HAVE_SYMLINK 1
+#endif /* !defined HAVE_SYMLINK */
+
+#ifndef HAVE_SYS_STAT_H
+#define HAVE_SYS_STAT_H 1
+#endif /* !defined HAVE_SYS_STAT_H */
+
+#ifndef HAVE_SYS_WAIT_H
+#define HAVE_SYS_WAIT_H 1
+#endif /* !defined HAVE_SYS_WAIT_H */
+
+#ifndef HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
+#endif /* !defined HAVE_UNISTD_H */
+
+#ifndef HAVE_UTMPX_H
+#define HAVE_UTMPX_H 1
+#endif /* !defined HAVE_UTMPX_H */
+
+#ifndef NETBSD_INSPIRED
+# define NETBSD_INSPIRED 1
+#endif
+
+#if HAVE_INCOMPATIBLE_CTIME_R
+#define asctime_r _incompatible_asctime_r
+#define ctime_r _incompatible_ctime_r
+#endif /* HAVE_INCOMPATIBLE_CTIME_R */
+
+/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
+#define _GNU_SOURCE 1
+/* Fix asctime_r on Solaris 11. */
+#define _POSIX_PTHREAD_SEMANTICS 1
+/* Enable strtoimax on pre-C99 Solaris 11. */
+#define __EXTENSIONS__ 1
+
+/* To avoid having 'stat' fail unnecessarily with errno == EOVERFLOW,
+ enable large files on GNUish systems ... */
+#ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+#endif
+/* ... and on AIX ... */
+#define _LARGE_FILES 1
+/* ... and enable large inode numbers on Mac OS X 10.5 and later. */
+#define _DARWIN_USE_64_BIT_INODE 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
+#undef localtime_rz
+#undef mktime_z
+#undef posix2time_z
+#undef time2posix_z
+#undef timezone_t
+#undef tzalloc
+#undef tzfree
+
+#include /* for time_t */
+#include
+#include /* for CHAR_BIT et al. */
+#include
+
+#include
+
+#ifndef ENAMETOOLONG
+# define ENAMETOOLONG EINVAL
+#endif
+#ifndef ENOTSUP
+# define ENOTSUP EINVAL
+#endif
+#ifndef EOVERFLOW
+# define EOVERFLOW EINVAL
+#endif
+
+#if HAVE_GETTEXT
+#include
+#endif /* HAVE_GETTEXT */
+
+#if HAVE_UNISTD_H
+#include /* for R_OK, and other POSIX goodness */
+#endif /* HAVE_UNISTD_H */
+
+#ifndef HAVE_STRFTIME_L
+# if _POSIX_VERSION < 200809
+# define HAVE_STRFTIME_L 0
+# else
+# define HAVE_STRFTIME_L 1
+# endif
+#endif
+
+#ifndef USG_COMPAT
+# ifndef _XOPEN_VERSION
+# define USG_COMPAT 0
+# else
+# define USG_COMPAT 1
+# endif
+#endif
+
+#ifndef HAVE_TZNAME
+# if _POSIX_VERSION < 198808 && !USG_COMPAT
+# define HAVE_TZNAME 0
+# else
+# define HAVE_TZNAME 1
+# endif
+#endif
+
+#ifndef R_OK
+#define R_OK 4
+#endif /* !defined R_OK */
+
+/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */
+#define is_digit(c) ((unsigned)(c) - '0' <= 9)
+
+/*
+** Define HAVE_STDINT_H's default value here, rather than at the
+** start, since __GLIBC__ and INTMAX_MAX's values depend on
+** previously-included files. glibc 2.1 and Solaris 10 and later have
+** stdint.h, even with pre-C99 compilers.
+*/
+#ifndef HAVE_STDINT_H
+#define HAVE_STDINT_H \
+ (199901 <= __STDC_VERSION__ \
+ || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
+ || __CYGWIN__ || INTMAX_MAX)
+#endif /* !defined HAVE_STDINT_H */
+
+#if HAVE_STDINT_H
+#include
+#endif /* !HAVE_STDINT_H */
+
+#ifndef HAVE_INTTYPES_H
+# define HAVE_INTTYPES_H HAVE_STDINT_H
+#endif
+#if HAVE_INTTYPES_H
+# include
+#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
+# ifdef LLONG_MAX
+typedef long long int_fast64_t;
+# 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
+typedef long int_fast64_t;
+# define INT_FAST64_MIN LONG_MIN
+# define INT_FAST64_MAX LONG_MAX
+# endif
+#endif
+
+#ifndef PRIdFAST64
+# if INT_FAST64_MAX == LLONG_MAX
+# define PRIdFAST64 "lld"
+# else
+# define PRIdFAST64 "ld"
+# endif
+#endif
+
+#ifndef SCNdFAST64
+# define SCNdFAST64 PRIdFAST64
+#endif
+
+#ifndef INT_FAST32_MAX
+# if INT_MAX >> 31 == 0
+typedef long int_fast32_t;
+# define INT_FAST32_MAX LONG_MAX
+# define INT_FAST32_MIN LONG_MIN
+# else
+typedef int int_fast32_t;
+# define INT_FAST32_MAX INT_MAX
+# define INT_FAST32_MIN INT_MIN
+# endif
+#endif
+
+#ifndef INTMAX_MAX
+# ifdef LLONG_MAX
+typedef long long intmax_t;
+# if HAVE_STRTOLL
+# define strtoimax strtoll
+# endif
+# define INTMAX_MAX LLONG_MAX
+# define INTMAX_MIN LLONG_MIN
+# else
+typedef long intmax_t;
+# define INTMAX_MAX LONG_MAX
+# define INTMAX_MIN LONG_MIN
+# endif
+# ifndef strtoimax
+# define strtoimax strtol
+# endif
+#endif
+
+#ifndef PRIdMAX
+# if INTMAX_MAX == LLONG_MAX
+# define PRIdMAX "lld"
+# else
+# define PRIdMAX "ld"
+# endif
+#endif
+
+#ifndef 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 */
+#ifndef INT32_MIN
+#define INT32_MIN (-1 - INT32_MAX)
+#endif /* !defined INT32_MIN */
+
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) -1)
+#endif
+
+#if 3 <= __GNUC__
+# define ATTRIBUTE_CONST __attribute__ ((const))
+# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# define ATTRIBUTE_PURE __attribute__ ((__pure__))
+# define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
+#else
+# define ATTRIBUTE_CONST /* empty */
+# define ATTRIBUTE_MALLOC /* 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.
+*/
+
+#ifndef EPOCH_LOCAL
+# define EPOCH_LOCAL 0
+#endif
+#ifndef EPOCH_OFFSET
+# define EPOCH_OFFSET 0
+#endif
+#ifndef RESERVE_STD_EXT_IDS
+# define RESERVE_STD_EXT_IDS 0
+#endif
+
+/* If standard C identifiers with external linkage (e.g., localtime)
+ are reserved and are not already being renamed anyway, rename them
+ as if compiling with '-Dtime_tz=time_t'. */
+#if !defined time_tz && RESERVE_STD_EXT_IDS && USE_LTZ
+# define time_tz time_t
+#endif
+
+/*
+** Compile with -Dtime_tz=T to build the tz package with a private
+** time_t type equivalent to T rather than the system-supplied time_t.
+** This debugging feature can test unusual design decisions
+** (e.g., time_t wider than 'long', or unsigned time_t) even on
+** typical platforms.
+*/
+#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
+# define TZ_TIME_T 1
+#else
+# define TZ_TIME_T 0
+#endif
+
+#if TZ_TIME_T
+# ifdef LOCALTIME_IMPLEMENTATION
+static time_t sys_time(time_t *x) { return time(x); }
+# endif
+
+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 strftime
+# define strftime tz_strftime
+# undef time
+# define time tz_time
+# undef time2posix
+# define time2posix tz_time2posix
+# undef time2posix_z
+# define time2posix_z tz_time2posix_z
+# undef time_t
+# define time_t tz_time_t
+# undef timegm
+# define timegm tz_timegm
+# undef timelocal
+# define timelocal tz_timelocal
+# undef timeoff
+# define timeoff tz_timeoff
+# undef tzalloc
+# define tzalloc tz_tzalloc
+# undef tzfree
+# define tzfree tz_tzfree
+# undef tzset
+# define tzset tz_tzset
+# undef tzsetwall
+# define tzsetwall tz_tzsetwall
+# if HAVE_STRFTIME_L
+# undef strftime_l
+# define strftime_l tz_strftime_l
+# endif
+# if HAVE_TZNAME
+# undef tzname
+# define tzname tz_tzname
+# endif
+# if USG_COMPAT
+# undef daylight
+# define daylight tz_daylight
+# undef timezone
+# define timezone tz_timezone
+# endif
+# ifdef ALTZONE
+# undef altzone
+# define altzone tz_altzone
+# endif
+
+char *ctime(time_t const *);
+char *ctime_r(time_t const *, char *);
+double difftime(time_t, time_t) ATTRIBUTE_CONST;
+size_t strftime(char *restrict, size_t, char const *restrict,
+ struct tm const *restrict);
+# if HAVE_STRFTIME_L
+size_t strftime_l(char *restrict, size_t, char const *restrict,
+ struct tm const *restrict, locale_t);
+# endif
+struct tm *gmtime(time_t const *);
+struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
+struct tm *localtime(time_t const *);
+struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
+time_t mktime(struct tm *);
+time_t time(time_t *);
+void tzset(void);
+#endif
+
+#if !HAVE_DECL_ASCTIME_R && !defined asctime_r
+extern char *asctime_r(struct tm const *restrict, char *restrict);
+#endif
+
+#ifndef HAVE_DECL_ENVIRON
+# if defined environ || defined __USE_GNU
+# define HAVE_DECL_ENVIRON 1
+# else
+# define HAVE_DECL_ENVIRON 0
+# endif
+#endif
+
+#if !HAVE_DECL_ENVIRON
+extern char **environ;
+#endif
+
+#if TZ_TIME_T || !HAVE_POSIX_DECLS
+# if HAVE_TZNAME
+extern char *tzname[];
+# endif
+# if USG_COMPAT
+extern long timezone;
+extern int daylight;
+# endif
+#endif
+
+#ifdef ALTZONE
+extern long altzone;
+#endif
+
+/*
+** The STD_INSPIRED functions are similar, but most also need
+** declarations if time_tz is defined.
+*/
+
+#ifdef STD_INSPIRED
+# if TZ_TIME_T || !defined tzsetwall
+void tzsetwall(void);
+# endif
+# if TZ_TIME_T || !defined offtime
+struct tm *offtime(time_t const *, long);
+# endif
+# if TZ_TIME_T || !defined timegm
+time_t timegm(struct tm *);
+# endif
+# if TZ_TIME_T || !defined timelocal
+time_t timelocal(struct tm *);
+# endif
+# if TZ_TIME_T || !defined timeoff
+time_t timeoff(struct tm *, long);
+# endif
+# if TZ_TIME_T || !defined time2posix
+time_t time2posix(time_t);
+# endif
+# if TZ_TIME_T || !defined posix2time
+time_t posix2time(time_t);
+# endif
+#endif
+
+/* Infer TM_ZONE on systems where this information is known, but suppress
+ guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
+#if (defined __GLIBC__ \
+ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
+ || (defined __APPLE__ && defined __MACH__))
+# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
+# define TM_GMTOFF tm_gmtoff
+# endif
+# if !defined TM_ZONE && !defined NO_TM_ZONE
+# define TM_ZONE tm_zone
+# endif
+#endif
+
+/*
+** Define functions that are ABI compatible with NetBSD but have
+** better prototypes. NetBSD 6.1.4 defines a pointer type timezone_t
+** and labors under the misconception that 'const timezone_t' is a
+** pointer to a constant. This use of 'const' is ineffective, so it
+** is not done here. What we call 'struct state' NetBSD calls
+** 'struct __state', but this is a private name so it doesn't matter.
+*/
+#if NETBSD_INSPIRED
+typedef struct state *timezone_t;
+struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
+ struct tm *restrict);
+time_t mktime_z(timezone_t restrict, struct tm *restrict);
+timezone_t tzalloc(char const *);
+void tzfree(timezone_t);
+# ifdef STD_INSPIRED
+# if TZ_TIME_T || !defined posix2time_z
+time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_PURE;
+# endif
+# if TZ_TIME_T || !defined time2posix_z
+time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
+# endif
+# endif
+#endif
+
+/*
+** Finally, some convenience items.
+*/
+
+#if HAVE_STDBOOL_H
+# include
+#else
+# define true 1
+# define false 0
+# define bool int
+#endif
+
+#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
+#define TYPE_SIGNED(type) (((type) -1) < 0)
+#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
+
+/* Max and min values of the integer type T, of which only the bottom
+ B bits are used, and where the highest-order used bit is considered
+ to be a sign bit if T is signed. */
+#define MAXVAL(t, b) \
+ ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
+ - 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
+#define MINVAL(t, b) \
+ ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
+
+/* The extreme time values, assuming no padding. */
+#define TIME_T_MIN_NO_PADDING MINVAL(time_t, TYPE_BIT(time_t))
+#define TIME_T_MAX_NO_PADDING MAXVAL(time_t, TYPE_BIT(time_t))
+
+/* The extreme time values. These are macros, not constants, so that
+ any portability problem occur only when compiling .c files that use
+ the macros, which is safer for applications that need only zdump and zic.
+ This implementation assumes no padding if time_t is signed and
+ either the compiler lacks support for _Generic or time_t is not one
+ of the standard signed integer types. */
+#if HAVE_GENERIC
+# define TIME_T_MIN \
+ _Generic((time_t) 0, \
+ signed char: SCHAR_MIN, short: SHRT_MIN, \
+ int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \
+ default: TIME_T_MIN_NO_PADDING)
+# define TIME_T_MAX \
+ (TYPE_SIGNED(time_t) \
+ ? _Generic((time_t) 0, \
+ signed char: SCHAR_MAX, short: SHRT_MAX, \
+ int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
+ default: TIME_T_MAX_NO_PADDING) \
+ : (time_t) -1)
+#else
+# define TIME_T_MIN TIME_T_MIN_NO_PADDING
+# define TIME_T_MAX TIME_T_MAX_NO_PADDING
+#endif
+
+/*
+** 302 / 1000 is log10(2.0) rounded up.
+** Subtract one for the sign bit if the type is signed;
+** add one for integer division truncation;
+** add one more for a minus sign if the type is signed.
+*/
+#define INT_STRLEN_MAXIMUM(type) \
+ ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
+ 1 + TYPE_SIGNED(type))
+
+/*
+** INITIALIZE(x)
+*/
+
+#ifdef GCC_LINT
+# define INITIALIZE(x) ((x) = 0)
+#else
+# define INITIALIZE(x)
+#endif
+
+#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.
+** The default is to use gettext if available, and use MSGID otherwise.
+*/
+
+#if HAVE_GETTEXT
+#define _(msgid) gettext(msgid)
+#else /* !HAVE_GETTEXT */
+#define _(msgid) msgid
+#endif /* !HAVE_GETTEXT */
+
+#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
+# define TZ_DOMAIN "tz"
+#endif
+
+#if HAVE_INCOMPATIBLE_CTIME_R
+#undef asctime_r
+#undef ctime_r
+char *asctime_r(struct tm const *, char *);
+char *ctime_r(time_t const *, char *);
+#endif /* HAVE_INCOMPATIBLE_CTIME_R */
+
+/* Handy macros that are independent of tzfile implementation. */
+
+#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR 12
+
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_JANUARY 0
+#define TM_FEBRUARY 1
+#define TM_MARCH 2
+#define TM_APRIL 3
+#define TM_MAY 4
+#define TM_JUNE 5
+#define TM_JULY 6
+#define TM_AUGUST 7
+#define TM_SEPTEMBER 8
+#define TM_OCTOBER 9
+#define TM_NOVEMBER 10
+#define TM_DECEMBER 11
+
+#define TM_YEAR_BASE 1900
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+
+/*
+** Since everything in isleap is modulo 400 (or a factor of 400), we know that
+** isleap(y) == isleap(y % 400)
+** and so
+** isleap(a + b) == isleap((a + b) % 400)
+** or
+** isleap(a + b) == isleap(a % 400 + b % 400)
+** This is true even if % means modulo rather than Fortran remainder
+** (which is allowed by C89 but not by C99 or later).
+** We use this to avoid addition overflow problems.
+*/
+
+#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
+
+
+/*
+** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
+*/
+
+#define AVGSECSPERYEAR 31556952L
+#define SECSPERREPEAT \
+ ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
+#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
+
+#endif /* !defined PRIVATE_H */
Property changes on: vendor/tzdb/tzcode2018e/private.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/strftime.c
===================================================================
--- vendor/tzdb/tzcode2018e/strftime.c (nonexistent)
+++ vendor/tzdb/tzcode2018e/strftime.c (revision 337695)
@@ -0,0 +1,633 @@
+/* Convert a broken-down timestamp to a string. */
+
+/* Copyright 1989 The Regents of the University of California.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE. */
+
+/*
+** Based on the UCB version with the copyright notice appearing above.
+**
+** This is ANSIish only when "multibyte character == plain character".
+*/
+
+#include "private.h"
+
+#include
+#include
+#include
+
+#ifndef DEPRECATE_TWO_DIGIT_YEARS
+# define DEPRECATE_TWO_DIGIT_YEARS false
+#endif
+
+struct lc_time_T {
+ const char * mon[MONSPERYEAR];
+ const char * month[MONSPERYEAR];
+ const char * wday[DAYSPERWEEK];
+ const char * weekday[DAYSPERWEEK];
+ const char * X_fmt;
+ const char * x_fmt;
+ const char * c_fmt;
+ const char * am;
+ const char * pm;
+ const char * date_fmt;
+};
+
+#define Locale (&C_time_locale)
+
+static const struct lc_time_T C_time_locale = {
+ {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ }, {
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+ }, {
+ "Sun", "Mon", "Tue", "Wed",
+ "Thu", "Fri", "Sat"
+ }, {
+ "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday"
+ },
+
+ /* X_fmt */
+ "%H:%M:%S",
+
+ /*
+ ** x_fmt
+ ** C99 and later require this format.
+ ** Using just numbers (as here) makes Quakers happier;
+ ** it's also compatible with SVR4.
+ */
+ "%m/%d/%y",
+
+ /*
+ ** c_fmt
+ ** C99 and later require this format.
+ ** Previously this code used "%D %X", but we now conform to C99.
+ ** Note that
+ ** "%a %b %d %H:%M:%S %Y"
+ ** is used by Solaris 2.3.
+ */
+ "%a %b %e %T %Y",
+
+ /* am */
+ "AM",
+
+ /* pm */
+ "PM",
+
+ /* date_fmt */
+ "%a %b %e %H:%M:%S %Z %Y"
+};
+
+enum warn { IN_NONE, IN_SOME, IN_THIS, IN_ALL };
+
+static char * _add(const char *, char *, const char *);
+static char * _conv(int, const char *, char *, const char *);
+static char * _fmt(const char *, const struct tm *, char *, const char *,
+ enum warn *);
+static char * _yconv(int, int, bool, bool, char *, char const *);
+
+#ifndef YEAR_2000_NAME
+#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
+#endif /* !defined YEAR_2000_NAME */
+
+#if HAVE_STRFTIME_L
+size_t
+strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
+ 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;
+ enum warn warn = IN_NONE;
+
+ tzset();
+ p = _fmt(format, t, s, s + maxsize, &warn);
+ if (DEPRECATE_TWO_DIGIT_YEARS
+ && warn != IN_NONE && getenv(YEAR_2000_NAME)) {
+ fprintf(stderr, "\n");
+ fprintf(stderr, "strftime format \"%s\" ", format);
+ fprintf(stderr, "yields only two digits of years in ");
+ if (warn == IN_SOME)
+ fprintf(stderr, "some locales");
+ else if (warn == IN_THIS)
+ fprintf(stderr, "the current locale");
+ else fprintf(stderr, "all locales");
+ fprintf(stderr, "\n");
+ }
+ if (p == s + maxsize)
+ return 0;
+ *p = '\0';
+ return p - s;
+}
+
+static char *
+_fmt(const char *format, const struct tm *t, char *pt,
+ const char *ptlim, enum warn *warnp)
+{
+ for ( ; *format; ++format) {
+ if (*format == '%') {
+label:
+ switch (*++format) {
+ case '\0':
+ --format;
+ break;
+ case 'A':
+ pt = _add((t->tm_wday < 0 ||
+ t->tm_wday >= DAYSPERWEEK) ?
+ "?" : Locale->weekday[t->tm_wday],
+ pt, ptlim);
+ continue;
+ case 'a':
+ pt = _add((t->tm_wday < 0 ||
+ t->tm_wday >= DAYSPERWEEK) ?
+ "?" : Locale->wday[t->tm_wday],
+ pt, ptlim);
+ continue;
+ case 'B':
+ pt = _add((t->tm_mon < 0 ||
+ t->tm_mon >= MONSPERYEAR) ?
+ "?" : Locale->month[t->tm_mon],
+ pt, ptlim);
+ continue;
+ case 'b':
+ case 'h':
+ pt = _add((t->tm_mon < 0 ||
+ t->tm_mon >= MONSPERYEAR) ?
+ "?" : Locale->mon[t->tm_mon],
+ pt, ptlim);
+ continue;
+ case 'C':
+ /*
+ ** %C used to do a...
+ ** _fmt("%a %b %e %X %Y", t);
+ ** ...whereas now POSIX 1003.2 calls for
+ ** something completely different.
+ ** (ado, 1993-05-24)
+ */
+ pt = _yconv(t->tm_year, TM_YEAR_BASE,
+ true, false, pt, ptlim);
+ continue;
+ case 'c':
+ {
+ enum warn warn2 = IN_SOME;
+
+ pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
+ if (warn2 == IN_ALL)
+ warn2 = IN_THIS;
+ if (warn2 > *warnp)
+ *warnp = warn2;
+ }
+ continue;
+ case 'D':
+ pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
+ continue;
+ case 'd':
+ pt = _conv(t->tm_mday, "%02d", pt, ptlim);
+ continue;
+ case 'E':
+ case 'O':
+ /*
+ ** Locale modifiers of C99 and later.
+ ** The sequences
+ ** %Ec %EC %Ex %EX %Ey %EY
+ ** %Od %oe %OH %OI %Om %OM
+ ** %OS %Ou %OU %OV %Ow %OW %Oy
+ ** are supposed to provide alternative
+ ** representations.
+ */
+ goto label;
+ case 'e':
+ pt = _conv(t->tm_mday, "%2d", pt, ptlim);
+ continue;
+ case 'F':
+ pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
+ continue;
+ case 'H':
+ pt = _conv(t->tm_hour, "%02d", pt, ptlim);
+ continue;
+ case 'I':
+ pt = _conv((t->tm_hour % 12) ?
+ (t->tm_hour % 12) : 12,
+ "%02d", pt, ptlim);
+ continue;
+ case 'j':
+ pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
+ continue;
+ case 'k':
+ /*
+ ** This used to be...
+ ** _conv(t->tm_hour % 12 ?
+ ** t->tm_hour % 12 : 12, 2, ' ');
+ ** ...and has been changed to the below to
+ ** match SunOS 4.1.1 and Arnold Robbins'
+ ** strftime version 3.0. That is, "%k" and
+ ** "%l" have been swapped.
+ ** (ado, 1993-05-24)
+ */
+ pt = _conv(t->tm_hour, "%2d", pt, ptlim);
+ continue;
+#ifdef KITCHEN_SINK
+ case 'K':
+ /*
+ ** After all this time, still unclaimed!
+ */
+ pt = _add("kitchen sink", pt, ptlim);
+ continue;
+#endif /* defined KITCHEN_SINK */
+ case 'l':
+ /*
+ ** This used to be...
+ ** _conv(t->tm_hour, 2, ' ');
+ ** ...and has been changed to the below to
+ ** match SunOS 4.1.1 and Arnold Robbin's
+ ** strftime version 3.0. That is, "%k" and
+ ** "%l" have been swapped.
+ ** (ado, 1993-05-24)
+ */
+ pt = _conv((t->tm_hour % 12) ?
+ (t->tm_hour % 12) : 12,
+ "%2d", pt, ptlim);
+ continue;
+ case 'M':
+ pt = _conv(t->tm_min, "%02d", pt, ptlim);
+ continue;
+ case 'm':
+ pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
+ continue;
+ case 'n':
+ pt = _add("\n", pt, ptlim);
+ continue;
+ case 'p':
+ pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
+ Locale->pm :
+ Locale->am,
+ pt, ptlim);
+ continue;
+ case 'R':
+ pt = _fmt("%H:%M", t, pt, ptlim, warnp);
+ continue;
+ case 'r':
+ pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
+ continue;
+ case 'S':
+ pt = _conv(t->tm_sec, "%02d", pt, ptlim);
+ continue;
+ case 's':
+ {
+ struct tm tm;
+ char buf[INT_STRLEN_MAXIMUM(
+ time_t) + 1];
+ time_t mkt;
+
+ tm = *t;
+ mkt = mktime(&tm);
+ if (TYPE_SIGNED(time_t))
+ sprintf(buf, "%"PRIdMAX,
+ (intmax_t) mkt);
+ else sprintf(buf, "%"PRIuMAX,
+ (uintmax_t) mkt);
+ pt = _add(buf, pt, ptlim);
+ }
+ continue;
+ case 'T':
+ pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
+ continue;
+ case 't':
+ pt = _add("\t", pt, ptlim);
+ continue;
+ case 'U':
+ pt = _conv((t->tm_yday + DAYSPERWEEK -
+ t->tm_wday) / DAYSPERWEEK,
+ "%02d", pt, ptlim);
+ continue;
+ case 'u':
+ /*
+ ** From Arnold Robbins' strftime version 3.0:
+ ** "ISO 8601: Weekday as a decimal number
+ ** [1 (Monday) - 7]"
+ ** (ado, 1993-05-24)
+ */
+ pt = _conv((t->tm_wday == 0) ?
+ DAYSPERWEEK : t->tm_wday,
+ "%d", pt, ptlim);
+ continue;
+ case 'V': /* ISO 8601 week number */
+ case 'G': /* ISO 8601 year (four digits) */
+ case 'g': /* ISO 8601 year (two digits) */
+/*
+** From Arnold Robbins' strftime version 3.0: "the week number of the
+** year (the first Monday as the first day of week 1) as a decimal number
+** (01-53)."
+** (ado, 1993-05-24)
+**
+** From by Markus Kuhn:
+** "Week 01 of a year is per definition the first week which has the
+** Thursday in this year, which is equivalent to the week which contains
+** the fourth day of January. In other words, the first week of a new year
+** is the week which has the majority of its days in the new year. Week 01
+** might also contain days from the previous year and the week before week
+** 01 of a year is the last week (52 or 53) of the previous year even if
+** it contains days from the new year. A week starts with Monday (day 1)
+** and ends with Sunday (day 7). For example, the first week of the year
+** 1997 lasts from 1996-12-30 to 1997-01-05..."
+** (ado, 1996-01-02)
+*/
+ {
+ int year;
+ int base;
+ int yday;
+ int wday;
+ int w;
+
+ year = t->tm_year;
+ base = TM_YEAR_BASE;
+ yday = t->tm_yday;
+ wday = t->tm_wday;
+ for ( ; ; ) {
+ int len;
+ int bot;
+ int top;
+
+ len = isleap_sum(year, base) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ /*
+ ** What yday (-3 ... 3) does
+ ** the ISO year begin on?
+ */
+ bot = ((yday + 11 - wday) %
+ DAYSPERWEEK) - 3;
+ /*
+ ** What yday does the NEXT
+ ** ISO year begin on?
+ */
+ top = bot -
+ (len % DAYSPERWEEK);
+ if (top < -3)
+ top += DAYSPERWEEK;
+ top += len;
+ if (yday >= top) {
+ ++base;
+ w = 1;
+ break;
+ }
+ if (yday >= bot) {
+ w = 1 + ((yday - bot) /
+ DAYSPERWEEK);
+ break;
+ }
+ --base;
+ yday += isleap_sum(year, base) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ }
+#ifdef XPG4_1994_04_09
+ if ((w == 52 &&
+ t->tm_mon == TM_JANUARY) ||
+ (w == 1 &&
+ t->tm_mon == TM_DECEMBER))
+ w = 53;
+#endif /* defined XPG4_1994_04_09 */
+ if (*format == 'V')
+ pt = _conv(w, "%02d",
+ pt, ptlim);
+ else if (*format == 'g') {
+ *warnp = IN_ALL;
+ pt = _yconv(year, base,
+ false, true,
+ pt, ptlim);
+ } else pt = _yconv(year, base,
+ true, true,
+ pt, ptlim);
+ }
+ continue;
+ case 'v':
+ /*
+ ** From Arnold Robbins' strftime version 3.0:
+ ** "date as dd-bbb-YYYY"
+ ** (ado, 1993-05-24)
+ */
+ pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
+ continue;
+ case 'W':
+ pt = _conv((t->tm_yday + DAYSPERWEEK -
+ (t->tm_wday ?
+ (t->tm_wday - 1) :
+ (DAYSPERWEEK - 1))) / DAYSPERWEEK,
+ "%02d", pt, ptlim);
+ continue;
+ case 'w':
+ pt = _conv(t->tm_wday, "%d", pt, ptlim);
+ continue;
+ case 'X':
+ pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
+ continue;
+ case 'x':
+ {
+ enum warn warn2 = IN_SOME;
+
+ pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
+ if (warn2 == IN_ALL)
+ warn2 = IN_THIS;
+ if (warn2 > *warnp)
+ *warnp = warn2;
+ }
+ continue;
+ case 'y':
+ *warnp = IN_ALL;
+ pt = _yconv(t->tm_year, TM_YEAR_BASE,
+ false, true,
+ pt, ptlim);
+ continue;
+ case 'Y':
+ pt = _yconv(t->tm_year, TM_YEAR_BASE,
+ true, true,
+ pt, ptlim);
+ continue;
+ case 'Z':
+#ifdef TM_ZONE
+ pt = _add(t->TM_ZONE, pt, ptlim);
+#elif HAVE_TZNAME
+ if (t->tm_isdst >= 0)
+ pt = _add(tzname[t->tm_isdst != 0],
+ pt, ptlim);
+#endif
+ /*
+ ** C99 and later say that %Z must be
+ ** replaced by the empty string if the
+ ** time zone is not determinable.
+ */
+ continue;
+ case 'z':
+#if defined TM_GMTOFF || USG_COMPAT || defined ALTZONE
+ {
+ long diff;
+ char const * sign;
+ bool negative;
+
+# ifdef TM_GMTOFF
+ diff = t->TM_GMTOFF;
+# else
+ /*
+ ** C99 and later say that the UT offset must
+ ** be computed by looking only at
+ ** tm_isdst. This requirement is
+ ** incorrect, since it means the code
+ ** must rely on magic (in this case
+ ** altzone and timezone), and the
+ ** magic might not have the correct
+ ** offset. Doing things correctly is
+ ** tricky and requires disobeying the standard;
+ ** see GNU C strftime for details.
+ ** For now, punt and conform to the
+ ** standard, even though it's incorrect.
+ **
+ ** C99 and later say that %z must be replaced by
+ ** the empty string if the time zone is not
+ ** determinable, so output nothing if the
+ ** appropriate variables are not available.
+ */
+ if (t->tm_isdst < 0)
+ continue;
+ if (t->tm_isdst == 0)
+# if USG_COMPAT
+ diff = -timezone;
+# else
+ continue;
+# endif
+ else
+# ifdef ALTZONE
+ diff = -altzone;
+# else
+ continue;
+# endif
+# endif
+ negative = diff < 0;
+ if (diff == 0) {
+#ifdef TM_ZONE
+ negative = t->TM_ZONE[0] == '-';
+#else
+ negative = t->tm_isdst < 0;
+# if HAVE_TZNAME
+ if (tzname[t->tm_isdst != 0][0] == '-')
+ negative = true;
+# endif
+#endif
+ }
+ if (negative) {
+ sign = "-";
+ diff = -diff;
+ } else sign = "+";
+ pt = _add(sign, pt, ptlim);
+ diff /= SECSPERMIN;
+ diff = (diff / MINSPERHOUR) * 100 +
+ (diff % MINSPERHOUR);
+ pt = _conv(diff, "%04d", pt, ptlim);
+ }
+#endif
+ continue;
+ case '+':
+ pt = _fmt(Locale->date_fmt, t, pt, ptlim,
+ warnp);
+ continue;
+ case '%':
+ /*
+ ** X311J/88-090 (4.12.3.5): if conversion char is
+ ** undefined, behavior is undefined. Print out the
+ ** character itself as printf(3) also does.
+ */
+ default:
+ break;
+ }
+ }
+ if (pt == ptlim)
+ break;
+ *pt++ = *format;
+ }
+ return pt;
+}
+
+static char *
+_conv(int n, const char *format, char *pt, const char *ptlim)
+{
+ char buf[INT_STRLEN_MAXIMUM(int) + 1];
+
+ sprintf(buf, format, n);
+ return _add(buf, pt, ptlim);
+}
+
+static char *
+_add(const char *str, char *pt, const char *ptlim)
+{
+ while (pt < ptlim && (*pt = *str++) != '\0')
+ ++pt;
+ return pt;
+}
+
+/*
+** POSIX and the C Standard are unclear or inconsistent about
+** what %C and %y do if the year is negative or exceeds 9999.
+** Use the convention that %C concatenated with %y yields the
+** same output as %Y, and that %Y contains at least 4 bytes,
+** with more only if necessary.
+*/
+
+static char *
+_yconv(int a, int b, bool convert_top, bool convert_yy,
+ char *pt, const char *ptlim)
+{
+ register int lead;
+ register int trail;
+
+#define DIVISOR 100
+ trail = a % DIVISOR + b % DIVISOR;
+ lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
+ trail %= DIVISOR;
+ if (trail < 0 && lead > 0) {
+ trail += DIVISOR;
+ --lead;
+ } else if (lead < 0 && trail > 0) {
+ trail -= DIVISOR;
+ ++lead;
+ }
+ if (convert_top) {
+ if (lead == 0 && trail < 0)
+ pt = _add("-0", pt, ptlim);
+ else pt = _conv(lead, "%02d", pt, ptlim);
+ }
+ if (convert_yy)
+ pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim);
+ return pt;
+}
Property changes on: vendor/tzdb/tzcode2018e/strftime.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/theory.html
===================================================================
--- vendor/tzdb/tzcode2018e/theory.html (nonexistent)
+++ vendor/tzdb/tzcode2018e/theory.html (revision 337695)
@@ -0,0 +1,1304 @@
+
+
+ Theory and pragmatics of the tz code and data
+
+
+
+
+Theory and pragmatics of the tz code and data
+ Outline
+
+
+
+ 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.
+It organizes time zone and daylight saving time
+data by partitioning the world into regions
+whose clocks all agree about timestamps that occur after the POSIX Epoch
+(1970-01-01 00:00:00 UTC).
+The database labels each such region with a notable location and
+records all known clock transitions for that 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 timestamps 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.
+Although some information outside the scope of the database is
+collected in a file backzone that is distributed along
+with the database proper, this file is less reliable and does not
+necessarily follow database guidelines.
+
+
+
+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-2017, 2018
+Edition.
+Because the database's scope encompasses real-world changes to civil
+timekeeping, its model for describing time is more complex than the
+standard and daylight saving times supported by POSIX.
+A tz region corresponds to a ruleset that can
+have more than two changes per year, these changes need not merely
+flip back and forth between two alternatives, and the rules themselves
+can change at times.
+Whether and when a tz region changes its
+clock, and even the region's notional base offset from UTC, are variable.
+It does not always make sense to talk about a region's
+"base offset", since it is not necessarily a single number.
+
+
+
+
+
+ Names of time zone rulesets
+
+Each tz region has a unique name that
+corresponds to a set of time zone rules.
+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 contains data that may be useful for other selection
+interfaces.
+
+
+
+The 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'.
+Some names are further qualified to help avoid confusion; for example,
+'America/Indiana/Petersburg' distinguishes Petersburg,
+Indiana from other Petersburgs in America.
+
+
+
+Here are the general guidelines used for
+choosing tz region 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 Asia/Brunei to
+ Asia/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,
+ do not 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
America/Costa_Rica to
+ America/San_Jose and America/Guyana
+ to America/Georgetown.
+
+ -
+ Keep locations compact.
+ Use cities or small islands, not countries or regions, so that any
+ future changes do not split individual locations into different
+
tz regions.
+ E.g., prefer Europe/Paris to Europe/France,
+ since
+ France
+ has had multiple time zones.
+
+ -
+ Use mainstream English spelling, e.g., prefer
+
Europe/Rome to Europe/Roma, and
+ prefer Europe/Athens to the Greek
+ Europe/Αθήνα or the Romanized
+ Europe/Athína.
+ The POSIX file name restrictions encourage this guideline.
+
+ -
+ Use the most populous among locations in a region,
+ e.g., prefer
Asia/Shanghai to
+ Asia/Beijing.
+ Among locations with similar populations, pick the best-known
+ location, e.g., prefer Europe/Rome to
+ Europe/Milan.
+
+ -
+ Use the singular form, e.g., prefer
Atlantic/Canary to
+ Atlantic/Canaries.
+
+ -
+ Omit common suffixes like '
_Islands' and
+ '_City', unless that would lead to ambiguity.
+ E.g., prefer America/Cayman to
+ America/Cayman_Islands and
+ America/Guatemala to
+ America/Guatemala_City, but prefer
+ America/Mexico_City to
+ America/Mexico
+ because the
+ country of Mexico has several time zones.
+
+ -
+ Use '
_' to represent a space.
+
+ -
+ Omit '
.' from abbreviations in names.
+ E.g., prefer Atlantic/St_Helena to
+ Atlantic/St._Helena.
+
+ -
+ Do not change established names if they only marginally violate
+ the above guidelines.
+ For example, do not change the existing name
Europe/Rome to
+ Europe/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 tz regions.
+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 local mean
+time (LMT) offset with one hour for every 15°
+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 guideline 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' and 'GMT+0',
+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 guidelines used for choosing time zone abbreviations,
+in decreasing order of importance:
+
+
+
+ -
+ Use three to six characters that are ASCII alphanumerics or
+ '
+' or '-'.
+ Previous editions of this database also used characters like
+ space and '?', but these characters have a
+ special meaning to the
+ UNIX shell
+ and cause commands like
+ 'set
+ `date`'
+ to have unexpected effects.
+ Previous editions of this guideline 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,6} 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'.
+
+
+ These abbreviations (for standard/daylight/etc. time) are:
+ ACST/ACDT Australian Central,
+ AST/ADT/APT/AWT/ADDT Atlantic,
+ AEST/AEDT Australian Eastern,
+ AHST/AHDT Alaska-Hawaii,
+ AKST/AKDT Alaska,
+ AWST/AWDT Australian Western,
+ BST/BDT Bering,
+ CAT/CAST Central Africa,
+ CET/CEST/CEMT Central European,
+ ChST Chamorro,
+ CST/CDT/CWT/CPT/CDDT Central [North America],
+ CST/CDT China,
+ GMT/BST/IST/BDST Greenwich,
+ EAT East Africa,
+ EST/EDT/EWT/EPT/EDDT Eastern [North America],
+ EET/EEST Eastern European,
+ GST Guam,
+ HST/HDT Hawaii,
+ HKT/HKST Hong Kong,
+ IST India,
+ IST/GMT Irish,
+ IST/IDT/IDDT Israel,
+ JST/JDT Japan,
+ KST/KDT Korea,
+ MET/MEST Middle European (a backward-compatibility alias for
+ Central European),
+ MSK/MSD Moscow,
+ MST/MDT/MWT/MPT/MDDT Mountain,
+ NST/NDT/NWT/NPT/NDDT Newfoundland,
+ NST/NDT/NWT/NPT Nome,
+ NZMT/NZST New Zealand through 1945,
+ NZST/NZDT New Zealand 1946–present,
+ PKT/PKST Pakistan,
+ PST/PDT/PWT/PPT/PDDT Pacific,
+ SAST South Africa,
+ SST Samoa,
+ WAT/WAST West Africa,
+ WET/WEST/WEMT Western European,
+ WIB Waktu Indonesia Barat,
+ WIT Waktu Indonesia Timur,
+ WITA Waktu Indonesia Tengah,
+ YST/YDT/YWT/YPT/YDDT Yukon.
+
+
+ -
+
+ For times taken from a city's longitude, use the
+ traditional xMT notation.
+ The only abbreviation like this in current use is 'GMT'.
+ The others are for timestamps before 1960,
+ except that Monrovia Mean Time persisted until 1972.
+ Typically, numeric abbreviations (e.g., '-004430' for
+ MMT) would cause trouble here, as the numeric strings would exceed
+ the POSIX length limit.
+
+
+
+ These abbreviations are:
+ AMT Amsterdam, Asunción, Athens;
+ BMT Baghdad, Bangkok, Batavia, Bern, Bogotá, Bridgetown, Brussels,
+ Bucharest;
+ CMT Calamarca, Caracas, Chisinau, Colón, Copenhagen, Córdoba;
+ DMT Dublin/Dunsink;
+ EMT Easter;
+ FFMT Fort-de-France;
+ FMT Funchal;
+ GMT Greenwich;
+ HMT Havana, Helsinki, Horta, Howrah;
+ IMT Irkutsk, Istanbul;
+ JMT Jerusalem;
+ KMT Kaunas, Kiev, Kingston;
+ LMT Lima, Lisbon, local, Luanda;
+ MMT Macassar, Madras, Malé, Managua, Minsk, Monrovia, Montevideo,
+ Moratuwa, Moscow;
+ PLMT Phù Liễn;
+ PMT Paramaribo, Paris, Perm, Pontianak, Prague;
+ PMMT Port Moresby;
+ QMT Quito;
+ RMT Rangoon, Riga, Rome;
+ SDMT Santo Domingo;
+ SJMT San José;
+ SMT Santiago, Simferopol, Singapore, Stanley;
+ TBMT Tbilisi;
+ TMT Tallinn, Tehran;
+ WMT Warsaw.
+
+
+
+ A few abbreviations also follow the pattern that
+ GMT/BST established for time in the UK.
+ They are:
+ CMT/BST for Calamarca Mean Time and Bolivian Summer Time
+ 1890–1932,
+ DMT/IST for Dublin/Dunsink Mean Time and Irish Summer Time
+ 1880–1916,
+ MMT/MST/MDST for Moscow 1880–1919, and
+ RMT/LST for Riga Mean Time and Latvian Summer time 1880–1926.
+ An extra-special case is SET for Swedish Time (svensk
+ normaltid) 1879–1899, 3° west of the Stockholm
+ Observatory.
+
+
+ -
+ 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.
+
+ -
+ Use current abbreviations for older timestamps to avoid confusion.
+ For example, in 1910 a common English abbreviation for time
+ in central Europe was 'MEZ' (short for both "Middle European
+ Zone" and for "Mitteleuropäische Zeit" in German).
+ Nowadays 'CET' ("Central European Time") is more common in
+ English, and the database uses 'CET' even for circa-1910
+ timestamps as this is less confusing for modern users and avoids
+ the need for determining when 'CET' supplanted 'MEZ' in common
+ usage.
+
+ -
+ Use a consistent style in a
tz region's history.
+ For example, if history tends to use numeric
+ abbreviations and a particular entry could go either way, use a
+ numeric abbreviation.
+
+ -
+ Use
+ Universal Time
+ (UT) (with time zone abbreviation '
-00') for
+ locations while uninhabited.
+ The leading '-' is a flag that the UT offset 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' means one thing in China and something else
+in North America, and 'IST' can refer to time in India, Ireland or
+Israel.
+To avoid ambiguity, use numeric UT offsets like
+'-0600' instead of time zone abbreviations like 'CST'.
+
+
+
+
+ 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
+ timestamps, 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
tz regions 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.
+
+ -
+ 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
+ "History of
+ legal time in Britain".
+ Other countries are not done nearly as well.
+
+ -
+ Sometimes, different people in the same city maintain clocks
+ that differ significantly.
+ Historically, railway time was used by railroad companies (which
+ did not always
+ agree with each other), church-clock time was used for birth
+ certificates, etc.
+ More recently, competing political groups might disagree about
+ clock settings. Often this is merely common practice, but
+ sometimes it is set by law.
+ For example, from 1891 to 1911 the UT offset in France
+ was legally UT +00:09:21 outside train stations and
+ UT +00:04:21 inside. Other examples include
+ Chillicothe in 1920, Palm Springs in 1946/7, and Jerusalem and
+ Ürümqi to this day.
+
+ -
+ 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 tz region'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 tz regions 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 tz region
+ 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 code can handle.
+ For example, from 1909 to 1937 Netherlands clocks were legally Amsterdam Mean
+ Time (estimated to be UT
+ +00:19:32.13), but the tz
+ code cannot represent the fractional second.
+ In practice these old specifications were rarely if ever
+ implemented to subsecond precision.
+
+ -
+ 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, but many people used
+ other calendars and other timescales.
+ For example, the Roman Empire used
+ the Julian
+ calendar,
+ and Roman
+ timekeeping had twelve varying-length daytime hours with a
+ non-hour-based system at night.
+
+ -
+ Early clocks were less reliable, and data entries do not represent
+ clock error.
+
+ -
+ The
tz database assumes Universal Time
+ (UT) as an origin, even though UT is not
+ standardized for older timestamps.
+ In the tz database commentary,
+ UT denotes a family of time standards that includes
+ Coordinated Universal Time (UTC) along with other
+ variants such as UT1 and GMT,
+ with days starting at midnight.
+ Although UT equals UTC for modern
+ timestamps, UTC was not defined until 1960, so
+ commentary uses the more-general abbreviation UT for
+ timestamps that might predate 1960.
+ Since UT, UT1, etc. disagree slightly,
+ and since pre-1972 UTC seconds varied in length,
+ interpretation of older timestamps can be problematic when
+ subsecond accuracy is needed.
+
+ -
+ Civil time was not based on atomic time before 1972, and we do not
+ 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: Stephenson FR, Morrison LV, Hohenkerk CY.
+ Measurement of
+ the Earth's rotation: 720 BC to AD 2015.
+ Proc Royal Soc A. 2016 Dec 7;472:20160404.
+ Also see: Espenak F. Uncertainty
+ in Delta T (ΔT).
+
+ -
+ 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 is not clear how to apply it here.
+
+
+
+
+In short, many, perhaps most, of the tz
+database's pre-1970 and future timestamps 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 tz regions
+merely because two locations
+differ in LMT or transitioned to standard time at
+different dates.
+
+
+
+
+ Time and date functions
+
+The tz code contains time and date functions
+that are upwards compatible with those of POSIX.
+Code compatible with this package is already
+part of many platforms, where the
+primary use of this package is to update obsolete time-related files.
+To do this, you may need to compile the time zone compiler
+'zic' supplied with this package instead of using the
+system 'zic', since the format of zic's
+input is occasionally extended, and a platform may still be shipping
+an older zic.
+
+
+POSIX properties and limitations
+
+ -
+
+ In POSIX, time display in a process is controlled by the
+ environment variable TZ.
+ Unfortunately, the POSIX
+ TZ string takes a form that is hard to describe and
+ is error-prone in practice.
+ Also, POSIX TZ strings cannot deal with daylight
+ saving time rules not based on the Gregorian calendar (as in
+ Iran), or with situations where more than two time zone
+ abbreviations or UT offsets are used in an area.
+
+
+
+ The POSIX TZ string takes the following form:
+
+
+
+ stdoffset[dst[offset][,date[/time],date[/time]]]
+
+
+
+ where:
+
+
+
+ - std and dst
-
+ are 3 or more characters specifying the standard
+ and daylight saving time (DST) zone names.
+ Starting with POSIX.1-2001, std and dst
+ may also be in a quoted form like '
<+09>';
+ this allows "+" and "-" in the names.
+
+ - offset
-
+ 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 ruleset
+ for DST, and its rules can differ from year to year;
+ typically US DST rules are used.
+
+ - time
-
+ 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)
-
+ origin-1 day number not counting February 29
+
+ - n (0≤n≤365)
-
+ origin-0 day number counting February 29 if present
+
+ Mm.n.d
+ (0[Sunday]≤d≤6[Saturday], 1≤n≤5,
+ 1≤m≤12)-
+ for the dth day of week n of
+ month m of the year, where week 1 is the first
+ week in which day d appears, and
+ '
5' stands for the last week in which
+ day d appears (which may be either the 4th or
+ 5th week).
+ Typically, this is the only useful form; the n
+ and Jn forms are rarely used.
+
+
+
+
+
+
+ Here is an example POSIX TZ string for New
+ Zealand after 2007.
+ It says that standard time (NZST) is 12 hours ahead
+ of UT, and that daylight saving time
+ (NZDT) is observed from September's last Sunday at
+ 02:00 until April's first Sunday at 03:00:
+
+
+ TZ='NZST-12NZDT,M9.5.0,M4.1.0/3'
+
+
+ This POSIX TZ string is hard to remember, and
+ mishandles some timestamps before 2008.
+ With this package you can use this instead:
+
+
+ TZ='Pacific/Auckland'
+
+ -
+ POSIX does not define the exact meaning of
TZ values like
+ "EST5EDT".
+ Typically the current US DST rules
+ are used to interpret such values, but this means that the
+ US DST rules are compiled into each
+ program that does time conversion.
+ This means that when
+ US time conversion rules change (as in the United
+ States in 1987), all programs that do time conversion must be
+ recompiled to ensure proper results.
+
+ -
+ The
TZ environment variable is process-global, which
+ makes it hard to write efficient, thread-safe applications that
+ need access to multiple time zone rulesets.
+
+ -
+ In POSIX, there is no tamper-proof way for a process to learn the
+ system's best idea of local wall clock.
+ (This is important for applications that an administrator wants
+ used only at certain times – without regard to whether the
+ user has fiddled the
+
TZ environment variable.
+ While an administrator can "do everything in UT" to
+ get around the problem, doing so is inconvenient and precludes
+ handling daylight saving time shifts - as might be required to
+ limit phone calls to off-peak hours.)
+
+ -
+ POSIX provides no convenient and efficient way to determine
+ the UT offset and time zone abbreviation of arbitrary
+ timestamps, particularly for
tz regions
+ that do not fit into the POSIX model.
+
+ -
+ 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.
+
+
+
+Extensions to POSIX in the
+tz code
+
+ -
+
+ The TZ environment variable is used in generating
+ the name of a binary file from which time-related information is read
+ (or is interpreted à la POSIX); TZ is no longer
+ constrained to be a three-letter time zone
+ abbreviation followed by a number of hours and an optional three-letter
+ daylight time zone abbreviation.
+ The daylight saving time rules to be used for a
+ particular tz region are encoded in the
+ binary file; the format of the file
+ allows U.S., Australian, and other rules to be encoded, and
+ allows for situations where more than two time zone
+ abbreviations are used.
+
+
+ It was recognized that allowing the TZ environment
+ variable to take on values such as 'America/New_York'
+ might cause "old" programs (that expect TZ to have a
+ certain form) to operate incorrectly; consideration was given to using
+ some other environment variable (for example, TIMEZONE)
+ to hold the string used to generate the binary file's name.
+ In the end, however, it was decided to continue using
+ TZ: it is widely used for time zone purposes;
+ separately maintaining both TZ
+ and TIMEZONE seemed a nuisance; and systems where
+ "new" forms of TZ might cause problems can simply
+ use TZ values such as "EST5EDT" which
+ can be used both by "new" programs (à la POSIX) and "old"
+ programs (as zone names and offsets).
+
+
+ -
+ The code supports platforms with a UT offset member
+ in
struct tm, e.g., tm_gmtoff.
+
+ -
+ The code supports platforms with a time zone abbreviation member in
+
struct tm, e.g., tm_zone.
+
+ -
+ Functions
tzalloc, tzfree,
+ localtime_rz, and mktime_z for
+ more-efficient thread-safe applications that need to use multiple
+ time zone rulesets.
+ The tzalloc and tzfree functions
+ allocate and free objects of type timezone_t,
+ and localtime_rz and mktime_z are
+ like localtime_r and mktime with an
+ extra timezone_t argument.
+ The functions were inspired by NetBSD.
+
+ -
+ A function
tzsetwall has been added to arrange for the
+ system's best approximation to local wall clock time to be delivered
+ by subsequent calls to localtime.
+ Source code for portable applications that "must" run on local wall
+ clock time should call tzsetwall;
+ if such code is moved to "old" systems that do not
+ provide tzsetwall, you will not be able to generate an
+ executable program.
+ (These functions also arrange for local wall clock time to
+ be used if tzset is called – directly or
+ indirectly – and there is no TZ environment
+ variable; portable applications should not, however, rely on this
+ behavior since it is 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.
+
+
+
+POSIX features no longer needed
+
+POSIX and ISO C
+define some APIs that are vestigial:
+they are not needed, and are relics of a too-simple model that does
+not suffice to handle many real-world timestamps.
+Although the tz code supports these
+vestigial APIs for backwards compatibility, they should
+be avoided in portable applications.
+The vestigial APIs are:
+
+
+ -
+ The POSIX
tzname variable does not suffice and is no
+ longer needed.
+ To get a timestamp's time zone abbreviation, consult
+ the tm_zone member if available; otherwise,
+ use strftime's "%Z" conversion
+ specification.
+
+ -
+ The POSIX
daylight and timezone
+ variables do not suffice and are no longer needed.
+ To get a timestamp's UT offset, consult
+ the tm_gmtoff member if available; otherwise,
+ subtract values returned by localtime
+ and gmtime using the rules of the Gregorian calendar,
+ or use strftime's "%z" conversion
+ specification if a string like "+0900" suffices.
+
+ -
+ The
tm_isdst member is almost never needed and most of
+ its uses should be discouraged in favor of the abovementioned
+ APIs.
+ Although it can still be used in arguments to
+ mktime to disambiguate timestamps near
+ a DST transition when the clock jumps back, this
+ disambiguation does not work when standard time itself jumps back,
+ which can occur when a location changes to a time zone with a
+ lesser UT offset.
+
+
+
+Other portability notes
+
+ -
+ The 7th Edition
+ UNIX
timezone function is not present in this
+ package; it is impossible to reliably map timezone's
+ arguments (a "minutes west of GMT" value and a
+ "daylight saving time in effect" flag) to a time zone
+ abbreviation, and we refuse to guess.
+ Programs that in the past used the timezone function
+ may now examine localtime(&clock)->tm_zone
+ (if TM_ZONE is defined) or
+ tzname[localtime(&clock)->tm_isdst]
+ (if HAVE_TZNAME is defined) to learn the correct time
+ zone abbreviation to use.
+
+ -
+ The 4.2BSD
+
gettimeofday function is not
+ used in this package.
+ This formerly let users obtain the current UTC offset
+ and DST flag, but this functionality was removed in
+ later versions of BSD.
+
+ -
+ In SVR2, time conversion fails for near-minimum or
+ near-maximum
time_t values when doing conversions
+ for places that do not use UT.
+ This package takes care to do these conversions correctly.
+ A comment in the source code tells how to get compatibly wrong
+ results.
+
+ -
+ The functions that are conditionally compiled
+ if
STD_INSPIRED is defined should, at this point, be
+ looked on primarily as food for thought.
+ They are not in any sense "standard compatible" – some are
+ not, in fact, specified in any standard.
+ They do, however, represent responses of various authors to
+ standardization proposals.
+
+ -
+ Other time conversion proposals, in particular the one developed
+ by folks at Hewlett Packard, offer a wider selection of functions
+ that provide capabilities beyond those provided here.
+ The absence of such functions from this package is not meant to
+ discourage the development, standardization, or use of such
+ functions.
+ Rather, their absence reflects the decision to make this package
+ contain valid extensions to POSIX, to ensure its broad
+ acceptability.
+ If more powerful time conversion functions can be standardized, so
+ much the better.
+
+
+
+
+
+ Interface stability
+
+The tz code and data supply the following interfaces:
+
+
+
+ -
+ A set of
tz region names as per
+ "Names of time zone rulesets" above.
+
+ -
+ Library functions described in "Time and date
+ functions" above.
+
+ -
+ The programs
tzselect, zdump,
+ and zic, documented in their man pages.
+
+ -
+ The format of
zic input files, documented in
+ the zic man page.
+
+ -
+ The format of
zic output files, documented in
+ the tzfile man page.
+
+ -
+ The format of zone table files, documented in
zone1970.tab.
+
+ -
+ The format of the country code file, documented in
iso3166.tab.
+
+ -
+ The version number of the code and data, as the first line of
+ the text file '
version' in each release.
+
+
+
+
+Interface changes in a release attempt to preserve compatibility with
+recent releases.
+For example, tz data files typically do not
+rely on recently-added zic features, so that users can
+run older zic versions to process newer data files.
+Downloading
+the tz database describes how releases
+are tagged and distributed.
+
+
+
+Interfaces not listed above are less stable.
+For example, users should not rely on particular UT
+offsets or abbreviations for timestamps, as data entries are often
+based on guesswork and these guesses may be corrected or improved.
+
+
+
+
+ Calendrical issues
+
+Calendrical issues are a bit out of scope for a time zone database,
+but they indicate the sort of problems that we would run into if we
+extended the time zone database further into the past.
+An excellent resource in this area is Edward M. Reingold
+and Nachum Dershowitz, Calendrical
+Calculations: The Ultimate Edition, Cambridge University Press (2018).
+Other information and sources are given in the file 'calendars'
+in the tz distribution.
+They sometimes disagree.
+
+
+
+
+ Time and time zones on other planets
+
+Some people's work schedules
+use Mars time.
+Jet Propulsion Laboratory (JPL) coordinators kept Mars time on
+and off during the
+Mars
+Pathfinder mission.
+Some of their family members 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.
+
+
+
+A Mars solar day is called a "sol" and has a mean period equal to
+about 24 hours 39 minutes 35.244 seconds in terrestrial time.
+It is divided into a conventional 24-hour clock, so each Mars second
+equals about 1.02749125 terrestrial seconds.
+
+
+
+The prime
+meridian of Mars goes through the center of the crater
+Airy-0, named in
+honor of the British astronomer who built the Greenwich telescope that
+defines Earth's prime meridian.
+Mean solar time on the Mars prime meridian is
+called Mars
+Coordinated Time (MTC).
+
+
+
+Each landed mission on Mars has adopted a different reference for
+solar time keeping, so there is no real standard for Mars time zones.
+For example, the
+Mars
+Exploration Rover project (2004) defined two time zones "Local
+Solar Time A" and "Local Solar Time B" for its two missions, each zone
+designed so that its time equals local true solar time at
+approximately the middle of the nominal mission.
+Such a "time zone" is not particularly suited for any application
+other than the mission itself.
+
+
+
+Many calendars have been proposed for Mars, but none have achieved
+wide acceptance.
+Astronomers often use Mars Sol Date (MSD) which is a
+sequential count of Mars solar days elapsed since about 1873-12-29
+12:00 GMT.
+
+
+
+In our solar system, Mars is the planet with time and calendar most
+like Earth's.
+On other planets, Sun-based time and calendars would work quite
+differently.
+For example, although Mercury's
+sidereal
+rotation period is 58.646 Earth days, Mercury revolves around the
+Sun so rapidly that an observer on Mercury's equator would see a
+sunrise only every 175.97 Earth days, i.e., a Mercury year is 0.5 of a
+Mercury day.
+Venus is more complicated, partly because its rotation is slightly
+retrograde:
+its year is 1.92 of its days.
+Gas giants like Jupiter are trickier still, as their polar and
+equatorial regions rotate at different rates, so that the length of a
+day depends on latitude.
+This effect is most pronounced on Neptune, where the day is about 12
+hours at the poles and 18 hours at the equator.
+
+
+
+Although the tz database does not support
+time on other planets, it is documented here in the hopes that support
+will be added eventually.
+
+
+
+Sources for time on other planets:
+
+
+
+ -
+ Michael Allison and Robert Schmunk,
+ "Technical
+ Notes on Mars Solar Time as Adopted by the Mars24 Sunclock"
+ (2015-06-30).
+
+ -
+ Jia-Rui Chong,
+ "Workdays
+ Fit for a Martian", Los Angeles Times
+ (2004-01-14), pp A1, A20–A21.
+
+ -
+ Tom Chmielewski,
+ "Jet
+ Lag Is Worse on Mars", The Atlantic (2015-02-26)
+
+ -
+ Matt Williams,
+ "How
+ long is a day on the other planets of the solar system?"
+ (2017-04-27).
+
+
+
+
+
+
+
Property changes on: vendor/tzdb/tzcode2018e/theory.html
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/html
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/time2posix.3
===================================================================
--- vendor/tzdb/tzcode2018e/time2posix.3 (nonexistent)
+++ vendor/tzdb/tzcode2018e/time2posix.3 (revision 337695)
@@ -0,0 +1,129 @@
+.TH TIME2POSIX 3
+.SH NAME
+time2posix, posix2time \- convert seconds since the Epoch
+.SH SYNOPSIS
+.nf
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
+.B #include
+.PP
+.B time_t time2posix(time_t t);
+.PP
+.B time_t posix2time(time_t t);
+.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
+..
+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.
+.PP
+If the time package is configured with leap-second support
+enabled,
+however,
+no such adjustment is needed and
+time_t values continue to increase over leap events
+(as a true
+.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
+Typically this is not a problem as the type time_t is intended
+to be
+(mostly)
+opaque \*(en time_t values should only be obtained-from and
+passed-to functions such as
+.IR time(2) ,
+.IR localtime(3) ,
+.IR mktime(3) ,
+and
+.IR difftime(3) .
+However,
+POSIX gives an arithmetic
+expression for directly computing a time_t value from a given date/time,
+and the same relationship is assumed by some
+(usually older)
+applications.
+Any programs creating/dissecting time_t's
+using such a relationship will typically not handle intervals
+over leap seconds correctly.
+.PP
+The
+.I time2posix
+and
+.I posix2time
+functions are provided to address this time_t mismatch by converting
+between local time_t values and their POSIX equivalents.
+This is done by accounting for the number of time-base changes that
+would have taken place on a POSIX system as leap seconds were inserted
+or deleted.
+These converted values can then be used in lieu of correcting the older
+applications,
+or when communicating with POSIX-compliant systems.
+.PP
+.I Time2posix
+is single-valued.
+That is,
+every local time_t
+corresponds to a single POSIX time_t.
+.I Posix2time
+is less well-behaved:
+for a positive leap second hit the result is not unique,
+and for a negative leap second hit the corresponding
+POSIX time_t doesn't exist so an adjacent value is returned.
+Both of these are good indicators of the inferiority of the
+POSIX representation.
+.PP
+The following table summarizes the relationship between a time
+T and it's conversion to,
+and back from,
+the POSIX representation over the leap second inserted at the end of June,
+1993.
+.nf
+.ta \w'93/06/30 'u +\w'23:59:59 'u +\w'A+0 'u +\w'X=time2posix(T) 'u
+DATE TIME T X=time2posix(T) posix2time(X)
+93/06/30 23:59:59 A+0 B+0 A+0
+93/06/30 23:59:60 A+1 B+1 A+1 or A+2
+93/07/01 00:00:00 A+2 B+1 A+1 or A+2
+93/07/01 00:00:01 A+3 B+2 A+3
+
+A leap second deletion would look like...
+
+DATE TIME T X=time2posix(T) posix2time(X)
+??/06/30 23:59:58 A+0 B+0 A+0
+??/07/01 00:00:00 A+1 B+2 A+1
+??/07/01 00:00:01 A+2 B+3 A+2
+.sp
+.ce
+ [Note: posix2time(B+1) => A+0 or A+1]
+.fi
+.PP
+If leap-second support is not enabled,
+local time_t's and
+POSIX time_t's are equivalent,
+and both
+.I time2posix
+and
+.I posix2time
+degenerate to the identity function.
+.SH SEE ALSO
+difftime(3),
+localtime(3),
+mktime(3),
+time(2)
+.\" This file is in the public domain, so clarified as of
+.\" 1996-06-05 by Arthur David Olson.
Property changes on: vendor/tzdb/tzcode2018e/time2posix.3
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/time2posix.3.txt
===================================================================
--- vendor/tzdb/tzcode2018e/time2posix.3.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/time2posix.3.txt (revision 337695)
@@ -0,0 +1,76 @@
+TIME2POSIX(3) Library Functions Manual TIME2POSIX(3)
+
+NAME
+ time2posix, posix2time - convert seconds since the Epoch
+
+SYNOPSIS
+ #include
+
+ time_t time2posix(time_t t);
+
+ time_t posix2time(time_t t);
+
+ cc ... -ltz
+
+DESCRIPTION
+ 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
+ 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.
+
+ The time2posix and posix2time functions are provided to address this
+ time_t mismatch by converting between local time_t values and their
+ POSIX equivalents. This is done by accounting for the number of time-
+ base changes that would have taken place on a POSIX system as leap
+ seconds were inserted or deleted. These converted values can then be
+ used in lieu of correcting the older applications, or when
+ communicating with POSIX-compliant systems.
+
+ Time2posix is single-valued. That is, every local time_t corresponds
+ to a single POSIX time_t. Posix2time is less well-behaved: for a
+ positive leap second hit the result is not unique, and for a negative
+ leap second hit the corresponding POSIX time_t doesn't exist so an
+ adjacent value is returned. Both of these are good indicators of the
+ inferiority of the POSIX representation.
+
+ The following table summarizes the relationship between a time T and
+ it's conversion to, and back from, the POSIX representation over the
+ leap second inserted at the end of June, 1993.
+ DATE TIME T X=time2posix(T) posix2time(X)
+ 93/06/30 23:59:59 A+0 B+0 A+0
+ 93/06/30 23:59:60 A+1 B+1 A+1 or A+2
+ 93/07/01 00:00:00 A+2 B+1 A+1 or A+2
+ 93/07/01 00:00:01 A+3 B+2 A+3
+
+ A leap second deletion would look like...
+
+ DATE TIME T X=time2posix(T) posix2time(X)
+ ??/06/30 23:59:58 A+0 B+0 A+0
+ ??/07/01 00:00:00 A+1 B+2 A+1
+ ??/07/01 00:00:01 A+2 B+3 A+2
+
+ [Note: posix2time(B+1) => A+0 or A+1]
+
+ If leap-second support is not enabled, local time_t's and POSIX
+ time_t's are equivalent, and both time2posix and posix2time degenerate
+ to the identity function.
+
+SEE ALSO
+ difftime(3), localtime(3), mktime(3), time(2)
+
+ TIME2POSIX(3)
Property changes on: vendor/tzdb/tzcode2018e/time2posix.3.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tz-art.html
===================================================================
--- vendor/tzdb/tzcode2018e/tz-art.html (nonexistent)
+++ vendor/tzdb/tzcode2018e/tz-art.html (revision 337695)
@@ -0,0 +1,610 @@
+
+
+
+
+Time and the Arts
+
+
+Time and the Arts
+Documentaries
+
+-
+"Daylight
+Saving Time Explained" (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.
+-
+"The Problem
+with Time & Timezones – Computerphile" (2013; 10:12) delves
+into problems that programmers have with timekeeping.
+-
+All The Time In The World:
+Explaining The Mysteries Of Time Zones" (2017; 2:15)
+briefly says why France has more time zones than Russia.
+
-
+"About Time" (1962; 53 minutes) is part of the
+Bell Science extravaganza, with Frank Baxter, Richard Deacon, and Les Tremayne.
+Its advisor was Richard Feynman, and it was voiced by Mel Blanc.
+(IMDb entry.)
+
+Movies
+
+-
+In the 1946 movie A Matter of Life and Death
+(U.S. title Stairway to Heaven)
+there is a reference to British Double Summer Time.
+The time does not play a large part in the plot;
+it's just a passing reference to the time when one of the
+characters was supposed to have died (but didn't).
+The IMDb page is at
+
+http://us.imdb.com/title/tt0038733/
+. (Dave Cantor)
+
-
+The 1953 railway comedy movie The Titfield Thunderbolt 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:
+
+http://us.imdb.com/title/tt0046436/
+. (Mark Brader, 2009-10-02)
+
+-
+The premise of the 1999 caper movie Entrapment involves computers
+in an international banking network being shut down briefly at
+midnight in each time zone to avoid any problems at the transition
+from the year 1999 to 2000 in that zone. (Hmmmm.) If this shutdown
+is extended by 10 seconds, it will create a one-time opportunity for
+a gigantic computerized theft. To achieve this, at one location the
+crooks interfere with the microwave system supplying time signals to
+the computer, advancing the time by 0.1 second each minute over the
+last hour of 1999. (So this movie teaches us that 0.1 × 60 = 10.)
+IMDb page:
+
+http://us.imdb.com/title/tt0137494/
+. (Mark Brader, 2009-10-02)
+
+-
+One mustn't forget the
+trailer
+(2014; 2:23) for the movie Daylight Saving.
+
+
+TV episodes
+
+-
+An episode of The Adventures of Superman 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.
+
+-
+"The Chimes of Big Ben", The Prisoner, episode 2, ITC, 1967-10-06.
+Our protagonist tumbles to
+the fraudulent nature of a Poland-to-England escape upon hearing "Big
+Ben" chiming on Polish local time.
+
+-
+"The Susie", Seinfeld, season 8, episode 15, NBC, 1997-02-13.
+Kramer decides that daylight saving time
+isn't coming fast enough, so he sets his watch ahead an hour.
+
+-
+"20 Hours in America", The West Wing, season 4, episodes 1–2,
+2002-09-25, contained a scene that
+saw White House staffers stranded in Indiana; they thought they had time to
+catch Air Force One but were done in by intra-Indiana local time changes.
+
+-
+"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?,
+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.
+
+-
+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).
+
+-
+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.
+
+-
+In the "Run by the Monkeys" episode of Da Vinci's Inquest
+(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.
+
+-
+In "The Todd Couple" episode of Outsourced (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.)
+
+-
+In the "14 Days to Go"/"T Minus..." episode of
+You, Me and the Apocalypse
+(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.)
+
+-
+"The Lost Hour", Eerie, Indiana, episode 10, NBC, 1991-12-01.
+Despite Indiana's then-lack of DST, Marshall changes his clock with
+unusual consequences.
+See "Eerie,
+Indiana was a few dimensions ahead of its time".
+
+-
+"Time Tunnel", The Adventures of Pete & Pete, season 2, episode 5,
+Nickelodeon, 1994-10-23.
+The two Petes travel back in time an hour on the day that DST ends.
+
+-
+"King-Size Homer", The Simpsons, episode 135, Fox, 1995-11-05.
+Homer, working from home, remarks "8:58, first
+time I've ever been early for work. Except for all those daylight
+savings days. Lousy farmers."
+
+-
+"Tracks", The Good Wife, season 7, episode 12,
+CBS, 2016-01-17.
+The applicability of a contract hinges on the
+time zone associated with a video timestamp.
+
+-
+"Justice", Veep, season 6, episode 4, HBO, 2017-05-07.
+Jonah's inability to understand DST ends up impressing a wealthy
+backer who sets him up for a 2020 presidential run.
+
+
+Books, plays, and magazines
+
+-
+Jules Verne, Around the World in Eighty Days
+(Le tour du monde en quatre-vingts jours), 1873.
+Wall-clock time plays a central role in the plot.
+European readers of the 1870s clearly held the U.S. press in
+deep contempt; the protagonists cross the U.S. without once
+reading a paper.
+Available versions include
+an English
+translation, and
+the original French
+"with illustrations from the original 1873 French-language edition".
+
+-
+Nick Enright, Daylight Saving, 1989.
+A fast-paced comedy about love and loneliness as the clocks turn back.
+
+-
+Umberto Eco, The Island of the Day Before
+(L'isola del giorno prima), 1994.
+"...the story of a 17th century Italian nobleman trapped near an island
+on the International Date Line. Time and time zones play an integral
+part in the novel." (Paul Eggert, 2006-04-22)
+
+-
+John Dunning, Two
+O'Clock, Eastern Wartime, 2001.
+Mystery, history, daylight saving time, and old-time radio.
+
+-
+Surrealist artist Guy Billout's work "Date Line" appeared on page 103
+of the 1999-11 Atlantic Monthly.
+
+-
+"Gloom, Gloom, Go Away" by Walter Kirn appeared on page 106 of Time
+magazine's 2002-11-11 issue; among other things, it proposed
+year-round DST as a way of lessening wintertime despair.
+
+
+Music
+
+Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:
+
+Artist Karrin Allyson
+CD I Didn't Know About You
+Copyright Date 1993
+Label Concord Jazz, Inc.
+ID CCD-4543
+Track Time 3:44
+Personnel Karrin Allyson, vocal;
+Russ Long, piano;
+Gerald Spaits, bass;
+Todd Strait, drums
+Notes CD notes "additional lyric by Karrin Allyson;
+arranged by Russ Long and Karrin Allyson"
+ADO Rating 1 star
+AMG Rating 4 stars
+Penguin Rating 3.5 stars
+
+Artist Kevin Mahogany
+CD Double Rainbow
+Copyright Date 1993
+Label Enja Records
+ID ENJ-7097 2
+Track Time 6:27
+Personnel Kevin Mahogany, vocal;
+Kenny Barron, piano;
+Ray Drummond, bass;
+Ralph Moore, tenor saxophone;
+Lewis Nash, drums
+ADO Rating 1.5 stars
+AMG Rating 3 stars
+Penguin Rating 3 stars
+
+Artist Joe Williams
+CD Here's to Life
+Copyright Date 1994
+Label Telarc International Corporation
+ID CD-83357
+Track Time 3:58
+Personnel Joe Williams, vocal
+The Robert Farnon [39 piece] Orchestra
+Notes This CD is also available as part of a 3-CD package from
+Telarc, "Triple Play" (CD-83461)
+ADO Rating black dot
+AMG Rating 2 stars
+Penguin Rating 3 stars
+
+Artist Charles Fambrough
+CD Keeper of the Spirit
+Copyright Date 1995
+Label AudioQuest Music
+ID AQ-CD1033
+Track Time 7:07
+Personnel Charles Fambrough, bass;
+Joel Levine, tenor recorder;
+Edward Simon, piano;
+Lenny White, drums;
+Marion Simon, percussion
+ADO Rating 2 stars
+AMG Rating unrated
+Penguin Rating 3 stars
+
+
+Also of note:
+
+Artist Holly Cole Trio
+CD Blame It On My Youth
+Copyright Date 1992
+Label Manhattan
+ID CDP 7 97349 2
+Total Time 37:45
+Personnel Holly Cole, voice;
+Aaron Davis, piano;
+David Piltch, string bass
+Notes Lyrical reference to "Eastern Standard Time" in
+Tom Waits' "Purple Avenue"
+ADO Rating 2.5 stars
+AMG Rating 3 stars
+Penguin Rating unrated
+
+Artist Milt Hinton
+CD Old Man Time
+Copyright Date 1990
+Label Chiaroscuro
+ID CR(D) 310
+Total Time 149:38 (two CDs)
+Personnel Milt Hinton, bass;
+Doc Cheatham, Dizzy Gillespie, Clark Terry, trumpet;
+Al Grey, trombone;
+Eddie Barefield, Joe Camel (Flip Phillips), Buddy Tate,
+clarinet and saxophone;
+John Bunch, Red Richards, Norman Simmons, Derek Smith,
+Ralph Sutton, piano;
+Danny Barker, Al Casey, guitar;
+Gus Johnson, Gerryck King, Bob Rosengarden, Jackie Williams,
+drums;
+Lionel Hampton, vibraphone;
+Cab Calloway, Joe Williams, vocal;
+Buck Clayton, arrangements
+Notes tunes include Old Man Time, Time After Time,
+Sometimes I'm Happy,
+A Hot Time in the Old Town Tonight,
+Four or Five Times, Now's the Time,
+Time on My Hands, This Time It's Us,
+and Good Time Charlie.
+Album info
+is available.
+ADO Rating 3 stars
+AMG Rating 4.5 stars
+Penguin Rating 3 stars
+
+Artist Alan Broadbent
+CD Pacific Standard Time
+Copyright Date 1995
+Label Concord Jazz, Inc.
+ID CCD-4664
+Total Time 62:42
+Personnel Alan Broadbent, piano;
+Putter Smith, Bass;
+Frank Gibson, Jr., drums
+Notes The CD cover features an analemma for equation-of-time fans
+ADO Rating 1 star
+AMG Rating 4 stars
+Penguin Rating 3.5 stars
+
+Artist Anthony Braxton/Richard Teitelbaum
+CD Silence/Time Zones
+Copyright Date 1996
+Label Black Lion
+ID BLCD 760221
+Total Time 72:58
+Personnel Anthony Braxton, sopranino and alto saxophones,
+contrebasse clarinet, miscellaneous instruments;
+Leo Smith, trumpet and miscellaneous instruments;
+Leroy Jenkins, violin and miscellaneous instruments;
+Richard Teitelbaum, modular moog and micromoog synthesizer
+ADO Rating black dot
+AMG Rating 4 stars
+
+Artist Charles Gayle
+CD Time Zones
+Copyright Date 2006
+Label Tompkins Square
+ID TSQ2839
+Total Time 49:06
+Personnel Charles Gayle, piano
+ADO Rating 1 star
+AMG Rating 4.5 stars
+
+Artist The Get Up Kids
+CD Eudora
+Copyright Date 2001
+Label Vagrant
+ID 357
+Total Time 65:12
+Notes Includes the song "Central Standard Time." Thanks to Colin Bowern for this information.
+AMG Rating 2.5 stars
+
+
+Artist Coldplay
+Song Clocks
+Copyright Date 2003
+Label Capitol Records
+ID 52608
+Total Time 4:13
+Notes Won the 2004 Record of the Year honor at the
+Grammy Awards. Co-written and performed by Chris Martin,
+great-great-grandson of DST inventor William Willett. The song's first
+line is "Lights go out and I can't be saved".
+
+
+Artist Jaime Guevara
+Song Qué
+hora es
+Date 1993
+Total Time 3:04
+Notes The song protested "Sixto Hour" in Ecuador
+(1992–3). Its lyrics include "Amanecía en mitad de la noche, los
+guaguas iban a clase sin sol" ("It was dawning in the middle of the
+night, the buses went to class without sun").
+
+
+Artist Irving Kahal and Harry Richman
+Song There Ought to be a Moonlight Saving Time
+Copyright Date 1931
+Notes This musical standard was a No. 1 hit for Guy Lombardo
+in 1931, and was also performed by Maurice Chevalier, Blossom Dearie
+and many others. The phrase "Moonlight saving time" also appears in
+the 1995 country song "Not Enough Hours in the Night" written by Aaron
+Barker, Kim Williams and Rob Harbin and performed by Doug
+Supernaw.
+
+
+Artist The Microscopic Septet
+CD Lobster Leaps In
+Copyright Date 2008
+Label Cuneiform
+ID 272
+Total Time 73:05
+Notes Includes the song "Twilight Time Zone."
+AMG Rating 3.5 stars
+ADO Rating 2 stars
+
+
+
+Artist Bob Dylan
+CD The Times They Are a-Changin'
+Copyright Date 1964
+Label Columbia
+ID CK-8905
+Total Time 45:36
+AMG Rating 4.5 stars
+ADO Rating 1.5 stars
+Notes The title song is also available on "Bob Dylan's Greatest Hits" and "The Essential Bob Dylan."
+
+
+Artist Luciana Souza
+CD Tide
+Copyright Date 2009
+Label Universal Jazz France
+ID B0012688-02
+Total Time 42:31
+AMG Rating 3.5 stars
+ADO Rating 2.5 stars
+Notes Includes the song "Fire and Wood" with the lyric
+"The clocks were turned back you remember/Think it's still November."
+
+
+Artist Ken Nordine
+CD You're Getting Better: The Word Jazz Dot Masters
+Copyright Date 2005
+Label Geffen
+ID B0005171-02
+Total Time 156:22
+ADO Rating 1 star
+AMG Rating 4.5 stars
+Notes Includes the piece "What Time Is It"
+("He knew what time it was everywhere...that counted").
+
+Comics
+
+-
+The webcomic xkcd has the strip
+"The Sun" (2009-12-09) and the panels
+"Backward in Time" (2012-02-14),
+"EST" (2012-05-28),
+"ISO 8601" (2013-02-27),
+"Now" (2014-02-26),
+"Doomsday Clock" (2016-03-14),
+"Bad Map Projection: Time Zones"
+(2017-02-15), and
+"Supervillain Plan" (2017-08-30).
+The related book What If? has an entry
+"Leap Seconds" (2012-12-31).
+
+-
+Pig kills time in Pearls
+Before Swine (2016-11-06).
+
+-
+Stonehenge is abandoned in Non Sequitur
+(2017-03-12).
+
-
+The boss freaks out in Dilbert (1998-03-14).
+
+-
+Peppermint Patty: "What if the world comes to an end tonight, Marcie?"
+
+Marcie: "I promise there'll be a tomorrow, sir ... in fact,
+it's already tomorrow in Australia!"
+
+(Charles M. Schulz, Peanuts, 1980-06-13)
+
+
+Jokes
+
+-
+The idea behind daylight saving time was first proposed as a joke by
+Benjamin Franklin. To enforce it, he suggested, "Every
+morning, as soon as the sun rises, let all the bells in every church
+be set ringing; and if that is not sufficient, let cannon be fired in
+every street, to wake the sluggards effectually, and make them open
+their eyes to see their true interest. All the difficulty will be in
+the first two or three days: after which the reformation will be as
+natural and easy as the present irregularity; for, ce n'est que le
+premier pas qui coûte."
+Franklin's
+joke was first published on 1784-04-26 by the
+Journal de Paris as an
+anonymous letter translated into French.
+
+-
+"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 Animal Crackers, 1930,
+as noted by Will Fitzgerald)
+
+-
+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.!
+
+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!
+
+(From the play Inherit the Wind 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.)
+
+-
+"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)
+
+-
+"A fundamental belief held by Americans is that if you are on land, you
+cannot be killed by a fish...So most Americans remain on land, believing
+they're safe. Unfortunately, this belief – like so many myths, such as that
+there's a reason for 'Daylight Saving Time' – is false."
+(Dave Barry column, 2000-07-02)
+
+-
+"I once had sex for an hour and five minutes, but that was on the day
+when you turn the clocks ahead."
+(Garry Shandling, 52nd Annual Emmys, 2000-09-10)
+
+-
+"Would it impress you if I told you I invented Daylight Savings Time?"
+("Sahjhan" to "Lilah" in dialog from the "Loyalty" episode of Angel,
+originally aired 2002-02-25)
+
+-
+"I thought you said Tulsa was a three-hour flight."
+"Well, you're forgetting about the time difference."
+("Joey" and "Chandler" in dialog from the episode of Friends
+entitled "The One With Rachel's Phone Number," originally aired 2002-12-05)
+
+-
+"Is that a pertinent fact,
+or are you just trying to dazzle me with your command of time zones?"
+(Kelsey Grammer as "Frasier Crane" to "Roz" from the episode of Frasier
+entitled "The Kid," originally aired 1997-11-04)
+
+-
+"I put myself and my staff through this crazy, huge ordeal, all because
+I refused to go on at midnight, okay? And so I work, you know, and
+then I get this job at eleven, supposed to be a big deal. Then
+yesterday daylight [saving] time ended. Right now it's basically
+midnight." (Conan O'Brien on the 2010-11-08 premiere of Conan.)
+
+-
+"The best method, I told folks, was to hang a large clock high on a
+barn wall where all the cows could see it. If you have Holsteins, you
+will need to use an analog clock." (Jerry Nelson, How
+to adjust dairy cows to daylight saving time", Successful Farming,
+2017-10-09.)
+
+-
+"And now, driving to California, I find that I must enter a password
+in order to change the time zone on my laptop clock. Evidently,
+someone is out to mess up my schedule and my clock must be secured."
+(Garrison Keillor,
+"We've
+never been here before", 2017-08-22)
+
+-
+"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, Rowan & Martin's Laugh-In No. 65, 1970-03-09)
+
+
+See also
+
+
+
+This web page is in the public domain, so clarified as of
+2009-05-17 by Arthur David Olson.
+
+Please send corrections to this web page to the
+time zone mailing list.
+
+
+
Property changes on: vendor/tzdb/tzcode2018e/tz-art.html
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/html
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tz-how-to.html
===================================================================
--- vendor/tzdb/tzcode2018e/tz-how-to.html (nonexistent)
+++ vendor/tzdb/tzcode2018e/tz-how-to.html (revision 337695)
@@ -0,0 +1,682 @@
+
+
+
+How to Read the tz Database
+
+
+
+How to Read the tz
+Database Source Files
+by Bill Seymour
+This page uses the America/Chicago and
+Pacific/Honolulu zones as examples of how to infer
+times of day from the tz database
+source files. It might be helpful, but not absolutely necessary,
+for the reader to have already downloaded the
+latest release of the database and become familiar with the basic layout
+of the data files. The format is explained in the “man
+page” for the zic compiler, zic.8.txt, in
+the code subdirectory.
+
+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.
+
+First, let’s consider the special daylight saving time rules
+for Chicago (from the northamerica file in
+the data subdirectory):
+
+
+
+ From the Source File
+
+
+
+
+#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
+
+
+
+
+ Reformatted a Bit
+
+
+ From
+ To
+ On
+ At
+ Action
+
+
+ 1920 only
+ June 13th
+ 02:00 local
+ go to daylight saving time
+
+
+ 1920
+ 1921
+ last Sunday
+ in October
+ return to standard time
+
+
+ 1921 only
+ in March
+ go to daylight saving time
+
+
+ 1922
+ 1966
+ in April
+
+
+ 1954
+ in September
+ return to standard time
+
+
+ 1955
+ 1966
+ in October
+
+
+
+We’ll basically just ignore the TYPE column.
+In the 2007j release, the most recent as of this writing, the
+TYPE column never contains anything but a hyphen,
+a kind of null value. (From the description in zic.8.txt,
+this appears to be a mechanism for removing years from a set
+in some localizable way. It’s used in the file, pacificnew,
+to determine whether a given year will have a US presidential election;
+but everything related to that use is commented out.)
+
+
The SAVE 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.
+
+
The LETTER (sometimes called LETTER/S)
+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 LETTER column
+in the Chicago rules. More about this when we talk about
+“Zone” lines.
+
+
One important thing to notice is that “Rule” lines
+want at once to be both transitions and steady states:
+
+- 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).
+- On the other hand, the
SAVE and LETTER
+columns contain state that exists between transitions. More about this
+when we talk about the US rules.
+
+
+In the example above, the transition to daylight saving time
+happened on the 13th 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?
+
+OK, now for the somewhat more interesting “US” rules:
+
+
+
+ From the Source File
+
+
+
+
+#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
+
+
+
+
+ Reformatted a Bit
+
+
+ From
+ To
+ On
+ At
+ Action
+
+
+ 1918
+ 1919
+ last Sunday
+ in March
+ 02:00 local
+ go to daylight saving time
+
+
+ in October
+ return to standard time
+
+
+ 1942 only
+ February 9th
+ go to “war time”
+
+
+ 1945 only
+ August 14th
+ 23:00 UT
+
+ rename “war time” to “peace
time;”
+ clocks don’t change
+
+
+
+ September 30th
+ 02:00 local
+ return to standard time
+
+
+ 1967
+ 2006
+ last Sunday
+ in October
+
+
+ 1973
+ in April
+ go to daylight saving time
+
+
+ 1974 only
+ January 6th
+
+
+ 1975 only
+ February 23rd
+
+
+ 1976
+ 1986
+ last Sunday
+ in April
+
+
+ 1987
+ 2006
+ first Sunday
+
+
+ 2007
+ present
+ second Sunday in March
+
+
+ first Sunday in November
+ return to standard time
+
+
+
+There are two interesting things to note here.
+
+First, the time that something happens (in the AT
+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
+prime meridian.
+‘g’ stands for “GMT”;
+‘u’ stands for “UT” or “UTC”
+(whichever was official at the time); ‘z’ stands for the
+nautical time zone
+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.
+
+Second, the day in the ON column, in addition to
+“lastSun” or a particular day of the month,
+can have the form, “Sun>=x” or
+“Sun<=x,” where x is a day
+of the month. For example, “Sun>=8” 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
+“Sun” in either form, but can be the usual
+three-character English abbreviation for any day of the week.
+
+And the US rules give us more examples of a couple of things
+already mentioned:
+
+
+- The rules for changing to and from daylight saving time are
+actually different sets 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).
+
+- The
SAVE and LETTER columns
+contain steady state, not transitions. Consider, for example,
+the transition from “war time” to “peace time”
+that happened on August 14, 1945. The “1:00” in
+the SAVE column is not an instruction to advance
+the clock an hour. It means that clocks should be one hour
+ahead of standard time, which they already are because of the previous
+rule, so there should be no change.
+
+
+
+OK, now let’s look at a Zone record:
+
+
+
+ From the Source File
+
+
+
+
+#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
+
+
+
+
+ Columns Renamed
+
+
+ Standard Offset
+ from Prime
+ Meridian
+ Daylight
Saving Time
+ Abbreviation(s)
+ Ending at Local Time
+
+
+ Date
+ Time
+
+
+ −5:50:36
+ not observed
+ LMT
+ 1883-11-18
+ 12:09:24
+
+
+ −6:00:00
+ US rules
+ CST or CDT
+ 1920-01-01
+ 00:00:00
+
+
+ Chicago rules
+ 1936-03-01
+ 02:00:00
+
+
+ −5:00:00
+ not observed
+ EST
+ 1936-11-15
+
+
+ −6:00:00
+ Chicago rules
+ CST or CDT
+ 1942-01-01
+ 00:00:00
+
+
+ US rules
+ CST, CWT or CPT
+ 1946-01-01
+
+
+ Chicago rules
+ CST or CDT
+ 1967-01-01
+
+
+ US rules
+ —
+
+
+
+There are a couple of interesting differences between Zones and Rules.
+
+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 continuation lines. Thus, the keyword,
+“Zone,” and the zone name are not
+repeated. The last line is the one without anything in
+the [UNTIL] column.
+
+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 [UNTIL]
+column up to the date and time in the current
+line’s [UNTIL] column. In other words, the date and
+time in the [UNTIL] column is the instant that separates
+this state from the next. Where that would be ambiguous because
+we’re setting our clocks back, the [UNTIL] column
+specifies the first occurrence of the instant. The state specified by
+the last line, the one without anything in the [UNTIL]
+column, continues to the present.
+
+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. 8-) For some places near the International
+Date Line, the first two lines will show solar times
+differing by 24 hours; this corresponds to a movement of the Date
+Line. For example:
+
+
+#Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone America/Juneau 15:02:19 - LMT 1867 Oct 18
+ -8:57:41 - LMT ...
+
+
+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. <aside>(6 October in the Julian calendar,
+which Russia was still using then for religious reasons, was followed
+by a second instance of the same day with a different name, 18
+October in the Gregorian calendar. Isn’t civil time
+wonderful? 8-))</aside>
+
+The abbreviation, “LMT” stands for “local mean
+time”, which is an invention of
+the tz
+database 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.)
+
+The RULES column tells us whether daylight saving time is being observed:
+
+- A hyphen, a kind of null value, means that we have not set our
+clocks ahead of standard time.
+
+- An amount of time (usually but not necessarily “1:00”
+meaning one hour) means that we have set our clocks ahead by that
+amount.
+
+- Some alphabetic string means that we might have set our
+clocks ahead; and we need to check the rule the name of which is the
+given alphabetic string.
+
+
+An example of a specific amount of time is:
+
+#Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone Pacific/Honolulu ... 1933 Apr 30 2:00
+ -10:30 1:00 HDT 1933 May 21 2:00
+ ...
+
+
+Hawaii tried daylight saving time for three weeks in 1933 and
+decided they didn’t like it. 8-) Note that
+the GMTOFF column always contains the standard time
+offset, so the wall clock time during this period was GMT −
+10:30 + 1:00 = GMT − 9:30.
+
+The FORMAT column specifies the usual abbreviation of
+the time zone name. It can have one of three forms:
+
+
+- a string of three or more characters that are either ASCII alphanumerics,
+“
+”, or “-”,
+in which case that’s the abbreviation
+
+- a pair of strings separated by a slash
+(‘
/’), 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
+
+- a string containing “
%s,” in which case
+the “%s” will be replaced by the text in the
+appropriate Rule’s LETTER column
+
+
+The last two make sense only if there’s a named rule in effect.
+
+An example of a slash is:
+
+#Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone Europe/London ... 1996
+ 0:00 EU GMT/BST
+
+
+The current time in the UK is called either Greenwich mean time or
+British summer time.
+
+One wrinkle, not fully explained in zic.8.txt, is what
+happens when switching to a named rule. To what values should
+the SAVE and LETTER data be initialized?
+
+
+- If at least one transition has happened, use
+the
SAVE and LETTER data from the most
+recent.
+
+- If switching to a named rule before any transition has happened,
+assume standard time (
SAVE zero), and use
+the LETTER data from the earliest transition with
+a SAVE of zero.
+
+
+
+And three last things about the FORMAT column:
+
+
+- The tz
+database gives abbreviations for time zone names in popular
+usage, which is not necessarily “correct” by law. For
+example, the last line in
+
Zone Pacific/Honolulu (shown below) gives
+“HST” for “Hawaii standard time” even though the
+legal
+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.
+
+ - No attempt is made to localize
+the abbreviations. They are intended to be the values returned through the
+
"%Z" format specifier to
+C’s
+strftime
+function in the
+“C” locale.
+
+ - If there is no generally-accepted abbreviation for a time zone,
+a numeric offset is used instead, e.g.,
+07 for 7 hours
+ahead of Greenwich. By convention, -00 is used in a
+zone while uninhabited, where the offset is zero but in some sense
+the true offset is undefined.
+
+
+As a final example, here’s the complete history for Hawaii:
+
+
+
+ Relevant Excerpts from the US Rules
+
+
+
+
+#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
+
+
+
+
+ The Zone Record
+
+
+
+
+#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
+
+
+
+
+ What We Infer
+
+
+ Wall-Clock
Offset from
Prime Meridian
+ Adjust
Clocks
+ Time Zone
+ Ending at Local Time
+
+
+ Abbrv.
+ Name
+ Date
+ Time
+
+
+ −10:31:26
+ —
+ LMT
+ local mean time
+ 1900-01-01
+ 12:00
+
+
+ −10:30
+ +0:01:26
+ HST
+ Hawaii standard time
+ 1933-04-30
+ 02:00
+
+
+ −9:30
+ +1:00
+ HDT
+ Hawaii daylight time
+ 1933-05-21
+
+
+ −10:30¹
+ −1:00¹
+ HST¹
+ Hawaii standard time
+ 1942-02-09
+
+
+ −9:30
+ +1:00
+ HWT
+ Hawaii war time
+ 1945-08-14
+ 13:30²
+
+
+ 0
+ HPT
+ Hawaii peace time
+ 1945-09-30
+ 02:00
+
+
+ −10:30
+ −1:00
+ HST
+ Hawaii standard time
+ 1947-06-08
+
+
+ −10:00³
+ +0:30³
+ —
+
+
+
+ ¹Switching to US rules…most recent transition (in 1919) was to standard time
+
+
+
+
+ ²23:00 UT
+ + (−9:30) = 13:30 local
+
+
+
+
+ ³Since 1947–06–08T12:30Z,
+ the civil time in Hawaii has been
+ UT/UTC
+ − 10:00 year-round.
+
+
+
+
+There will be a short quiz later. 8-)
+
+
+
+This web page is in the public domain, so clarified as of
+2015-10-20 by Bill Seymour.
+
+All suggestions and corrections will be welcome; all flames will be amusing.
+Mail to was at pobox dot com.
+
+
+
Property changes on: vendor/tzdb/tzcode2018e/tz-how-to.html
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/html
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tz-link.html
===================================================================
--- vendor/tzdb/tzcode2018e/tz-link.html (nonexistent)
+++ vendor/tzdb/tzcode2018e/tz-link.html (revision 337695)
@@ -0,0 +1,953 @@
+
+
+
+Sources for time zone and daylight saving time data
+
+
+
+Sources for time zone and daylight saving time data
+
+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.
+
+The tz database
+
+The public-domain
+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 time zone boundaries and daylight saving rules.
+This database (known as tz,
+tzdb, or zoneinfo)
+is used by several implementations,
+including
+the
+GNU
+C Library (used in
+GNU/Linux),
+Android,
+B2G
+OS,
+FreeBSD,
+NetBSD,
+OpenBSD,
+Chromium OS,
+Cygwin,
+DJGPP,
+MINIX,
+MySQL,
+webOS,
+AIX,
+BlackBerry 10,
+iOS,
+macOS,
+Microsoft Windows,
+OpenVMS,
+Oracle Database, and
+Oracle Solaris.
+
+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.
+For example, America/New_York
+represents most of the US eastern time zone;
+America/Phoenix represents most of Arizona, which
+uses mountain time without daylight saving time (DST);
+America/Detroit represents most of Michigan, which uses
+eastern time but with different DST rules in 1975;
+and other entries represent smaller regions like Starke County,
+Indiana, which switched from central to eastern time in 1991
+and switched back in 2006.
+To use the database on an extended POSIX
+implementation set the TZ
+environment variable to the location's full name,
+e.g., TZ="America/New_York".
+
+Associated with each region is a history of offsets from
+Universal
+Time (UT), which is Greenwich Mean
+Time (GMT) with days beginning at midnight;
+for time stamps after 1960 this is more precisely Coordinated
+Universal Time (UTC).
+The database also records when daylight saving time was in use,
+along with some time zone abbreviations such as EST
+for Eastern Standard Time in the US.
+Downloading the tz database
+
+The following shell commands download
+the latest release's two
+tarballs
+to a GNU/Linux or similar host.
+mkdir tzdb
+cd tzdb
+wget https://www.iana.org/time-zones/repository/tzcode-latest.tar.gz
+wget https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz
+gzip -dc tzcode-latest.tar.gz | tar -xf -
+gzip -dc tzdata-latest.tar.gz | tar -xf -
+
+Alternatively, the following shell commands download the same
+release in a single-tarball format containing extra data
+useful for regression testing:
+wget https://www.iana.org/time-zones/repository/tzdb-latest.tar.lz
+lzip -dc tzdb-latest.tar.lz | tar -xf -
+
+These commands use convenience links to the latest release
+of the tz database hosted by the
+Time Zone Database website
+of the Internet Assigned Numbers
+Authority (IANA).
+Older releases are in files named
+tzcodeV.tar.gz,
+tzdataV.tar.gz, and
+tzdb-V.tar.lz,
+where V is the version.
+Since 1996, each version has been a four-digit year followed by
+lower-case letter (a through z,
+then za through zz, then zza
+through zzz, and so on).
+Since version 2016h, each release has contained a text file named
+"version" whose first (and currently only) line is the version.
+The releases are also available in an
+FTP directory via a
+less-secure protocol.
+Alternatively, a development repository of code and data can be
+retrieved from GitHub via the shell
+command:
+git clone https://github.com/eggert/tz
+
+
+Since version 2012e, each release has been tagged in development repositories.
+Untagged commits are less well tested and probably contain
+more errors.
+
+After obtaining the code and data files, see the
+README file for what to do next.
+The code lets you compile the tz source files into
+machine-readable binary files, one for each location. It also lets
+you read a tz binary file and interpret time stamps for that
+location.
+Changes to the tz database
+
+The tz code and data
+are by no means authoritative. If you find errors, please
+send changes to tz@iana.org,
+the time zone mailing list. You can also subscribe to it
+and browse the archive of old
+messages.
+
+If your government plans to change its time zone boundaries or
+daylight saving rules, inform tz@iana.org well in
+advance, as this will coordinate updates to many cell phones,
+computers, and other devices around the world. 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; see "On
+the Timing of Time Zone Changes" for examples.
+
+
+Changes to the tz code and data are often
+propagated to clients via operating system updates, so
+client tz data can often be corrected by
+applying these updates. With GNU/Linux and similar systems, if your
+maintenance provider has not yet adopted the
+latest tz data, you can often short-circuit
+the process by tailoring the generic instructions in
+the tz README file and installing the latest
+data yourself. System-specific instructions for installing the
+latest tz data have also been published
+for AIX,
+Android,
+ICU,
+IBM
+and Oracle
+Java, Joda-Time, MySQL,
+and Noda Time (see below).
+
+Sources for the tz database are
+UTF-8
+text files
+with lines terminated by LF,
+which can be modified by common text editors such
+as GNU Emacs,
+gedit, and
+vim.
+Specialized source-file editing can be done via the
+Sublime
+zoneinfo package for Sublime Text and the VSCode
+zoneinfo extension for Visual
+Studio Code.
+
+
+For further information about updates, please see
+Procedures for
+Maintaining the Time Zone Database (Internet RFC 6557). More detail can be
+found in Theory and pragmatics of the tz code and data.
+
+Commentary on the tz database
+
+- The article
+tz database is
+an encyclopedic summary.
+- How to Read the
+tz Database Source Files explains the
tz
+database format.
+- A
+literary appreciation of the Olson/Zoneinfo/tz database comments on the
+database's style.
+
+Web sites using recent versions of the
+tz database
+
+These are listed roughly in ascending order of complexity and fanciness.
+
+
+- Time.is shows locations'
+time and zones.
+- TimeJones.com,
+Time Zone Converter and
+The World Clock
+are time zone converters.
+- Date and Time Gateway
+lets you see the
TZ values directly.
+- Current
+Time in 1000 Places uses descriptions of the values.
+- Time Zone
+Converter
+uses a pulldown menu.
+- Complete
+timezone information for all countries displays tables of DST rules.
+
- The World Clock –
+Worldwide lets you sort zone names and convert times.
+- 24TimeZones has a world
+time map and a time converter.
+- Time Difference
+calculates the current time difference between locations.
+- Weather Now and
+The Time Now list the weather too.
+
+Network protocols for tz data
+
+- The Internet Engineering Task Force's
+Time Zone Data
+Distribution Service (tzdist) working group defined TZDIST
+(Internet RFC 7808), a time zone data distribution service,
+along with CalDAV
+(Internet RFC 7809), a calendar access protocol for
+transferring time zone data by reference. The draft TZDIST
+Geolocate Extension lets a client determine its time zone region
+from its geographic location using a 'geo' URI.
+- The
+Internet Calendaring and Scheduling Core Object Specification
+(iCalendar) (Internet RFC 5445)
+covers time zone
+data; see its VTIMEZONE calendar component.
+The iCalendar format requires specialized parsers and generators; a
+variant xCal
+(Internet RFC 6321) uses
+XML format, and a variant
+jCal
+(Internet RFC 7265)
+uses JSON format.
+
+Other tz compilers
+
+- Vzic is a C
+program that compiles
+
tz source into iCalendar-compatible VTIMEZONE files.
+Vzic is freely
+available under the GNU
+General Public License (GPL).
+- tziCal – tz
+database conversion utility is like Vzic, except for the .NET framework
+and with a BSD-style license.
+- DateTime::TimeZone
+contains a script
parse_olson that compiles
+tz source into Perl
+modules. It is part of the Perl DateTime Project, which is freely
+available under both the GPL and the Perl Artistic
+License. DateTime::TimeZone also contains a script
+tests_from_zdump that generates test cases for each clock
+transition in the tz database.
+- The Time Zone
+Database Parser is a
+C++ parser and
+runtime library that is moving
+forward for inclusion in the next iteration of ISO
+International Standard ISO/IEC 14882:2017(E) – Programming
+Language C++.
+It is freely available under the
+MIT license.
+- International Components for
+Unicode (ICU) contains C/C++ and Java
+libraries for internationalization that
+has a compiler from
tz source
+and from CLDR data
+(mentioned below)
+into an ICU-specific format.
+ICU is freely available under a
+BSD-style license.
+- The Tzdata package for
+the Elixir language downloads
+and compiles tz source and exposes APIs for use. It is
+freely available under the MIT license.
+- Java-based compilers and libraries include:
+
+- The TZUpdater
+tool compiles
tz source into the format used by
+Oracle Java.
+- The Java
+8
java.time API can be supplemented by ThreeTen-Extra,
+which is freely available under a BSD-style license.
+- Joda-Time – Java date
+and time API contains a class
+
org.joda.time.tz.ZoneInfoCompiler that compiles
+tz source into a binary format. It inspired
+Java 8 java.time, which its users should migrate to once
+they can assume Java 8 or later. It is available under the Apache License.
+- Time4J –
+Advanced date, time and interval library for Java contains a class
+
net.time4j.tool.TimezoneRepositoryCompiler that compiles
+tz source into a binary format. Time4J is
+available under the GNU Lesser
+General Public License (LGPL).
+- ICU (mentioned above) contains compilers and
+Java-based libraries.
+
+ - Noda Time – Date and
+time API for .NET
+and TZ4Net
+are similar to Joda-Time and Time4J, but for the .NET framework instead of
+Java. They are freely available under the
+Apache License
+and a BSD-style license, respectively.
+- JavaScript-based
+compilers and libraries include:
+
+- CompactTimeZoneGenerator
+compiles time zone data into a compact form designed for
+JavaScript. It is freely available under a combination of
+the MIT license and the Apache License.
+- Moment Timezone is a
+plugin for the Moment.js date
+manipulation library. It is freely available under the MIT
+license.
+- TimezoneJS.Date's
+API is upward compatible with standard JavaScript
+Dates. It is freely available under the Apache License.
+- Walltime-js
+translates UT to local time. It is freely available under
+the MIT license.
+
+ - JuliaTime contains a
+compiler from
tz source into
+Julia. It is freely available
+under the MIT license.
+- pytz – World Timezone
+Definitions for Python compiles
tz source into
+Python.
+It is freely available under a BSD-style license.
+- TZInfo –
+Ruby Timezone Library
+compiles
tz source into
+Ruby.
+It is freely available under the MIT license.
+- The Chronos Date/Time
+Library is
+a Smalltalk class
+library that compiles
tz source into a time
+zone repository whose format
+is either proprietary or an XML-encoded
+representation.
+- Tcl
+contains a developer-oriented parser that compiles
tz
+source into text files, along with a runtime that can read those
+files. Tcl is freely available under a BSD-style
+license.
+
+Other tz binary file readers
+
+- The GNU C
+Library
+has an independent, thread-safe implementation of
+a
tz binary file reader.
+This library is freely available under the LGPL
+and is widely used in GNU/Linux systems.
+- GNOME's
+GLib has
+a
tz binary file reader written in C that
+creates a GTimeZone object representing sets
+of UT offsets.
+It is freely available under the LGPL.
+- The
+BDE Standard Library's
+
baltzo::TimeZoneUtil component contains a C++
+implementation of a binary file reader. It is freely available under
+the Apache License.
+- CCTZ is a simple C++
+library that translates between UT and civil time and
+can read binary files. It is freely available under the Apache
+License.
+- ZoneInfo.java
+is a
tz binary file reader written in Java.
+It is freely available under the LGPL.
+- Timelib is a C
+library that reads tz binary files and converts
+time stamps from one time zone or format to another.
+It is used by PHP,
+HHVM,
+and MongoDB.
+It is freely available under the MIT license.
+- Timezone is a
+JavaScript library that supports date arithmetic that is time zone
+aware. It is freely available under the MIT license.
+- Tcl, mentioned above, also contains a
+
tz binary file reader.
+-
+DateTime::TimeZone::Tzfile
+is a
tz binary file reader written in Perl.
+It is freely available under the same terms as Perl
+(dual GPL and Artistic license).
+- The
+public-domain tz.js
+library contains a Python tool that
+converts
tz binary data into
+JSON-format data suitable for use
+in its JavaScript library for time zone conversion. Dates before 1970
+are not supported.
+- The timezone-olson
+package contains Haskell code that
+parses and uses
tz binary data. It is freely
+available under a BSD-style license.
+
+Other tz-based time zone software
+
+- FoxClocks
+is an extension for Google
+Chrome and for Mozilla
+Toolkit applications like Firefox and Thunderbird.
+It displays multiple clocks in the application window, and has a mapping
+interface to Google Earth.
+It is freely available under the GPL.
+- Go programming language
+implementations contain a copy of a 32-bit subset of a recent
+
tz database in a
+Go-specific format.
+- International
+clock (intclock) is a clock that displays multiple time zones on
+GNU/Linux and similar systems. It is freely available
+under the GPL.
+- Microsoft Windows 8.1
+and later has
tz data and CLDR
+data (mentioned below) used by
+Windows Runtime
+classes such as DateTimeFormatter.
+Exploring
+Windows Time Zones with System.TimeZoneInfo describes
+the older, proprietary method of Microsoft Windows 2000 and later,
+which stores time zone data in the
+Windows Registry. The
+Zone →
+Tzid table or XML
+file of the CLDR data maps proprietary zone IDs
+to tz names.
+ - Oracle
+Java contains a copy of a subset of a recent
+
tz database in a
+Java-specific format.
+- Time Zone
+Master is a Microsoft Windows clock program that can automatically
+download, compile and use
tz releases. The Basic version
+is free.
+- VelaTerra is
+a macOS program. Its developers
+offer free
+licenses to
tz contributors.
+
+Other time zone databases
+
+- Time-zone Atlas
+is Astrodienst's Web version of Shanks and Pottenger's
+time zone history atlases also published in software
+form by ACS-Starcrafts.
+These atlases are extensive but unreliable, as Shanks appears to have
+guessed many UT offsets and transitions. The atlases cite no
+sources and do not indicate which entries are guesswork.
+- HP-UX has a database in
+its own
tztab(4) format.
+- Microsoft Windows has proprietary data mentioned
+above.
+- World Time Server
+is another time zone database.
+- World Time Zones
+contains data from the Time Service Department of the
+US Naval Observatory.
+- The Standard
+Schedules Information Manual of the
+International Air Transport Association
+gives current time zone rules for airports served by commercial aviation.
+
+Maps
+
+- The United States Central
+Intelligence Agency (CIA) publishes a time
+zone map; the
+Perry–Castañeda
+Library Map Collection
+of the University of Texas at Austin has copies of
+recent editions.
+The pictorial quality is good,
+but the maps do not indicate daylight saving time,
+and parts of the data are a few years out of date.
+- Current time around the world
+and standard time zones map of the world
+has several fancy time zone maps; it covers Russia particularly well.
+The maps' pictorial quality is not quite as good as the
+CIA's
+but the maps are more up to date.
+- How
+much is time wrong around the world? 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.
+
+Time zone boundaries
+Geographical boundaries between time zone regions are available
+from several geolocation
+services and other sources.
+
+- Databases of time zone boundaries include:
+
+- Timezone
+Boundary Builder extracts
+Open Street Map data to build
+boundaries of
tz regions.
+Its code is freely available under the MIT license, and
+its data entries are freely available under the
+Open Data Commons
+Open Database License. The maps' borders appear to be quite accurate.
+- TZ timezones
+maps contains shapefiles of
+sets of
tz regions. This includes
+tz_world, a shapefile
+for all the world's regions. These maps are no longer maintained and
+are superseded by the Timezone Boundary Builder.
+- Whereonearth-timezone
+is in GeoJSON format
+(Internet RFC 7946), and combines the
+the tz_world shapefiles with the
+GeoPlanet
+dataset.
+
+- Programmatic interfaces that map geographical coordinates via tz_world to
+
tz regions include:
+
+- GeoTimeZone is
+written in C#
+and is freely available under the MIT license.
+- The latlong package
+is written in Go and is freely available under the Apache License.
+- LatLongToTimezone,
+in both Java and
+Swift
+form, is freely available under the MIT license.
+- For Node.js,
+the geo-tz module
+is freely available under the MIT license, and
+the tz-lookup module
+is in the public domain.
+- The timezonefinder
+library for Python is freely available under the MIT license.
+
- The timezone_finder
+library for Ruby is freely available under the MIT license.
+- What Time
+is It Here? applies MongoDB
+geospatial query operators to shapefiles' data.
+
+- Free access via a network API, if you register a key, is provided by
+the GeoNames Timezone web service,
+the Google Maps Time Zone API, and
+the Time Zone Database & API.
+Commercial network API access is provided
+by AskGeo
+and GeoGarage.
+
+- "How
+to get a time zone from a location using latitude and longitude
+coordinates?" discusses other geolocation possibilities.
+- Administrative
+Divisions of Countries ("Statoids") lists
+political subdivision data related to time zones.
+- Time
+zone boundaries for multizone countries summarizes legal
+boundaries between time zones within countries.
+- Manifold Software
+– GIS and Database Tools includes a Manifold-format map of
+world time zone boundaries distributed under the
+GPL.
+- A ship within the territorial
+waters of any nation uses that nation's time. In international
+waters, time zone boundaries are meridians 15° apart, except that
+UT−12 and UT+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
+common.
+
+Civil time concepts and history
+
+- A
+Walk through Time
+surveys the evolution of timekeeping.
+- About Daylight
+Saving Time – History, rationale, laws & dates
+is an overall history of DST.
+- Working with Time Zones
+contains guidelines and best practices for software applications that
+deal with civil time.
+- A Brief
+History of Daylight Saving Time summarizes some of the contentious
+history of DST.
+- A History of
+the International Date Line tells the story of the most important
+time zone boundary.
+- Basic Time
+Zone Concepts discusses terminological issues behind time zones.
+
+National histories of legal time
+
+- Australia
+- The Parliamentary Library has commissioned a research
+paper on daylight saving time in Australia.
+The Bureau of Meteorology publishes a list of Implementation
+Dates of Daylight Savings Time within Australia.
+- Belgium
+- The Royal Observatory of Belgium maintains a table of time in Belgium (in Dutch).
+- Brazil
+- The Time Service Department of the National Observatory
+records Brazil's daylight saving time decrees (in
+Portuguese).
+- Canada
+- National Research Council Canada publishes current
+and some older information about time
+zones & daylight saving time.
+- Chile
+- The Hydrographic and Oceanographic Service of the Chilean Navy publishes a
+history of
+Chile's official time (in Spanish).
+- Czech Republic
+- When daylight saving time starts and ends (in Czech)
+summarizes and cites historical DST regulations.
+- Germany
+- The National Institute for Science and Technology maintains the Realisation
+of Legal Time in Germany.
+- Israel
+- The Interior Ministry periodically issues announcements (in Hebrew).
+- Italy
+- The National Institute of Metrological Research maintains a
+table of civil time
+(in Italian).
+- Mexico
+- The Investigation and Analysis Service of the Mexican Library of
+Congress has published a history of Mexican local time (in Spanish).
+- Malaysia
+- See Singapore below.
+- Netherlands
+- Legal time in the Netherlands (in Dutch)
+covers the history of local time in the Netherlands from ancient times.
+- New Zealand
+- The Department of Internal Affairs maintains a brief History of
+Daylight Saving. The privately-maintained History of New Zealand
+time has more details.
+- Singapore
+- Why
+is Singapore in the "Wrong" Time Zone? details the
+history of legal time in Singapore and Malaysia.
+- United Kingdom
+- History of
+legal time in Britain discusses in detail the country
+with perhaps the best-documented history of clock adjustments.
+The National Physical Laboratory also maintains an Archive
+of Summer time dates.
+- United States
+- The Department of Transportation's Recent
+Time Zone Proceedings lists changes to time zone boundaries.
+- Uruguay
+- The Oceanography, Hydrography, and Meteorology Service of the Uruguayan
+Navy (SOHMA) publishes an annual almanac
+(in Spanish).
+
+Precision timekeeping
+
+- The
+Science of Timekeeping is a thorough introduction
+to the theory and practice of precision timekeeping.
+- The Science of
+Time 2016 contains several freely-readable papers.
+- NTP: The Network
+Time Protocol (Internet RFC 5905)
+discusses how to synchronize clocks of
+Internet hosts.
+- The Precision
+Time Protocol (IEEE 1588)
+can achieve submicrosecond clock accuracy on a local area network.
+- Timezone
+Options for DHCP
+(Internet RFC 4833)
+specifies a DHCP
+option for a server to configure
+a client's time zone and daylight saving settings automatically.
+- Astronomical
+Times explains more abstruse astronomical time scales like
+TDT,
+TCG, and
+TDB.
+Time
+Scales goes into more detail, particularly for historical variants.
+- The IAU's SOFA
+collection contains C and Fortran
+code for converting among time scales like
+TAI,
+TDB, TDT and
+UTC.
+- Mars24 Sunclock
+– Time on Mars describes Airy Mean Time (AMT) and the
+diverse local time
+scales used by each landed mission on Mars.
+- LeapSecond.com 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.
+- IERS
+Bulletins contains official publications of the International
+Earth Rotation and Reference Systems Service, which decides when leap
+seconds occur. The
tz code and data support leap seconds
+via an optional "right" configuration, as opposed to the
+default "posix" configuration.
+- Leap Smear
+discusses how to gradually adjust POSIX clocks near a
+leap second so that they disagree with UTC by at most a
+half second, even though every POSIX minute has exactly
+sixty seconds. This approach works with the default
tz
+"posix" configuration, is supported by
+the NTP reference implementation, and is used by major
+cloud service providers.
+- The Leap
+Second Discussion List covers McCarthy
+and Klepczynski's 1999 proposal to discontinue leap seconds,
+discussed further in
+The
+leap second: its history and possible future.
+UTC
+might be redefined
+without Leap Seconds gives pointers on this
+contentious issue, which was active until 2015 and could become active
+again.
+
+Time notation
+
+- The Unicode Common Locale Data
+Repository (CLDR) Project has localizations for time
+zone names, abbreviations, identifiers, and formats. For example, it
+contains French translations for "Eastern European Summer Time",
+"EEST", and
+"Bucharest". Its
+by-type
+charts show these values for many locales. Data values are available in
+both LDML
+(an XML format) and JSON.
+
-
+A summary of
+the international standard date and time notation is a good
+summary of
+ISO
+8601:2004 – Data elements and interchange formats – Information
+interchange – Representation of dates and times.
+-
+XML
+Schema: Datatypes – dateTime specifies a format inspired by
+ISO 8601 that is in common use in XML data.
+- §3.3 of
+Internet Message Format (Internet RFC 5322)
+specifies the time notation used in email and HTTP
+headers.
+-
+Date and Time
+on the Internet: Timestamps (Internet RFC 3339)
+specifies an ISO 8601
+profile for use in new Internet
+protocols.
+-
+Date & Time
+Formats on the Web surveys web- and Internet-oriented date and time
+formats.
+- Alphabetic time zone abbreviations should not be used as unique
+identifiers for UT offsets as they are ambiguous in
+practice. For example, in English-speaking North America
+"CST" denotes 6 hours behind UT,
+but in China it denotes 8 hours ahead of UT,
+and French-speaking North Americans prefer
+"HNC" to
+"CST". The
tz
+database contains English abbreviations for many time stamps;
+unfortunately some of these abbreviations were merely the database maintainers'
+inventions, and these have been removed when possible.
+- Numeric time zone abbreviations typically count hours east of
+UT, e.g., +09 for Japan and
+−10 for Hawaii. However, the POSIX
+
TZ environment variable uses the opposite convention.
+For example, one might use TZ="JST-9" and
+TZ="HST10"
+for Japan and Hawaii, respectively. If the
+tz database is available, it is usually better to use
+settings like TZ="Asia/Tokyo" and
+TZ="Pacific/Honolulu" 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
+POSIX TZ to a value like
+"GMT-9", though, since this would incorrectly imply that
+local time is nine hours ahead of UT and the time zone
+is called "GMT".
+
+See also
+
+
+
+This web page is in the public domain, so clarified as of
+2009-05-17 by Arthur David Olson.
+
+Please send corrections to this web page to the
+time zone mailing list.
+
+
+
Property changes on: vendor/tzdb/tzcode2018e/tz-link.html
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/html
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tzfile.5
===================================================================
--- vendor/tzdb/tzcode2018e/tzfile.5 (nonexistent)
+++ vendor/tzdb/tzcode2018e/tzfile.5 (revision 337695)
@@ -0,0 +1,190 @@
+.TH TZFILE 5
+.SH NAME
+tzfile \- time zone information
+.SH DESCRIPTION
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
+The time zone information files used by
+.BR tzset (3)
+are typically found under a directory with a name like
+.IR /usr/share/zoneinfo .
+These files begin with a 44-byte header containing the following fields:
+.IP * 2
+The magic four-byte ASCII sequence
+.q "TZif"
+identifies the file as a time zone information file.
+.IP *
+A byte identifying the version of the file's format
+(as of 2017, either an ASCII NUL, or
+.q "2",
+or
+.q "3" ).
+.IP *
+Fifteen bytes containing zeros reserved for future use.
+.IP *
+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:
+.RS
+.TP
+.I tzh_ttisgmtcnt
+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 entries are stored in the file.
+.TP
+.I tzh_timecnt
+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 entries are stored
+in the file (must not be zero).
+.TP
+.I tzh_charcnt
+The number of bytes of time zone abbreviation strings
+stored in the file.
+.RE
+.PP
+The above header is followed by the following fields, whose lengths
+depend on the contents of the header:
+.IP * 2
+.I 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
+.BR time (2))
+at which the rules for computing local time change.
+.IP *
+.I 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 the next field.
+.IP *
+.I tzh_typecnt
+.I ttinfo
+entries, each defined as follows:
+.in +.5i
+.sp
+.nf
+.ta .5i +\w'unsigned char\0\0'u
+struct ttinfo {
+ int32_t tt_gmtoff;
+ unsigned char tt_isdst;
+ unsigned char tt_abbrind;
+};
+.in -.5i
+.fi
+.sp
+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
+.IR tt_abbrind .
+In each structure,
+.I tt_gmtoff
+gives the number of seconds to be added to UT,
+.I tt_isdst
+tells whether
+.I tm_isdst
+should be set by
+.BR localtime (3)
+and
+.I tt_abbrind
+serves as an index into the array of time zone abbreviation bytes
+that follow the
+.I ttinfo
+structure(s) in the file.
+.IP *
+.I tzh_leapcnt
+pairs of four-byte values, written in standard byte order;
+the first value of each pair gives the nonnegative time
+(as returned by
+.BR time (2))
+at which a leap second occurs;
+the second gives the
+.I 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.
+Each transition is for one leap second, either positive or negative;
+transitions always separated by at least 28 days minus 1 second.
+.IP *
+.I tzh_ttisstdcnt
+standard/wall indicators, each stored as a one-byte value;
+they tell whether the transition times associated with local time types
+were specified as standard time or wall clock time,
+and are used when a time zone file is used in handling POSIX-style
+time zone environment variables.
+.IP *
+.I 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 UT or local time,
+and are used when a time zone file is used in handling POSIX-style
+time zone environment variables.
+.PP
+The
+.BR localtime (3)
+function
+uses the first standard-time
+.I ttinfo
+structure in the file
+(or simply the first
+.I ttinfo
+structure in the absence of a standard-time structure)
+if either
+.I tzh_timecnt
+is zero or the time argument is less than the first transition time recorded
+in the file.
+.SS Version 2 format
+For version-2-format time zone files,
+the above header and data are followed by a second header and data,
+identical in format except that
+eight bytes are used for each transition time or leap second time.
+(Leap second counts remain four bytes.)
+After the second header and data comes a newline-enclosed,
+POSIX-TZ-environment-variable-style string for use in handling instants
+after the last transition time stored in the file
+(with nothing between the newlines if there is no POSIX representation for
+such instants).
+The POSIX-style string must agree with the local time type after
+both data's last transition times; for example, given the string
+.q "WET0WEST,M3.5.0,M10.5.0/3"
+then if a last transition time is in July, the transition's local time
+type must specify a daylight-saving time abbreviated
+.q "WEST"
+that is one hour east of UT.
+.SS Version 3 format
+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
+.BR 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
+.BR time (2),
+.BR localtime (3),
+.BR tzset (3),
+.BR tzselect (8),
+.BR zdump (8),
+.BR zic (8)
+.\" This file is in the public domain, so clarified as of
+.\" 1996-06-05 by Arthur David Olson.
Property changes on: vendor/tzdb/tzcode2018e/tzfile.5
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tzfile.5.txt
===================================================================
--- vendor/tzdb/tzcode2018e/tzfile.5.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/tzfile.5.txt (revision 337695)
@@ -0,0 +1,129 @@
+TZFILE(5) File Formats Manual TZFILE(5)
+
+NAME
+ tzfile - time zone information
+
+DESCRIPTION
+ The time zone information files used by tzset(3) are typically found
+ under a directory with a name like /usr/share/zoneinfo. These files
+ begin with a 44-byte header containing the following fields:
+
+ * The magic four-byte ASCII sequence "TZif" identifies the file as a
+ time zone information file.
+
+ * A byte identifying the version of the file's format (as of 2017,
+ either an ASCII NUL, or "2", or "3").
+
+ * Fifteen bytes containing zeros reserved for future use.
+
+ * 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 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 entries are stored
+ in the file.
+
+ tzh_timecnt
+ 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 entries are
+ stored in the file (must not be zero).
+
+ tzh_charcnt
+ The number of bytes of time zone abbreviation strings stored
+ in the file.
+
+ The above header is followed by the following fields, whose lengths
+ depend on the contents of the header:
+
+ * 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.
+
+ * 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 the next field.
+
+ * tzh_typecnt ttinfo entries, each defined as follows:
+
+ struct ttinfo {
+ int32_t tt_gmtoff;
+ unsigned char tt_isdst;
+ unsigned char tt_abbrind;
+ };
+
+ 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 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 bytes
+ that follow the ttinfo structure(s) in the file.
+
+ * tzh_leapcnt pairs of four-byte values, written in standard byte
+ order; the first value of each pair gives the nonnegative time (as
+ returned by time(2)) at which a leap second occurs; the second gives
+ 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. Each transition is for one leap second,
+ either positive or negative; transitions always separated by at least
+ 28 days minus 1 second.
+
+ * tzh_ttisstdcnt standard/wall indicators, each stored as a one-byte
+ value; they tell whether the transition times associated with local
+ time types were specified as standard time or wall clock time, and
+ are used when a time zone file is used in handling POSIX-style time
+ zone environment variables.
+
+ * 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 UT or local time, and are used when a time
+ zone file is used in handling POSIX-style time zone environment
+ variables.
+
+ The localtime(3) function uses the first standard-time ttinfo structure
+ in the file (or simply the first ttinfo structure in the absence of a
+ standard-time structure) if either tzh_timecnt is zero or the time
+ argument is less than the first transition time recorded in the file.
+
+ Version 2 format
+ For version-2-format time zone files, the above header and data are
+ followed by a second header and data, identical in format except that
+ eight bytes are used for each transition time or leap second time.
+ (Leap second counts remain four bytes.) After the second header and
+ data comes a newline-enclosed, POSIX-TZ-environment-variable-style
+ string for use in handling instants after the last transition time
+ stored in the file (with nothing between the newlines if there is no
+ POSIX representation for such instants). The POSIX-style string must
+ agree with the local time type after both data's last transition times;
+ for example, given the string "WET0WEST,M3.5.0,M10.5.0/3" then if a
+ last transition time is in July, the transition's local time type must
+ specify a daylight-saving time abbreviated "WEST" that is one hour east
+ of UT.
+
+ Version 3 format
+ 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
+ time(2), localtime(3), tzset(3), tzselect(8), zdump(8), zic(8)
+
+ TZFILE(5)
Property changes on: vendor/tzdb/tzcode2018e/tzfile.5.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tzfile.h
===================================================================
--- vendor/tzdb/tzcode2018e/tzfile.h (nonexistent)
+++ vendor/tzdb/tzcode2018e/tzfile.h (revision 337695)
@@ -0,0 +1,117 @@
+#ifndef TZFILE_H
+
+#define TZFILE_H
+
+/*
+** This file is in the public domain, so clarified as of
+** 1996-06-05 by Arthur David Olson.
+*/
+
+/*
+** This header is for use ONLY with the time conversion code.
+** There is no guarantee that it will remain unchanged,
+** or that it will remain at all.
+** Do NOT copy it to any system include directory.
+** Thank you!
+*/
+
+/*
+** Information about time zone files.
+*/
+
+#ifndef TZDIR
+#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
+#endif /* !defined TZDIR */
+
+#ifndef TZDEFAULT
+#define TZDEFAULT "/etc/localtime"
+#endif /* !defined TZDEFAULT */
+
+#ifndef TZDEFRULES
+#define TZDEFRULES "posixrules"
+#endif /* !defined TZDEFRULES */
+
+/*
+** Each file begins with. . .
+*/
+
+#define TZ_MAGIC "TZif"
+
+struct tzhead {
+ char tzh_magic[4]; /* TZ_MAGIC */
+ 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 */
+ char tzh_timecnt[4]; /* coded number of transition times */
+ char tzh_typecnt[4]; /* coded number of local time types */
+ char tzh_charcnt[4]; /* coded number of abbr. chars */
+};
+
+/*
+** . . .followed by. . .
+**
+** tzh_timecnt (char [4])s coded transition times a la time(2)
+** tzh_timecnt (unsigned char)s types of local time starting at above
+** tzh_typecnt repetitions of
+** one (char [4]) coded UT offset in seconds
+** one (unsigned char) used to set tm_isdst
+** one (unsigned char) that's an abbreviation list index
+** tzh_charcnt (char)s '\0'-terminated zone abbreviations
+** tzh_leapcnt repetitions of
+** one (char [4]) coded leap second transition times
+** one (char [4]) total correction after above
+** tzh_ttisstdcnt (char)s indexed by type; if 1, transition
+** time is standard time, if 0,
+** transition time is wall clock time
+** if absent, transition times are
+** assumed to be wall clock time
+** 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
+*/
+
+/*
+** If tzh_version is '2' or greater, the above is followed by a second instance
+** of tzhead and a second instance of the data in which each coded transition
+** time uses 8 rather than 4 chars,
+** then a POSIX-TZ-environment-variable-style string for use in handling
+** instants after the last transition time stored in the file
+** (with nothing between the newlines if there is no POSIX representation for
+** such instants).
+**
+** If tz_version is '3' or greater, the above is extended as follows.
+** First, the POSIX TZ string's hour offset may range from -167
+** through 167 as compared to the POSIX-required 0 through 24.
+** Second, its DST start time may be January 1 at 00:00 and its stop
+** time December 31 at 24:00 plus the difference between DST and
+** standard time, indicating DST all year.
+*/
+
+/*
+** In the current implementation, "tzset()" refuses to deal with files that
+** exceed any of the limits below.
+*/
+
+#ifndef TZ_MAX_TIMES
+#define TZ_MAX_TIMES 2000
+#endif /* !defined TZ_MAX_TIMES */
+
+#ifndef TZ_MAX_TYPES
+/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
+#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
+#endif /* !defined TZ_MAX_TYPES */
+
+#ifndef TZ_MAX_CHARS
+#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+ /* (limited by what unsigned chars can hold) */
+#endif /* !defined TZ_MAX_CHARS */
+
+#ifndef TZ_MAX_LEAPS
+#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
+#endif /* !defined TZ_MAX_LEAPS */
+
+#endif /* !defined TZFILE_H */
Property changes on: vendor/tzdb/tzcode2018e/tzfile.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tzselect.8
===================================================================
--- vendor/tzdb/tzcode2018e/tzselect.8 (nonexistent)
+++ vendor/tzdb/tzcode2018e/tzselect.8 (revision 337695)
@@ -0,0 +1,113 @@
+.TH TZSELECT 8
+.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
+program asks the user for information about the current location,
+and outputs the resulting time zone description to standard output.
+The output is suitable as a value for the TZ environment variable.
+.PP
+All interaction with the user is done via standard input and standard error.
+.SH OPTIONS
+.TP
+.BI "\*-c " coord
+Instead of asking for continent and then country and then city,
+ask for selection from time zones whose largest cities
+are closest to the location with geographical coordinates
+.I coord.
+Use ISO 6709 notation for
+.I coord,
+that is, a latitude immediately followed by a longitude. The latitude
+and longitude should be signed integers followed by an optional
+decimal point and fraction: positive numbers represent north and east,
+negative south and west. Latitudes with two and longitudes with three
+integer digits are treated as degrees; latitudes with four or six and
+longitudes with five or seven integer digits are treated as
+.I "DDMM, DDDMM, DDMMSS,"
+or
+.I DDDMMSS
+representing
+.I DD
+or
+.I DDD
+degrees,
+.I MM
+minutes,
+and zero or
+.I SS
+seconds, with any trailing fractions represent fractional minutes or
+(if
+.I SS
+is present) seconds. The decimal point is that of the current locale.
+For example, in the (default) C locale,
+.B "\*-c\ +40.689\*-074.045"
+specifies 40.689\(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
+Name of a Posix-compliant
+.I awk
+program (default:
+.BR awk ).
+.TP
+\f3TZDIR\fP
+Name of the directory containing time zone data files (default:
+.BR /usr/share/zoneinfo ).
+.SH FILES
+.TP
+\f2TZDIR\fP\f3/iso3166.tab\fP
+Table of ISO 3166 2-letter country codes and country names.
+.TP
+\f2TZDIR\fP\f3/zone1970.tab\fP
+Table of country codes, latitude and longitude, zone names, and
+descriptive comments.
+.TP
+\f2TZDIR\fP\f3/\fP\f2TZ\fP
+Time zone data file for time zone \f2TZ\fP.
+.SH "EXIT STATUS"
+The exit status is zero if a time zone was successfully obtained from the user,
+nonzero otherwise.
+.SH "SEE ALSO"
+newctime(3), tzfile(5), zdump(8), zic(8)
+.SH NOTES
+Applications should not assume that
+.BR tzselect 's
+output matches the user's political preferences.
+.\" This file is in the public domain, so clarified as of
+.\" 2009-05-17 by Arthur David Olson.
Property changes on: vendor/tzdb/tzcode2018e/tzselect.8
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tzselect.8.txt
===================================================================
--- vendor/tzdb/tzcode2018e/tzselect.8.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/tzselect.8.txt (revision 337695)
@@ -0,0 +1,77 @@
+TZSELECT(8) System Manager's Manual TZSELECT(8)
+
+NAME
+ tzselect - select a time zone
+
+SYNOPSIS
+ tzselect [ -c coord ] [ -n limit ] [ --help ] [ --version ]
+
+DESCRIPTION
+ The tzselect program asks the user for information about the current
+ location, and outputs the resulting time zone description to standard
+ output. The output is suitable as a value for the TZ environment
+ variable.
+
+ 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).
+
+ TZDIR Name of the directory containing time zone data files (default:
+ /usr/share/zoneinfo).
+
+FILES
+ TZDIR/iso3166.tab
+ Table of ISO 3166 2-letter country codes and country names.
+
+ TZDIR/zone1970.tab
+ Table of country codes, latitude and longitude, zone names, and
+ descriptive comments.
+
+ TZDIR/TZ
+ Time zone data file for time zone TZ.
+
+EXIT STATUS
+ The exit status is zero if a time zone was successfully obtained from
+ the user, nonzero otherwise.
+
+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)
Property changes on: vendor/tzdb/tzcode2018e/tzselect.8.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/tzselect.ksh
===================================================================
--- vendor/tzdb/tzcode2018e/tzselect.ksh (nonexistent)
+++ vendor/tzdb/tzcode2018e/tzselect.ksh (revision 337695)
@@ -0,0 +1,561 @@
+#!/bin/bash
+
+PKGVERSION='(tzcode) '
+TZVERSION=see_Makefile
+REPORT_BUGS_TO=tz@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. This file is in the public domain.
+
+# Porting notes:
+#
+# This script requires a Posix-like shell and prefers the extension of a
+# 'select' statement. The 'select' statement was introduced in the
+# Korn shell and is available in Bash and other shell implementations.
+# If your host lacks both Bash and the Korn shell, you can get their
+# source from one of these locations:
+#
+# Bash
+# Korn Shell
+# MirBSD Korn Shell
+#
+# 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:
+#
+# Gawk (GNU awk)
+# mawk
+
+
+# Specify default values for environment variables if they are unset.
+: ${AWK=awk}
+: ${TZDIR=`pwd`}
+
+# Output one argument as-is to standard output.
+# Safer than 'echo', which can mishandle '\' or leading '-'.
+say() {
+ printf '%s\n' "$1"
+}
+
+# Check for awk Posix compliance.
+($AWK -v x=y 'BEGIN { exit 123 }') /dev/null 2>&1
+[ $? = 123 ] || {
+ say >&2 "$0: Sorry, your '$AWK' program is not Posix compatible."
+ exit 1
+}
+
+coord=
+location_limit=10
+zonetabtype=zone1970
+
+usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT]
+Select a time zone interactively.
+
+Options:
+
+ -c COORD
+ Instead of asking for continent and then country and then city,
+ ask for selection from time zones whose largest cities
+ are closest to the location with geographical coordinates COORD.
+ COORD should use ISO 6709 notation, for example, '-c +4852+00220'
+ for Paris (in degrees and minutes, North and East), or
+ '-c -35-058' for Buenos Aires (in degrees, South and West).
+
+ -n LIMIT
+ Display at most LIMIT locations when -c is used (default $location_limit).
+
+ --version
+ Output version information.
+
+ --help
+ Output this help.
+
+Report bugs to $REPORT_BUGS_TO."
+
+# Ask the user to select from the function's arguments,
+# and assign the selected argument to the variable 'select_result'.
+# Exit on EOF or I/O error. Use the shell's 'select' builtin if available,
+# falling back on a less-nice but portable substitute otherwise.
+if
+ case $BASH_VERSION in
+ ?*) : ;;
+ '')
+ # '; exit' should be redundant, but Dash doesn't properly fail without it.
+ (eval 'set --; select x; do break; done; exit') /dev/null
+ 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/$zonetabtype.tab
+for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
+do
+ <"$f" || {
+ say >&2 "$0: time zone files are not set up correctly"
+ exit 1
+ }
+done
+
+# If the current locale does not support UTF-8, convert data to current
+# locale's format if possible, as the shell aligns columns better that way.
+# Check the UTF-8 of U+12345 CUNEIFORM SIGN URU TIMES KI.
+! $AWK 'BEGIN { u12345 = "\360\222\215\205"; exit length(u12345) != 1 }' &&
+ { tmp=`(mktemp -d) 2>/dev/null` || {
+ tmp=${TMPDIR-/tmp}/tzselect.$$ &&
+ (umask 77 && mkdir -- "$tmp")
+ };} &&
+ trap 'status=$?; rm -fr -- "$tmp"; exit $status' 0 HUP INT PIPE TERM &&
+ (iconv -f UTF-8 -t //TRANSLIT <"$TZ_COUNTRY_TABLE" >$tmp/iso3166.tab) \
+ 2>/dev/null &&
+ TZ_COUNTRY_TABLE=$tmp/iso3166.tab &&
+ iconv -f UTF-8 -t //TRANSLIT <"$TZ_ZONE_TABLE" >$tmp/$zonetabtype.tab &&
+ TZ_ZONE_TABLE=$tmp/$zonetabtype.tab
+
+newline='
+'
+IFS=$newline
+
+
+# Awk script to read a time zone table and output the same table,
+# with each column preceded by its distance from 'here'.
+output_distances='
+ BEGIN {
+ FS = "\t"
+ while (getline &2 'Please identify a location' \
+ 'so that time zone rules can be set correctly.'
+
+ continent=
+ country=
+ region=
+
+ case $coord in
+ ?*)
+ continent=coord;;
+ '')
+
+ # Ask the user for continent or ocean.
+
+ echo >&2 'Please select a continent, ocean, "coord", or "TZ".'
+
+ quoted_continents=`
+ $AWK '
+ 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
+ Americas) continent=America;;
+ *" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''`
+ esac
+ '
+ esac
+
+ case $continent in
+ TZ)
+ # Ask the user for a Posix TZ string. Check that it conforms.
+ while
+ echo >&2 'Please enter the desired value' \
+ 'of the TZ environment variable.'
+ echo >&2 'For example, AEST-10 is a zone named AEST' \
+ 'that is 10 hours'
+ echo >&2 'ahead (east) of Greenwich,' \
+ 'with no daylight saving time.'
+ read TZ
+ $AWK -v TZ="$TZ" 'BEGIN {
+ tzname = "(<[[:alnum:]+-]{3,}>|[[:alpha:]]{3,})"
+ time = "(2[0-4]|[0-1]?[0-9])" \
+ "(:[0-5][0-9](:[0-5][0-9])?)?"
+ offset = "[-+]?" time
+ mdate = "M([1-9]|1[0-2])\\.[1-5]\\.[0-6]"
+ jdate = "((J[1-9]|[0-9]|J?[1-9][0-9]" \
+ "|J?[1-2][0-9][0-9])|J?3[0-5][0-9]|J?36[0-5])"
+ datetime = ",(" mdate "|" jdate ")(/" time ")?"
+ tzpattern = "^(:.*|" tzname offset "(" tzname \
+ "(" offset ")?(" datetime datetime ")?)?)$"
+ if (TZ ~ tzpattern) exit 1
+ exit 0
+ }'
+ do
+ say >&2 "'$TZ' is not a conforming Posix 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 \
+ -v continent="$continent" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ '
+ BEGIN { FS = "\t" }
+ /^#/ { next }
+ $3 ~ ("^" continent "/") {
+ ncc = split($1, cc, /,/)
+ for (i = 1; i <= ncc; i++)
+ if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i]
+ }
+ END {
+ while (getline &2 'Please select a country' \
+ 'whose clocks agree with yours.'
+ doselect $countries
+ country=$select_result;;
+ *)
+ country=$countries
+ esac
+
+
+ # Get list of names of time zone rule regions in the country.
+ regions=`$AWK \
+ -v country="$country" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ '
+ BEGIN {
+ FS = "\t"
+ cc = country
+ while (getline &2 'Please select one of the following' \
+ 'time zone regions.'
+ doselect $regions
+ region=$select_result;;
+ *)
+ region=$regions
+ esac
+
+ # Determine TZ from country and region.
+ TZ=`$AWK \
+ -v country="$country" \
+ -v region="$region" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ '
+ BEGIN {
+ FS = "\t"
+ cc = country
+ while (getline &2 "$0: time zone files are not set up correctly"
+ exit 1
+ }
+ esac
+
+
+ # Use the proposed TZ to output the current date relative to UTC.
+ # Loop until they agree in seconds.
+ # Give up after 8 unsuccessful tries.
+
+ extra_info=
+ for i in 1 2 3 4 5 6 7 8
+ do
+ TZdate=`LANG=C TZ="$TZ_for_date" date`
+ UTdate=`LANG=C TZ=UTC0 date`
+ TZsec=`expr "$TZdate" : '.*:\([0-5][0-9]\)'`
+ UTsec=`expr "$UTdate" : '.*:\([0-5][0-9]\)'`
+ case $TZsec in
+ $UTsec)
+ extra_info="
+Selected time is now: $TZdate.
+Universal Time is now: $UTdate."
+ break
+ esac
+ done
+
+
+ # Output TZ info and ask the user to confirm.
+
+ echo >&2 ""
+ echo >&2 "The following information has been given:"
+ echo >&2 ""
+ case $country%$region%$coord in
+ ?*%?*%) say >&2 " $country$newline $region";;
+ ?*%%) say >&2 " $country";;
+ %?*%?*) say >&2 " coord $coord$newline $region";;
+ %%?*) say >&2 " coord $coord";;
+ *) say >&2 " TZ='$TZ'"
+ esac
+ say >&2 ""
+ say >&2 "Therefore TZ='$TZ' will be used.$extra_info"
+ say >&2 "Is the above information OK?"
+
+ doselect Yes No
+ ok=$select_result
+ case $ok in
+ Yes) break
+ esac
+do coord=
+done
+
+case $SHELL in
+*csh) file=.login line="setenv TZ '$TZ'";;
+*) file=.profile line="TZ='$TZ'; export TZ"
+esac
+
+test -t 1 && say >&2 "
+You can make this change permanent for yourself by appending the line
+ $line
+to the file '$file' in your home directory; then log out and log in again.
+
+Here is that TZ value again, this time on standard output so that you
+can use the $0 command in shell scripts:"
+
+say "$TZ"
Index: vendor/tzdb/tzcode2018e/version
===================================================================
--- vendor/tzdb/tzcode2018e/version (nonexistent)
+++ vendor/tzdb/tzcode2018e/version (revision 337695)
@@ -0,0 +1 @@
+2018e
Index: vendor/tzdb/tzcode2018e/workman.sh
===================================================================
--- vendor/tzdb/tzcode2018e/workman.sh (nonexistent)
+++ vendor/tzdb/tzcode2018e/workman.sh (revision 337695)
@@ -0,0 +1,32 @@
+#! /bin/sh
+
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# Tell groff not to emit SGR escape sequences (ANSI color escapes).
+GROFF_NO_SGR=1
+export GROFF_NO_SGR
+
+echo ".am TH
+.hy 0
+.na
+..
+.rm }H
+.rm }F" | nroff -man - ${1+"$@"} | perl -ne '
+ binmode STDIN, '\'':encoding(utf8)'\'';
+ binmode STDOUT, '\'':encoding(utf8)'\'';
+ chomp;
+ s/.\010//g;
+ s/\s*$//;
+ if (/^$/) {
+ $sawblank = 1;
+ next;
+ } else {
+ if ($sawblank && $didprint) {
+ print "\n";
+ $sawblank = 0;
+ }
+ print "$_\n";
+ $didprint = 1;
+ }
+'
Property changes on: vendor/tzdb/tzcode2018e/workman.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/zdump.8
===================================================================
--- vendor/tzdb/tzcode2018e/zdump.8 (nonexistent)
+++ vendor/tzdb/tzcode2018e/zdump.8 (revision 337695)
@@ -0,0 +1,226 @@
+.TH ZDUMP 8
+.SH NAME
+zdump \- time zone dumper
+.SH SYNOPSIS
+.B zdump
+[
+.I option
+\&... ] [
+.I zonename
+\&... ]
+.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
+..
+.ie \n(.g .ds - \f(CW-\fP
+.el ds - \-
+.I Zdump
+prints the current time in each
+.I zonename
+named on the command line.
+.PP
+These options are available:
+.TP
+.BI "\*-\*-version"
+Output version information and exit.
+.TP
+.B \*-i
+.I "(This option is experimental: its behavior may change in future versions.)"
+Output a description of time intervals. For each
+.I zonename
+on the command line, output an interval-format description of the
+zone. See
+.q "INTERVAL FORMAT"
+below.
+.TP
+.B \*-v
+Output a verbose description of time intervals.
+For each
+.I zonename
+on the command line,
+print the time at the lowest possible time value,
+the time one day after the lowest possible time value,
+the times both one second before and exactly at
+each detected time discontinuity,
+the time at one day less than the highest possible time value,
+and the time at the highest possible time value.
+Each line 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
+.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 interval output at the given year(s).
+Cutoff times are computed using the proleptic Gregorian calendar with year 0
+and with Universal Time (UT) ignoring leap seconds.
+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 interval 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 "INTERVAL FORMAT"
+.I "This format is experimental: it may change in future versions."
+.PP
+The interval format is a compact text representation that is intended
+to be both human- and machine-readable. It consists of an empty line,
+then a line
+.q "TZ=\fIstring\fP"
+where
+.I string
+is a double-quoted string giving the zone name, a second line
+.q "\*- \*- \fIinterval\fP"
+describing the time interval before the first transition if any, and
+zero or more following lines
+.q "\fIdate time interval\fP",
+one line for each transition time and following interval. Fields are
+separated by single tabs.
+.PP
+Dates are in
+.IR yyyy - mm - dd
+format and times are in 24-hour
+.IR hh : mm : ss
+format where
+.IR hh <24.
+Times are in local time immediately after the transition. A
+time interval description consists of a UT offset in signed
+.RI \(+- hhmmss
+format, a time zone abbreviation, and an isdst flag. An abbreviation
+that equals the UT offset is omitted; other abbreviations are
+double-quoted strings unless they consist of one or more alphabetic
+characters. An isdst flag is omitted for standard time, and otherwise
+is a decimal integer that is unsigned and positive (typically 1) for
+daylight saving time and negative for unknown.
+.PP
+In times and in UT offsets with absolute value less than 100 hours,
+the seconds are omitted if they are zero, and
+the minutes are also omitted if they are also zero. Positive UT
+offsets are east of Greenwich. The UT offset \*-00 denotes a UT
+placeholder in areas where the actual offset is unspecified; by
+convention, this occurs when the UT offset is zero and the time zone
+abbreviation begins with
+.q "\*-"
+or is
+.q "zzz".
+.PP
+In double-quoted strings, escape sequences represent unusual
+characters. The escape sequences are \es for space, and \e", \e\e,
+\ef, \en, \er, \et, and \ev with their usual meaning in the C
+programming language. E.g., the double-quoted string
+\*(lq"CET\es\e"\e\e"\*(rq represents the character sequence \*(lqCET
+"\e\*(rq.\""
+.PP
+.ne 9
+Here is an example of the output, with the leading empty line omitted.
+(This example is shown with tab stops set far enough apart so that the
+tabbed columns line up.)
+.nf
+.sp
+.if \n(.g .ft CW
+.if t .in +.5i
+.if n .in +2
+.nr w \w'1896-01-13 'u
+.ta \nwu +\nwu +\nwu +\nwu
+TZ="Pacific/Honolulu"
+- - -10:31:26 LMT
+1896-01-13 12:01:26 -10:30 HST
+1933-04-30 03 -09:30 HDT 1
+1933-05-21 11 -10:30 HST
+1942-02-09 03 -09:30 HDT 1
+1945-09-30 01 -10:30 HST
+1947-06-08 02:30 -10 HST
+.in
+.if \n(.g .ft
+.sp
+.fi
+Here, local time begins 10 hours, 31 minutes and 26 seconds west of
+UT, and is a standard time abbreviated LMT. Immediately after the
+first transition, the date is 1896-01-13 and the time is 12:01:26, and
+the following time interval is 10.5 hours west of UT, a standard time
+abbreviated HST. Immediately after the second transition, the date is
+1933-04-30 and the time is 03:00:00 and the following time interval is
+9.5 hours west of UT, is abbreviated HDT, and is daylight saving time.
+Immediately after the last transition the date is 1947-06-08 and the
+time is 02:30:00, and the following time interval is 10 hours west of
+UT, a standard time abbreviated HST.
+.PP
+.ne 10
+Here are excerpts from another example:
+.nf
+.sp
+.if \n(.g .ft CW
+.if t .in +.5i
+.if n .in +2
+TZ="Europe/Astrakhan"
+- - +03:12:12 LMT
+1924-04-30 23:47:48 +03
+1930-06-21 01 +04
+1981-04-01 01 +05 1
+1981-09-30 23 +04
+\&...
+2014-10-26 01 +03
+2016-03-27 03 +04
+.in
+.if \n(.g .ft
+.sp
+.fi
+This time zone is east of UT, so its UT offsets are positive. Also,
+many of its time zone abbreviations are omitted since they duplicate
+the text of the UT offset.
+.SH LIMITATIONS
+Time discontinuities are found by sampling the results returned by 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
+.B \*-v
+and
+.B \*-V
+output,
+.q "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
+.q "UTC"
+for newer and
+.q "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
+.\" 2009-05-17 by Arthur David Olson.
Property changes on: vendor/tzdb/tzcode2018e/zdump.8
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/zdump.8.txt
===================================================================
--- vendor/tzdb/tzcode2018e/zdump.8.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/zdump.8.txt (revision 337695)
@@ -0,0 +1,144 @@
+ZDUMP(8) System Manager's Manual ZDUMP(8)
+
+NAME
+ zdump - time zone dumper
+
+SYNOPSIS
+ zdump [ option ... ] [ zonename ... ]
+
+DESCRIPTION
+ Zdump prints the current time in each zonename named on the command
+ line.
+
+ These options are available:
+
+ --version
+ Output version information and exit.
+
+ -i (This option is experimental: its behavior may change in future
+ versions.) Output a description of time intervals. For each
+ zonename on the command line, output an interval-format
+ description of the zone. See "INTERVAL FORMAT" below.
+
+ -v Output a verbose description of time intervals. For each
+ zonename on the command line, print the time at the lowest
+ possible time value, the time one day after the lowest possible
+ time value, the times both one second before and exactly at each
+ detected time discontinuity, the time at one day less than the
+ highest possible time value, and the time at the highest
+ possible time value. Each line 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 interval output at the given year(s). Cutoff times are
+ computed using the proleptic Gregorian calendar with year 0 and
+ with Universal Time (UT) ignoring leap seconds. 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 interval 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.
+
+INTERVAL FORMAT
+ This format is experimental: it may change in future versions.
+
+ The interval format is a compact text representation that is intended
+ to be both human- and machine-readable. It consists of an empty line,
+ then a line "TZ=string" where string is a double-quoted string giving
+ the zone name, a second line "- - interval" describing the time
+ interval before the first transition if any, and zero or more following
+ lines "date time interval", one line for each transition time and
+ following interval. Fields are separated by single tabs.
+
+ Dates are in yyyy-mm-dd format and times are in 24-hour hh:mm:ss format
+ where hh<24. Times are in local time immediately after the transition.
+ A time interval description consists of a UT offset in signed +-hhmmss
+ format, a time zone abbreviation, and an isdst flag. An abbreviation
+ that equals the UT offset is omitted; other abbreviations are double-
+ quoted strings unless they consist of one or more alphabetic
+ characters. An isdst flag is omitted for standard time, and otherwise
+ is a decimal integer that is unsigned and positive (typically 1) for
+ daylight saving time and negative for unknown.
+
+ In times and in UT offsets with absolute value less than 100 hours, the
+ seconds are omitted if they are zero, and the minutes are also omitted
+ if they are also zero. Positive UT offsets are east of Greenwich. The
+ UT offset -00 denotes a UT placeholder in areas where the actual offset
+ is unspecified; by convention, this occurs when the UT offset is zero
+ and the time zone abbreviation begins with "-" or is "zzz".
+
+ In double-quoted strings, escape sequences represent unusual
+ characters. The escape sequences are \s for space, and \", \\, \f, \n,
+ \r, \t, and \v with their usual meaning in the C programming language.
+ E.g., the double-quoted string ""CET\s\"\\"" represents the character
+ sequence "CET "\".
+
+ Here is an example of the output, with the leading empty line omitted.
+ (This example is shown with tab stops set far enough apart so that the
+ tabbed columns line up.)
+
+ TZ="Pacific/Honolulu"
+ - - -10:31:26 LMT
+ 1896-01-13 12:01:26 -10:30 HST
+ 1933-04-30 03 -09:30 HDT 1
+ 1933-05-21 11 -10:30 HST
+ 1942-02-09 03 -09:30 HDT 1
+ 1945-09-30 01 -10:30 HST
+ 1947-06-08 02:30 -10 HST
+
+ Here, local time begins 10 hours, 31 minutes and 26 seconds west of UT,
+ and is a standard time abbreviated LMT. Immediately after the first
+ transition, the date is 1896-01-13 and the time is 12:01:26, and the
+ following time interval is 10.5 hours west of UT, a standard time
+ abbreviated HST. Immediately after the second transition, the date is
+ 1933-04-30 and the time is 03:00:00 and the following time interval is
+ 9.5 hours west of UT, is abbreviated HDT, and is daylight saving time.
+ Immediately after the last transition the date is 1947-06-08 and the
+ time is 02:30:00, and the following time interval is 10 hours west of
+ UT, a standard time abbreviated HST.
+
+ Here are excerpts from another example:
+
+ TZ="Europe/Astrakhan"
+ - - +03:12:12 LMT
+ 1924-04-30 23:47:48 +03
+ 1930-06-21 01 +04
+ 1981-04-01 01 +05 1
+ 1981-09-30 23 +04
+ ...
+ 2014-10-26 01 +03
+ 2016-03-27 03 +04
+
+ This time zone is east of UT, so its UT offsets are positive. Also,
+ many of its time zone abbreviations are omitted since they duplicate
+ the text of the UT offset.
+
+LIMITATIONS
+ 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 -v and -V 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)
+
+ ZDUMP(8)
Property changes on: vendor/tzdb/tzcode2018e/zdump.8.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/zdump.c
===================================================================
--- vendor/tzdb/tzcode2018e/zdump.c (nonexistent)
+++ vendor/tzdb/tzcode2018e/zdump.c (revision 337695)
@@ -0,0 +1,1116 @@
+/*
+** This file is in the public domain, so clarified as of
+** 2009-05-17 by Arthur David Olson.
+*/
+
+#include "version.h"
+
+#ifndef NETBSD_INSPIRED
+# define NETBSD_INSPIRED 1
+#endif
+
+#include "private.h"
+#include
+
+#ifndef HAVE_SNPRINTF
+# define HAVE_SNPRINTF (199901 <= __STDC_VERSION__)
+#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 */
+
+#ifndef ZDUMP_HI_YEAR
+#define ZDUMP_HI_YEAR 2500
+#endif /* !defined ZDUMP_HI_YEAR */
+
+#ifndef MAX_STRING_LENGTH
+#define MAX_STRING_LENGTH 1024
+#endif /* !defined MAX_STRING_LENGTH */
+
+#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 };
+
+#if HAVE_GETTEXT
+#include /* for setlocale */
+#endif /* HAVE_GETTEXT */
+
+#if ! HAVE_LOCALTIME_RZ
+# undef timezone_t
+# define timezone_t char **
+#endif
+
+#if !HAVE_POSIX_DECLS
+extern int getopt(int argc, char * const argv[],
+ const char * options);
+extern char * optarg;
+extern int optind;
+#endif
+
+/* 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) -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) -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 void showtrans(char const *, struct tm const *, time_t, char const *,
+ char const *);
+static const char *tformat(void);
+static time_t yeartot(intmax_t) ATTRIBUTE_PURE;
+
+/* Unlike '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;
+}
+
+/* Return a pointer to a newly allocated buffer of size SIZE, exiting
+ on failure. SIZE should be nonzero. */
+static void * ATTRIBUTE_MALLOC
+xmalloc(size_t size)
+{
+ void *p = malloc(size);
+ if (!p) {
+ perror(progname);
+ exit(EXIT_FAILURE);
+ }
+ return p;
+}
+
+#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
+# define USE_LOCALTIME_RZ false
+#endif
+
+#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 = xmalloc(sumsize(sizeof *environ,
+ (e - environ) * sizeof *environ));
+ to = 1;
+ for (e = environ; (env[to] = *e); e++)
+ to += strncmp(*e, "TZ=", 3) != 0;
+ }
+ env0 = xmalloc(sumsize(sizeof "TZ=", strlen(val)));
+ 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 UT 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 UT, 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_rz localtime_rz
+#else /* !defined TYPECHECK */
+
+static struct tm *
+my_localtime_rz(timezone_t tz, time_t *tp, struct tm *tmp)
+{
+ tmp = localtime_rz(tz, tp, tmp);
+ if (tmp) {
+ struct tm tm;
+ register time_t t;
+
+ tm = *tmp;
+ 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;
+}
+#endif /* !defined TYPECHECK */
+
+static void
+abbrok(const char *const abbrp, const char *const zone)
+{
+ register const char * cp;
+ register const char * wp;
+
+ if (warned)
+ return;
+ cp = abbrp;
+ while (is_alpha(*cp) || is_digit(*cp) || *cp == '-' || *cp == '+')
+ ++cp;
+ if (cp - abbrp < 3)
+ wp = _("has fewer than 3 characters");
+ else if (cp - abbrp > 6)
+ wp = _("has more than 6 characters");
+ else if (*cp)
+ wp = _("has characters other than ASCII alphanumerics, '-' or '+'");
+ else
+ return;
+ fflush(stdout);
+ fprintf(stderr,
+ _("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"),
+ progname, zone, abbrp, wp);
+ 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 = xmalloc(*bufalloc);
+ }
+ 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)
+{
+ fprintf(stream,
+_("%s: usage: %s OPTIONS ZONENAME ...\n"
+ "Options include:\n"
+ " -c [L,]U Start at year L (default -500), end before year U (default 2500)\n"
+ " -t [L,]U Start at time L, end before time U (in seconds since 1970)\n"
+ " -i List transitions briefly (format is experimental)\n" \
+ " -v List transitions verbosely\n"
+ " -V List transitions a bit less verbosely\n"
+ " --help Output this help\n"
+ " --version Output version info\n"
+ "\n"
+ "Report bugs to %s.\n"),
+ progname, progname, REPORT_BUGS_TO);
+ if (status == EXIT_SUCCESS)
+ close_file(stream);
+ exit(status);
+}
+
+int
+main(int argc, char *argv[])
+{
+ /* These are static so that they're initially zero. */
+ static char * abbrev;
+ static size_t abbrevsize;
+
+ register int i;
+ register bool vflag;
+ register bool Vflag;
+ register char * cutarg;
+ register char * cuttimes;
+ register time_t cutlotime;
+ register time_t cuthitime;
+ time_t now;
+ bool iflag = false;
+
+ cutlotime = absolute_min_time;
+ cuthitime = absolute_max_time;
+#if HAVE_GETTEXT
+ setlocale(LC_ALL, "");
+#ifdef TZ_DOMAINDIR
+ bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
+#endif /* defined TEXTDOMAINDIR */
+ textdomain(TZ_DOMAIN);
+#endif /* HAVE_GETTEXT */
+ progname = argv[0];
+ for (i = 1; i < argc; ++i)
+ if (strcmp(argv[i], "--version") == 0) {
+ printf("zdump %s%s\n", PKGVERSION, TZVERSION);
+ return EXIT_SUCCESS;
+ } else if (strcmp(argv[i], "--help") == 0) {
+ usage(stdout, EXIT_SUCCESS);
+ }
+ vflag = Vflag = false;
+ cutarg = cuttimes = NULL;
+ for (;;)
+ switch (getopt(argc, argv, "c:it:vV")) {
+ case 'c': cutarg = optarg; break;
+ case 't': cuttimes = optarg; break;
+ case 'i': iflag = true; 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 (iflag | 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) {
+ lo = strtoimax(cutarg, &loend, 10);
+ if (cutarg != loend && !*loend) {
+ hi = lo;
+ cuthiyear = hi;
+ } else if (cutarg != loend && *loend == ','
+ && (hi = strtoimax(loend + 1, &hiend, 10),
+ loend + 1 != hiend && !*hiend)) {
+ cutloyear = lo;
+ cuthiyear = hi;
+ } else {
+ fprintf(stderr, _("%s: wild -c argument %s\n"),
+ progname, cutarg);
+ return EXIT_FAILURE;
+ }
+ }
+ 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;
+ }
+ }
+ }
+ gmtzinit();
+ INITIALIZE (now);
+ if (! (iflag | vflag | Vflag))
+ now = time(NULL);
+ longest = 0;
+ for (i = optind; i < argc; i++) {
+ size_t arglen = strlen(argv[i]);
+ if (longest < arglen)
+ longest = arglen < INT_MAX ? arglen : INT_MAX;
+ }
+
+ for (i = optind; i < argc; ++i) {
+ timezone_t tz = tzalloc(argv[i]);
+ char const *ab;
+ time_t t;
+ struct tm tm, newtm;
+ bool tm_ok;
+ if (!tz) {
+ perror(argv[i]);
+ return EXIT_FAILURE;
+ }
+ if (! (iflag | vflag | Vflag)) {
+ show(tz, argv[i], now, false);
+ tzfree(tz);
+ continue;
+ }
+ warned = false;
+ t = absolute_min_time;
+ if (! (iflag | Vflag)) {
+ show(tz, argv[i], t, true);
+ t += SECSPERDAY;
+ show(tz, argv[i], t, true);
+ }
+ if (t < cutlotime)
+ t = cutlotime;
+ INITIALIZE (ab);
+ tm_ok = my_localtime_rz(tz, &t, &tm) != NULL;
+ if (tm_ok) {
+ ab = saveabbr(&abbrev, &abbrevsize, &tm);
+ if (iflag) {
+ showtrans("\nTZ=%f", &tm, t, ab, argv[i]);
+ showtrans("-\t-\t%Q", &tm, t, ab, argv[i]);
+ }
+ }
+ while (t < cuthitime) {
+ time_t newt = ((t < absolute_max_time - SECSPERDAY / 2
+ && t + SECSPERDAY / 2 < cuthitime)
+ ? t + SECSPERDAY / 2
+ : cuthitime);
+ struct tm *newtmp = localtime_rz(tz, &newt, &newtm);
+ bool newtm_ok = newtmp != NULL;
+ if (tm_ok != newtm_ok
+ || (tm_ok && (delta(&newtm, &tm) != newt - t
+ || newtm.tm_isdst != tm.tm_isdst
+ || strcmp(abbr(&newtm), ab) != 0))) {
+ newt = hunt(tz, argv[i], t, newt);
+ newtmp = localtime_rz(tz, &newt, &newtm);
+ newtm_ok = newtmp != NULL;
+ if (iflag)
+ showtrans("%Y-%m-%d\t%L\t%Q", newtmp, newt,
+ newtm_ok ? abbr(&newtm) : NULL, argv[i]);
+ else {
+ show(tz, argv[i], newt - 1, true);
+ show(tz, argv[i], newt, true);
+ }
+ }
+ t = newt;
+ tm_ok = newtm_ok;
+ if (newtm_ok) {
+ ab = saveabbr(&abbrev, &abbrevsize, &newtm);
+ tm = newtm;
+ }
+ }
+ if (! (iflag | Vflag)) {
+ t = absolute_max_time;
+ t -= SECSPERDAY;
+ show(tz, argv[i], t, true);
+ t += SECSPERDAY;
+ show(tz, argv[i], t, true);
+ }
+ tzfree(tz);
+ }
+ close_file(stdout);
+ if (errout && (ferror(stderr) || fclose(stderr) != 0))
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
+}
+
+static time_t
+yeartot(intmax_t y)
+{
+ register intmax_t myy, seconds, years;
+ register time_t t;
+
+ myy = EPOCH_YEAR;
+ t = 0;
+ 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;
+ 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 {
+ 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(timezone_t tz, char *name, time_t lot, time_t hit)
+{
+ static char * loab;
+ static size_t loabsize;
+ char const * ab;
+ time_t t;
+ struct tm lotm;
+ struct tm tm;
+ bool lotm_ok = my_localtime_rz(tz, &lot, &lotm) != NULL;
+ bool tm_ok;
+
+ if (lotm_ok)
+ ab = saveabbr(&loab, &loabsize, &lotm);
+ for ( ; ; ) {
+ time_t diff = hit - lot;
+ if (diff < 2)
+ break;
+ t = lot;
+ t += diff / 2;
+ if (t <= lot)
+ ++t;
+ else if (t >= hit)
+ --t;
+ tm_ok = my_localtime_rz(tz, &t, &tm) != NULL;
+ if (lotm_ok & tm_ok
+ ? (delta(&tm, &lotm) == t - lot
+ && tm.tm_isdst == lotm.tm_isdst
+ && strcmp(abbr(&tm), ab) == 0)
+ : lotm_ok == tm_ok) {
+ lot = t;
+ if (tm_ok)
+ lotm = tm;
+ } else hit = t;
+ }
+ return hit;
+}
+
+/*
+** Thanks to Paul Eggert for logic used in delta_nonneg.
+*/
+
+static intmax_t
+delta_nonneg(struct tm *newp, struct tm *oldp)
+{
+ register intmax_t result;
+ register int tmy;
+
+ result = 0;
+ for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
+ result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE);
+ result += newp->tm_yday - oldp->tm_yday;
+ result *= HOURSPERDAY;
+ result += newp->tm_hour - oldp->tm_hour;
+ result *= MINSPERHOUR;
+ result += newp->tm_min - oldp->tm_min;
+ result *= SECSPERMIN;
+ result += newp->tm_sec - oldp->tm_sec;
+ return result;
+}
+
+static intmax_t
+delta(struct tm *newp, struct tm *oldp)
+{
+ return (newp->tm_year < oldp->tm_year
+ ? -delta_nonneg(oldp, newp)
+ : delta_nonneg(newp, oldp));
+}
+
+#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 UT for
+ the same instant, return A's UT offset in seconds, where positive
+ offsets are east of Greenwich. On failure, return LONG_MIN.
+
+ If T is nonnull, *T is the timestamp that corresponds to A; call
+ my_gmtime_r and use its result instead of B. Otherwise, B is the
+ possibly nonnull result of an earlier call to my_gmtime_r. */
+static long
+gmtoff(struct tm const *a, time_t *t, struct tm const *b)
+{
+#ifdef TM_GMTOFF
+ return a->TM_GMTOFF;
+#else
+ struct tm tm;
+ if (t)
+ b = my_gmtime_r(t, &tm);
+ 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(timezone_t tz, char *zone, time_t t, bool v)
+{
+ register struct tm * tmp;
+ register struct tm * gmtmp;
+ struct tm tm, gmtm;
+
+ printf("%-*s ", longest, zone);
+ if (v) {
+ gmtmp = my_gmtime_r(&t, &gmtm);
+ if (gmtmp == NULL) {
+ printf(tformat(), t);
+ } else {
+ dumptime(gmtmp);
+ printf(" UT");
+ }
+ printf(" = ");
+ }
+ tmp = my_localtime_rz(tz, &t, &tm);
+ dumptime(tmp);
+ if (tmp != NULL) {
+ if (*abbr(tmp) != '\0')
+ printf(" %s", abbr(tmp));
+ if (v) {
+ long off = gmtoff(tmp, NULL, gmtmp);
+ printf(" isdst=%d", tmp->tm_isdst);
+ if (off != LONG_MIN)
+ printf(" gmtoff=%ld", off);
+ }
+ }
+ printf("\n");
+ if (tmp != NULL && *abbr(tmp) != '\0')
+ abbrok(abbr(tmp), zone);
+}
+
+#if HAVE_SNPRINTF
+# define my_snprintf snprintf
+#else
+# include
+
+/* A substitute for snprintf that is good enough for zdump. */
+static int ATTRIBUTE_FORMAT((printf, 3, 4))
+my_snprintf(char *s, size_t size, char const *format, ...)
+{
+ int n;
+ va_list args;
+ char const *arg;
+ size_t arglen, slen;
+ char buf[1024];
+ va_start(args, format);
+ if (strcmp(format, "%s") == 0) {
+ arg = va_arg(args, char const *);
+ arglen = strlen(arg);
+ } else {
+ n = vsprintf(buf, format, args);
+ if (n < 0)
+ return n;
+ arg = buf;
+ arglen = n;
+ }
+ slen = arglen < size ? arglen : size - 1;
+ memcpy(s, arg, slen);
+ s[slen] = '\0';
+ n = arglen <= INT_MAX ? arglen : -1;
+ va_end(args);
+ return n;
+}
+#endif
+
+/* Store into BUF, of size SIZE, a formatted local time taken from *TM.
+ Use ISO 8601 format +HH:MM:SS. Omit :SS if SS is zero, and omit
+ :MM too if MM is also zero.
+
+ Return the length of the resulting string. If the string does not
+ fit, return the length that the string would have been if it had
+ fit; do not overrun the output buffer. */
+static int
+format_local_time(char *buf, size_t size, struct tm const *tm)
+{
+ int ss = tm->tm_sec, mm = tm->tm_min, hh = tm->tm_hour;
+ return (ss
+ ? my_snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
+ : mm
+ ? my_snprintf(buf, size, "%02d:%02d", hh, mm)
+ : my_snprintf(buf, size, "%02d", hh));
+}
+
+/* Store into BUF, of size SIZE, a formatted UT offset for the
+ localtime *TM corresponding to time T. Use ISO 8601 format
+ +HHMMSS, or -HHMMSS for timestamps west of Greenwich; use the
+ format -00 for unknown UT offsets. If the hour needs more than
+ two digits to represent, extend the length of HH as needed.
+ Otherwise, omit SS if SS is zero, and omit MM too if MM is also
+ zero.
+
+ Return the length of the resulting string, or -1 if the result is
+ not representable as a string. If the string does not fit, return
+ the length that the string would have been if it had fit; do not
+ overrun the output buffer. */
+static int
+format_utc_offset(char *buf, size_t size, struct tm const *tm, time_t t)
+{
+ long off = gmtoff(tm, &t, NULL);
+ char sign = ((off < 0
+ || (off == 0
+ && (*abbr(tm) == '-' || strcmp(abbr(tm), "zzz") == 0)))
+ ? '-' : '+');
+ long hh;
+ int mm, ss;
+ if (off < 0)
+ {
+ if (off == LONG_MIN)
+ return -1;
+ off = -off;
+ }
+ ss = off % 60;
+ mm = off / 60 % 60;
+ hh = off / 60 / 60;
+ return (ss || 100 <= hh
+ ? my_snprintf(buf, size, "%c%02ld%02d%02d", sign, hh, mm, ss)
+ : mm
+ ? my_snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
+ : my_snprintf(buf, size, "%c%02ld", sign, hh));
+}
+
+/* Store into BUF (of size SIZE) a quoted string representation of P.
+ If the representation's length is less than SIZE, return the
+ length; the representation is not null terminated. Otherwise
+ return SIZE, to indicate that BUF is too small. */
+static size_t
+format_quoted_string(char *buf, size_t size, char const *p)
+{
+ char *b = buf;
+ size_t s = size;
+ if (!s)
+ return size;
+ *b++ = '"', s--;
+ for (;;) {
+ char c = *p++;
+ if (s <= 1)
+ return size;
+ switch (c) {
+ default: *b++ = c, s--; continue;
+ case '\0': *b++ = '"', s--; return size - s;
+ case '"': case '\\': break;
+ case ' ': c = 's'; break;
+ case '\f': c = 'f'; break;
+ case '\n': c = 'n'; break;
+ case '\r': c = 'r'; break;
+ case '\t': c = 't'; break;
+ case '\v': c = 'v'; break;
+ }
+ *b++ = '\\', *b++ = c, s -= 2;
+ }
+}
+
+/* Store into BUF (of size SIZE) a timestamp formatted by TIME_FMT.
+ TM is the broken-down time, T the seconds count, AB the time zone
+ abbreviation, and ZONE_NAME the zone name. Return true if
+ successful, false if the output would require more than SIZE bytes.
+ TIME_FMT uses the same format that strftime uses, with these
+ additions:
+
+ %f zone name
+ %L local time as per format_local_time
+ %Q like "U\t%Z\tD" where U is the UT offset as for format_utc_offset
+ and D is the isdst flag; except omit D if it is zero, omit %Z if
+ it equals U, quote and escape %Z if it contains nonalphabetics,
+ and omit any trailing tabs. */
+
+static bool
+istrftime(char *buf, size_t size, char const *time_fmt,
+ struct tm const *tm, time_t t, char const *ab, char const *zone_name)
+{
+ char *b = buf;
+ size_t s = size;
+ char const *f = time_fmt, *p;
+
+ for (p = f; ; p++)
+ if (*p == '%' && p[1] == '%')
+ p++;
+ else if (!*p
+ || (*p == '%'
+ && (p[1] == 'f' || p[1] == 'L' || p[1] == 'Q'))) {
+ size_t formatted_len;
+ size_t f_prefix_len = p - f;
+ size_t f_prefix_copy_size = p - f + 2;
+ char fbuf[100];
+ bool oversized = sizeof fbuf <= f_prefix_copy_size;
+ char *f_prefix_copy = oversized ? xmalloc(f_prefix_copy_size) : fbuf;
+ memcpy(f_prefix_copy, f, f_prefix_len);
+ strcpy(f_prefix_copy + f_prefix_len, "X");
+ formatted_len = strftime(b, s, f_prefix_copy, tm);
+ if (oversized)
+ free(f_prefix_copy);
+ if (formatted_len == 0)
+ return false;
+ formatted_len--;
+ b += formatted_len, s -= formatted_len;
+ if (!*p++)
+ break;
+ switch (*p) {
+ case 'f':
+ formatted_len = format_quoted_string(b, s, zone_name);
+ break;
+ case 'L':
+ formatted_len = format_local_time(b, s, tm);
+ break;
+ case 'Q':
+ {
+ bool show_abbr;
+ int offlen = format_utc_offset(b, s, tm, t);
+ if (! (0 <= offlen && offlen < s))
+ return false;
+ show_abbr = strcmp(b, ab) != 0;
+ b += offlen, s -= offlen;
+ if (show_abbr) {
+ char const *abp;
+ size_t len;
+ if (s <= 1)
+ return false;
+ *b++ = '\t', s--;
+ for (abp = ab; is_alpha(*abp); abp++)
+ continue;
+ len = (!*abp && *ab
+ ? my_snprintf(b, s, "%s", ab)
+ : format_quoted_string(b, s, ab));
+ if (s <= len)
+ return false;
+ b += len, s -= len;
+ }
+ formatted_len
+ = (tm->tm_isdst
+ ? my_snprintf(b, s, &"\t\t%d"[show_abbr], tm->tm_isdst)
+ : 0);
+ }
+ break;
+ }
+ if (s <= formatted_len)
+ return false;
+ b += formatted_len, s -= formatted_len;
+ f = p + 1;
+ }
+ *b = '\0';
+ return true;
+}
+
+/* Show a time transition. */
+static void
+showtrans(char const *time_fmt, struct tm const *tm, time_t t, char const *ab,
+ char const *zone_name)
+{
+ if (!tm) {
+ printf(tformat(), t);
+ putchar('\n');
+ } else {
+ char stackbuf[1000];
+ size_t size = sizeof stackbuf;
+ char *buf = stackbuf;
+ char *bufalloc = NULL;
+ while (! istrftime(buf, size, time_fmt, tm, t, ab, zone_name)) {
+ size = sumsize(size, size);
+ free(bufalloc);
+ buf = bufalloc = xmalloc(size);
+ }
+ puts(buf);
+ free(bufalloc);
+ }
+}
+
+static char const *
+abbr(struct tm const *tmp)
+{
+#ifdef TM_ZONE
+ return tmp->TM_ZONE;
+#else
+# if HAVE_TZNAME
+ if (0 <= tmp->tm_isdst && tzname[0 < tmp->tm_isdst])
+ return tzname[0 < tmp->tm_isdst];
+# endif
+ return "";
+#endif
+}
+
+/*
+** The code below can fail on certain theoretical systems;
+** it works on all known real-world systems as of 2004-12-30.
+*/
+
+static const char *
+tformat(void)
+{
+ if (0 > (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))
+ 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))
+ return "%lu";
+ return "%u";
+}
+
+static void
+dumptime(register const struct tm *timeptr)
+{
+ static const char wday_name[][4] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char mon_name[][4] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ register const char * wn;
+ register const char * mn;
+ register int lead;
+ register int trail;
+
+ if (timeptr == NULL) {
+ printf("NULL");
+ return;
+ }
+ /*
+ ** 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.
+ */
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday >=
+ (int) (sizeof wday_name / sizeof wday_name[0]))
+ wn = "???";
+ else wn = wday_name[timeptr->tm_wday];
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon >=
+ (int) (sizeof mon_name / sizeof mon_name[0]))
+ mn = "???";
+ else mn = mon_name[timeptr->tm_mon];
+ printf("%s %s%3d %.2d:%.2d:%.2d ",
+ wn, mn,
+ timeptr->tm_mday, timeptr->tm_hour,
+ timeptr->tm_min, timeptr->tm_sec);
+#define DIVISOR 10
+ trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
+ lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
+ trail / DIVISOR;
+ trail %= DIVISOR;
+ if (trail < 0 && lead > 0) {
+ trail += DIVISOR;
+ --lead;
+ } else if (lead < 0 && trail > 0) {
+ trail -= DIVISOR;
+ ++lead;
+ }
+ if (lead == 0)
+ printf("%d", trail);
+ else printf("%d%d", lead, ((trail < 0) ? -trail : trail));
+}
Property changes on: vendor/tzdb/tzcode2018e/zdump.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/zic.8
===================================================================
--- vendor/tzdb/tzcode2018e/zic.8 (nonexistent)
+++ vendor/tzdb/tzcode2018e/zic.8 (revision 337695)
@@ -0,0 +1,599 @@
+.TH ZIC 8
+.SH NAME
+zic \- time zone compiler
+.SH SYNOPSIS
+.B zic
+[
+.I option
+\&... ] [
+.I filename
+\&... ]
+.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
+..
+.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.
+If a
+.I filename
+is
+.q "\*-" ,
+the standard input is read.
+.PP
+These options are available:
+.TP
+.BI "\*-\*-version"
+Output version information and exit.
+.TP
+.BI "\*-d " directory
+Create time conversion information files in the named directory rather than
+in the standard directory named below.
+.TP
+.BI "\*-l " timezone
+Use the given time zone as local time.
+.I Zic
+will act as if the input contained a link line of the form
+.sp
+.ti +.5i
+Link \fItimezone\fP localtime
+.TP
+.BI "\*-p " timezone
+Use the given time zone's rules when handling POSIX-format
+time zone environment variables.
+.I Zic
+will act as if the input contained a link line of the form
+.sp
+.ti +.5i
+Link \fItimezone\fP posixrules
+.TP
+.BI "\*-t " file
+When creating local time information, put the configuration link in
+the named file rather than in the standard location.
+.TP
+.BI "\*-L " leapsecondfilename
+Read leap second information from the file with the given name.
+If this option is not used,
+no leap second information appears in output files.
+.TP
+.B \*-v
+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.
+.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
+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.
+.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)
+\*
+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 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.
+.PP
+Names must be in English and are case insensitive.
+They appear in several contexts, and include month and weekday names
+and keywords such as
+.BR "maximum" ,
+.BR "only" ,
+.BR "Rolling" ,
+and
+.BR "Zone" .
+A name can be abbreviated by omitting all but an initial prefix; any
+abbreviation must be unambiguous in context.
+.PP
+A rule line has the form
+.nf
+.ti +.5i
+.ta \w'Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00s\0\0'u +\w'1:00d\0\0'u
+.sp
+Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+.sp
+For example:
+.ti +.5i
+.sp
+Rule US 1967 1973 \*- Apr lastSun 2:00s 1:00d D
+.sp
+.fi
+The fields that make up a rule line are:
+.TP "\w'LETTER/S'u"
+.B NAME
+Gives the (arbitrary) name of the set of rules this rule is part of.
+.TP
+.B FROM
+Gives the first year in which the rule applies.
+Any signed integer year can be supplied; the proleptic Gregorian calendar
+is assumed, with year 0 preceding year 1.
+The word
+.B minimum
+(or an abbreviation) means the indefinite past.
+The word
+.B maximum
+(or an abbreviation) means the indefinite future.
+Rules can describe times that are not representable as time values,
+with the unrepresentable times ignored; this allows rules to be portable
+among hosts with differing time value types.
+.TP
+.B TO
+Gives the final year in which the rule applies.
+In addition to
+.B minimum
+and
+.B maximum
+(as above),
+the word
+.B only
+(or an abbreviation)
+may be used to repeat the value of the
+.B FROM
+field.
+.TP
+.B TYPE
+should be
+.q \*-
+and is present for compatibility with older versions of
+.I zic
+in which it could contain year types.
+.TP
+.B IN
+Names the month in which the rule takes effect.
+Month names may be abbreviated.
+.TP
+.B ON
+Gives the day on which the rule takes effect.
+Recognized forms include:
+.nf
+.in +.5i
+.sp
+.ta \w'Sun<=25\0\0'u
+5 the fifth of the month
+lastSun the last Sunday in the month
+lastMon the last Monday in the month
+Sun>=8 first Sunday on or after the eighth
+Sun<=25 last Sunday on or before the 25th
+.fi
+.in -.5i
+.sp
+A weekday name (e.g.,
+.BR "Sunday" )
+or a weekday name preceded by
+.q "last"
+(e.g.,
+.BR "lastSunday" )
+may be abbreviated or spelled out in full.
+Note that there must be no spaces within the
+.B ON
+field.
+.TP
+.B AT
+Gives the time of day at which the rule takes effect.
+Recognized forms include:
+.nf
+.in +.5i
+.sp
+.ta \w'00:19:32.13\0\0'u
+2 time in hours
+2:00 time in hours and minutes
+01:28:14 time in hours, minutes, and seconds
+00:19:32.13 time with fractional seconds
+15:00 24-hour format time (for times after noon)
+260:00 260 hours after 00:00
+\*-2:30 2.5 hours before 00:00
+\*- equivalent to 0
+.fi
+.in -.5i
+.sp
+where hour 0 is midnight at the start of the day,
+and hour 24 is midnight at the end of the day.
+Although
+.I zic
+rounds times to the nearest integer second
+(breaking ties to the even integer), the fractions may be useful
+to other applications requiring greater precision.
+The source format does not specify any maximum precision.
+Any of these forms may be followed by the letter
+.B w
+if the given time is local
+.q "wall clock"
+time,
+.B s
+if the given time is local
+.q "standard"
+time, or
+.B u
+(or
+.B g
+or
+.BR z )
+if the given time is universal time;
+in the absence of an indicator,
+wall clock time is assumed.
+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
+effect, and whether the resulting time is standard or daylight saving.
+This field has the same format as the
+.B AT
+field
+except with a different set of suffix letters:
+.B s
+for standard time and
+.B d
+for daylight saving time.
+The suffix letter is typically omitted, and defaults to
+.B s
+if the offset is zero and to
+.B d
+otherwise.
+Negative offsets are allowed; in Ireland, for example, daylight saving
+time is observed in winter and has a negative offset relative to
+Irish Standard Time.
+The offset is merely added to standard time; for example,
+.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"
+or
+.q "D"
+in
+.q "EST"
+or
+.q "EDT" )
+of time zone abbreviations to be used when this rule is in effect.
+If this field is
+.q \*- ,
+the variable part is null.
+.PP
+A zone line has the form
+.sp
+.nf
+.ti +.5i
+.ta \w'Zone\0\0'u +\w'Asia/Amman\0\0'u +\w'GMTOFF\0\0'u +\w'Jordan\0\0'u +\w'FORMAT\0\0'u
+Zone NAME GMTOFF RULES FORMAT [UNTIL]
+.sp
+For example:
+.sp
+.ti +.5i
+Zone Asia/Amman 2:00 Jordan EE%sT 2017 Oct 27 01:00
+.sp
+.fi
+The fields that make up a zone line are:
+.TP "\w'GMTOFF'u"
+.B NAME
+The name of the time zone.
+This is the name used in creating the time conversion information file for the
+zone.
+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 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 UT.
+.TP
+.B RULES
+The name of the rules that apply in the time zone or,
+alternatively, a field in the same format as a rule-line SAVE column,
+giving of the amount of time to be added to local standard time
+effect, and whether the resulting time is standard or daylight saving.
+If this field is
+.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.
+The pair of characters
+.B %s
+is used to show where the
+.q "variable part"
+of the time zone abbreviation goes.
+Alternatively, a format can use the pair of characters
+.B %z
+to stand for the UT 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 UT.
+Alternatively,
+a slash (/)
+separates standard and daylight abbreviations.
+To conform to POSIX, a time zone abbreviation should contain only
+alphanumeric ASCII characters, "+" and "\*-".
+.TP
+.B UNTIL
+The time at which the UT offset or the rule(s) change for a location.
+It takes the form of YEAR [MONTH [DAY [TIME]]].
+If this is specified,
+the time zone information is generated from the given UT offset
+and rule change until the time specified, which is interpreted using
+the rules in effect just before the transition.
+The month, day, and time of day have the same format as the 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"
+line; this has the same form as a zone line except that the
+string
+.q "Zone"
+and the name are omitted, as the continuation line will
+place information starting at the time specified as the
+.q "until"
+information in the previous line in the file used by the previous line.
+Continuation lines may contain
+.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 TARGET LINK-NAME
+.sp
+For example:
+.sp
+.ti +.5i
+Link Europe/Istanbul Asia/Istanbul
+.sp
+.fi
+The
+.B TARGET
+field should appear as the
+.B NAME
+field in some zone line.
+The
+.B LINK-NAME
+field is used as an alternative 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
+.ti +.5i
+.ta \w'Leap\0\0'u +\w'YEAR\0\0'u +\w'MONTH\0\0'u +\w'DAY\0\0'u +\w'HH:MM:SS\0\0'u +\w'CORR\0\0'u
+.sp
+Leap YEAR MONTH DAY HH:MM:SS CORR R/S
+.sp
+For example:
+.ti +.5i
+.sp
+Leap 2016 Dec 31 23:59:60 + S
+.sp
+.fi
+The
+.BR YEAR ,
+.BR MONTH ,
+.BR DAY ,
+and
+.B HH:MM:SS
+fields tell when the leap second happened.
+The
+.B CORR
+field
+should be
+.q "+"
+if a second was added
+or
+.q "\*-"
+if a second was skipped.
+The
+.B R/S
+field
+should be (an abbreviation of)
+.q "Stationary"
+if the leap second time given by the other fields should be interpreted as UTC
+or
+(an abbreviation of)
+.q "Rolling"
+if the leap second time given by the other fields should be interpreted as
+local wall clock time.
+.SH "EXTENDED EXAMPLE"
+Here is an extended example of
+.I zic
+input, intended to illustrate many of its features.
+In this example, the EU rules are for the European Union
+and for its predecessor organization, the European Communities.
+.br
+.ne 22
+.nf
+.in +2m
+.ta \w'# Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u
+.sp
+# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+Rule Swiss 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 \*-
+.sp
+.ta \w'# Zone\0\0'u +\w'Europe/Zurich\0\0'u +\w'GMTOFF\0\0'u +\w'0:34:08\0\0'u +\w'FORMAT\0\0'u
+# Zone NAME GMTOFF RULES 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
+Link Europe/Zurich Europe/Vaduz
+.sp
+.in
+.fi
+In this example, the zone is named Europe/Zurich but it has an alias
+as Europe/Vaduz. This example says that Zurich was 34 minutes and 8
+seconds east of UT until 1853-07-16 at 00:00, when the legal offset
+was changed to 7\(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 the UT offset became one hour
+and Swiss daylight saving rules (defined with lines beginning with "Rule
+Swiss") apply. From 1981 to the present, EU daylight saving rules have
+applied, and the UTC offset has remained at one hour.
+.PP
+In 1941 and 1942, daylight saving time applied from the first Monday
+in May at 01:00 to the first Monday in October at 02:00.
+The pre-1981 EU daylight-saving rules have no effect
+here, but are included for completeness. Since 1981, daylight
+saving has begun on the last Sunday in March at 01:00 UTC.
+Until 1995 it ended the last Sunday in September at 01:00 UTC,
+but this changed to the last Sunday in October starting in 1996.
+.PP
+For purposes of
+display, "LMT" and "BMT" were initially used, respectively. Since
+Swiss rules and later EU rules were applied, the display name for the
+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,
+you may need to use local standard time in the
+.B AT
+field of the earliest transition time's rule to ensure that
+the earliest transition time recorded in the compiled file is correct.
+.PP
+If,
+for a particular zone,
+a clock advance caused by the start of daylight saving
+coincides with and is equal to
+a clock retreat caused by a change in UT offset,
+.IR 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.
+.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 FILES
+.ta \w'/usr/share/zoneinfo\0\0'u
+/etc/localtime default local time zone file
+/usr/share/zoneinfo default time zone information directory
+.SH "SEE ALSO"
+newctime(3), tzfile(5), zdump(8)
+.\" This file is in the public domain, so clarified as of
+.\" 2009-05-17 by Arthur David Olson.
Property changes on: vendor/tzdb/tzcode2018e/zic.8
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/zic.8.txt
===================================================================
--- vendor/tzdb/tzcode2018e/zic.8.txt (nonexistent)
+++ vendor/tzdb/tzcode2018e/zic.8.txt (revision 337695)
@@ -0,0 +1,372 @@
+ZIC(8) System Manager's Manual ZIC(8)
+
+NAME
+ zic - time zone compiler
+
+SYNOPSIS
+ 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.
+
+ These options are available:
+
+ --version
+ Output version information and exit.
+
+ -d directory
+ Create time conversion information files in the named directory
+ rather than in the standard directory named below.
+
+ -l timezone
+ Use the given time zone as local time. Zic will act as if the
+ input contained a link line of the form
+
+ Link timezone localtime
+
+ -p timezone
+ Use the given time zone's rules when handling POSIX-format time
+ zone environment variables. Zic will act as if the input
+ contained a link line of the form
+
+ Link timezone posixrules
+
+ -t file
+ When creating local time information, put the configuration link
+ in the named file rather than in the standard location.
+
+ -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.
+
+ -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.
+
+ 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) 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 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 must be in English and are case insensitive. They appear in
+ several contexts, and include month and weekday names and keywords such
+ as maximum, only, Rolling, and Zone. A name can be abbreviated by
+ omitting all but an initial prefix; any abbreviation must be
+ unambiguous in context.
+
+ A rule line has the form
+
+ Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+
+ For example:
+
+ Rule US 1967 1973 - Apr lastSun 2:00s 1:00d D
+
+ The fields that make up a rule line are:
+
+ NAME Gives the (arbitrary) name of the set of rules this rule is
+ part of.
+
+ FROM Gives the first year in which the rule applies. Any signed
+ integer year can be supplied; the proleptic Gregorian calendar
+ is assumed, with year 0 preceding year 1. The word minimum (or
+ an abbreviation) means the indefinite past. The word maximum
+ (or an abbreviation) means the indefinite future. Rules can
+ describe times that are not representable as time values, with
+ the unrepresentable times ignored; this allows rules to be
+ portable among hosts with differing time value types.
+
+ TO Gives the final year in which the rule applies. In addition to
+ minimum and maximum (as above), the word only (or an
+ abbreviation) may be used to repeat the value of the FROM
+ field.
+
+ 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.
+
+ ON Gives the day on which the rule takes effect. Recognized forms
+ include:
+
+ 5 the fifth of the month
+ lastSun the last Sunday in the month
+ lastMon the last Monday in the month
+ Sun>=8 first Sunday on or after the eighth
+ Sun<=25 last Sunday on or before the 25th
+
+ A weekday name (e.g., Sunday) or a weekday name preceded by
+ "last" (e.g., lastSunday) may be abbreviated or spelled out in
+ full. Note that there must be no spaces within the ON field.
+
+ AT Gives the time of day at which the rule takes effect.
+ Recognized forms include:
+
+ 2 time in hours
+ 2:00 time in hours and minutes
+ 01:28:14 time in hours, minutes, and seconds
+ 00:19:32.13 time with fractional seconds
+ 15:00 24-hour format time (for times after noon)
+ 260:00 260 hours after 00:00
+ -2:30 2.5 hours before 00:00
+ - equivalent to 0
+
+ where hour 0 is midnight at the start of the day, and hour 24
+ is midnight at the end of the day. Although zic rounds times
+ to the nearest integer second (breaking ties to the even
+ integer), the fractions may be useful to other applications
+ requiring greater precision. The source format does not
+ specify any maximum precision. Any of these forms may be
+ followed by the letter 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. 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, and whether the resulting time is
+ standard or daylight saving. This field has the same format as
+ the AT field except with a different set of suffix letters: s
+ for standard time and d for daylight saving time. The suffix
+ letter is typically omitted, and defaults to s if the offset is
+ zero and to d otherwise. Negative offsets are allowed; in
+ Ireland, for example, daylight saving time is observed in
+ winter and has a negative offset relative to Irish Standard
+ Time. The offset is merely added to standard time; for
+ example, 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.
+
+ A zone line has the form
+
+ Zone NAME GMTOFF RULES FORMAT [UNTIL]
+
+ For example:
+
+ Zone Asia/Amman 2:00 Jordan EE%sT 2017 Oct 27 01: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. 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 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 UT.
+
+ RULES The name of the rules that apply in the time zone or,
+ alternatively, a field in the same format as a rule-line SAVE
+ column, giving of the amount of time to be added to local
+ standard time effect, and whether the resulting time is standard
+ or daylight saving. If this field is - 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.
+
+ 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. Alternatively, a format can
+ use the pair of characters %z to stand for the UT 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 UT. Alternatively,
+ a slash (/) separates standard and daylight abbreviations. To
+ conform to POSIX, a time zone abbreviation should contain only
+ alphanumeric ASCII characters, "+" and "-".
+
+ UNTIL The time at which the UT offset or the rule(s) change for a
+ location. It takes the form of YEAR [MONTH [DAY [TIME]]]. If
+ this is specified, the time zone information is generated from
+ the given UT offset and rule change until the time specified,
+ which is interpreted using the rules in effect just before the
+ transition. The month, day, and time of day have the same format
+ as the 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
+ are omitted, as the continuation line will place information
+ starting at the time specified as the "until" information in the
+ previous line in the file used by the previous line.
+ Continuation lines may contain "until" information, just as zone
+ 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 TARGET LINK-NAME
+
+ For example:
+
+ Link Europe/Istanbul Asia/Istanbul
+
+ The TARGET field should appear as the NAME field in some zone line.
+ The LINK-NAME field is used as an alternative 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. 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:
+
+ Leap YEAR MONTH DAY HH:MM:SS CORR R/S
+
+ For example:
+
+ Leap 2016 Dec 31 23:59:60 + S
+
+ The YEAR, MONTH, DAY, and HH:MM:SS fields tell when the leap second
+ happened. The CORR field should be "+" if a second was added or "-" if
+ a second was skipped. The R/S field should be (an abbreviation of)
+ "Stationary" if the leap second time given by the other fields should
+ be interpreted as UTC or (an abbreviation of) "Rolling" if the leap
+ second time given by the other fields should be interpreted as local
+ wall clock time.
+
+EXTENDED EXAMPLE
+ Here is an extended example of zic input, intended to illustrate many
+ of its features. In this example, the EU rules are for the European
+ Union and for its predecessor organization, the European Communities.
+
+ # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+ Rule Swiss 1941 1942 - May Mon>=1 1:00 1:00 S
+ Rule Swiss 1941 1942 - Oct Mon>=1 2:00 0 -
+ Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
+ Rule EU 1977 only - Sep lastSun 1:00u 0 -
+ Rule EU 1978 only - Oct 1 1:00u 0 -
+ Rule EU 1979 1995 - Sep lastSun 1:00u 0 -
+ Rule EU 1981 max - Mar lastSun 1:00u 1:00 S
+ Rule EU 1996 max - Oct lastSun 1:00u 0 -
+
+ # Zone NAME GMTOFF RULES 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 Europe/Vaduz
+
+ In this example, the zone is named Europe/Zurich but it has an alias as
+ Europe/Vaduz. This example says that Zurich was 34 minutes and 8
+ seconds east of UT until 1853-07-16 at 00:00, when the legal offset was
+ changed to 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 the UT offset became one hour and Swiss
+ daylight saving rules (defined with lines beginning with "Rule Swiss")
+ apply. From 1981 to the present, EU daylight saving rules have
+ applied, and the UTC offset has remained at one hour.
+
+ 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 time zone has been CET for standard time and CEST
+ for daylight saving time.
+
+NOTES
+ For areas with more than two types of local time, you may need to use
+ local standard time in the AT field of the earliest transition time's
+ rule to ensure that the earliest transition time recorded in the
+ compiled file is correct.
+
+ 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 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.
+
+FILES
+ /etc/localtime default local time zone file
+ /usr/share/zoneinfo default time zone information directory
+
+SEE ALSO
+ newctime(3), tzfile(5), zdump(8)
+
+ ZIC(8)
Property changes on: vendor/tzdb/tzcode2018e/zic.8.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: vendor/tzdb/tzcode2018e/zic.c
===================================================================
--- vendor/tzdb/tzcode2018e/zic.c (nonexistent)
+++ vendor/tzdb/tzcode2018e/zic.c (revision 337695)
@@ -0,0 +1,3286 @@
+/*
+** This file is in the public domain, so clarified as of
+** 2006-07-17 by Arthur David Olson.
+*/
+
+#include "version.h"
+#include "private.h"
+#include "tzfile.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#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 PRIdZIC PRIdFAST64
+#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
+# include
+# undef mkdir
+# define mkdir(name, mode) _mkdir(name)
+#endif
+
+#if HAVE_SYS_STAT_H
+#include
+#endif
+#ifdef S_IRUSR
+#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
+#else
+#define MKDIR_UMASK 0755
+#endif
+/* Port to native MS-Windows and to ancient UNIX. */
+#if !defined S_ISDIR && defined S_IFDIR && defined S_IFMT
+# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+
+#if HAVE_SYS_WAIT_H
+#include /* for WIFEXITED and WEXITSTATUS */
+#endif /* HAVE_SYS_WAIT_H */
+
+#ifndef WIFEXITED
+#define WIFEXITED(status) (((status) & 0xff) == 0)
+#endif /* !defined WIFEXITED */
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
+#endif /* !defined WEXITSTATUS */
+
+/* The maximum ptrdiff_t value, for pre-C99 platforms. */
+#ifndef PTRDIFF_MAX
+static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t));
+#endif
+
+/* The type for line numbers. Use PRIdMAX to format them; formerly
+ there was also "#define PRIdLINENO PRIdMAX" and formats used
+ PRIdLINENO, but xgettext cannot grok that. */
+typedef intmax_t lineno;
+
+struct rule {
+ const char * r_filename;
+ lineno r_linenum;
+ const char * r_name;
+
+ zic_t r_loyear; /* for example, 1986 */
+ zic_t r_hiyear; /* for example, 1986 */
+ const char * r_yrtype;
+ bool r_lowasnum;
+ bool r_hiwasnum;
+
+ int r_month; /* 0..11 */
+
+ int r_dycode; /* see below */
+ int r_dayofmonth;
+ int r_wday;
+
+ 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 */
+ bool r_isdst; /* is this daylight saving time? */
+ zic_t r_stdoff; /* offset from default time (which is
+ usually standard time) */
+ const char * r_abbrvar; /* variable part of abbreviation */
+
+ bool r_todo; /* a rule to do (used in outzone) */
+ zic_t r_temp; /* used in outzone */
+};
+
+/*
+** r_dycode r_dayofmonth r_wday
+*/
+
+#define DC_DOM 0 /* 1..31 */ /* unused */
+#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */
+#define DC_DOWLEQ 2 /* 1..31 */ /* 0..6 (Sun..Sat) */
+
+struct zone {
+ const char * z_filename;
+ lineno z_linenum;
+
+ const char * z_name;
+ zic_t z_gmtoff;
+ char * z_rule;
+ const char * z_format;
+ char z_format_specifier;
+
+ bool z_isdst;
+ zic_t z_stdoff;
+
+ struct rule * z_rules;
+ ptrdiff_t z_nrules;
+
+ struct rule z_untilrule;
+ 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 readlink(file, buf, size) (errno = ENOTSUP, -1)
+# define symlink(from, to) (errno = ENOTSUP, -1)
+# define S_ISLNK(m) 0
+#endif
+#ifndef AT_SYMLINK_FOLLOW
+# define linkat(fromdir, from, todir, to, flag) \
+ (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to))
+#endif
+
+static void addtt(zic_t starttime, int type);
+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 *, const char *, bool);
+static char ** getfields(char * buf);
+static zic_t gethms(const char * string, const char * errstring,
+ bool);
+static zic_t getstdoff(char *, 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 bool inzcont(char ** fields, int nfields);
+static bool inzone(char ** fields, int nfields);
+static bool inzsub(char **, int, bool);
+static bool itsdir(char const *);
+static bool itssymlink(char const *);
+static bool is_alpha(char a);
+static char lowerit(char);
+static void mkdirs(char const *, bool);
+static void newabbr(const char * abbr);
+static zic_t oadd(zic_t t1, zic_t t2);
+static void outzone(const struct zone * zp, ptrdiff_t ntzones);
+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, zic_t t2);
+static bool yearistype(zic_t 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
+ tz binary files whose POSIX-TZ-style strings contain '<'; see
+ 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 bool errors;
+static bool warnings;
+static const char * filename;
+static int leapcnt;
+static bool leapseen;
+static zic_t leapminyear;
+static zic_t leapmaxyear;
+static lineno linenum;
+static int max_abbrvar_len = PERCENT_Z_LEN_BOUND;
+static int max_format_len;
+static zic_t max_year;
+static zic_t min_year;
+static bool noise;
+static const char * rfilename;
+static lineno rlinenum;
+static const char * progname;
+static ptrdiff_t timecnt;
+static ptrdiff_t timecnt_alloc;
+static int typecnt;
+
+/*
+** Line codes.
+*/
+
+#define LC_RULE 0
+#define LC_ZONE 1
+#define LC_LINK 2
+#define LC_LEAP 3
+
+/*
+** Which fields are which on a Zone line.
+*/
+
+#define ZF_NAME 1
+#define ZF_GMTOFF 2
+#define ZF_RULE 3
+#define ZF_FORMAT 4
+#define ZF_TILYEAR 5
+#define ZF_TILMONTH 6
+#define ZF_TILDAY 7
+#define ZF_TILTIME 8
+#define ZONE_MINFIELDS 5
+#define ZONE_MAXFIELDS 9
+
+/*
+** Which fields are which on a Zone continuation line.
+*/
+
+#define ZFC_GMTOFF 0
+#define ZFC_RULE 1
+#define ZFC_FORMAT 2
+#define ZFC_TILYEAR 3
+#define ZFC_TILMONTH 4
+#define ZFC_TILDAY 5
+#define ZFC_TILTIME 6
+#define ZONEC_MINFIELDS 3
+#define ZONEC_MAXFIELDS 7
+
+/*
+** Which files are which on a Rule line.
+*/
+
+#define RF_NAME 1
+#define RF_LOYEAR 2
+#define RF_HIYEAR 3
+#define RF_COMMAND 4
+#define RF_MONTH 5
+#define RF_DAY 6
+#define RF_TOD 7
+#define RF_STDOFF 8
+#define RF_ABBRVAR 9
+#define RULE_FIELDS 10
+
+/*
+** Which fields are which on a Link line.
+*/
+
+#define LF_FROM 1
+#define LF_TO 2
+#define LINK_FIELDS 3
+
+/*
+** Which fields are which on a Leap line.
+*/
+
+#define LP_YEAR 1
+#define LP_MONTH 2
+#define LP_DAY 3
+#define LP_TIME 4
+#define LP_CORR 5
+#define LP_ROLL 6
+#define LEAP_FIELDS 7
+
+/*
+** Year synonyms.
+*/
+
+#define YR_MINIMUM 0
+#define YR_MAXIMUM 1
+#define YR_ONLY 2
+
+static struct rule * rules;
+static ptrdiff_t nrules; /* number of rules */
+static ptrdiff_t nrules_alloc;
+
+static struct zone * zones;
+static ptrdiff_t nzones; /* number of zones */
+static ptrdiff_t nzones_alloc;
+
+struct link {
+ const char * l_filename;
+ lineno l_linenum;
+ const char * l_from;
+ const char * l_to;
+};
+
+static struct link * links;
+static ptrdiff_t nlinks;
+static ptrdiff_t nlinks_alloc;
+
+struct lookup {
+ const char * l_word;
+ const int l_value;
+};
+
+static struct lookup const * byword(const char * string,
+ const struct lookup * lp);
+
+static struct lookup const zi_line_codes[] = {
+ { "Rule", LC_RULE },
+ { "Zone", LC_ZONE },
+ { "Link", LC_LINK },
+ { NULL, 0 }
+};
+static struct lookup const leap_line_codes[] = {
+ { "Leap", LC_LEAP },
+ { NULL, 0}
+};
+
+static struct lookup const mon_names[] = {
+ { "January", TM_JANUARY },
+ { "February", TM_FEBRUARY },
+ { "March", TM_MARCH },
+ { "April", TM_APRIL },
+ { "May", TM_MAY },
+ { "June", TM_JUNE },
+ { "July", TM_JULY },
+ { "August", TM_AUGUST },
+ { "September", TM_SEPTEMBER },
+ { "October", TM_OCTOBER },
+ { "November", TM_NOVEMBER },
+ { "December", TM_DECEMBER },
+ { NULL, 0 }
+};
+
+static struct lookup const wday_names[] = {
+ { "Sunday", TM_SUNDAY },
+ { "Monday", TM_MONDAY },
+ { "Tuesday", TM_TUESDAY },
+ { "Wednesday", TM_WEDNESDAY },
+ { "Thursday", TM_THURSDAY },
+ { "Friday", TM_FRIDAY },
+ { "Saturday", TM_SATURDAY },
+ { NULL, 0 }
+};
+
+static struct lookup const lasts[] = {
+ { "last-Sunday", TM_SUNDAY },
+ { "last-Monday", TM_MONDAY },
+ { "last-Tuesday", TM_TUESDAY },
+ { "last-Wednesday", TM_WEDNESDAY },
+ { "last-Thursday", TM_THURSDAY },
+ { "last-Friday", TM_FRIDAY },
+ { "last-Saturday", TM_SATURDAY },
+ { NULL, 0 }
+};
+
+static struct lookup const begin_years[] = {
+ { "minimum", YR_MINIMUM },
+ { "maximum", YR_MAXIMUM },
+ { NULL, 0 }
+};
+
+static struct lookup const end_years[] = {
+ { "minimum", YR_MINIMUM },
+ { "maximum", YR_MAXIMUM },
+ { "only", YR_ONLY },
+ { NULL, 0 }
+};
+
+static struct lookup const leap_types[] = {
+ { "Rolling", true },
+ { "Stationary", false },
+ { NULL, 0 }
+};
+
+static const int len_months[2][MONSPERYEAR] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static const int len_years[2] = {
+ DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+static struct attype {
+ zic_t at;
+ bool dontmerge;
+ unsigned char type;
+} * attypes;
+static zic_t gmtoffs[TZ_MAX_TYPES];
+static char isdsts[TZ_MAX_TYPES];
+static unsigned char abbrinds[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 zic_t corr[TZ_MAX_LEAPS];
+static char roll[TZ_MAX_LEAPS];
+
+/*
+** 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 void *
+memcheck(void *ptr)
+{
+ if (ptr == NULL)
+ memory_exhausted(strerror(errno));
+ return ptr;
+}
+
+static void * ATTRIBUTE_MALLOC
+emalloc(size_t size)
+{
+ return memcheck(malloc(size));
+}
+
+static void *
+erealloc(void *ptr, size_t size)
+{
+ return memcheck(realloc(ptr, size));
+}
+
+static char * ATTRIBUTE_MALLOC
+ecpyalloc (char const *str)
+{
+ return memcheck(strdup(str));
+}
+
+static void *
+growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
+{
+ if (nitems < *nitems_alloc)
+ return ptr;
+ else {
+ ptrdiff_t nitems_max = PTRDIFF_MAX - WORK_AROUND_QTBUG_53071;
+ ptrdiff_t amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
+ if ((amax - 1) / 3 * 2 < *nitems_alloc)
+ memory_exhausted(_("integer overflow"));
+ *nitems_alloc += (*nitems_alloc >> 1) + 1;
+ return erealloc(ptr, size_product(*nitems_alloc, itemsize));
+ }
+}
+
+/*
+** Error handling.
+*/
+
+static void
+eats(char const *name, lineno num, char const *rname, lineno rnum)
+{
+ filename = name;
+ linenum = num;
+ rfilename = rname;
+ rlinenum = rnum;
+}
+
+static void
+eat(char const *name, lineno num)
+{
+ eats(name, num, NULL, -1);
+}
+
+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
+ ** zic ... 2>&1 | error -t "*" -v
+ ** on BSD systems.
+ */
+ if (filename)
+ fprintf(stderr, _("\"%s\", line %"PRIdMAX": "), filename, linenum);
+ vfprintf(stderr, string, args);
+ if (rfilename != NULL)
+ fprintf(stderr, _(" (rule from \"%s\", line %"PRIdMAX")"),
+ rfilename, rlinenum);
+ fprintf(stderr, "\n");
+}
+
+static void ATTRIBUTE_FORMAT((printf, 1, 2))
+error(const char *const string, ...)
+{
+ va_list args;
+ va_start(args, string);
+ verror(string, args);
+ va_end(args);
+ errors = true;
+}
+
+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 *dir, char const *name)
+{
+ char const *e = (ferror(stream) ? _("I/O error")
+ : fclose(stream) != 0 ? strerror(errno) : NULL);
+ if (e) {
+ fprintf(stderr, "%s: %s%s%s%s%s\n", progname,
+ dir ? dir : "", dir ? "/" : "",
+ name ? name : "", name ? ": " : "",
+ e);
+ exit(EXIT_FAILURE);
+ }
+}
+
+static _Noreturn void
+usage(FILE *stream, int status)
+{
+ fprintf(stream,
+ _("%s: usage is %s [ --version ] [ --help ] [ -v ] \\\n"
+ "\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n"
+ "\t[ -t localtime-link ] [ -L leapseconds ] [ filename ... ]\n\n"
+ "Report bugs to %s.\n"),
+ progname, progname, REPORT_BUGS_TO);
+ if (status == EXIT_SUCCESS)
+ close_file(stream, NULL, NULL);
+ exit(status);
+}
+
+/* Change the working directory to DIR, possibly creating DIR and its
+ ancestors. After this is done, all files are accessed with names
+ relative to DIR. */
+static void
+change_directory (char const *dir)
+{
+ if (chdir(dir) != 0) {
+ int chdir_errno = errno;
+ if (chdir_errno == ENOENT) {
+ mkdirs(dir, false);
+ chdir_errno = chdir(dir) == 0 ? 0 : errno;
+ }
+ if (chdir_errno != 0) {
+ fprintf(stderr, _("%s: Can't chdir to %s: %s\n"),
+ progname, dir, strerror(chdir_errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
+static const char * psxrules;
+static const char * lcltime;
+static const char * directory;
+static const char * leapsec;
+static const char * tzdefault;
+static const char * yitcommand;
+
+int
+main(int argc, char **argv)
+{
+ register int c, k;
+ register ptrdiff_t i, j;
+
+#ifdef S_IWGRP
+ umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
+#endif
+#if HAVE_GETTEXT
+ setlocale(LC_ALL, "");
+#ifdef TZ_DOMAINDIR
+ bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
+#endif /* defined TEXTDOMAINDIR */
+ textdomain(TZ_DOMAIN);
+#endif /* HAVE_GETTEXT */
+ progname = argv[0];
+ if (TYPE_BIT(zic_t) < 64) {
+ fprintf(stderr, "%s: %s\n", progname,
+ _("wild compilation-time specification of zic_t"));
+ return EXIT_FAILURE;
+ }
+ for (k = 1; k < argc; k++)
+ if (strcmp(argv[k], "--version") == 0) {
+ printf("zic %s%s\n", PKGVERSION, TZVERSION);
+ close_file(stdout, NULL, NULL);
+ return EXIT_SUCCESS;
+ } else if (strcmp(argv[k], "--help") == 0) {
+ usage(stdout, EXIT_SUCCESS);
+ }
+ while ((c = getopt(argc, argv, "d:l:L:p:st:vy:")) != EOF && c != -1)
+ switch (c) {
+ default:
+ usage(stderr, EXIT_FAILURE);
+ case 'd':
+ if (directory == NULL)
+ directory = optarg;
+ else {
+ fprintf(stderr,
+_("%s: More than one -d option specified\n"),
+ progname);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 'l':
+ if (lcltime == NULL)
+ lcltime = optarg;
+ else {
+ fprintf(stderr,
+_("%s: More than one -l option specified\n"),
+ progname);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 'p':
+ if (psxrules == NULL)
+ psxrules = optarg;
+ else {
+ fprintf(stderr,
+_("%s: More than one -p option specified\n"),
+ progname);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 't':
+ if (tzdefault != NULL) {
+ fprintf(stderr,
+ _("%s: More than one -t option"
+ " specified\n"),
+ progname);
+ return EXIT_FAILURE;
+ }
+ tzdefault = optarg;
+ break;
+ case 'y':
+ if (yitcommand == NULL) {
+ warning(_("-y is obsolescent"));
+ yitcommand = optarg;
+ } else {
+ fprintf(stderr,
+_("%s: More than one -y option specified\n"),
+ progname);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 'L':
+ if (leapsec == NULL)
+ leapsec = optarg;
+ else {
+ fprintf(stderr,
+_("%s: More than one -L option specified\n"),
+ progname);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 'v':
+ noise = true;
+ break;
+ case 's':
+ warning(_("-s ignored"));
+ break;
+ }
+ if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
+ usage(stderr, EXIT_FAILURE); /* usage message by request */
+ if (directory == NULL)
+ directory = TZDIR;
+ if (tzdefault == NULL)
+ tzdefault = TZDEFAULT;
+ if (yitcommand == NULL)
+ yitcommand = "yearistype";
+
+ if (optind < argc && leapsec != NULL) {
+ infile(leapsec);
+ adjleap();
+ }
+
+ for (k = optind; k < argc; k++)
+ infile(argv[k]);
+ if (errors)
+ return EXIT_FAILURE;
+ associate();
+ change_directory(directory);
+ for (i = 0; i < nzones; i = j) {
+ /*
+ ** Find the next non-continuation zone entry.
+ */
+ for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
+ continue;
+ outzone(&zones[i], j - i);
+ }
+ /*
+ ** Make links.
+ */
+ for (i = 0; i < nlinks; ++i) {
+ eat(links[i].l_filename, links[i].l_linenum);
+ dolink(links[i].l_from, links[i].l_to, false);
+ if (noise)
+ for (j = 0; j < nlinks; ++j)
+ if (strcmp(links[i].l_to,
+ links[j].l_from) == 0)
+ warning(_("link to link"));
+ }
+ if (lcltime != NULL) {
+ eat(_("command line"), 1);
+ dolink(lcltime, tzdefault, true);
+ }
+ if (psxrules != NULL) {
+ eat(_("command line"), 1);
+ dolink(psxrules, TZDEFRULES, true);
+ }
+ 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 };
+ ptrdiff_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] == '.') {
+ int len = component_len;
+ error(_("file name '%s' contains '%.*s' component"),
+ name, 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);
+}
+
+/* Create symlink contents suitable for symlinking FROM to TO, as a
+ freshly allocated string. FROM should be a relative file name, and
+ is relative to the global variable DIRECTORY. TO can be either
+ relative or absolute. */
+static char *
+relname(char const *from, char const *to)
+{
+ size_t i, taillen, dotdotetcsize;
+ size_t dir_len = 0, dotdots = 0, linksize = SIZE_MAX;
+ char const *f = from;
+ char *result = NULL;
+ if (*to == '/') {
+ /* Make F absolute too. */
+ size_t len = strlen(directory);
+ bool needslash = len && directory[len - 1] != '/';
+ linksize = len + needslash + strlen(from) + 1;
+ f = result = emalloc(linksize);
+ strcpy(result, directory);
+ result[len] = '/';
+ strcpy(result + len + needslash, from);
+ }
+ for (i = 0; f[i] && f[i] == to[i]; i++)
+ if (f[i] == '/')
+ dir_len = i + 1;
+ for (; to[i]; i++)
+ dotdots += to[i] == '/' && to[i - 1] != '/';
+ taillen = strlen(f + dir_len);
+ dotdotetcsize = 3 * dotdots + taillen + 1;
+ if (dotdotetcsize <= linksize) {
+ if (!result)
+ result = emalloc(dotdotetcsize);
+ for (i = 0; i < dotdots; i++)
+ memcpy(result + 3 * i, "../", 3);
+ memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
+ }
+ return result;
+}
+
+/* Hard link FROM to TO, following any symbolic links.
+ Return 0 if successful, an error number otherwise. */
+static int
+hardlinkerr(char const *from, char const *to)
+{
+ int r = linkat(AT_FDCWD, from, AT_FDCWD, to, AT_SYMLINK_FOLLOW);
+ return r == 0 ? 0 : errno;
+}
+
+static void
+dolink(char const *fromfield, char const *tofield, bool staysymlink)
+{
+ bool todirs_made = false;
+ int link_errno;
+
+ /*
+ ** We get to be careful here since
+ ** there's a fair chance of root running us.
+ */
+ if (itsdir(fromfield)) {
+ fprintf(stderr, _("%s: link from %s/%s failed: %s\n"),
+ progname, directory, fromfield, strerror(EPERM));
+ exit(EXIT_FAILURE);
+ }
+ if (staysymlink)
+ staysymlink = itssymlink(tofield);
+ if (remove(tofield) == 0)
+ todirs_made = true;
+ else if (errno != ENOENT) {
+ char const *e = strerror(errno);
+ fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
+ progname, directory, tofield, e);
+ exit(EXIT_FAILURE);
+ }
+ link_errno = staysymlink ? ENOTSUP : hardlinkerr(fromfield, tofield);
+ if (link_errno == ENOENT && !todirs_made) {
+ mkdirs(tofield, true);
+ todirs_made = true;
+ link_errno = hardlinkerr(fromfield, tofield);
+ }
+ if (link_errno != 0) {
+ bool absolute = *fromfield == '/';
+ char *linkalloc = absolute ? NULL : relname(fromfield, tofield);
+ char const *contents = absolute ? fromfield : linkalloc;
+ int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
+ if (!todirs_made
+ && (symlink_errno == ENOENT || symlink_errno == ENOTSUP)) {
+ mkdirs(tofield, true);
+ if (symlink_errno == ENOENT)
+ symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
+ }
+ free(linkalloc);
+ if (symlink_errno == 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(fromfield, "rb");
+ if (!fp) {
+ char const *e = strerror(errno);
+ fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
+ progname, directory, fromfield, e);
+ exit(EXIT_FAILURE);
+ }
+ tp = fopen(tofield, "wb");
+ if (!tp) {
+ char const *e = strerror(errno);
+ fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
+ progname, directory, tofield, e);
+ exit(EXIT_FAILURE);
+ }
+ while ((c = getc(fp)) != EOF)
+ putc(c, tp);
+ close_file(fp, directory, fromfield);
+ close_file(tp, directory, tofield);
+ if (link_errno != ENOTSUP)
+ warning(_("copy used because hard link failed: %s"),
+ strerror(link_errno));
+ else if (symlink_errno != ENOTSUP)
+ warning(_("copy used because symbolic link failed: %s"),
+ strerror(symlink_errno));
+ }
+ }
+}
+
+#define TIME_T_BITS_IN_FILE 64
+
+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
+ [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
+
+ 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 true if NAME is a directory. */
+static bool
+itsdir(char const *name)
+{
+ 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) {
+ size_t n = strlen(name);
+ char *nameslashdot = emalloc(n + 3);
+ bool dir;
+ memcpy(nameslashdot, name, n);
+ strcpy(&nameslashdot[n], &"/."[! (n && name[n - 1] != '/')]);
+ dir = stat(nameslashdot, &st) == 0 || errno == EOVERFLOW;
+ free(nameslashdot);
+ return dir;
+ }
+ return false;
+}
+
+/* Return true if NAME is a symbolic link. */
+static bool
+itssymlink(char const *name)
+{
+ char c;
+ return 0 <= readlink(name, &c, 1);
+}
+
+/*
+** Associate sets of rules with zones.
+*/
+
+/*
+** Sort by rule name.
+*/
+
+static int
+rcomp(const void *cp1, const void *cp2)
+{
+ return strcmp(((const struct rule *) cp1)->r_name,
+ ((const struct rule *) cp2)->r_name);
+}
+
+static void
+associate(void)
+{
+ register struct zone * zp;
+ register struct rule * rp;
+ register ptrdiff_t i, j, base, out;
+
+ if (nrules != 0) {
+ 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)
+ continue;
+ if (strcmp(rules[i].r_filename,
+ rules[i + 1].r_filename) == 0)
+ continue;
+ eat(rules[i].r_filename, rules[i].r_linenum);
+ warning(_("same rule name in multiple files"));
+ eat(rules[i + 1].r_filename, rules[i + 1].r_linenum);
+ warning(_("same rule name in multiple files"));
+ for (j = i + 2; j < nrules; ++j) {
+ if (strcmp(rules[i].r_name,
+ rules[j].r_name) != 0)
+ break;
+ if (strcmp(rules[i].r_filename,
+ rules[j].r_filename) == 0)
+ continue;
+ if (strcmp(rules[i + 1].r_filename,
+ rules[j].r_filename) == 0)
+ continue;
+ break;
+ }
+ i = j - 1;
+ }
+ }
+ for (i = 0; i < nzones; ++i) {
+ zp = &zones[i];
+ zp->z_rules = NULL;
+ zp->z_nrules = 0;
+ }
+ for (base = 0; base < nrules; base = out) {
+ rp = &rules[base];
+ for (out = base + 1; out < nrules; ++out)
+ if (strcmp(rp->r_name, rules[out].r_name) != 0)
+ break;
+ for (i = 0; i < nzones; ++i) {
+ zp = &zones[i];
+ if (strcmp(zp->z_rule, rp->r_name) != 0)
+ continue;
+ zp->z_rules = rp;
+ zp->z_nrules = out - base;
+ }
+ }
+ for (i = 0; i < nzones; ++i) {
+ zp = &zones[i];
+ if (zp->z_nrules == 0) {
+ /*
+ ** Maybe we have a local standard time offset.
+ */
+ eat(zp->z_filename, zp->z_linenum);
+ zp->z_stdoff = getstdoff(zp->z_rule, &zp->z_isdst);
+ /*
+ ** Note, though, that if there's no rule,
+ ** a '%s' in the format is a bad thing.
+ */
+ if (zp->z_format_specifier == 's')
+ error("%s", _("%s in ruleless zone"));
+ }
+ }
+ if (errors)
+ exit(EXIT_FAILURE);
+}
+
+static void
+infile(const char *name)
+{
+ register FILE * fp;
+ register char ** fields;
+ register char * cp;
+ register const struct lookup * lp;
+ register int nfields;
+ register bool wantcont;
+ register lineno num;
+ char buf[BUFSIZ];
+
+ if (strcmp(name, "-") == 0) {
+ name = _("standard input");
+ fp = stdin;
+ } else if ((fp = fopen(name, "r")) == NULL) {
+ const char *e = strerror(errno);
+
+ fprintf(stderr, _("%s: Can't open %s: %s\n"),
+ progname, name, e);
+ exit(EXIT_FAILURE);
+ }
+ wantcont = false;
+ for (num = 1; ; ++num) {
+ eat(name, num);
+ if (fgets(buf, sizeof buf, fp) != buf)
+ break;
+ cp = strchr(buf, '\n');
+ if (cp == NULL) {
+ error(_("line too long"));
+ exit(EXIT_FAILURE);
+ }
+ *cp = '\0';
+ fields = getfields(buf);
+ nfields = 0;
+ while (fields[nfields] != NULL) {
+ static char nada;
+
+ if (strcmp(fields[nfields], "-") == 0)
+ fields[nfields] = &nada;
+ ++nfields;
+ }
+ if (nfields == 0) {
+ /* nothing to do */
+ } else if (wantcont) {
+ wantcont = inzcont(fields, nfields);
+ } else {
+ struct lookup const *line_codes
+ = name == leapsec ? leap_line_codes : zi_line_codes;
+ lp = byword(fields[0], line_codes);
+ if (lp == NULL)
+ error(_("input line of unknown type"));
+ else switch (lp->l_value) {
+ case LC_RULE:
+ inrule(fields, nfields);
+ wantcont = false;
+ break;
+ case LC_ZONE:
+ wantcont = inzone(fields, nfields);
+ break;
+ case LC_LINK:
+ inlink(fields, nfields);
+ wantcont = false;
+ break;
+ case LC_LEAP:
+ inleap(fields, nfields);
+ wantcont = false;
+ break;
+ default: /* "cannot happen" */
+ fprintf(stderr,
+_("%s: panic: Invalid l_value %d\n"),
+ progname, lp->l_value);
+ exit(EXIT_FAILURE);
+ }
+ }
+ free(fields);
+ }
+ close_file(fp, NULL, filename);
+ if (wantcont)
+ error(_("expected continuation line not found"));
+}
+
+/*
+** Convert a string of one of the forms
+** h -h hh:mm -hh:mm hh:mm:ss -hh:mm:ss
+** into a number of seconds.
+** A null string maps to zero.
+** Call error with errstring and return zero on errors.
+*/
+
+static zic_t
+gethms(char const *string, char const *errstring, bool signable)
+{
+ zic_t hh;
+ int sign, mm = 0, ss = 0;
+ char hhx, mmx, ssx, xr = '0', xs;
+ int tenths = 0;
+ bool ok = true;
+
+ if (string == NULL || *string == '\0')
+ return 0;
+ if (!signable)
+ sign = 1;
+ else if (*string == '-') {
+ sign = -1;
+ ++string;
+ } else sign = 1;
+ switch (sscanf(string,
+ "%"SCNdZIC"%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
+ &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs)) {
+ default: ok = false; break;
+ case 8:
+ ok = '0' <= xr && xr <= '9';
+ /* fallthrough */
+ case 7:
+ ok &= ssx == '.';
+ if (ok && noise)
+ warning(_("fractional seconds rejected by"
+ " pre-2018 versions of zic"));
+ /* fallthrough */
+ case 5: ok &= mmx == ':'; /* fallthrough */
+ case 3: ok &= hhx == ':'; /* fallthrough */
+ case 1: break;
+ }
+ if (!ok) {
+ error("%s", errstring);
+ return 0;
+ }
+ if (hh < 0 ||
+ mm < 0 || mm >= MINSPERHOUR ||
+ ss < 0 || ss > SECSPERMIN) {
+ error("%s", errstring);
+ return 0;
+ }
+ if (ZIC_MAX / SECSPERHOUR < hh) {
+ error(_("time overflow"));
+ return 0;
+ }
+ ss += 5 + ((ss ^ 1) & (xr == '0')) <= tenths; /* Round to even. */
+ 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(sign * hh * SECSPERHOUR,
+ sign * (mm * SECSPERMIN + ss));
+}
+
+static zic_t
+getstdoff(char *field, bool *isdst)
+{
+ int dst = -1;
+ zic_t stdoff;
+ size_t fieldlen = strlen(field);
+ if (fieldlen != 0) {
+ char *ep = field + fieldlen - 1;
+ switch (*ep) {
+ case 'd': dst = 1; *ep = '\0'; break;
+ case 's': dst = 0; *ep = '\0'; break;
+ }
+ }
+ stdoff = gethms(field, _("invalid saved time"), true);
+ *isdst = dst < 0 ? stdoff != 0 : dst;
+ return stdoff;
+}
+
+static void
+inrule(char **fields, int nfields)
+{
+ static struct rule r;
+
+ if (nfields != RULE_FIELDS) {
+ error(_("wrong number of fields on Rule line"));
+ return;
+ }
+ if (*fields[RF_NAME] == '\0') {
+ error(_("nameless rule"));
+ return;
+ }
+ r.r_filename = filename;
+ r.r_linenum = linenum;
+ r.r_stdoff = getstdoff(fields[RF_STDOFF], &r.r_isdst);
+ rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
+ fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
+ r.r_name = ecpyalloc(fields[RF_NAME]);
+ r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
+ if (max_abbrvar_len < strlen(r.r_abbrvar))
+ max_abbrvar_len = strlen(r.r_abbrvar);
+ rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
+ rules[nrules++] = r;
+}
+
+static bool
+inzone(char **fields, int nfields)
+{
+ register ptrdiff_t i;
+
+ if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) {
+ error(_("wrong number of fields on Zone line"));
+ return false;
+ }
+ if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0) {
+ error(
+_("\"Zone %s\" line and -l option are mutually exclusive"),
+ tzdefault);
+ return false;
+ }
+ if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) {
+ error(
+_("\"Zone %s\" line and -p option are mutually exclusive"),
+ TZDEFRULES);
+ return false;
+ }
+ for (i = 0; i < nzones; ++i)
+ if (zones[i].z_name != NULL &&
+ strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) {
+ error(_("duplicate zone name %s"
+ " (file \"%s\", line %"PRIdMAX")"),
+ fields[ZF_NAME],
+ zones[i].z_filename,
+ zones[i].z_linenum);
+ return false;
+ }
+ return inzsub(fields, nfields, false);
+}
+
+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 inzsub(fields, nfields, true);
+}
+
+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 bool hasuntil;
+
+ if (iscont) {
+ i_gmtoff = ZFC_GMTOFF;
+ i_rule = ZFC_RULE;
+ i_format = ZFC_FORMAT;
+ i_untilyear = ZFC_TILYEAR;
+ i_untilmonth = ZFC_TILMONTH;
+ i_untilday = ZFC_TILDAY;
+ i_untiltime = ZFC_TILTIME;
+ z.z_name = NULL;
+ } else if (!namecheck(fields[ZF_NAME]))
+ return false;
+ else {
+ i_gmtoff = ZF_GMTOFF;
+ i_rule = ZF_RULE;
+ i_format = ZF_FORMAT;
+ i_untilyear = ZF_TILYEAR;
+ i_untilmonth = ZF_TILMONTH;
+ i_untilday = ZF_TILDAY;
+ i_untiltime = ZF_TILTIME;
+ z.z_name = ecpyalloc(fields[ZF_NAME]);
+ }
+ z.z_filename = filename;
+ z.z_linenum = linenum;
+ z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"), true);
+ if ((cp = strchr(fields[i_format], '%')) != 0) {
+ if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
+ || strchr(fields[i_format], '/')) {
+ error(_("invalid abbreviation format"));
+ return false;
+ }
+ }
+ z.z_rule = ecpyalloc(fields[i_rule]);
+ 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;
+ if (hasuntil) {
+ z.z_untilrule.r_filename = filename;
+ z.z_untilrule.r_linenum = linenum;
+ rulesub(&z.z_untilrule,
+ fields[i_untilyear],
+ "only",
+ "",
+ (nfields > i_untilmonth) ?
+ fields[i_untilmonth] : "Jan",
+ (nfields > i_untilday) ? fields[i_untilday] : "1",
+ (nfields > i_untiltime) ? fields[i_untiltime] : "0");
+ z.z_untiltime = rpytime(&z.z_untilrule,
+ z.z_untilrule.r_loyear);
+ if (iscont && nzones > 0 &&
+ z.z_untiltime > min_time &&
+ z.z_untiltime < max_time &&
+ zones[nzones - 1].z_untiltime > min_time &&
+ zones[nzones - 1].z_untiltime < max_time &&
+ zones[nzones - 1].z_untiltime >= z.z_untiltime) {
+ error(_(
+"Zone continuation line end time is not after end time of previous line"
+ ));
+ return false;
+ }
+ }
+ zones = growalloc(zones, sizeof *zones, nzones, &nzones_alloc);
+ zones[nzones++] = z;
+ /*
+ ** If there was an UNTIL field on this line,
+ ** there's more information about the zone on the next line.
+ */
+ return hasuntil;
+}
+
+static void
+inleap(char **fields, int nfields)
+{
+ register const char * cp;
+ register const struct lookup * lp;
+ register zic_t i, j;
+ 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"));
+ return;
+ }
+ dayoff = 0;
+ cp = fields[LP_YEAR];
+ if (sscanf(cp, "%"SCNdZIC"%c", &year, &xs) != 1) {
+ /*
+ ** Leapin' Lizards!
+ */
+ error(_("invalid leaping year"));
+ return;
+ }
+ if (!leapseen || leapmaxyear < year)
+ leapmaxyear = year;
+ if (!leapseen || leapminyear > year)
+ leapminyear = year;
+ leapseen = true;
+ j = EPOCH_YEAR;
+ while (j != year) {
+ if (year > j) {
+ i = len_years[isleap(j)];
+ ++j;
+ } else {
+ --j;
+ i = -len_years[isleap(j)];
+ }
+ dayoff = oadd(dayoff, i);
+ }
+ if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) {
+ error(_("invalid month name"));
+ return;
+ }
+ month = lp->l_value;
+ j = TM_JANUARY;
+ while (j != month) {
+ i = len_months[isleap(year)][j];
+ dayoff = oadd(dayoff, i);
+ ++j;
+ }
+ cp = fields[LP_DAY];
+ 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, day - 1);
+ if (dayoff < min_time / SECSPERDAY) {
+ error(_("time too small"));
+ return;
+ }
+ if (dayoff > max_time / SECSPERDAY) {
+ error(_("time too large"));
+ return;
+ }
+ t = dayoff * SECSPERDAY;
+ tod = gethms(fields[LP_TIME], _("invalid time of day"), false);
+ cp = fields[LP_CORR];
+ {
+ register bool positive;
+ int count;
+
+ if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
+ positive = false;
+ count = 1;
+ } else if (strcmp(cp, "+") == 0) {
+ positive = true;
+ count = 1;
+ } else {
+ error(_("illegal CORRECTION field on Leap line"));
+ return;
+ }
+ if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) {
+ error(_(
+ "illegal Rolling/Stationary field on Leap line"
+ ));
+ return;
+ }
+ t = tadd(t, tod);
+ if (t < 0) {
+ error(_("leap second precedes Epoch"));
+ return;
+ }
+ leapadd(t, positive, lp->l_value, count);
+ }
+}
+
+static void
+inlink(char **fields, int nfields)
+{
+ struct link l;
+
+ if (nfields != LINK_FIELDS) {
+ error(_("wrong number of fields on Link line"));
+ return;
+ }
+ if (*fields[LF_FROM] == '\0') {
+ error(_("blank FROM field on Link line"));
+ return;
+ }
+ if (! 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 = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
+ links[nlinks++] = l;
+}
+
+static void
+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"));
+ return;
+ }
+ rp->r_month = lp->l_value;
+ 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;
+ *ep = '\0';
+ break;
+ case 'w': /* Wall */
+ 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;
+ *ep = '\0';
+ break;
+ }
+ }
+ rp->r_tod = gethms(dp, _("invalid time of day"), false);
+ free(dp);
+ /*
+ ** Year work.
+ */
+ cp = loyearp;
+ lp = byword(cp, begin_years);
+ rp->r_lowasnum = lp == NULL;
+ if (!rp->r_lowasnum) switch (lp->l_value) {
+ case YR_MINIMUM:
+ rp->r_loyear = ZIC_MIN;
+ break;
+ case YR_MAXIMUM:
+ rp->r_loyear = ZIC_MAX;
+ break;
+ default: /* "cannot happen" */
+ fprintf(stderr,
+ _("%s: panic: Invalid l_value %d\n"),
+ progname, lp->l_value);
+ exit(EXIT_FAILURE);
+ } else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_loyear, &xs) != 1) {
+ error(_("invalid starting year"));
+ return;
+ }
+ cp = hiyearp;
+ lp = byword(cp, end_years);
+ rp->r_hiwasnum = lp == NULL;
+ if (!rp->r_hiwasnum) switch (lp->l_value) {
+ case YR_MINIMUM:
+ rp->r_hiyear = ZIC_MIN;
+ break;
+ case YR_MAXIMUM:
+ rp->r_hiyear = ZIC_MAX;
+ break;
+ case YR_ONLY:
+ rp->r_hiyear = rp->r_loyear;
+ break;
+ default: /* "cannot happen" */
+ fprintf(stderr,
+ _("%s: panic: Invalid l_value %d\n"),
+ progname, lp->l_value);
+ exit(EXIT_FAILURE);
+ } else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_hiyear, &xs) != 1) {
+ error(_("invalid ending year"));
+ return;
+ }
+ if (rp->r_loyear > rp->r_hiyear) {
+ error(_("starting year greater than ending year"));
+ return;
+ }
+ if (*typep == '\0')
+ rp->r_yrtype = NULL;
+ else {
+ if (rp->r_loyear == rp->r_hiyear) {
+ error(_("typed single year"));
+ return;
+ }
+ warning(_("year type \"%s\" is obsolete; use \"-\" instead"),
+ typep);
+ rp->r_yrtype = ecpyalloc(typep);
+ }
+ /*
+ ** Day work.
+ ** Accept things such as:
+ ** 1
+ ** lastSunday
+ ** last-Sunday (undocumented; warn about this)
+ ** Sun<=20
+ ** Sun>=7
+ */
+ dp = ecpyalloc(dayp);
+ if ((lp = byword(dp, lasts)) != NULL) {
+ rp->r_dycode = DC_DOWLEQ;
+ rp->r_wday = lp->l_value;
+ rp->r_dayofmonth = len_months[1][rp->r_month];
+ } else {
+ if ((ep = strchr(dp, '<')) != 0)
+ rp->r_dycode = DC_DOWLEQ;
+ else if ((ep = strchr(dp, '>')) != 0)
+ rp->r_dycode = DC_DOWGEQ;
+ else {
+ ep = dp;
+ rp->r_dycode = DC_DOM;
+ }
+ if (rp->r_dycode != DC_DOM) {
+ *ep++ = 0;
+ if (*ep++ != '=') {
+ error(_("invalid day of month"));
+ free(dp);
+ return;
+ }
+ if ((lp = byword(dp, wday_names)) == NULL) {
+ error(_("invalid weekday name"));
+ free(dp);
+ return;
+ }
+ rp->r_wday = lp->l_value;
+ }
+ 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"));
+ free(dp);
+ return;
+ }
+ }
+ free(dp);
+}
+
+static void
+convert(const int_fast32_t val, char *const buf)
+{
+ register int i;
+ register int shift;
+ unsigned char *const b = (unsigned char *) buf;
+
+ for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
+ b[i] = val >> shift;
+}
+
+static void
+convert64(const zic_t val, char *const buf)
+{
+ register int i;
+ register int shift;
+ unsigned char *const b = (unsigned char *) buf;
+
+ for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
+ b[i] = val >> shift;
+}
+
+static void
+puttzcode(const int_fast32_t val, FILE *const fp)
+{
+ char buf[4];
+
+ convert(val, buf);
+ fwrite(buf, sizeof buf, 1, fp);
+}
+
+static void
+puttzcode64(const zic_t val, FILE *const fp)
+{
+ char buf[8];
+
+ convert64(val, buf);
+ fwrite(buf, sizeof buf, 1, fp);
+}
+
+static int
+atcomp(const void *avp, const void *bvp)
+{
+ const zic_t a = ((const struct attype *) avp)->at;
+ const zic_t b = ((const struct attype *) bvp)->at;
+
+ return (a < b) ? -1 : (a > b);
+}
+
+static bool
+is32(const zic_t x)
+{
+ return INT32_MIN <= x && x <= INT32_MAX;
+}
+
+static void
+writezone(const char *const name, const char *const string, char version)
+{
+ register FILE * fp;
+ register ptrdiff_t i, j;
+ register int leapcnt32, leapi32;
+ register ptrdiff_t timecnt32, timei32;
+ register int pass;
+ static const struct tzhead tzh0;
+ static struct tzhead tzh;
+ bool dir_checked = false;
+ zic_t one = 1;
+ zic_t y2038_boundary = one << 31;
+ ptrdiff_t 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)
+ qsort(attypes, timecnt, sizeof *attypes, atcomp);
+ /*
+ ** Optimize.
+ */
+ {
+ ptrdiff_t fromi, toi;
+
+ toi = 0;
+ fromi = 0;
+ while (fromi < timecnt && attypes[fromi].at < early_time)
+ ++fromi;
+ for ( ; fromi < timecnt; ++fromi) {
+ if (toi > 1 && ((attypes[fromi].at +
+ gmtoffs[attypes[toi - 1].type]) <=
+ (attypes[toi - 1].at +
+ gmtoffs[attypes[toi - 2].type]))) {
+ attypes[toi - 1].type =
+ attypes[fromi].type;
+ continue;
+ }
+ if (toi == 0
+ || attypes[fromi].dontmerge
+ || attypes[toi - 1].type != attypes[fromi].type)
+ attypes[toi++] = attypes[fromi];
+ }
+ timecnt = toi;
+ }
+
+ if (noise && timecnt > 1200) {
+ if (timecnt > TZ_MAX_TIMES)
+ warning(_("reference clients mishandle"
+ " more than %d transition times"),
+ TZ_MAX_TIMES);
+ else
+ warning(_("pre-2014 clients may mishandle"
+ " more than 1200 transition times"));
+ }
+ /*
+ ** Transfer.
+ */
+ for (i = 0; i < timecnt; ++i) {
+ 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.
+ */
+ for (i = 0; i < timecnt; ++i) {
+ j = leapcnt;
+ while (--j >= 0)
+ if (ats[i] > trans[j] - corr[j]) {
+ ats[i] = tadd(ats[i], corr[j]);
+ break;
+ }
+ }
+ /*
+ ** Figure out 32-bit-limited starts and counts.
+ */
+ timecnt32 = timecnt;
+ timei32 = 0;
+ leapcnt32 = leapcnt;
+ leapi32 = 0;
+ while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
+ --timecnt32;
+ while (timecnt32 > 0 && !is32(ats[timei32])) {
+ --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])) {
+ --leapcnt32;
+ ++leapi32;
+ }
+ /*
+ ** Remove old file, if any, to snap links.
+ */
+ if (remove(name) == 0)
+ dir_checked = true;
+ else if (errno != ENOENT) {
+ const char *e = strerror(errno);
+
+ fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
+ progname, directory, name, e);
+ exit(EXIT_FAILURE);
+ }
+ fp = fopen(name, "wb");
+ if (!fp) {
+ int fopen_errno = errno;
+ if (fopen_errno == ENOENT && !dir_checked) {
+ mkdirs(name, true);
+ fp = fopen(name, "wb");
+ fopen_errno = errno;
+ }
+ if (!fp) {
+ fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
+ progname, directory, name, strerror(fopen_errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+ for (pass = 1; pass <= 2; ++pass) {
+ register ptrdiff_t thistimei, thistimecnt, thistimelim;
+ register int thisleapi, thisleapcnt, thisleaplim;
+ int writetype[TZ_MAX_TYPES];
+ int typemap[TZ_MAX_TYPES];
+ register int thistypecnt;
+ char thischars[TZ_MAX_CHARS];
+ int thischarcnt;
+ bool toomanytimes;
+ int indmap[TZ_MAX_CHARS];
+
+ if (pass == 1) {
+ thistimei = timei32;
+ thistimecnt = timecnt32;
+ toomanytimes = thistimecnt >> 31 >> 1 != 0;
+ thisleapi = leapi32;
+ thisleapcnt = leapcnt32;
+ } else {
+ thistimei = 0;
+ thistimecnt = timecnt;
+ toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
+ thisleapi = 0;
+ thisleapcnt = leapcnt;
+ }
+ if (toomanytimes)
+ error(_("too many transition times"));
+ thistimelim = thistimei + thistimecnt;
+ thisleaplim = thisleapi + thisleapcnt;
+ for (i = 0; i < typecnt; ++i)
+ writetype[i] = thistimecnt == timecnt;
+ if (thistimecnt == 0) {
+ /*
+ ** No transition times fall in the current
+ ** (32- or 64-bit) window.
+ */
+ if (typecnt != 0)
+ writetype[typecnt - 1] = true;
+ } else {
+ for (i = thistimei - 1; i < thistimelim; ++i)
+ if (i >= 0)
+ writetype[types[i]] = true;
+ /*
+ ** For America/Godthab and Antarctica/Palmer
+ */
+ if (thistimei == 0)
+ writetype[0] = true;
+ }
+#ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
+ /*
+ ** For some pre-2011 systems: if the last-to-be-written
+ ** standard (or daylight) type has an offset different from the
+ ** most recently used offset,
+ ** append an (unused) copy of the most recently used type
+ ** (to help get global "altzone" and "timezone" variables
+ ** set correctly).
+ */
+ {
+ register int mrudst, mrustd, hidst, histd, type;
+
+ hidst = histd = mrudst = mrustd = -1;
+ for (i = thistimei; i < thistimelim; ++i)
+ if (isdsts[types[i]])
+ mrudst = types[i];
+ else mrustd = types[i];
+ for (i = 0; i < typecnt; ++i)
+ if (writetype[i]) {
+ if (isdsts[i])
+ hidst = i;
+ else histd = i;
+ }
+ if (hidst >= 0 && mrudst >= 0 && hidst != mrudst &&
+ gmtoffs[hidst] != gmtoffs[mrudst]) {
+ isdsts[mrudst] = -1;
+ type = addtype(gmtoffs[mrudst],
+ &chars[abbrinds[mrudst]],
+ true,
+ ttisstds[mrudst],
+ ttisgmts[mrudst]);
+ isdsts[mrudst] = 1;
+ writetype[type] = true;
+ }
+ if (histd >= 0 && mrustd >= 0 && histd != mrustd &&
+ gmtoffs[histd] != gmtoffs[mrustd]) {
+ isdsts[mrustd] = -1;
+ type = addtype(gmtoffs[mrustd],
+ &chars[abbrinds[mrustd]],
+ false,
+ ttisstds[mrustd],
+ ttisgmts[mrustd]);
+ isdsts[mrustd] = 0;
+ writetype[type] = true;
+ }
+ }
+#endif /* !defined LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */
+ thistypecnt = 0;
+ for (i = 0; i < typecnt; ++i)
+ typemap[i] = writetype[i] ? thistypecnt++ : -1;
+ for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
+ indmap[i] = -1;
+ thischarcnt = 0;
+ for (i = 0; i < typecnt; ++i) {
+ register char * thisabbr;
+
+ if (!writetype[i])
+ continue;
+ if (indmap[abbrinds[i]] >= 0)
+ continue;
+ thisabbr = &chars[abbrinds[i]];
+ for (j = 0; j < thischarcnt; ++j)
+ if (strcmp(&thischars[j], thisabbr) == 0)
+ break;
+ if (j == thischarcnt) {
+ strcpy(&thischars[thischarcnt], thisabbr);
+ thischarcnt += strlen(thisabbr) + 1;
+ }
+ indmap[abbrinds[i]] = j;
+ }
+#define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp)
+ tzh = tzh0;
+ memcpy(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);
+ DO(tzh_ttisgmtcnt);
+ DO(tzh_ttisstdcnt);
+ DO(tzh_leapcnt);
+ DO(tzh_timecnt);
+ DO(tzh_typecnt);
+ DO(tzh_charcnt);
+#undef DO
+ for (i = thistimei; i < thistimelim; ++i)
+ if (pass == 1)
+ /*
+ ** 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]];
+ fwrite(&uc, sizeof uc, 1, fp);
+ }
+ for (i = 0; i < typecnt; ++i)
+ if (writetype[i]) {
+ puttzcode(gmtoffs[i], fp);
+ putc(isdsts[i], fp);
+ putc((unsigned char) indmap[abbrinds[i]], fp);
+ }
+ if (thischarcnt != 0)
+ fwrite(thischars, sizeof thischars[0],
+ thischarcnt, fp);
+ for (i = thisleapi; i < thisleaplim; ++i) {
+ register zic_t todo;
+
+ if (roll[i]) {
+ if (timecnt == 0 || trans[i] < ats[0]) {
+ j = 0;
+ while (isdsts[j])
+ if (++j >= typecnt) {
+ j = 0;
+ break;
+ }
+ } else {
+ j = 1;
+ while (j < timecnt &&
+ trans[i] >= ats[j])
+ ++j;
+ j = types[j - 1];
+ }
+ todo = tadd(trans[i], -gmtoffs[j]);
+ } else todo = trans[i];
+ if (pass == 1)
+ puttzcode(todo, fp);
+ else puttzcode64(todo, fp);
+ puttzcode(corr[i], fp);
+ }
+ for (i = 0; i < typecnt; ++i)
+ if (writetype[i])
+ putc(ttisstds[i], fp);
+ for (i = 0; i < typecnt; ++i)
+ if (writetype[i])
+ putc(ttisgmts[i], fp);
+ }
+ fprintf(fp, "\n%s\n", string);
+ close_file(fp, directory, name);
+ free(ats);
+}
+
+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 UT 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,
+ bool isdst, zic_t stdoff, bool doquotes)
+{
+ register char * cp;
+ register char * slashp;
+ register size_t len;
+ char const *format = zp->z_format;
+
+ slashp = strchr(format, '/');
+ if (slashp == NULL) {
+ 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 (isdst) {
+ strcpy(abbr, slashp + 1);
+ } else {
+ memcpy(abbr, format, slashp - format);
+ abbr[slashp - format] = '\0';
+ }
+ len = strlen(abbr);
+ if (!doquotes)
+ return len;
+ for (cp = abbr; is_alpha(*cp); cp++)
+ continue;
+ if (len > 0 && *cp == '\0')
+ return len;
+ abbr[len + 2] = '\0';
+ abbr[len + 1] = '>';
+ memmove(abbr + 1, abbr, len);
+ abbr[0] = '<';
+ return len + 2;
+}
+
+static void
+updateminmax(const zic_t x)
+{
+ if (min_year > x)
+ min_year = x;
+ if (max_year < x)
+ max_year = x;
+}
+
+static int
+stringoffset(char *result, zic_t offset)
+{
+ register int hours;
+ register int minutes;
+ register int seconds;
+ bool negative = offset < 0;
+ int len = negative;
+
+ if (negative) {
+ offset = -offset;
+ result[0] = '-';
+ }
+ seconds = offset % SECSPERMIN;
+ offset /= SECSPERMIN;
+ minutes = offset % MINSPERHOUR;
+ offset /= MINSPERHOUR;
+ hours = offset;
+ if (hours >= HOURSPERDAY * DAYSPERWEEK) {
+ result[0] = '\0';
+ return 0;
+ }
+ len += sprintf(result + len, "%d", hours);
+ if (minutes != 0 || seconds != 0) {
+ len += sprintf(result + len, ":%02d", minutes);
+ if (seconds != 0)
+ len += sprintf(result + len, ":%02d", seconds);
+ }
+ return len;
+}
+
+static int
+stringrule(char *result, const struct rule *const rp, const zic_t dstoff,
+ const zic_t gmtoff)
+{
+ register zic_t tod = rp->r_tod;
+ register int compat = 0;
+
+ if (rp->r_dycode == DC_DOM) {
+ register int month, total;
+
+ if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
+ return -1;
+ total = 0;
+ for (month = 0; month < rp->r_month; ++month)
+ total += len_months[0][month];
+ /* 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) {
+ 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 {
+ wdayoff = rp->r_dayofmonth % DAYSPERWEEK;
+ if (wdayoff)
+ compat = 2013;
+ wday -= wdayoff;
+ tod += wdayoff * SECSPERDAY;
+ week = rp->r_dayofmonth / DAYSPERWEEK;
+ }
+ } else return -1; /* "cannot happen" */
+ if (wday < 0)
+ wday += DAYSPERWEEK;
+ result += sprintf(result, "M%d.%d.%d",
+ rp->r_month + 1, week, wday);
+ }
+ if (rp->r_todisgmt)
+ tod += gmtoff;
+ if (rp->r_todisstd && !rp->r_isdst)
+ tod += dstoff;
+ if (tod != 2 * SECSPERMIN * MINSPERHOUR) {
+ *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 compat;
+}
+
+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, struct zone const *zpfirst, ptrdiff_t zonecount)
+{
+ register const struct zone * zp;
+ register struct rule * rp;
+ register struct rule * stdrp;
+ register struct rule * dstrp;
+ register ptrdiff_t 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;
+ stdrp = dstrp = NULL;
+ for (i = 0; i < zp->z_nrules; ++i) {
+ rp = &zp->z_rules[i];
+ if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
+ continue;
+ if (rp->r_yrtype != NULL)
+ continue;
+ if (!rp->r_isdst) {
+ if (stdrp == NULL)
+ stdrp = rp;
+ else return -1;
+ } else {
+ if (dstrp == NULL)
+ dstrp = rp;
+ else return -1;
+ }
+ }
+ if (stdrp == NULL && dstrp == NULL) {
+ /*
+ ** There are no rules running through "max".
+ ** 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 (!rp->r_isdst && rule_cmp(stdabbrrp, rp) < 0)
+ stdabbrrp = rp;
+ if (rule_cmp(stdrp, rp) < 0)
+ stdrp = rp;
+ }
+ /*
+ ** Horrid special case: if year is 2037,
+ ** presume this is a zone handled on a year-by-year basis;
+ ** do not try to apply a rule to the zone.
+ */
+ if (stdrp != NULL && stdrp->r_hiyear == 2037)
+ return YEAR_BY_YEAR_ZONE;
+
+ if (stdrp != NULL && stdrp->r_isdst) {
+ /* 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_isdst = stdrp->r_isdst;
+ 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_isdst = 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_isdst))
+ return -1;
+ abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
+ len = doabbr(result, zp, abbrvar, false, 0, true);
+ offsetlen = stringoffset(result + len, -zp->z_gmtoff);
+ if (! offsetlen) {
+ result[0] = '\0';
+ return -1;
+ }
+ len += offsetlen;
+ if (dstrp == NULL)
+ return compat;
+ len += doabbr(result + len, zp, dstrp->r_abbrvar,
+ dstrp->r_isdst, 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 -1;
+ }
+ 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 -1;
+ }
+ if (compat < c)
+ compat = c;
+ return compat;
+}
+
+static void
+outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
+{
+ register const struct zone * zp;
+ register struct rule * rp;
+ register ptrdiff_t i, j;
+ register bool usestart, useuntil;
+ register zic_t starttime, untiltime;
+ 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;
+ register char * envvar;
+ register int max_abbr_len;
+ register int max_envvar_len;
+ register bool prodstic; /* all rules are min to max */
+ register int compat;
+ register bool do_extend;
+ register char version;
+ ptrdiff_t lastatmax = -1;
+ zic_t one = 1;
+ zic_t y2038_boundary = one << 31;
+ zic_t max_year0;
+
+ max_abbr_len = 2 + max_format_len + max_abbrvar_len;
+ max_envvar_len = 2 * max_abbr_len + 5 * 9;
+ startbuf = emalloc(max_abbr_len + 1);
+ ab = emalloc(max_abbr_len + 1);
+ envvar = emalloc(max_envvar_len + 1);
+ INITIALIZE(untiltime);
+ INITIALIZE(starttime);
+ /*
+ ** Now. . .finally. . .generate some useful data!
+ */
+ timecnt = 0;
+ typecnt = 0;
+ charcnt = 0;
+ prodstic = zonecount == 1;
+ /*
+ ** Thanks to Earl Chew
+ ** for noting the need to unconditionally initialize startttisstd.
+ */
+ startttisstd = false;
+ startttisgmt = false;
+ min_year = max_year = EPOCH_YEAR;
+ if (leapseen) {
+ updateminmax(leapminyear);
+ updateminmax(leapmaxyear + (leapmaxyear < ZIC_MAX));
+ }
+ for (i = 0; i < zonecount; ++i) {
+ zp = &zpfirst[i];
+ if (i < zonecount - 1)
+ updateminmax(zp->z_untilrule.r_loyear);
+ for (j = 0; j < zp->z_nrules; ++j) {
+ rp = &zp->z_rules[j];
+ if (rp->r_lowasnum)
+ updateminmax(rp->r_loyear);
+ if (rp->r_hiwasnum)
+ updateminmax(rp->r_hiyear);
+ if (rp->r_lowasnum || rp->r_hiwasnum)
+ prodstic = false;
+ }
+ }
+ /*
+ ** Generate lots of data if a rule can't cover all future times.
+ */
+ 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 (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,
+ ** we only need one cycle to define the zone.
+ */
+ if (prodstic) {
+ min_year = 1900;
+ max_year = min_year + years_of_observations;
+ }
+ }
+ /*
+ ** For the benefit of older systems,
+ ** generate data from 1900 through 2038.
+ */
+ if (min_year > 1900)
+ min_year = 1900;
+ max_year0 = max_year;
+ if (max_year < 2038)
+ max_year = 2038;
+ for (i = 0; i < zonecount; ++i) {
+ /*
+ ** A guess that may well be corrected later.
+ */
+ stdoff = 0;
+ zp = &zpfirst[i];
+ usestart = i > 0 && (zp - 1)->z_untiltime > early_time;
+ useuntil = i < (zonecount - 1);
+ if (useuntil && zp->z_untiltime <= early_time)
+ continue;
+ gmtoff = zp->z_gmtoff;
+ eat(zp->z_filename, zp->z_linenum);
+ *startbuf = '\0';
+ startoff = zp->z_gmtoff;
+ if (zp->z_nrules == 0) {
+ stdoff = zp->z_stdoff;
+ doabbr(startbuf, zp, NULL, zp->z_isdst, stdoff, false);
+ type = addtype(oadd(zp->z_gmtoff, stdoff),
+ startbuf, zp->z_isdst, startttisstd,
+ startttisgmt);
+ if (usestart) {
+ addtt(starttime, 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;
+ /*
+ ** Mark which rules to do in the current year.
+ ** For those to do, calculate rpytime(rp, year);
+ */
+ for (j = 0; j < zp->z_nrules; ++j) {
+ rp = &zp->z_rules[j];
+ eats(zp->z_filename, zp->z_linenum,
+ rp->r_filename, rp->r_linenum);
+ rp->r_todo = year >= rp->r_loyear &&
+ year <= rp->r_hiyear &&
+ yearistype(year, rp->r_yrtype);
+ if (rp->r_todo) {
+ rp->r_temp = rpytime(rp, year);
+ rp->r_todo
+ = (rp->r_temp < y2038_boundary
+ || year <= max_year0);
+ }
+ }
+ for ( ; ; ) {
+ register ptrdiff_t k;
+ register zic_t jtime, ktime;
+ register zic_t offset;
+
+ INITIALIZE(ktime);
+ if (useuntil) {
+ /*
+ ** Turn untiltime into UT
+ ** assuming the current gmtoff and
+ ** stdoff values.
+ */
+ untiltime = zp->z_untiltime;
+ if (!zp->z_untilrule.r_todisgmt)
+ untiltime = tadd(untiltime,
+ -gmtoff);
+ if (!zp->z_untilrule.r_todisstd)
+ untiltime = tadd(untiltime,
+ -stdoff);
+ }
+ /*
+ ** Find the rule (of those to do, if any)
+ ** that takes effect earliest in the year.
+ */
+ k = -1;
+ for (j = 0; j < zp->z_nrules; ++j) {
+ rp = &zp->z_rules[j];
+ if (!rp->r_todo)
+ continue;
+ eats(zp->z_filename, zp->z_linenum,
+ rp->r_filename, rp->r_linenum);
+ offset = rp->r_todisgmt ? 0 : gmtoff;
+ if (!rp->r_todisstd)
+ offset = oadd(offset, stdoff);
+ jtime = rp->r_temp;
+ if (jtime == min_time ||
+ jtime == max_time)
+ continue;
+ jtime = tadd(jtime, -offset);
+ if (k < 0 || jtime < ktime) {
+ k = j;
+ ktime = jtime;
+ } 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;
+ if (useuntil && ktime >= untiltime)
+ break;
+ stdoff = rp->r_stdoff;
+ if (usestart && ktime == starttime)
+ usestart = false;
+ if (usestart) {
+ if (ktime < starttime) {
+ startoff = oadd(zp->z_gmtoff,
+ stdoff);
+ doabbr(startbuf, zp,
+ rp->r_abbrvar,
+ rp->r_isdst,
+ rp->r_stdoff,
+ false);
+ continue;
+ }
+ if (*startbuf == '\0' &&
+ startoff == oadd(zp->z_gmtoff,
+ stdoff)) {
+ doabbr(startbuf,
+ zp,
+ rp->r_abbrvar,
+ rp->r_isdst,
+ rp->r_stdoff,
+ false);
+ }
+ }
+ eats(zp->z_filename, zp->z_linenum,
+ rp->r_filename, rp->r_linenum);
+ doabbr(ab, zp, rp->r_abbrvar,
+ rp->r_isdst, rp->r_stdoff, false);
+ offset = oadd(zp->z_gmtoff, rp->r_stdoff);
+ type = addtype(offset, ab, rp->r_isdst,
+ rp->r_todisstd, rp->r_todisgmt);
+ if (rp->r_hiyear == ZIC_MAX
+ && ! (0 <= lastatmax
+ && ktime < attypes[lastatmax].at))
+ lastatmax = timecnt;
+ addtt(ktime, type);
+ }
+ }
+ if (usestart) {
+ if (*startbuf == '\0' &&
+ zp->z_format != NULL &&
+ strchr(zp->z_format, '%') == NULL &&
+ strchr(zp->z_format, '/') == NULL)
+ 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"));
+ else addtt(starttime,
+ addtype(startoff, startbuf,
+ startoff != zp->z_gmtoff,
+ startttisstd,
+ startttisgmt));
+ }
+ /*
+ ** Now we may get to set starttime for the next zone line.
+ */
+ if (useuntil) {
+ startttisstd = zp->z_untilrule.r_todisstd;
+ startttisgmt = zp->z_untilrule.r_todisgmt;
+ starttime = zp->z_untiltime;
+ if (!startttisstd)
+ starttime = tadd(starttime, -stdoff);
+ if (!startttisgmt)
+ starttime = tadd(starttime, -gmtoff);
+ }
+ }
+ if (0 <= lastatmax)
+ attypes[lastatmax].dontmerge = true;
+ 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)) {
+ addtt(rpytime(&xr, max_year + 1), typecnt-1);
+ attypes[timecnt - 1].dontmerge = true;
+ }
+ }
+ writezone(zpfirst->z_name, envvar, version);
+ free(startbuf);
+ free(ab);
+ free(envvar);
+}
+
+static void
+addtt(zic_t starttime, int type)
+{
+ 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)
+ strcpy(chars, &chars[abbrinds[type]]);
+ abbrinds[0] = 0;
+ charcnt = strlen(chars) + 1;
+ typecnt = 1;
+ timecnt = 0;
+ type = 0;
+ }
+ attypes = growalloc(attypes, sizeof *attypes, timecnt, &timecnt_alloc);
+ attypes[timecnt].at = starttime;
+ attypes[timecnt].dontmerge = false;
+ attypes[timecnt].type = type;
+ ++timecnt;
+}
+
+static int
+addtype(zic_t gmtoff, char const *abbr, bool isdst, bool ttisstd, bool ttisgmt)
+{
+ register int i, j;
+
+ /*
+ ** See if there's already an entry for this zone type.
+ ** If so, just return its index.
+ */
+ for (i = 0; i < typecnt; ++i) {
+ if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
+ strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
+ ttisstd == ttisstds[i] &&
+ ttisgmt == ttisgmts[i])
+ return i;
+ }
+ /*
+ ** There isn't one; add a new one, unless there are already too
+ ** many.
+ */
+ if (typecnt >= TZ_MAX_TYPES) {
+ error(_("too many local time types"));
+ exit(EXIT_FAILURE);
+ }
+ if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) {
+ error(_("UT offset out of range"));
+ exit(EXIT_FAILURE);
+ }
+ gmtoffs[i] = gmtoff;
+ isdsts[i] = isdst;
+ ttisstds[i] = ttisstd;
+ ttisgmts[i] = ttisgmt;
+
+ for (j = 0; j < charcnt; ++j)
+ if (strcmp(&chars[j], abbr) == 0)
+ break;
+ if (j == charcnt)
+ newabbr(abbr);
+ abbrinds[i] = j;
+ ++typecnt;
+ return i;
+}
+
+static void
+leapadd(zic_t t, bool positive, int rolling, int count)
+{
+ register int i, j;
+
+ if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) {
+ error(_("too many leap seconds"));
+ exit(EXIT_FAILURE);
+ }
+ for (i = 0; i < leapcnt; ++i)
+ if (t <= trans[i])
+ break;
+ do {
+ for (j = leapcnt; j > i; --j) {
+ trans[j] = trans[j - 1];
+ corr[j] = corr[j - 1];
+ roll[j] = roll[j - 1];
+ }
+ trans[i] = t;
+ corr[i] = positive ? 1 : -count;
+ roll[i] = rolling;
+ ++leapcnt;
+ } while (positive && --count != 0);
+}
+
+static void
+adjleap(void)
+{
+ register int i;
+ register zic_t last = 0;
+ register zic_t prevtrans = 0;
+
+ /*
+ ** propagate leap seconds forward
+ */
+ for (i = 0; i < leapcnt; ++i) {
+ if (trans[i] - prevtrans < 28 * SECSPERDAY) {
+ error(_("Leap seconds too close together"));
+ exit(EXIT_FAILURE);
+ }
+ prevtrans = trans[i];
+ trans[i] = tadd(trans[i], last);
+ last = corr[i] += last;
+ }
+}
+
+static char *
+shellquote(char *b, char const *s)
+{
+ *b++ = '\'';
+ while (*s) {
+ if (*s == '\'')
+ *b++ = '\'', *b++ = '\\', *b++ = '\'';
+ *b++ = *s++;
+ }
+ *b++ = '\'';
+ return b;
+}
+
+static bool
+yearistype(zic_t year, const char *type)
+{
+ char *buf;
+ char *b;
+ int result;
+
+ if (type == NULL || *type == '\0')
+ return true;
+ buf = emalloc(1 + 4 * strlen(yitcommand) + 2
+ + INT_STRLEN_MAXIMUM(zic_t) + 2 + 4 * strlen(type) + 2);
+ b = shellquote(buf, yitcommand);
+ *b++ = ' ';
+ b += sprintf(b, "%"PRIdZIC, year);
+ *b++ = ' ';
+ b = shellquote(b, type);
+ *b = '\0';
+ result = system(buf);
+ if (WIFEXITED(result)) {
+ int status = WEXITSTATUS(result);
+ if (status <= 1) {
+ free(buf);
+ return status == 0;
+ }
+ }
+ error(_("Wild result from command execution"));
+ fprintf(stderr, _("%s: command was '%s', result was %d\n"),
+ progname, buf, result);
+ exit(EXIT_FAILURE);
+}
+
+/* Is A a space character in the C locale? */
+static bool
+is_space(char 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 bool
+ciequal(register const char *ap, register const char *bp)
+{
+ while (lowerit(*ap) == lowerit(*bp++))
+ if (*ap++ == '\0')
+ return true;
+ return false;
+}
+
+static bool
+itsabbr(register const char *abbr, register const char *word)
+{
+ if (lowerit(*abbr) != lowerit(*word))
+ return false;
+ ++word;
+ while (*++abbr != '\0')
+ do {
+ if (*word == '\0')
+ return false;
+ } while (lowerit(*word++) != lowerit(*abbr));
+ return true;
+}
+
+/* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */
+
+static bool
+ciprefix(char const *abbr, char const *word)
+{
+ do
+ if (!*abbr)
+ return true;
+ while (lowerit(*abbr++) == lowerit(*word++));
+
+ return false;
+}
+
+static const struct lookup *
+byword(const char *word, const struct lookup *table)
+{
+ register const struct lookup * foundlp;
+ register const struct lookup * lp;
+
+ if (word == NULL || table == NULL)
+ return NULL;
+
+ /* If TABLE is LASTS and the word starts with "last" followed
+ by a non-'-', skip the "last" and look in WDAY_NAMES instead.
+ Warn about any usage of the undocumented prefix "last-". */
+ if (table == lasts && ciprefix("last", word) && word[4]) {
+ if (word[4] == '-')
+ warning(_("\"%s\" is undocumented; use \"last%s\" instead"),
+ word, word + 5);
+ else {
+ word += 4;
+ table = wday_names;
+ }
+ }
+
+ /*
+ ** Look for exact match.
+ */
+ for (lp = table; lp->l_word != NULL; ++lp)
+ if (ciequal(word, lp->l_word))
+ return lp;
+ /*
+ ** Look for inexact match.
+ */
+ foundlp = NULL;
+ for (lp = table; lp->l_word != NULL; ++lp)
+ if (ciprefix(word, lp->l_word)) {
+ if (foundlp == NULL)
+ foundlp = lp;
+ else return NULL; /* multiple inexact matches */
+ }
+
+ /* Warn about any backward-compatibility issue with pre-2017c zic. */
+ if (foundlp) {
+ bool pre_2017c_match = false;
+ for (lp = table; lp->l_word; lp++)
+ if (itsabbr(word, lp->l_word)) {
+ if (pre_2017c_match) {
+ warning(_("\"%s\" is ambiguous in pre-2017c zic"), word);
+ break;
+ }
+ pre_2017c_match = true;
+ }
+ }
+
+ return foundlp;
+}
+
+static char **
+getfields(register char *cp)
+{
+ register char * dp;
+ register char ** array;
+ register int nsubs;
+
+ if (cp == NULL)
+ return NULL;
+ array = emalloc(size_product(strlen(cp) + 1, sizeof *array));
+ nsubs = 0;
+ for ( ; ; ) {
+ while (is_space(*cp))
+ ++cp;
+ if (*cp == '\0' || *cp == '#')
+ break;
+ array[nsubs++] = dp = cp;
+ do {
+ if ((*dp = *cp++) != '"')
+ ++dp;
+ else while ((*dp = *cp++) != '"')
+ if (*dp != '\0')
+ ++dp;
+ else {
+ error(_("Odd number of quotation marks"));
+ exit(EXIT_FAILURE);
+ }
+ } while (*cp && *cp != '#' && !is_space(*cp));
+ if (is_space(*cp))
+ ++cp;
+ *dp = '\0';
+ }
+ array[nsubs] = NULL;
+ return array;
+}
+
+static _Noreturn void
+time_overflow(void)
+{
+ error(_("time overflow"));
+ exit(EXIT_FAILURE);
+}
+
+static ATTRIBUTE_PURE zic_t
+oadd(zic_t t1, zic_t t2)
+{
+ 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.
+*/
+
+static zic_t
+rpytime(const struct rule *rp, zic_t wantedy)
+{
+ register int m, i;
+ register zic_t dayoff; /* with a nod to Margaret O. */
+ register zic_t t, y;
+
+ if (wantedy == ZIC_MIN)
+ return min_time;
+ if (wantedy == ZIC_MAX)
+ return max_time;
+ dayoff = 0;
+ m = TM_JANUARY;
+ y = EPOCH_YEAR;
+ while (wantedy != y) {
+ if (wantedy > y) {
+ i = len_years[isleap(y)];
+ ++y;
+ } else {
+ --y;
+ i = -len_years[isleap(y)];
+ }
+ dayoff = oadd(dayoff, i);
+ }
+ while (m != rp->r_month) {
+ i = len_months[isleap(y)][m];
+ dayoff = oadd(dayoff, i);
+ ++m;
+ }
+ i = rp->r_dayofmonth;
+ if (m == TM_FEBRUARY && i == 29 && !isleap(y)) {
+ if (rp->r_dycode == DC_DOWLEQ)
+ --i;
+ else {
+ error(_("use of 2/29 in non leap-year"));
+ exit(EXIT_FAILURE);
+ }
+ }
+ --i;
+ dayoff = oadd(dayoff, i);
+ if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
+ register zic_t wday;
+
+#define LDAYSPERWEEK ((zic_t) DAYSPERWEEK)
+ wday = EPOCH_WDAY;
+ /*
+ ** Don't trust mod of negative numbers.
+ */
+ if (dayoff >= 0)
+ wday = (wday + dayoff) % LDAYSPERWEEK;
+ else {
+ wday -= ((-dayoff) % LDAYSPERWEEK);
+ if (wday < 0)
+ wday += LDAYSPERWEEK;
+ }
+ while (wday != rp->r_wday)
+ if (rp->r_dycode == DC_DOWGEQ) {
+ dayoff = oadd(dayoff, 1);
+ if (++wday >= LDAYSPERWEEK)
+ wday = 0;
+ ++i;
+ } else {
+ dayoff = oadd(dayoff, -1);
+ if (--wday < 0)
+ wday = LDAYSPERWEEK - 1;
+ --i;
+ }
+ if (i < 0 || i >= len_months[isleap(y)][m]) {
+ if (noise)
+ warning(_("rule goes past start/end of month; \
+will not work with pre-2004 versions of zic"));
+ }
+ }
+ if (dayoff < min_time / SECSPERDAY)
+ return min_time;
+ if (dayoff > max_time / SECSPERDAY)
+ return max_time;
+ t = (zic_t) dayoff * SECSPERDAY;
+ return tadd(t, rp->r_tod);
+}
+
+static void
+newabbr(const char *string)
+{
+ register int i;
+
+ if (strcmp(string, GRANDPARENTED) != 0) {
+ register const char * cp;
+ const char * mp;
+
+ cp = string;
+ mp = NULL;
+ while (is_alpha(*cp) || ('0' <= *cp && *cp <= '9')
+ || *cp == '-' || *cp == '+')
+ ++cp;
+ if (noise && cp - string < 3)
+ 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 characters");
+ if (*cp != '\0')
+mp = _("time zone abbreviation differs from POSIX standard");
+ if (mp != NULL)
+ warning("%s (%s)", mp, string);
+ }
+ i = strlen(string) + 1;
+ if (charcnt + i > TZ_MAX_CHARS) {
+ error(_("too many, or too long, time zone abbreviations"));
+ exit(EXIT_FAILURE);
+ }
+ strcpy(&chars[charcnt], string);
+ charcnt += i;
+}
+
+/* Ensure that the directories of ARGNAME exist, by making any missing
+ ones. If ANCESTORS, do this only for ARGNAME's ancestors; otherwise,
+ do it for ARGNAME too. Exit with failure if there is trouble.
+ Do not consider an existing non-directory to be trouble. */
+static void
+mkdirs(char const *argname, bool ancestors)
+{
+ register char * name;
+ register char * cp;
+
+ cp = name = ecpyalloc(argname);
+
+ /* On MS-Windows systems, do not worry about drive letters or
+ backslashes, as this should suffice in practice. Time zone
+ names do not use drive letters and backslashes. If the -d
+ option of zic does not name an already-existing directory,
+ it can use slashes to separate the already-existing
+ ancestor prefix from the to-be-created subdirectories. */
+
+ /* Do not mkdir a root directory, as it must exist. */
+ while (*cp == '/')
+ cp++;
+
+ while (cp && ((cp = strchr(cp, '/')) || !ancestors)) {
+ if (cp)
+ *cp = '\0';
+ /*
+ ** Try to create it. It's OK if creation fails because
+ ** the directory already exists, perhaps because some
+ ** other process just created it. For simplicity do
+ ** not check first whether it already exists, as that
+ ** is checked anyway if the mkdir fails.
+ */
+ if (mkdir(name, MKDIR_UMASK) != 0) {
+ /* For speed, skip itsdir if errno == EEXIST. Since
+ mkdirs is called only after open fails with ENOENT
+ on a subfile, EEXIST implies itsdir here. */
+ int err = errno;
+ if (err != EEXIST && !itsdir(name)) {
+ error(_("%s: Can't create directory %s: %s"),
+ progname, name, strerror(err));
+ exit(EXIT_FAILURE);
+ }
+ }
+ if (cp)
+ *cp++ = '/';
+ }
+ free(name);
+}
Property changes on: vendor/tzdb/tzcode2018e/zic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property