[tz] [PROPOSED 18/18] New tzselection option ‘now’
Paul Eggert
eggert at cs.ucla.edu
Tue Dec 19 07:26:07 UTC 2023
* Makefile (ZONETABLES, VERSION_DEPS): Add zonenow.tab.
(CHECK_NOW_TIMESTAMP, CHECK_NOW_FUTURE_YEARS, CHECK_NOW_FUTURE_SECS):
New macros.
(check_now): New target rule.
(check_mild): Depend on it.
* NEWS: Mention this new feature.
* checknow.awk, zonenow.tab: New files.
* checktab.awk: Adjust (i.e., loosen) checks for zonenow.tab.
* tzselect.ksh (TZ_ZONETABTYPE_TABLE, TZ_ZONENOW_TABLE):
New vars, so that the code can switch back and for easily between
zone1970.tab and zonenow.tab.
(TZ_ZONE_TABLE): Set to one of those two vars, depending on user.
Let users choose ‘now’ if they care only about timestamps from now on.
Narrow ‘regions’ based on ‘now’ selection, if possible (which it
always is, with the current data).
---
Makefile | 31 +++++-
NEWS | 11 ++
checknow.awk | 53 +++++++++
checktab.awk | 7 +-
tzselect.ksh | 49 +++++++--
zonenow.tab | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 435 insertions(+), 14 deletions(-)
create mode 100644 checknow.awk
create mode 100644 zonenow.tab
diff --git a/Makefile b/Makefile
index a6051531..f473af67 100644
--- a/Makefile
+++ b/Makefile
@@ -580,7 +580,7 @@ YDATA= $(PRIMARY_YDATA) etcetera
NDATA= factory
TDATA_TO_CHECK= $(YDATA) $(NDATA) backward
TDATA= $(YDATA) $(NDATA) $(BACKWARD)
-ZONETABLES= zone1970.tab zone.tab
+ZONETABLES= zone.tab zone1970.tab zonenow.tab
TABDATA= iso3166.tab $(TZDATA_TEXT) $(ZONETABLES)
LEAP_DEPS= leapseconds.awk leap-seconds.list
TZDATA_ZI_DEPS= ziguard.awk zishrink.awk version $(TDATA) \
@@ -619,7 +619,7 @@ VERSION_DEPS= \
tzfile.5 tzfile.h tzselect.8 tzselect.ksh \
workman.sh zdump.8 zdump.c zic.8 zic.c \
ziguard.awk zishrink.awk \
- zone.tab zone1970.tab
+ zone.tab zone1970.tab zonenow.tab
all: tzselect zic zdump libtz.a $(TABDATA) \
vanguard.zi main.zi rearguard.zi
@@ -825,7 +825,8 @@ tzselect: tzselect.ksh version
check: check_back check_mild
check_mild: check_character_set check_white_space check_links \
- check_name_lengths check_slashed_abbrs check_sorted \
+ check_name_lengths check_now \
+ check_slashed_abbrs check_sorted \
check_tables check_web check_ziguard check_zishrink check_tzs
check_character_set: $(ENCHILADA)
@@ -893,7 +894,29 @@ check_links: checklinks.awk tzdata.zi
-f checklinks.awk tzdata.zi
touch $@
-check_tables: checktab.awk $(YDATA) backward $(ZONETABLES)
+# Check timestamps from now through 28 years from now, to make sure
+# that zonenow.tab contains all sequences of planned timestamps,
+# without any duplicate sequences. In theory this might require
+# 2800 years but that would take a long time to check.
+CHECK_NOW_TIMESTAMP = `./date +%s`
+CHECK_NOW_FUTURE_YEARS = 28
+CHECK_NOW_FUTURE_SECS = $(CHECK_NOW_FUTURE_YEARS) '*' 366 '*' 24 '*' 60 '*' 60
+check_now: checknow.awk date tzdata.zi zdump zic zone1970.tab zonenow.tab
+ rm -fr $@.dir
+ mkdir $@.dir
+ ./zic -d $@.dir tzdata.zi
+ now=$(CHECK_NOW_TIMESTAMP) && \
+ future=`expr $(CHECK_NOW_FUTURE_SECS) + $$now` && \
+ ./zdump -i -t $$now,$$future \
+ $$(find $$PWD/$@.dir/????*/ -type f) \
+ >$@.dir/zdump.tab
+ $(AWK) \
+ -v zdump_table=$@.dir/zdump.tab \
+ -f checknow.awk zonenow.tab
+ rm -fr $@.dir
+ touch $@
+
+check_tables: checktab.awk $(YDATA) backward zone.tab zone1970.tab
for tab in $(ZONETABLES); do \
test "$$tab" = zone.tab && links='$(BACKWARD)' || links=''; \
$(AWK) -f checktab.awk -v zone_table=$$tab $(YDATA) $$links \
diff --git a/NEWS b/NEWS
index f2d0bc3c..43070aae 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Unreleased, experimental changes
Briefly:
Ittoqqortoormiit, Greenland changes time zones on 2024-03-31.
Code and data fixes for Palestine timestamps starting in 2072.
+ A new data file zonenow.tab for timestamps starting now.
Changes to future timestamps
@@ -25,6 +26,13 @@ Unreleased, experimental changes
This does not affect UTC offsets, only the tm_isdst flag.
(Thanks to Thomas M. Steenholdt.)
+ New data file
+
+ A new data file zonenow.tab helps configure applications that use
+ timestamps dated from now on. This simplifies configuration,
+ since users choose from a smaller Zone set. The file's format is
+ experimental and subject to change.
+
Changes to code
localtime.c no longer mishandles TZif files that contain a single
@@ -32,6 +40,9 @@ Unreleased, experimental changes
DST was in effect before the transition too. (Thanks to Alois
Treindl for debugging help.)
+ tzselect now optionally reads zonenow.tab, to simplify when
+ configuring only for timestamps dated from now on.
+
tzselect no longer creates temporary files.
tzselect no longer mishandles the following:
diff --git a/checknow.awk b/checknow.awk
new file mode 100644
index 00000000..51ee998f
--- /dev/null
+++ b/checknow.awk
@@ -0,0 +1,53 @@
+# Check zonenow.tab for consistency with primary data.
+
+# Contributed by Paul Eggert. This file is in the public domain.
+
+function record_zone(zone, data) {
+ if (zone) {
+ zone_data[zone] = data
+ zones[data] = zones[data] " " zone
+ }
+}
+
+BEGIN {
+ while (getline <zdump_table) {
+ if ($0 ~ /^TZ/) {
+ record_zone(zone, data)
+ zone = $0
+ sub(/.*\.dir\//, "", zone)
+ sub(/"/, "", zone)
+ data = ""
+ } else if ($0 ~ /./)
+ data = data $0 "\n"
+ }
+ record_zone(zone, data)
+ FS = "\t"
+}
+
+/^[^#]/ {
+ zone = $3
+ data = zone_data[zone]
+ if (!data) {
+ printf "%s: no data\n"
+ status = 1
+ } else {
+ zone2 = zonenow[data]
+ if (zone2) {
+ printf "zones %s and %s identical from now on\n", zone, zone2
+ status = 1
+ } else
+ zonenow[data] = zone
+ }
+}
+
+END {
+ for (zone in zone_data) {
+ data = zone_data[zone]
+ if (!zonenow[data]) {
+ printf "checknow.tab should have one of:%s\n", zones[data]
+ zonenow[data] = zone # This suppresses duplicate diagnostics.
+ status = 1
+ }
+ }
+ exit status
+}
diff --git a/checktab.awk b/checktab.awk
index 2dbf485f..9a26e465 100644
--- a/checktab.awk
+++ b/checktab.awk
@@ -83,7 +83,7 @@ BEGIN {
cc = cca[i]
if (cc2name[cc]) {
cc_used[cc]++
- } else {
+ } else if (! (cc == "XX" && zone_table == "zonenow.tab")) {
printf "%s:%d: %s: unknown country code\n", \
zone_table, zone_NR, cc >>"/dev/stderr"
status = 1
@@ -110,7 +110,7 @@ BEGIN {
used_max_cc = cc
}
}
- if (used_max <= 1 && comments) {
+ if (used_max <= 1 && comments && zone_table != "zonenow.tab") {
printf "%s:%d: unnecessary comment '%s'\n", \
zone_table, i, comments \
>>"/dev/stderr"
@@ -149,7 +149,8 @@ $1 ~ /^#/ { next }
if ($3 ~ /%/) rulePercentUsed[$2] = 1
}
if (tz && tz ~ /\// && tz !~ /^Etc\//) {
- if (!tztab[tz] && FILENAME != "backward") {
+ if (!tztab[tz] && FILENAME != "backward" \
+ && zone_table != "zonenow.tab") {
printf "%s: no data for '%s'\n", zone_table, tz \
>>"/dev/stderr"
status = 1
diff --git a/tzselect.ksh b/tzselect.ksh
index f894bb56..70bda9c0 100644
--- a/tzselect.ksh
+++ b/tzselect.ksh
@@ -196,7 +196,8 @@ read_file() {
}
}
read_file TZ_COUNTRY_TABLE "$TZDIR/iso3166.tab"
-read_file TZ_ZONE_TABLE "$TZDIR/$zonetabtype.tab"
+read_file TZ_ZONETABTYPE_TABLE "$TZDIR/$zonetabtype.tab"
+TZ_ZONENOW_TABLE=
newline='
'
@@ -385,6 +386,7 @@ while
country_result=
region=
time=
+ TZ_ZONE_TABLE=$TZ_ZONETABTYPE_TABLE
case $coord in
?*)
@@ -393,7 +395,8 @@ while
# Ask the user for continent or ocean.
- echo >&2 'Please select a continent, ocean, "coord", "TZ", or "time".'
+ echo >&2 \
+ 'Please select a continent, ocean, "coord", "TZ", "time", or "now".'
quoted_continents=`
$AWK '
@@ -406,10 +409,10 @@ while
printf "'\''%s'\''\n", entry
}
BEGIN {
- TZ_ZONE_TABLE = substr(ARGV[1], 2)
+ TZ_ZONETABTYPE_TABLE = substr(ARGV[1], 2)
ARGV[1] = ""
FS = "\t"
- nlines = split(TZ_ZONE_TABLE, line, /\n/)
+ nlines = split(TZ_ZONETABTYPE_TABLE, line, /\n/)
for (i = 1; i <= nlines; i++) {
$0 = line[i]
if ($0 ~ /^[^#]/)
@@ -421,7 +424,7 @@ while
}
}
}
- ' ="$TZ_ZONE_TABLE" |
+ ' ="$TZ_ZONETABTYPE_TABLE" |
sort -u |
tr '\n' ' '
echo ''
@@ -431,12 +434,19 @@ while
doselect '"$quoted_continents"' \
"coord - I want to use geographical coordinates." \
"TZ - I want to specify the timezone using the POSIX TZ format." \
- "time - I know local time already."
+ "time - I know local time already." \
+ "now - Like \"time\", but configure only for timestamps from now on."
continent=$select_result
case $continent in
Americas) continent=America;;
*" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''`
esac
+ case $zonetabtype,$continent in
+ zonenow,*) ;;
+ *,now)
+ ${TZ_ZONENOW_TABLE:+:} read_file TZ_ZONENOW_TABLE "$TZDIR/zonenow.tab"
+ TZ_ZONE_TABLE=$TZ_ZONENOW_TABLE
+ esac
'
esac
@@ -529,7 +539,7 @@ while
`;;
*)
case $continent in
- time)
+ now|time)
minute_format='%a %b %d %H:%M'
old_minute=`TZ=UTC0 date +"$minute_format"`
for i in 1 2 3
@@ -609,6 +619,31 @@ while
="$continent_re" ="$TZ_COUNTRY_TABLE" ="$zone_table" |
sort -f
`
+ # If all zone table entries have comments, and there are
+ # at most 22 entries, asked based on those comments.
+ # This fits the prompt onto old-fashioned 24-line screens.
+ regions=`
+ $AWK '
+ BEGIN {
+ TZ_ZONE_TABLE = substr(ARGV[1], 2)
+ ARGV[1] = ""
+ FS = "\t"
+ nlines = split(TZ_ZONE_TABLE, line, /\n/)
+ for (i = 1; i <= nlines; i++) {
+ $0 = line[i]
+ if ($0 ~ /^[^#]/ && !missing_comment) {
+ if ($4)
+ comment[++inlines] = $4
+ else
+ missing_comment = 1
+ }
+ }
+ if (!missing_comment && inlines <= 22)
+ for (i = 1; i <= inlines; i++)
+ print comment[i]
+ }
+ ' ="$zone_table"
+ `
# If there's more than one country, ask the user which one.
case $countries in
diff --git a/zonenow.tab b/zonenow.tab
new file mode 100644
index 00000000..b1c1f332
--- /dev/null
+++ b/zonenow.tab
@@ -0,0 +1,298 @@
+# tzdb timezone descriptions, for users who do not care about old timestamps
+#
+# This file is in the public domain.
+#
+# From Paul Eggert (2023-12-18):
+# This file contains a table where each row stands for a timezone
+# where civil timestamps are predicted to agree from now on.
+# This file is like zone1970.tab (see zone1970.tab's coments),
+# but with the following changes:
+#
+# 1. Each timezone corresponds to a set of clocks that are planned
+# to agree from now on. This is a larger set of clocks than in
+# zone1970.tab, where each timezone's clocks must agree from 1970 on.
+# 2. The first column is irrelevant and ignored.
+# 3. The table is sorted in a different way:
+# first by standard time UTC offset;
+# then, if DST is used, by daylight saving UTC offset;
+# then by time zone abbreviation.
+#
+# The format of this table is experimental, and may change in future versions.
+#
+# This table is intended as an aid for users, to help them select timezones
+# appropriate for their practical needs. It is not intended to take or
+# endorse any position on legal or territorial claims.
+#
+#XX coordinates TZ comments
+#
+# -11 - SST
+XX -1416-17042 Pacific/Pago_Pago Midway; Samoa ("SST")
+#
+# -11
+XX -1901-16955 Pacific/Niue Niue
+#
+# -10 - HST
+XX +211825-1575130 Pacific/Honolulu Hawaii ("HST")
+#
+# -10
+XX -1732-14934 Pacific/Tahiti Tahiti; Cook Islands
+#
+# -10/-09 - HST / HDT (North America DST)
+XX +515248-1763929 America/Adak western Aleutians in Alaska ("HST/HDT")
+#
+# -09:30
+XX -0900-13930 Pacific/Marquesas Marquesas
+#
+# -09
+XX -2308-13457 Pacific/Gambier Gambier
+#
+# -09/-08 - AKST/AKDT (North America DST)
+XX +611305-1495401 America/Anchorage most of Alaska ("AKST/AKDT")
+#
+# -08
+XX -2504-13005 Pacific/Pitcairn Pitcairn
+#
+# -08/-07 - PST/PDT (North America DST)
+XX +340308-1181434 America/Los_Angeles Pacific ("PST/PDT") - US & Canada; Mexico near US border
+#
+# -07 - MST
+XX +332654-1120424 America/Phoenix Mountain Standard ("MST") - Arizona; western Mexico; Yukon
+#
+# -07/-06 - MST/MDT (North America DST)
+XX +394421-1045903 America/Denver Mountain ("MST/MDT") - US & Canada; Mexico near US border
+#
+# -06
+XX -0054-08936 Pacific/Galapagos Galápagos
+#
+# -06 - CST
+XX +1924-09909 America/Mexico_City Central Standard ("CST") - Saskatchewan; central Mexico; Central America
+#
+# -06/-05 (Chile DST)
+XX -2709-10926 Pacific/Easter Easter Island
+#
+# -06/-05 - CST/CDT (North America DST)
+XX +415100-0873900 America/Chicago Central ("CST/CDT") - US & Canada; Mexico near US border
+#
+# -05
+XX -1203-07703 America/Lima eastern South America
+#
+# -05 - EST
+XX +175805-0764736 America/Jamaica Eastern Standard ("EST") - Caymans; Jamaica; eastern Mexico; Panama
+#
+# -05/-04 - CST/CDT (Cuba DST)
+XX +2308-08222 America/Havana Cuba
+#
+# -05/-04 - EST/EDT (North America DST)
+XX +404251-0740023 America/New_York Eastern ("EST/EDT") - US & Canada
+#
+# -04
+XX +1030-06656 America/Caracas western South America
+#
+# -04 - AST
+XX +1828-06954 America/Santo_Domingo Atlantic Standard ("AST") - eastern Caribbean
+#
+# -04/-03 (Chile DST)
+XX -3327-07040 America/Santiago most of Chile
+#
+# -04/-03 (Paraguay DST)
+XX -2516-05740 America/Asuncion Paraguay
+#
+# -04/-03 - AST/ADT (North America DST)
+XX +4439-06336 America/Halifax Atlantic ("AST/ADT") - Canada; Bermuda
+#
+# -03:30/-02:30 - NST/NDT (North America DST)
+XX +4734-05243 America/St_Johns Newfoundland ("NST/NDT")
+#
+# -03
+XX -2332-04637 America/Sao_Paulo eastern South America
+#
+# -03/-02 (North America DST)
+XX +4703-05620 America/Miquelon St Pierre & Miquelon
+#
+# -02
+XX -0351-03225 America/Noronha Fernando de Noronha; South Georgia
+#
+# -02/-01 (EU DST)
+XX +6411-05144 America/Nuuk most of Greenland
+#
+# -01
+XX +1455-02331 Atlantic/Cape_Verde Cape Verde
+#
+# -01/+00 (EU DST)
+XX +3744-02540 Atlantic/Azores Azores
+# -01/+00 (EU DST) until 2024-03-01; then -02/-01 (EU DST)
+XX +7029-02158 America/Scoresbysund Ittoqqortoormiit
+#
+# +00 - GMT
+XX +0519-00402 Africa/Abidjan far western Africa; Iceland ("GMT")
+#
+# +00/+01 - GMT/BST (EU DST)
+XX +513030-0000731 Europe/London United Kingdom ("GMT/BST")
+#
+# +00/+01 - WET/WEST (EU DST)
+XX +3843-00908 Europe/Lisbon western Europe ("WET/WEST")
+#
+# +00/+01 - Troll DST
+XX -720041+0023206 Antarctica/Troll Troll Station in Antarctica
+#
+# +01 - CET
+XX +3647+00303 Africa/Algiers Algeria, Tunisia ("CET")
+#
+# +01 - WAT
+XX +0627+00324 Africa/Lagos western Africa ("WAT")
+#
+# +01/+00 - IST/GMT (EU DST in reverse)
+XX +5320-00615 Europe/Dublin Ireland ("IST/GMT")
+#
+# +01/+00 - (Morocco DST)
+XX +3339-00735 Africa/Casablanca Morocco
+#
+# +01/+02 - CET/CEST (EU DST)
+XX +4852+00220 Europe/Paris central Europe ("CET/CEST")
+#
+# +02 - CAT
+XX -2558+03235 Africa/Maputo central Africa ("CAT")
+#
+# +02 - EET
+XX +3254+01311 Africa/Tripoli Libya; Kaliningrad ("EET")
+#
+# +02 - SAST
+XX -2615+02800 Africa/Johannesburg southern Africa ("SAST")
+#
+# +02/+03 - EET/EEST (EU DST)
+XX +3758+02343 Europe/Athens eastern Europe ("EET/EEST")
+#
+# +02/+03 - EET/EEST (Egypt DST)
+XX +3003+03115 Africa/Cairo Egypt
+#
+# +02/+03 - EET/EEST (Lebanon DST)
+XX +3353+03530 Asia/Beirut Lebanon
+#
+# +02/+03 - EET/EEST (Moldova DST)
+XX +4700+02850 Europe/Chisinau Moldova
+#
+# +02/+03 - EET/EEST (Palestine DST)
+XX +3130+03428 Asia/Gaza Palestine
+#
+# +02/+03 - IST/IDT (Israel DST)
+XX +314650+0351326 Asia/Jerusalem Israel
+#
+# +03
+XX +4101+02858 Europe/Istanbul Near East; Belarus
+#
+# +03 - EAT
+XX -0117+03649 Africa/Nairobi eastern Africa ("EAT")
+#
+# +03 - MSK
+XX +554521+0373704 Europe/Moscow Moscow ("MSK")
+#
+# +03:30
+XX +3540+05126 Asia/Tehran Iran
+#
+# +04
+XX +2518+05518 Asia/Dubai Russia; Caucasus; Persian Gulf; Seychelles; Réunion
+#
+# +04:30
+XX +3431+06912 Asia/Kabul Afghanistan
+#
+# +05
+XX +4120+06918 Asia/Tashkent Russia; Tajikistan; Turkmenistan; Uzbekistan; Maldives
+#
+# +05 - PKT
+XX +2452+06703 Asia/Karachi Pakistan ("PKT")
+#
+# +05:30
+XX +0656+07951 Asia/Colombo Sri Lanka
+#
+# +05:30 - IST
+XX +2232+08822 Asia/Kolkata India ("IST")
+#
+# +05:45
+XX +2743+08519 Asia/Kathmandu Nepal
+#
+# +06
+XX +2343+09025 Asia/Dhaka Russia; Kyrgyzstan; Bhutan; Bangladesh; Chagos
+#
+# +06:30
+XX +1647+09610 Asia/Yangon Myanmar; Cocos
+#
+# +07
+XX +1345+10031 Asia/Bangkok Russia; Indochina; Christmas Island
+#
+# +07 - WIB
+XX -0610+10648 Asia/Jakarta Indonesia ("WIB")
+#
+# +08
+XX +0117+10351 Asia/Singapore Russia; Brunei; Malaysia; Singapore
+#
+# +08 - AWST
+XX -3157+11551 Australia/Perth Western Australia ("AWST")
+#
+# +08 - CST
+XX +3114+12128 Asia/Shanghai China ("CST")
+#
+# +08 - HKT
+XX +2217+11409 Asia/Hong_Kong Hong Kong ("HKT")
+#
+# +08 - PHT
+XX +1435+12100 Asia/Manila Philippines ("PHT")
+#
+# +08 - WITA
+XX -0507+11924 Asia/Makassar Indonesia ("WITA")
+#
+# +08:45
+XX -3143+12852 Australia/Eucla Eucla
+#
+# +09
+XX +5203+11328 Asia/Chita Russia; Palau; East Timor
+#
+# +09 - JST
+XX +353916+1394441 Asia/Tokyo Japan ("JST")
+#
+# +09 - KST
+XX +3733+12658 Asia/Seoul Korea ("KST")
+#
+# +09 - WIT
+XX -0232+14042 Asia/Jayapura Indonesia ("WIT")
+#
+# +09:30 - ACST
+XX -1228+13050 Australia/Darwin Northern Territory ("ACST")
+#
+# +09:30/+10:30 - ACST/ACDT (Australia DST)
+XX -3455+13835 Australia/Adelaide South Australia ("ACST/ACDT")
+#
+# +10
+XX +4310+13156 Asia/Vladivostok Russia; Yap; Chuuk; Papua New Guinea; Dumont d'Urville
+#
+# +10 - AEST
+XX -2728+15302 Australia/Brisbane Queensland ("AEST")
+#
+# +10 - ChST
+XX +1328+14445 Pacific/Guam Mariana Islands ("ChST")
+#
+# +10/+11 - AEST/AEDT (Australia DST)
+XX -3352+15113 Australia/Sydney southeast Australia ("AEST/AEDT")
+#
+# +10:30/+11
+XX -3133+15905 Australia/Lord_Howe Lord Howe Island
+#
+# +11
+XX -0613+15534 Pacific/Bougainville Russia; Kosrae; Bougainville; Solomons
+#
+# +11/+12 (Australia DST)
+XX -2903+16758 Pacific/Norfolk Norfolk Island
+#
+# +12
+XX +5301+15839 Asia/Kamchatka Russia; Tuvalu; Fiji; etc.
+#
+# +12/+13 (New Zealand DST)
+XX -3652+17446 Pacific/Auckland New Zealand ("NZST/NZDT")
+#
+# +12:45/+13:45 (Chatham DST)
+XX -4357-17633 Pacific/Chatham Chatham Islands
+#
+# +13
+XX -210800-1751200 Pacific/Tongatapu Kanton; Tokelau; Samoa (western); Tonga
+#
+# +14
+XX +0152-15720 Pacific/Kiritimati Kiritimati
--
2.40.1
More information about the tz
mailing list