From f22d6113226bd837be2f871104ca91faf945bc05 Mon Sep 17 00:00:00 2001 From: christos Date: Sat, 17 Feb 2024 14:54:47 +0000 Subject: [PATCH] Sync with tzcode2024a: Release 2024a - 2024-02-01 09:28:56 -0800 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes to code The FROM and TO columns of Rule lines can no longer be "minimum" or an abbreviation of "minimum", because TZif files do not support DST rules that extend into the indefinite past - although these rules were supported when TZif files had only 32-bit data, this stopped working when 64-bit TZif files were introduced in 1995. This should not be a problem for realistic data, since DST was first used in the 20th century. As a transition aid, FROM columns like "minimum" are now diagnosed and then treated as if they were the year 1900; this should suffice for TZif files on old systems with only 32-bit time_t, and it is more compatible with bugs in 2023c-and-earlier localtime.c. (Problem reported by Yoshito Umaoka.) localtime and related functions no longer mishandle some timestamps that occur about 400 years after a switch to a time zone with a DST schedule. In 2023d data this problem was visible for some timestamps in November 2422, November 2822, etc. in America/Ciudad_Juarez. (Problem reported by Gilmore Davidson.) strftime %s now uses tm_gmtoff if available. (Problem and draft patch reported by Dag-Erling Smørgrav.) Changes to build procedure The leap-seconds.list file is now copied from the IERS instead of from its downstream counterpart at NIST, as the IERS version is now in the public domain too and tends to be more up-to-date. (Thanks to Martin Burnicki for liaisoning with the IERS.) Changes to documentation The strftime man page documents which struct tm members affect which conversion specs, and that tzset is called. (Problems reported by Robert Elz and Steve Summit.) --- include/tzfile.h | 9 +- lib/libc/time/Makefile | 53 ++++- lib/libc/time/NEWS | 68 ++++++ lib/libc/time/localtime.c | 35 ++-- lib/libc/time/private.h | 32 ++- lib/libc/time/strftime.c | 8 +- lib/libc/time/theory.html | 37 ++-- lib/libc/time/tz-art.html | 412 ++++++++++++++++--------------------- lib/libc/time/tz-link.html | 97 ++++----- lib/libc/time/tzfile.5 | 32 +-- lib/libc/time/tzselect.ksh | 45 ++-- lib/libc/time/version | 2 +- lib/libc/time/zic.8 | 27 +-- lib/libc/time/zic.c | 77 +++---- 14 files changed, 493 insertions(+), 441 deletions(-) diff --git a/include/tzfile.h b/include/tzfile.h index a44ce3ed2b21..3f154e460f87 100644 --- a/include/tzfile.h +++ b/include/tzfile.h @@ -1,4 +1,4 @@ -/* $NetBSD: tzfile.h,v 1.12 2023/09/16 18:19:30 christos Exp $ */ +/* $NetBSD: tzfile.h,v 1.13 2024/02/17 14:54:47 christos Exp $ */ #ifndef _TZFILE_H_ #define _TZFILE_H_ @@ -85,11 +85,11 @@ struct tzhead { ** 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). +** (with nothing between the newlines if there is no POSIX.1-2017 +** 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 +** First, the 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 @@ -132,6 +132,7 @@ struct tzhead { #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) #define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY) #define MONSPERYEAR 12 +#define YEARSPERREPEAT 400 #define TM_SUNDAY 0 #define TM_MONDAY 1 diff --git a/lib/libc/time/Makefile b/lib/libc/time/Makefile index 4e45f93b915c..d48354c72df4 100644 --- a/lib/libc/time/Makefile +++ b/lib/libc/time/Makefile @@ -53,7 +53,7 @@ DATAFORM= main LOCALTIME= Factory -# The POSIXRULES macro controls interpretation of POSIX-like TZ +# The POSIXRULES macro controls interpretation of POSIX-2017.1-like TZ # settings like TZ='EET-2EEST' that lack DST transition rules. # If POSIXRULES is '-', no template is installed; this is the default. # Any other value for POSIXRULES is obsolete and should not be relied on, as: @@ -274,7 +274,7 @@ LDLIBS= # -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory; # the default is system-supplied, typically "/usr/lib/locale" # -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified -# DST transitions for POSIX-style TZ strings lacking them, +# DST transitions for POSIX.1-2017-style TZ strings lacking them, # in the usual case where POSIXRULES is '-'. If not specified, # TZDEFRULESTRING defaults to US rules for future DST transitions. # This mishandles some past timestamps, as US DST rules have changed. @@ -340,9 +340,10 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ # guess TM_GMTOFF from other macros; define NO_TM_GMTOFF to suppress this. # Similarly, if your system has a "zone abbreviation" field, define # -DTM_ZONE=tm_zone -# and define NO_TM_ZONE to suppress any guessing. Although these two fields -# not required by POSIX, a future version of POSIX is planned to require them -# and they are widely available on GNU/Linux and BSD systems. +# and define NO_TM_ZONE to suppress any guessing. +# Although these two fields are not required by POSIX.1-2017, +# POSIX 202x/D4 requires them and they are widely available +# on GNU/Linux and BSD systems. # # The next batch of options control support for external variables # exported by tzcode. In practice these variables are less useful @@ -352,7 +353,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ # # -DHAVE_TZNAME=0 # do not support "tzname" # # -DHAVE_TZNAME=1 # support "tzname", which is defined by system library # # -DHAVE_TZNAME=2 # support and define "tzname" -# # to the "CFLAGS=" line. "tzname" is required by POSIX 1988 and later. +# # to the "CFLAGS=" line. "tzname" is required by POSIX.1-1988 and later. # # If not defined, the code attempts to guess HAVE_TZNAME from other macros. # # Warning: unless time_tz is also defined, HAVE_TZNAME=1 can cause # # crashes when combined with some platforms' standard libraries, @@ -362,8 +363,8 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ # # -DUSG_COMPAT=0 # do not support # # -DUSG_COMPAT=1 # support, and variables are defined by system library # # -DUSG_COMPAT=2 # support and define variables -# # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by -# # Unix Systems Group code and are required by POSIX 2008 (with XSI) and later. +# # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by Unix +# # Systems Group code and are required by POSIX.1-2008 and later (with XSI). # # If not defined, the code attempts to guess USG_COMPAT from other macros. # # # # To support the external variable "altzone", add @@ -427,7 +428,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ # The name of a POSIX-like library archiver, its flags, C compiler, # linker flags, and 'make' utility. Ordinarily the defaults suffice. -# The commented-out values are the defaults specified by POSIX 202x/D3. +# The commented-out values are the defaults specified by POSIX.1-202x/D4. #AR = ar #ARFLAGS = -rv #CC = c17 @@ -439,6 +440,12 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ LEAPSECONDS= +# Where to fetch leap-seconds.list from. +leaplist_URI = \ + https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list +# The file is generated by the IERS Earth Orientation Centre, in Paris. +leaplist_TZ = Europe/Paris + # The zic command and its arguments. zic= ./zic @@ -471,7 +478,8 @@ AWK= awk # is typically nicer if it works. KSHELL= /bin/bash -# Name of curl , used for HTML validation. +# Name of curl , used for HTML validation +# and to fetch leap-seconds.list from upstream. CURL= curl # Name of GNU Privacy Guard , used to sign distributions. @@ -718,6 +726,28 @@ leapseconds: $(LEAP_DEPS) -f leapseconds.awk leap-seconds.list >$@.out mv $@.out $@ +# Awk script to extract a Git-style author from leap-seconds.list comments. +EXTRACT_AUTHOR = \ + author_line { sub(/^.[[:space:]]*/, ""); \ + sub(/:[[:space:]]*/, " <"); \ + printf "%s>\n", $$0; \ + success = 1; \ + exit \ + } \ + /Questions or comments to:/ { author_line = 1 } \ + END { exit !success } + +# Fetch leap-seconds.list from upstream. +fetch-leap-seconds.list: + $(CURL) -OR $(leaplist_URI) + +# Fetch leap-seconds.list from upstream and commit it to the local repository. +commit-leap-seconds.list: fetch-leap-seconds.list + author=$$($(AWK) '$(EXTRACT_AUTHOR)' leap-seconds.list) && \ + date=$$(TZ=$(leaplist_TZ) stat -c%y leap-seconds.list) && \ + git commit --author="$$author" --date="$$date" -m'make $@' \ + leap-seconds.list + # Arguments to pass to submakes of install_data. # They can be overridden by later submake arguments. INSTALLARGS = \ @@ -1315,7 +1345,8 @@ zic.o: private.h tzfile.h tzdir.h version.h .PHONY: ALL INSTALL all .PHONY: check check_mild check_time_t_alternatives .PHONY: check_web check_zishrink -.PHONY: clean clean_misc dummy.zd force_tzs +.PHONY: clean clean_misc commit-leap-seconds.list dummy.zd +.PHONY: fetch-leap-seconds.list force_tzs .PHONY: install install_data maintainer-clean names .PHONY: posix_only posix_right public .PHONY: rearguard_signatures rearguard_signatures_version diff --git a/lib/libc/time/NEWS b/lib/libc/time/NEWS index a265ae6a3fe7..fc55325b557d 100644 --- a/lib/libc/time/NEWS +++ b/lib/libc/time/NEWS @@ -1,5 +1,73 @@ News for the tz database +Release 2024a - 2024-02-01 09:28:56 -0800 + + Briefly: + Kazakhstan unifies on UTC+5 beginning 2024-03-01. + Palestine springs forward a week later after Ramadan. + zic no longer pretends to support indefinite-past DST. + localtime no longer mishandles Ciudad Juárez in 2422. + + Changes to future timestamps + + Kazakhstan unifies on UTC+5. This affects Asia/Almaty and + Asia/Qostanay which together represent the eastern portion of the + country that will transition from UTC+6 on 2024-03-01 at 00:00 to + join the western portion. (Thanks to Zhanbolat Raimbekov.) + + Palestine springs forward a week later than previously predicted + in 2024 and 2025. (Thanks to Heba Hamad.) Change spring-forward + predictions to the second Saturday after Ramadan, not the first; + this also affects other predictions starting in 2039. + + Changes to past timestamps + + Asia/Ho_Chi_Minh's 1955-07-01 transition occurred at 01:00 + not 00:00. (Thanks to Đoàn Trần Công Danh.) + + From 1947 through 1949, Toronto's transitions occurred at 02:00 + not 00:00. (Thanks to Chris Walton.) + + In 1911 Miquelon adopted standard time on June 15, not May 15. + + Changes to code + + The FROM and TO columns of Rule lines can no longer be "minimum" + or an abbreviation of "minimum", because TZif files do not support + DST rules that extend into the indefinite past - although these + rules were supported when TZif files had only 32-bit data, this + stopped working when 64-bit TZif files were introduced in 1995. + This should not be a problem for realistic data, since DST was + first used in the 20th century. As a transition aid, FROM columns + like "minimum" are now diagnosed and then treated as if they were + the year 1900; this should suffice for TZif files on old systems + with only 32-bit time_t, and it is more compatible with bugs in + 2023c-and-earlier localtime.c. (Problem reported by Yoshito + Umaoka.) + + localtime and related functions no longer mishandle some + timestamps that occur about 400 years after a switch to a time + zone with a DST schedule. In 2023d data this problem was visible + for some timestamps in November 2422, November 2822, etc. in + America/Ciudad_Juarez. (Problem reported by Gilmore Davidson.) + + strftime %s now uses tm_gmtoff if available. (Problem and draft + patch reported by Dag-Erling Smørgrav.) + + Changes to build procedure + + The leap-seconds.list file is now copied from the IERS instead of + from its downstream counterpart at NIST, as the IERS version is + now in the public domain too and tends to be more up-to-date. + (Thanks to Martin Burnicki for liaisoning with the IERS.) + + Changes to documentation + + The strftime man page documents which struct tm members affect + which conversion specs, and that tzset is called. (Problems + reported by Robert Elz and Steve Summit.) + + Release 2023d - 2023-12-21 20:02:24 -0800 Briefly: diff --git a/lib/libc/time/localtime.c b/lib/libc/time/localtime.c index b869ee35a1fb..b4c4d2fe5733 100644 --- a/lib/libc/time/localtime.c +++ b/lib/libc/time/localtime.c @@ -1,4 +1,4 @@ -/* $NetBSD: localtime.c,v 1.140 2024/01/20 14:52:49 christos Exp $ */ +/* $NetBSD: localtime.c,v 1.141 2024/02/17 14:54:47 christos Exp $ */ /* Convert timestamp from time_t to struct tm. */ @@ -12,13 +12,13 @@ #if 0 static char elsieid[] = "@(#)localtime.c 8.17"; #else -__RCSID("$NetBSD: localtime.c,v 1.140 2024/01/20 14:52:49 christos Exp $"); +__RCSID("$NetBSD: localtime.c,v 1.141 2024/02/17 14:54:47 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ /* ** Leap second handling from Bradley White. -** POSIX-style TZ environment variable handling from Guy Harris. +** POSIX.1-1988 style TZ environment variable handling from Guy Harris. */ /*LINTLIBRARY*/ @@ -115,7 +115,7 @@ static char const UNSPEC[] = "-00"; for ttunspecified to work without crashing. */ enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 }; -/* Limit to time zone abbreviation length in POSIX-style TZ strings. +/* Limit to time zone abbreviation length in POSIX.1-2017-style TZ strings. This is distinct from TZ_MAX_CHARS, which limits TZif file contents. */ #ifndef TZNAME_MAXIMUM # define TZNAME_MAXIMUM 255 @@ -993,7 +993,8 @@ getoffset(register const char *strp, int_fast32_t *const offsetp) /* ** Given a pointer into a timezone string, extract a rule in the form -** date[/time]. See POSIX section 8 for the format of "date" and "time". +** date[/time]. See POSIX Base Definitions section 8.3 variable TZ +** 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. */ @@ -1137,7 +1138,7 @@ transtime(const int year, register const struct rule *const rulep, } /* -** Given a POSIX section 8-style TZ string, fill in the rule tables as +** Given a POSIX.1-2017-style TZ string, fill in the rule tables as ** appropriate. */ @@ -1264,7 +1265,7 @@ tzparse(const char *name, struct state *sp, struct state const *basep) } yearlim = yearbeg; - if (increment_overflow(&yearlim, YEARSPERREPEAT + 1)) + if (increment_overflow(&yearlim, years_of_observations)) yearlim = INT_MAX; for (year = yearbeg; year < yearlim; year++) { int_fast32_t @@ -1301,7 +1302,7 @@ tzparse(const char *name, struct state *sp, struct state const *basep) if (endtime < leaplo) { yearlim = year; if (increment_overflow(&yearlim, - YEARSPERREPEAT + 1)) + years_of_observations)) yearlim = INT_MAX; } if (increment_overflow_time @@ -1313,7 +1314,7 @@ tzparse(const char *name, struct state *sp, struct state const *basep) if (! timecnt) { sp->ttis[0] = sp->ttis[1]; sp->typecnt = 1; /* Perpetual DST. */ - } else if (YEARSPERREPEAT < year - yearbeg) + } else if (years_of_observations <= year - yearbeg) sp->goback = sp->goahead = true; } else { register int_fast32_t theirstdoffset; @@ -1372,8 +1373,8 @@ tzparse(const char *name, struct state *sp, struct state const *basep) /* ** Transitions from DST to DDST ** will effectively disappear since - ** POSIX provides for only one DST - ** offset. + ** POSIX.1-2017 provides for only one + ** DST offset. */ if (isdst && !sp->ttis[j].tt_ttisstd) { sp->ats[i] += (time_t) @@ -1556,7 +1557,8 @@ tzfree(timezone_t sp) ** ** 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 timezone is POSIX-compatible, +** however, it's OK to omit this step +** if the timezone is compatible with POSIX.1-2017 ** since in that case tzset should have already done this step correctly. ** SETNAME's type is int_fast32_t for compatibility with gmtsub, ** but it is actually a boolean and its value should be 0 or 1. @@ -2465,15 +2467,18 @@ timelocal(struct tm *tmp) tmp->tm_isdst = -1; /* in case it wasn't initialized */ return mktime(tmp); } -#else +#endif + +#ifndef EXTERN_TIMEOFF # ifndef timeoff # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 . */ # endif -static +# define EXTERN_TIMEOFF static #endif + /* This function is obsolescent and may disapper in future releases. Callers can instead use mktime_z with a fixed-offset zone. */ -time_t +EXTERN_TIMEOFF time_t timeoff(struct tm *tmp, long offset) { if (tmp) diff --git a/lib/libc/time/private.h b/lib/libc/time/private.h index c597e3bd7f43..c32497edfca5 100644 --- a/lib/libc/time/private.h +++ b/lib/libc/time/private.h @@ -1,6 +1,6 @@ /* Private header for tzdb code. */ -/* $NetBSD: private.h,v 1.68 2024/01/20 14:52:49 christos Exp $ */ +/* $NetBSD: private.h,v 1.69 2024/02/17 14:54:47 christos Exp $ */ #ifndef PRIVATE_H #define PRIVATE_H @@ -778,7 +778,7 @@ struct tm *offtime(time_t const *, long); time_t timelocal(struct tm *); # endif # if TZ_TIME_T || !defined timeoff -time_t timeoff(struct tm *, long); +# define EXTERN_TIMEOFF # endif # if TZ_TIME_T || !defined time2posix time_t time2posix(time_t); @@ -790,7 +790,8 @@ time_t posix2time(time_t); /* 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__ \ +#if (200809 < _POSIX_VERSION \ + || defined __GLIBC__ \ || defined __tm_zone /* musl */ \ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \ || (defined __APPLE__ && defined __MACH__)) @@ -922,6 +923,19 @@ static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED # define UNINIT_TRAP 0 #endif +/* localtime.c sometimes needs access to timeoff if it is not already public. + tz_private_timeoff should be used only by localtime.c. */ +#if (!defined EXTERN_TIMEOFF \ + && defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP)) +# ifndef timeoff +# define timeoff tz_private_timeoff +# endif +# define EXTERN_TIMEOFF +#endif +#ifdef EXTERN_TIMEOFF +time_t timeoff(struct tm *, long); +#endif + #ifdef DEBUG # undef unreachable # define unreachable() abort() @@ -983,6 +997,18 @@ enum { #define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY) #define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT) +/* How many years to generate (in zic.c) or search through (in localtime.c). + This is two years larger than the obvious 400, to avoid edge cases. + E.g., suppose a non-POSIX.1-2017 rule applies from 2012 on with transitions + in March and September, plus 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 is not overkill for localtime.c, as a one-year bump + would mishandle 2023d's America/Ciudad_Juarez for November 2422. */ +enum { years_of_observations = YEARSPERREPEAT + 2 }; + #ifndef TM_SUNDAY enum { TM_SUNDAY, diff --git a/lib/libc/time/strftime.c b/lib/libc/time/strftime.c index d328771dd819..bf8ac8d5ec20 100644 --- a/lib/libc/time/strftime.c +++ b/lib/libc/time/strftime.c @@ -1,4 +1,4 @@ -/* $NetBSD: strftime.c,v 1.53 2024/01/20 14:52:49 christos Exp $ */ +/* $NetBSD: strftime.c,v 1.54 2024/02/17 14:54:47 christos Exp $ */ /* Convert a broken-down timestamp to a string. */ @@ -35,7 +35,7 @@ static char elsieid[] = "@(#)strftime.c 7.64"; static char elsieid[] = "@(#)strftime.c 8.3"; #else -__RCSID("$NetBSD: strftime.c,v 1.53 2024/01/20 14:52:49 christos Exp $"); +__RCSID("$NetBSD: strftime.c,v 1.54 2024/02/17 14:54:47 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -381,11 +381,15 @@ label: tm.tm_mday = t->tm_mday; tm.tm_mon = t->tm_mon; tm.tm_year = t->tm_year; +#ifdef TM_GMTOFF + mkt = timeoff(&tm, t->TM_GMTOFF); +#else tm.tm_isdst = t->tm_isdst; #if defined TM_GMTOFF && ! UNINIT_TRAP tm.TM_GMTOFF = t->TM_GMTOFF; #endif mkt = mktime_z(sp, &tm); +#endif /* If mktime fails, %s expands to the value of (time_t) -1 as a failure marker; this is better in practice diff --git a/lib/libc/time/theory.html b/lib/libc/time/theory.html index 369c75433ff2..516d2a525111 100644 --- a/lib/libc/time/theory.html +++ b/lib/libc/time/theory.html @@ -95,7 +95,7 @@ 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. +standard and daylight saving times supported by POSIX.1-2017. A tz timezone 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 @@ -187,7 +187,7 @@ in decreasing order of importance: href="https://en.wikipedia.org/wiki/ASCII">ASCII letters, '.', '-' and '_'. Do not use digits, as that might create an ambiguity with POSIX + href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">POSIX.1-2017 TZ strings. A file name component must not exceed 14 characters or start with '-'. @@ -362,6 +362,11 @@ The backward-compatibility file zone.tab is similar but conforms to the older-version guidelines related to ISO 3166-1; it lists only one country code per entry and unlike zone1970.tab it can list names defined in backward. +Applications that process only timestamps from now on can instead use the file +zonenow.tab, which partitions the world more coarsely, +into regions where clocks agree now and in the predicted future; +this file is smaller and simpler than zone1970.tab +and zone.tab.

@@ -373,7 +378,7 @@ nowadays distributions typically use it and no great weight should be attached to whether a link is defined in backward or in some other file. The source file etcetera defines names that may be useful -on platforms that do not support POSIX-style TZ strings; +on platforms that do not support POSIX.1-2017-style TZ strings; no other source file other than backward contains links to its zones. One of etcetera's names is Etc/UTC, @@ -421,7 +426,7 @@ in decreasing order of importance: expression [-+[:alnum:]]{3,6} should match the abbreviation. This guarantees that all abbreviations could have been specified by a - POSIX TZ string. + POSIX.1-2017 TZ string.

  • @@ -765,12 +770,12 @@ href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanes calendar with 24-hour days. These divergences range from relatively minor, such as Japanese bars giving times like "24:30" for the wee hours of the morning, to more-significant differences such as the + href="https://theworld.org/stories/2015-01-30/if-you-have-meeting-ethiopia-you-better-double-check-time">the east African practice of starting the day at dawn, renumbering the Western 06:00 to be 12:00. These practices are largely outside the scope of the tz code and data, which provide only limited support for date and time localization - such as that required by POSIX. + such as that required by POSIX.1-2017. If DST is not used a different time zone can often do the trick; for example, in Kenya a TZ setting like <-03>3 or America/Cayenne starts @@ -867,23 +872,23 @@ input is occasionally extended, and a platform may still be shipping an older zic.

    -

    POSIX properties and limitations

    +

    POSIX.1-2017 properties and limitations

    • - In POSIX, time display in a process is controlled by the + In POSIX.1-2017, time display in a process is controlled by the environment variable TZ. - Unfortunately, the POSIX + Unfortunately, the POSIX.1-2017 TZ string takes a form that is hard to describe and is error-prone in practice. - Also, POSIX TZ strings cannot deal with daylight + Also, POSIX.1-2017 TZ strings cannot deal with daylight saving time rules not based on the Gregorian calendar (as in Morocco), 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: + The POSIX.1-2017 TZ string takes the following form:

      @@ -950,7 +955,7 @@ an older zic.

      - Here is an example POSIX TZ string for New + Here is an example POSIX.1-2017 TZ string for New Zealand after 2007. It says that standard time (NZST) is 12 hours ahead of UT, and that daylight saving time @@ -961,7 +966,7 @@ an older zic.

      TZ='NZST-12NZDT,M9.5.0,M4.1.0/3'

      - This POSIX TZ string is hard to remember, and + This POSIX.1-2017 TZ string is hard to remember, and mishandles some timestamps before 2008. With this package you can use this instead:

      @@ -999,7 +1004,7 @@ an older zic. limit phone calls to off-peak hours.
    • - POSIX provides no convenient and efficient way to determine + POSIX.1-2017 provides no convenient and efficient way to determine the UT offset and time zone abbreviation of arbitrary timestamps, particularly for timezones that do not fit into the POSIX model. @@ -1026,14 +1031,14 @@ an older zic.
    -

    Extensions to POSIX in the +

    Extensions to POSIX.1-2017 in the tz code

    • The TZ environment variable is used in generating the name of a file from which time-related information is read - (or is interpreted à la POSIX); TZ is no longer + (or is interpreted à la POSIX.1-2017); TZ is no longer constrained to be a string containing abbreviations and numeric data as described above. The file's format is TZif, diff --git a/lib/libc/time/tz-art.html b/lib/libc/time/tz-art.html index e3be5f29889f..3ee1eb244731 100644 --- a/lib/libc/time/tz-art.html +++ b/lib/libc/time/tz-art.html @@ -210,7 +210,7 @@ Umberto Eco, 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 +on the International Date Line. Time and time zones play an integral part in the novel." (Paul Eggert, 2006-04-22)

    • @@ -230,94 +230,73 @@ year-round DST as a way of lessening wintertime despair.

    Music

    -

    -Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArtistKarrin Allyson
    CDI Didn't Know About You
    Copyright Date1993
    LabelConcord Jazz, Inc.
    IDCCD-4543
    Track Time3:44
    PersonnelKarrin Allyson, vocal; +
      +
    • +Recordings of "Save That Time," Russ Long, Serrob Publishing, BMI: +
        +
      • +Karrin Allyson, I Didn't Know About You (1993), track 11, 3:44. +Concord Jazz CCD-4543. +Karrin Allyson, vocal; Russ Long, piano; Gerald Spaits, bass; -Todd Strait, drums
    NotesCD notes "additional lyric by Karrin Allyson; -arranged by Russ Long and Karrin Allyson"
    ADO Rating1 star
    AMG Rating4 stars
    Penguin Rating3.5 stars
     
    ArtistKevin Mahogany
    CDDouble Rainbow
    Copyright Date1993
    LabelEnja Records
    IDENJ-7097 2
    Track Time6:27
    PersonnelKevin Mahogany, vocal; +Todd Strait, drums. +CD notes "additional lyric by Karrin Allyson; +arranged by Russ Long and Karrin Allyson". +ADO ★, +AMG +★★★★, Penguin ★★★⯪. + +
  • +Kevin Mahogany, Double Rainbow (1993), track 3, 6:27. Enja ENJ-7097 2. +Kevin Mahogany, vocal; Kenny Barron, piano; Ray Drummond, bass; Ralph Moore, tenor saxophone; -Lewis Nash, drums
  • ADO Rating1.5 stars
    AMG Rating3 stars
    Penguin Rating3 stars
     
    ArtistJoe Williams
    CDHere's to Life
    Copyright Date1994
    LabelTelarc International Corporation
    IDCD-83357
    Track Time3:58
    PersonnelJoe Williams, vocal -The Robert Farnon [39 piece] Orchestra
    NotesThis CD is also available as part of a 3-CD package from -Telarc, "Triple Play" (CD-83461)
    ADO Ratingblack dot
    AMG Rating2 stars
    Penguin Rating3 stars
     
    ArtistCharles Fambrough
    CDKeeper of the Spirit
    Copyright Date1995
    LabelAudioQuest Music
    IDAQ-CD1033
    Track Time7:07
    PersonnelCharles Fambrough, bass; +Lewis Nash, drums. +ADO ★⯪, +AMG +★★★, Penguin ★★★. + +
  • +Joe Williams, Here's to Life (1994), track 7, 3:58. +Telarc Jazz CD-83357. +Joe Williams, vocal; The Robert Farnon [39 piece] Orchestra. +Also in a 3-CD package "Triple Play", Telarc CD-83461. +ADO •, +AMG +★★, Penguin ★★★. +
  • +
  • +Charles Fambrough, Keeper of the Spirit (1995), track 7, 7:07. +AudioQuest AQ-CD1033. +Charles Fambrough, bass; Joel Levine, tenor recorder; Edward Simon, piano; Lenny White, drums; -Marion Simon, percussion
  • ADO Rating2 stars
    AMG Ratingunrated
    Penguin Rating3 stars
    -
    -

    Also of note:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArtistHolly Cole Trio
    CDBlame It On My Youth
    Copyright Date1992
    LabelManhattan
    IDCDP 7 97349 2
    Total Time37:45
    PersonnelHolly Cole, voice; +Marion Simon, percussion. +ADO ★, +AMG +unrated, Penguin ★★★. + + +
  • +Holly Cole Trio, Blame It On My Youth (1992). Manhattan CDP 7 97349 2, 37:45. +Holly Cole, voice; Aaron Davis, piano; -David Piltch, string bass
  • NotesLyrical reference to "Eastern Standard Time" in -Tom Waits' "Purple Avenue"
    ADO Rating2.5 stars
    AMG Rating3 stars
    Penguin Ratingunrated
     
    ArtistMilt Hinton
    CDOld Man Time
    Copyright Date1990
    LabelChiaroscuro
    IDCR(D) 310
    Total Time149:38 (two CDs)
    PersonnelMilt Hinton, bass; +David Piltch, string bass. +Lyrical reference to "Eastern Standard Time" in +Tom Waits's "Purple Avenue". +ADO ★★⯪, +AMG +★★★, Penguin unrated. + +
  • +Milt Hinton, +Old +Man Time (1990). +Chiaroscuro CR(D) 310, 149:38 (two CDs). +Milt Hinton, bass; Doc Cheatham, Dizzy Gillespie, Clark Terry, trumpet; Al Grey, trombone; Eddie Barefield, Joe Camel (Flip Phillips), Buddy Tate, @@ -329,165 +308,129 @@ Gus Johnson, Gerryck King, Bob Rosengarden, Jackie Williams, drums; Lionel Hampton, vibraphone; Cab Calloway, Joe Williams, vocal; -Buck Clayton, arrangements
  • Notestunes 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 Rating3 stars
    AMG Rating4.5 stars
    Penguin Rating3 stars
     
    ArtistAlan Broadbent
    CDPacific Standard Time
    Copyright Date1995
    LabelConcord Jazz, Inc.
    IDCCD-4664
    Total Time62:42
    PersonnelAlan Broadbent, piano; +Buck Clayton, arrangements. +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". +ADO ★★★, +AMG +★★★★⯪, Penguin ★★★. + +
  • +Alan Broadbent, Pacific Standard Time (1995). +Concord Jazz CCD-4664, 62:42. +Alan Broadbent, piano; Putter Smith, Bass; -Frank Gibson, Jr., drums
  • NotesThe CD cover features an analemma for equation-of-time fans
    ADO Rating1 star
    AMG Rating4 stars
    Penguin Rating3.5 stars
     
    ArtistAnthony Braxton/Richard Teitelbaum
    CDSilence/Time Zones
    Copyright Date1996
    LabelBlack Lion
    IDBLCD 760221
    Total Time72:58
    PersonnelAnthony Braxton, sopranino and alto saxophones, +Frank Gibson, Jr., drums. +The CD cover features an analemma for equation-of-time fans. +ADO ★, +AMG +★★★★, Penguin ★★★⯪. + +
  • +Anthony Braxton/Richard Teitelbaum, Silence/Time Zones (1996). +Black Lion BLCD 760221, 72:58. +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 Ratingblack dot
    AMG Rating4 stars
     
    ArtistCharles Gayle
    CDTime Zones
    Copyright Date2006
    LabelTompkins Square
    IDTSQ2839
    Total Time49:06
    PersonnelCharles Gayle, piano
    ADO Rating1 star
    AMG Rating4.5 stars
     
    ArtistThe Get Up Kids
    CDEudora
    Copyright Date2001
    LabelVagrant
    ID357
    Total Time65:12
    NotesIncludes the song "Central Standard Time." Thanks to Colin Bowern for this information.
    AMG Rating2.5 stars
     
    ArtistColdplay
    SongClocks
    Copyright Date2003
    LabelCapitol Records
    ID52608
    Total Time4:13
    NotesWon the 2004 Record of the Year honor at the +Richard Teitelbaum, modular moog and micromoog synthesizer. +ADO •, +AMG +★★★★. + +
  • +Charles Gayle, Time Zones (2006). Tompkins Square TSQ2839, 49:06. +Charles Gayle, piano. +ADO ★, +AMG +★★★★⯪. +
  • +
  • +The Get Up Kids, Eudora (2001). Vagrant 357, 65:12. +Includes the song "Central Standard Time." +Thanks to Colin Bowern for this information. +AMG +★★⯪. +
  • +
  • +Coldplay, "Clocks" (2003). +Capitol 52608, 4:13. +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".
  •  
    ArtistJaime Guevara
    Song +
  • +Jaime Guevara, "Qué -hora es
  • Date1993
    Total Time3:04
    NotesThe song protested "Sixto Hour" in Ecuador +hora es" (1993), 3:04. +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"). -
     
    ArtistIrving Kahal and Harry Richman
    SongThere Ought to be a Moonlight Saving Time
    Copyright Date1931
    NotesThis musical standard was a No. 1 hit for Guy Lombardo + +
  • +Irving Kahal and Harry Richman, +"There Ought to be a Moonlight Saving Time" (1931). +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.
  •  
    ArtistThe Microscopic Septet
    CDLobster Leaps In
    Copyright Date2008
    LabelCuneiform
    ID272
    Total Time73:05
    NotesIncludes the song "Twilight Time Zone."
    AMG Rating3.5 stars
    ADO Rating2 stars
     
    ArtistBob Dylan
    CDThe Times They Are a-Changin'
    Copyright Date1964
    LabelColumbia
    IDCK-8905
    Total Time45:36
    AMG Rating4.5 stars
    ADO Rating1.5 stars
    NotesThe title song is also available on "Bob Dylan's Greatest Hits" and "The Essential Bob Dylan."
     
    ArtistLuciana Souza
    CDTide
    Copyright Date2009
    LabelUniversal Jazz France
    IDB0012688-02
    Total Time42:31
    AMG Rating3.5 stars
    ADO Rating2.5 stars
    NotesIncludes the song "Fire and Wood" with the lyric +Supernaw. + +
  • +The Microscopic Septet, Lobster Leaps In (2008). +Cuneiform 272, 73:05. +Includes the song "Twilight Time Zone." +ADO ★★, +AMG +★★★⯪. +
  • +
  • +Bob Dylan, The Times They Are a-Changin' (1964). +Columbia CK-8905, 45:36. +ADO ★⯪, +AMG +★★★★⯪. +The title song is also available on "Bob Dylan's Greatest Hits" and "The Essential Bob Dylan." +
  • +
  • +Luciana Souza, Tide (2009). Universal Jazz France B0012688-02, 42:31. +ADO ★★⯪, +AMG +★★★⯪. +Includes the song "Fire and Wood" with the lyric "The clocks were turned back you remember/Think it's still November." -
  •  
    ArtistKen Nordine
    CDYou're Getting Better: The Word Jazz Dot Masters
    Copyright Date2005
    LabelGeffen
    IDB0005171-02
    Total Time156:22
    ADO Rating1 star
    AMG Rating4.5 stars
    NotesIncludes the piece "What Time Is It" -("He knew what time it was everywhere...that counted").
     
    ArtistChicago
    CDChicago Transit Authority
    Copyright Date1969
    LabelColumbia
    ID64409
    Total Time1:16:20
    AMG Rating4 stars
    NotesIncludes the song "Does Anybody Really Know What Time It Is?"
     
    ArtistEmanuele Arciuli
    ComposerWilliam Duckworth
    CDThe Time Curve Preludes
    Copyright Date2023
    LabelNeuma
    Total Time44:46
    NotesThe first work of postminimal music. Unlike minimalism, it does not assume that the listener has plenty of time.
    +
  • +
  • +Ken Nordine, You're Getting Better: The Word Jazz Dot Masters (2005). +Geffen B0005171-02, 156:22. +ADO ★, +AMG +★★★★⯪. +Includes the piece "What Time Is It" +("He knew what time it was everywhere...that counted"). +
  • +
  • +Chicago, Chicago Transit Authority (1969). Columbia 64409, 1:16:20. +AMG ★★★★. +Includes the song "Does Anybody Really Know What Time It Is?". +
  • +
  • +Emanuele Arciuli, +The Time Curve Preludes (2023). +Neuma 174, 44:46. +The title piece, composed by +William +Duckworth, is the first work of postminimal music. +Unlike minimalism, it does not assume that the listener has plenty of time. +
  • +

    Comics

    • @@ -507,7 +450,10 @@ along with the panels "6/6 Time" (2018-09-24), "Consensus New Year" (2018-12-31), "Leap Smearing" (2020-02-10), -and "Consensus Time" (2022-03-16). +"Consensus Time" (2022-03-16), +"Daylight Saving Choice" (2023-10-25), +"Date Line" (2023-11-13), +and "DateTime" (2023-12-13). The related book What If? has an entry "Leap Seconds" (2012-12-31).
    • @@ -520,9 +466,13 @@ Before Swine (2016-11-06). Stonehenge is abandoned in Non Sequitur (2017-03-12). +
    • -The boss freaks out in Dilbert (1998-03-14). +Caulfield proposes changing clocks just once a year in +Frazz +(2023-12-31), while Peter and Jason go multi-lingual and -zonal in +FoxTrot +(the same day).
    • Peppermint Patty: "What if the world comes to an end tonight, Marcie?" @@ -606,10 +556,10 @@ 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 +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.) +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 @@ -617,7 +567,7 @@ 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.) +2017-10-09)
    • "And now, driving to California, I find that I must enter a password diff --git a/lib/libc/time/tz-link.html b/lib/libc/time/tz-link.html index 84bea9353c55..9fb57c9058a9 100644 --- a/lib/libc/time/tz-link.html +++ b/lib/libc/time/tz-link.html @@ -114,7 +114,7 @@ Indiana, which switched from central to eastern time in 1991 and switched back in 2006. To use the database on an extended POSIX +title="Portable Operating System Interface">POSIX.1-2017 implementation set the TZ environment variable to the location's full name, e.g., TZ="America/New_York".

      @@ -172,7 +172,7 @@ Since version 2022a, each release has been distributed in ustar interchange format, compressed as described above; older releases use a nearly compatible format. Since version 2016h, each release has contained a text file named -"version" whose first (and currently only) line is the version. +"version" whose first (and currently only) line is the version. Older releases are archived, and are also available in an TZ values directly.
    • Current Time in 1000 Places uses descriptions of the values.
    • -
    • 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 @@ -511,12 +508,12 @@ It is freely available under the Apache License.
    • Many modern JavaScript runtimes support tz natively via the -timeZone option of Intl.DateTimeFormat. +timeZone option of Intl.DateTimeFormat. This can be used as-is or with most of the following libraries, -many of which also support runtimes lacking the timeZone option. +many of which also support runtimes lacking the timeZone option. The proposed Temporal +href="https://github.com/tc39/proposal-temporal">Temporal objects let programs access an abstract view of tzdb data, and are designed to replace JavaScript's -problematic Date objects when working with dates and times. +problematic Date objects when working with dates and times.
    • JuliaTime contains a compiler from tz source into Julia. It is freely available @@ -620,6 +617,16 @@ the Apache License.
    • library that translates between UT and civil time and can read TZif files. It is freely available under the Apache License. +
    • The +posix_tz_db +package contains Python code +to generate CSV and JSON tables that map +tz settings to POSIX.1-2017-like approximations. +For example, it maps "Africa/Cairo" +to "EET-2EEST,M4.5.5/0,M10.5.4/24", +an approximation valid for Cairo timestamps from 2023 on. +This can help porting to platforms that support only POSIX.1-2017. +The package is freely available under the MIT license.
    • Timelib is a C library that reads TZif files and converts timestamps from one time zone or format to another. @@ -666,9 +673,7 @@ available under a BSD-style license.
    • diff --git a/lib/libc/time/tzfile.5 b/lib/libc/time/tzfile.5 index e0161226164f..bd6e88526c4a 100644 --- a/lib/libc/time/tzfile.5 +++ b/lib/libc/time/tzfile.5 @@ -1,9 +1,9 @@ -.\" $NetBSD: tzfile.5,v 1.34 2023/09/16 18:40:26 christos Exp $ +.\" $NetBSD: tzfile.5,v 1.35 2024/02/17 14:54:47 christos Exp $ .\" .\" @(#)tzfile.5 8.3 .\" This file is in the public domain, so clarified as of .\" 2009-05-17 by Arthur David Olson. -.Dd September 16, 2023 +.Dd February 17, 2023 .Dt TZFILE 5 .Os .Sh NAME @@ -82,7 +82,7 @@ described in the file is associated with the time period starting with the same-indexed transition time and continuing up to but not including the next transition time. (The last time type is present only for consistency checking with the -POSIX-style TZ string described below.) +POSIX.1-2017-style TZ string described below.) These values serve as indices into the next field. .It Va tzh_typecnt .Va ttinfo @@ -184,7 +184,8 @@ must also be set. .Pp The standard/wall and UT/local indicators were designed for transforming a TZif file's transition times into transitions appropriate -for another time zone specified via a POSIX-style TZ string that lacks rules. +for another time zone specified via +a POSIX.1-2017-style TZ string that lacks rules. For example, when .Dv TZ="EET\*-2EEST" and there is no TZif file @@ -222,13 +223,14 @@ 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 second header and data comes a newline-enclosed string +in the style of the contents of a POSIX.1-2017 TZ environment variable, +for use in handling instants after the last transition time stored in the file or for all instants if the file has no transitions. -The POSIX-style TZ string is empty (i.e., nothing between the newlines) -if there is no POSIX-style representation for such instants. -If nonempty, the POSIX-style TZ string must agree with the local time +The TZ string is empty (i.e., nothing between the newlines) +if there is no POSIX.1-2017-style representation for such instants. +If nonempty, the TZ string must agree with the local time type after the last transition time if present in the eight-byte data; for example, given the string .Dq WET0WEST,M3.5.0/1,M10.5.0 @@ -240,8 +242,8 @@ Also, if there is at least one transition, time type 0 is associated with the time period from the indefinite past up to but not including the earliest transition time. .Ss Version 3 format -For version-3-format timezone files, the POSIX-TZ-style string may -use two minor extensions to the POSIX TZ format, as described in +For version-3-format timezone files, the TZ string may +use two minor extensions to the POSIX.1-2017 TZ format, as described in .Xr tzset 3 . First, the hours part of its transition times may be signed and range from \-167 through 167 @@ -362,7 +364,7 @@ version 2+ data even if the reader's native timestamps have only .It Some readers designed for version 2 might mishandle timestamps after a version 3 or higher file's last transition, because -they cannot parse extensions to POSIX in the TZ-like string. +they cannot parse extensions to POSIX.1-2017 in the TZ-like string. As a partial workaround, a writer can output more transitions than necessary, so that only far-future timestamps are mishandled by version 2 readers. @@ -414,7 +416,7 @@ Some readers mishandle a transition if its timestamp has the minimum possible signed 64-bit value. Timestamps less than \&-2**59 are not recommended. .It -Some readers mishandle POSIX-style TZ strings that +Some readers mishandle TZ strings that contain .Dq < or @@ -442,12 +444,12 @@ Some readers mishandle TZif files that specify daylight-saving time UT offsets that are less than the UT offsets for the corresponding standard time. These readers do not support locations like Ireland, which -uses the equivalent of the POSIX TZ string +uses the equivalent of the TZ string .Dq IST\&-1GMT0,M10.5.0,M3.5.0/1 , observing standard time (IST, +01) in summer and daylight saving time (GMT, +00) in winter. As a partial workaround, a writer can output data for the -equivalent of the POSIX TZ string +equivalent of the TZ string .Dq GMT0IST,M3.5.0/1,M10.5.0 , thus swapping standard and daylight saving time. Although this workaround misidentifies which part of the year diff --git a/lib/libc/time/tzselect.ksh b/lib/libc/time/tzselect.ksh index d1dc92b9964c..d3d234c13461 100644 --- a/lib/libc/time/tzselect.ksh +++ b/lib/libc/time/tzselect.ksh @@ -3,7 +3,7 @@ # Ask the user about the time zone, and output the resulting TZ value to stdout. # Interact with the user via stderr and stdin. # -# $NetBSD: tzselect.ksh,v 1.22 2023/09/16 18:40:26 christos Exp $ +# $NetBSD: tzselect.ksh,v 1.23 2024/02/17 14:54:47 christos Exp $ # PKGVERSION='(tzcode) ' TZVERSION=see_Makefile @@ -38,9 +38,13 @@ REPORT_BUGS_TO=tz@iana.org # nawk +# This script does not want path expansion. +set -f + # Specify default values for environment variables if they are unset. : ${AWK=awk} -: ${TZDIR=`pwd`} +: ${PWD=`pwd`} +: ${TZDIR=$PWD} # Output one argument as-is to standard output, with trailing newline. # Safer than 'echo', which can mishandle '\' or leading '-'. @@ -111,7 +115,8 @@ then else doselect() { # Field width of the prompt numbers. - select_width=`expr $# : '.*'` + print_nargs_length="BEGIN {print length(\"$#\");}" + select_width=`$AWK "$print_nargs_length"` select_i= @@ -122,14 +127,14 @@ else select_i=0 for select_word do - select_i=`expr $select_i + 1` + select_i=`$AWK "BEGIN { print $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` + shift `$AWK "BEGIN { print $select_i - 1 }"` select_result=$1 break fi @@ -163,7 +168,7 @@ do esac done -shift `expr $OPTIND - 1` +shift `$AWK "BEGIN { print $OPTIND - 1 }"` case $# in 0) ;; *) say >&2 "$0: $1: unknown argument"; exit 1 ;; @@ -400,19 +405,24 @@ while eval ' doselect '"$quoted_continents"' \ "coord - I want to use geographical coordinates." \ - "TZ - I want to specify the timezone using the Posix TZ format." \ + "TZ - I want to specify the timezone using a POSIX.1-2017 TZ string." \ "time - I know local time already." continent=$select_result case $continent in Americas) continent=America;; - *" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''` + *) + # Get the first word of $continent. Path expansion is disabled + # so this works even with "*", which should not happen. + IFS=" " + for continent in $continent ""; do break; done + IFS=$newline;; esac ' esac case $continent in TZ) - # Ask the user for a Posix TZ string. Check that it conforms. + # Ask the user for a POSIX.1-2017 TZ string. Check that it conforms. while echo >&2 'Please enter the desired value' \ 'of the TZ environment variable.' @@ -436,7 +446,7 @@ while exit 0 }' do - say >&2 "'$TZ' is not a conforming Posix timezone string." + say >&2 "'$tz' is not a conforming POSIX.1-2017 timezone string." done TZ_for_date=$TZ;; *) @@ -456,7 +466,7 @@ while -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ "$output_distances_or_times" <"$TZ_ZONE_TABLE" | sort -n | - sed "${location_limit}q" + $AWK "{print} NR == $location_limit { exit }" ` regions=`$AWK \ -v distance_table="$distance_table" ' @@ -640,15 +650,18 @@ while 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) + if $AWK ' + function getsecs(d) { + return match(d, /.*:[0-5][0-9]/) ? substr(d, RLENGTH - 1, 2) : "" + } + BEGIN { exit getsecs(ARGV[1]) != getsecs(ARGV[2]) } + ' ="$TZdate" ="$UTdate" + then extra_info=" Selected time is now: $TZdate. Universal Time is now: $UTdate." break - esac + fi done diff --git a/lib/libc/time/version b/lib/libc/time/version index 7daa77e00d99..04fe6744432f 100644 --- a/lib/libc/time/version +++ b/lib/libc/time/version @@ -1 +1 @@ -2023c +2024a diff --git a/lib/libc/time/zic.8 b/lib/libc/time/zic.8 index 90eb25afeba9..e1065d5c12b3 100644 --- a/lib/libc/time/zic.8 +++ b/lib/libc/time/zic.8 @@ -1,9 +1,9 @@ -.\" $NetBSD: zic.8,v 1.49 2023/12/07 23:42:28 kre Exp $ +.\" $NetBSD: zic.8,v 1.50 2024/02/17 14:54:47 christos Exp $ .\" @(#)zic.8 8.6 .\" This file is in the public domain, so clarified as of .\" 2009-05-17 by Arthur David Olson. .\" .TH zic 8 -.Dd December 6, 2023 +.Dd February 17, 2024 .Dt ZIC 8 .Os .Sh NAME @@ -151,7 +151,7 @@ boundaries, particularly if causes a TZif file to contain explicit entries for .No pre- Ns Ar hi transitions rather than concisely representing them -with an extended POSIX TZ string. +with an extended POSIX.1-2017 TZ string. Also see the .Fl b Cm slim option for another way to shrink output size. @@ -160,10 +160,10 @@ Generate redundant trailing explicit transitions for timestamps that occur less than .Ar hi seconds since the Epoch, even though the transitions could be -more concisely represented via the extended POSIX TZ string. +more concisely represented via the extended POSIX.1-2017 TZ string. This option does not affect the represented timestamps. Although it accommodates nonstandard TZif readers -that ignore the extended POSIX TZ string, +that ignore the extended POSIX.1-2017 TZ string, it increases the size of the altered output files. .It Fl t Ar file When creating local time information, put the configuration link in @@ -222,11 +222,11 @@ for .It The output file does not contain all the information about the long-term future of a timezone, because the future cannot be summarized as -an extended POSIX TZ string. +an extended POSIX.1-2017 TZ string. For example, as of 2023 this problem occurs for Morocco's daylight-saving rules, as on predictions for when Ramadan will be observed, something that -an extended POSIX TZ string cannot represent. +an extended POSIX.1-2017 TZ string cannot represent. .It The output contains data that may not be handled properly by client code designed for older @@ -356,24 +356,15 @@ an unquoted name should not contain characters from the set 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 -.Ql minimum -(or an abbreviation) means the indefinite past. -The word -.Ql 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. .\" .It Ar TO Gives the final year in which the rule applies. -In addition to -.Ql minimum -and +The word .Ql maximum -(as above), -the word +(or an abbreviation) means the indefinite future, and the word .Ql only (or an abbreviation) may be used to repeat the value of the diff --git a/lib/libc/time/zic.c b/lib/libc/time/zic.c index 56e92235f9f4..2a12d431e7e0 100644 --- a/lib/libc/time/zic.c +++ b/lib/libc/time/zic.c @@ -1,4 +1,4 @@ -/* $NetBSD: zic.c,v 1.90 2023/09/16 18:40:26 christos Exp $ */ +/* $NetBSD: zic.c,v 1.91 2024/02/17 14:54:47 christos Exp $ */ /* ** This file is in the public domain, so clarified as of ** 2006-07-17 by Arthur David Olson. @@ -11,7 +11,7 @@ #include #ifndef lint -__RCSID("$NetBSD: zic.c,v 1.90 2023/09/16 18:40:26 christos Exp $"); +__RCSID("$NetBSD: zic.c,v 1.91 2024/02/17 14:54:47 christos Exp $"); #endif /* !defined lint */ /* Use the system 'time' function, instead of any private replacement. @@ -47,6 +47,9 @@ static zic_t const # define ZIC_MAX_ABBR_LEN_WO_WARN 6 #endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */ +/* Minimum and maximum years, assuming signed 32-bit time_t. */ +enum { YEAR_32BIT_MIN = 1901, YEAR_32BIT_MAX = 2038 }; + /* An upper bound on how much a format might grow due to concatenation. */ enum { FORMAT_LEN_GROWTH_BOUND = 5 }; @@ -105,7 +108,6 @@ struct rule { zic_t r_loyear; /* for example, 1986 */ zic_t r_hiyear; /* for example, 1986 */ - bool r_lowasnum; bool r_hiwasnum; int r_month; /* 0..11 */ @@ -345,7 +347,7 @@ enum { */ enum { - YR_MINIMUM, + YR_MINIMUM, /* "minimum" is for backward compatibility only */ YR_MAXIMUM, YR_ONLY }; @@ -429,12 +431,10 @@ static struct lookup const lasts[] = { 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 } @@ -2165,13 +2165,12 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, */ cp = loyearp; lp = byword(cp, begin_years); - rp->r_lowasnum = lp == NULL; - if (!rp->r_lowasnum) switch (lp->l_value) { + if (lp) switch (lp->l_value) { case YR_MINIMUM: - rp->r_loyear = ZIC_MIN; - break; - case YR_MAXIMUM: - rp->r_loyear = ZIC_MAX; + warning(_("FROM year \"%s\" is obsolete;" + " treated as %d"), + cp, YEAR_32BIT_MIN - 1); + rp->r_loyear = YEAR_32BIT_MIN - 1; break; default: unreachable(); } else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_loyear, &xs) != 1) { @@ -2182,9 +2181,6 @@ rulesub(struct rule *rp, const char *loyearp, const char *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; @@ -2967,6 +2963,10 @@ rule_cmp(struct rule const *a, struct rule const *b) return a->r_dayofmonth - b->r_dayofmonth; } +/* Store into RESULT a POSIX.1-2017 TZ string that represent the future + predictions for the zone ZPFIRST with ZONECOUNT entries. Return a + compatibility indicator (a TZDB release year) if successful, a + negative integer if no such TZ string exissts. */ static int stringzone(char *result, int resultlen, const struct zone *const zpfirst, const int zonecount) @@ -3104,7 +3104,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) char * envvar; size_t max_abbr_len; size_t max_envvar_len; - bool prodstic; /* all rules are min to max */ int compat; bool do_extend; char version; @@ -3129,7 +3128,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) timecnt = 0; typecnt = 0; charcnt = 0; - prodstic = zonecount == 1; /* ** Thanks to Earl Chew ** for noting the need to unconditionally initialize startttisstd. @@ -3147,12 +3145,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) updateminmax(zp->z_untilrule.r_loyear); for (j = 0; j < zp->z_nrules; ++j) { struct rule *rp = &zp->z_rules[j]; - if (rp->r_lowasnum) - updateminmax(rp->r_loyear); + updateminmax(rp->r_loyear); if (rp->r_hiwasnum) updateminmax(rp->r_hiyear); - if (rp->r_lowasnum || rp->r_hiwasnum) - prodstic = false; } } /* @@ -3164,7 +3159,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) if (noise) { if (!*envvar) warning("%s %s", - _("no POSIX environment variable for zone"), + _("no POSIX.1-2017 environment variable" + " for zone"), zpfirst->z_name); else if (compat != 0) { /* Circa-COMPAT clients, and earlier clients, might @@ -3176,37 +3172,12 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) } } 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; - } } max_year = max(max_year, (redundant_time / (SECSPERDAY * DAYSPERNYEAR) + EPOCH_YEAR + 1)); @@ -3214,10 +3185,10 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) if (want_bloat()) { /* For the benefit of older systems, generate data from 1900 through 2038. */ - if (min_year > 1900) - min_year = 1900; - if (max_year < 2038) - max_year = 2038; + if (min_year > YEAR_32BIT_MIN - 1) + min_year = YEAR_32BIT_MIN - 1; + if (max_year < YEAR_32BIT_MAX) + max_year = YEAR_32BIT_MAX; } if (min_time < lo_time || hi_time < max_time) @@ -3437,8 +3408,8 @@ error(_("can't determine time zone abbreviation to use just after until time")); 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, + ** If we're extending the explicitly listed observations for + ** 400 years because we can't fill the POSIX.1-2017 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