1#!/bin/sh 2# Test 'date --debug' option. 3 4# Copyright (C) 2016-2023 Free Software Foundation, Inc. 5 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 3 of the License, or 9# (at your option) any later version. 10 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <https://www.gnu.org/licenses/>. 18 19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 20print_ver_ date 21 22export LC_ALL=C 23 24## Ensure timezones are supported. 25## (NOTE: America/Belize timezone does not change on DST) 26test "$(TZ=America/Belize date +%z)" = '-0600' \ 27 || skip_ 'Timezones database not found' 28 29date --debug >/dev/null 2>d_t_fmt.err || fail=1 30d_t_fmt=$(sed -n "s/.*'\(.*\)'$/\1/p" < d_t_fmt.err) || framework_failure_ 31test -n "$d_t_fmt" || fail=1 32 33## 34## Test 1: complex date string 35## 36in1='TZ="Asia/Tokyo" Sun, 90-12-11 + 3 days - 90 minutes' 37 38cat<<EOF>exp1 39date: parsed day part: Sun (day ordinal=0 number=0) 40date: parsed date part: (Y-M-D) 0090-12-11 41date: parsed relative part: +3 day(s) 42date: parsed relative part: +3 day(s) -90 minutes 43date: input timezone: TZ="Asia/Tokyo" in date string 44date: warning: adjusting year value 90 to 1990 45date: warning: using midnight as starting time: 00:00:00 46date: warning: day (Sun) ignored when explicit dates are given 47date: starting date/time: '(Y-M-D) 1990-12-11 00:00:00' 48date: warning: when adding relative days, it is recommended to specify noon 49date: after date adjustment (+0 years, +0 months, +3 days), 50date: new date/time = '(Y-M-D) 1990-12-14 00:00:00' 51date: '(Y-M-D) 1990-12-14 00:00:00' = 661100400 epoch-seconds 52date: after time adjustment (+0 hours, -90 minutes, +0 seconds, +0 ns), 53date: new time = 661095000 epoch-seconds 54date: timezone: TZ="Asia/Tokyo" environment value 55date: final: 661095000.000000000 (epoch-seconds) 56date: final: (Y-M-D) 1990-12-13 13:30:00 (UTC) 57date: final: (Y-M-D) 1990-12-13 22:30:00 (UTC+09) 58date: output format: '%a %b %e %T %z %Y' 59Thu Dec 13 07:30:00 -0600 1990 60EOF 61 62TZ=America/Belize date --debug -d "$in1" +'%a %b %e %T %z %Y' >out1 2>&1 || 63 fail=1 64 65compare exp1 out1 || fail=1 66 67## 68## Test 2: Invalid date from Coreutils' FAQ 69## (with explicit timezone added) 70in2='TZ="America/Edmonton" 2006-04-02 02:30:00' 71cat<<EOF>exp2 72date: parsed date part: (Y-M-D) 2006-04-02 73date: parsed time part: 02:30:00 74date: input timezone: TZ="America/Edmonton" in date string 75date: using specified time as starting value: '02:30:00' 76date: error: invalid date/time value: 77date: user provided time: '(Y-M-D) 2006-04-02 02:30:00' 78date: normalized time: '(Y-M-D) 2006-04-02 XX:XX:XX' 79date: -- 80date: possible reasons: 81date: nonexistent due to daylight-saving time; 82date: numeric values overflow; 83date: missing timezone 84date: invalid date 'TZ="America/Edmonton" 2006-04-02 02:30:00' 85EOF 86 87# date should return 1 (error) for invalid date 88returns_ 1 date --debug -d "$in2" >out2-t 2>&1 || fail=1 89 90# The output line of "normalized time" can differ between systems 91# (e.g. glibc vs musl) and should not be checked. 92# See: https://lists.gnu.org/archive/html/coreutils/2019-05/msg00039.html 93sed '/normalized time:/s/ [0-9][0-9]:[0-9][0-9]:[0-9][0-9]/ XX:XX:XX/' \ 94 out2-t > out2 || framework_failure_ 95 96compare exp2 out2 || fail=1 97 98## 99## Test 3: timespec (input always UTC, output is TZ-dependent) 100## 101in3='@1' 102cat<<EOF>exp3 103date: parsed number of seconds part: number of seconds: 1 104date: input timezone: '@timespec' - always UTC 105date: timezone: TZ="America/Lima" environment value 106date: final: 1.000000000 (epoch-seconds) 107date: final: (Y-M-D) 1970-01-01 00:00:01 (UTC) 108date: final: (Y-M-D) 1969-12-31 19:00:01 (UTC-05) 109date: output format: '%a %b %e %T %z %Y' 110Wed Dec 31 19:00:01 -0500 1969 111EOF 112 113TZ=America/Lima date --debug -d "$in3" +'%a %b %e %T %z %Y' >out3 2>&1 || fail=1 114compare exp3 out3 || fail=1 115 116## 117## Parsing a lone number. 118## Fixed in gnulib v0.1-1099-gf2d4b5c 119## https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=f2d4b5caa 120cat<<EOF>exp4 121date: parsed number part: (Y-M-D) 2013-01-01 122date: input timezone: TZ="UTC0" environment value or -u 123date: warning: using midnight as starting time: 00:00:00 124date: starting date/time: '(Y-M-D) 2013-01-01 00:00:00' 125date: '(Y-M-D) 2013-01-01 00:00:00' = 1356998400 epoch-seconds 126date: timezone: Universal Time 127date: final: 1356998400.000000000 (epoch-seconds) 128date: final: (Y-M-D) 2013-01-01 00:00:00 (UTC) 129date: final: (Y-M-D) 2013-01-01 00:00:00 (UTC+00) 130date: output format: '$d_t_fmt' 131Tue Jan 1 00:00:00 UTC 2013 132EOF 133 134date -u --debug -d '20130101' >out4 2>&1 || fail=1 135compare exp4 out4 || fail=1 136 137 138## 139## Parsing a relative number after a timezone string 140## Fixed in gnulib v0.1-1100-g5c438e8 141## https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=5c438e8ce7d 142cat<<EOF>exp5 143date: parsed date part: (Y-M-D) 2013-10-30 144date: parsed time part: 00:00:00 145date: parsed relative part: -8 day(s) 146date: parsed zone part: UTC+00 147date: input timezone: parsed date/time string (+00) 148date: using specified time as starting value: '00:00:00' 149date: starting date/time: '(Y-M-D) 2013-10-30 00:00:00 TZ=+00' 150date: warning: when adding relative days, it is recommended to specify noon 151date: after date adjustment (+0 years, +0 months, -8 days), 152date: new date/time = '(Y-M-D) 2013-10-22 00:00:00 TZ=+00' 153date: '(Y-M-D) 2013-10-22 00:00:00 TZ=+00' = 1382400000 epoch-seconds 154date: timezone: Universal Time 155date: final: 1382400000.000000000 (epoch-seconds) 156date: final: (Y-M-D) 2013-10-22 00:00:00 (UTC) 157date: final: (Y-M-D) 2013-10-22 00:00:00 (UTC+00) 158date: output format: '%F' 1592013-10-22 160EOF 161 162in5='2013-10-30 00:00:00 UTC -8 days' 163date -u --debug +%F -d "$in5" >out5 2>&1 || fail=1 164compare exp5 out5 || fail=1 165 166## 167## Explicitly warn about unexpected day/month shifts. 168## added in gnulib v0.1-1101-gf14eff1 169## https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=f14eff1b3cde2b 170TOOLONG='it is recommended to specify the 15th of the months' 171cat<<EOF>exp6 172date: parsed date part: (Y-M-D) 2016-10-31 173date: parsed relative part: -1 month(s) 174date: input timezone: TZ="UTC0" environment value or -u 175date: warning: using midnight as starting time: 00:00:00 176date: starting date/time: '(Y-M-D) 2016-10-31 00:00:00' 177date: warning: when adding relative months/years, $TOOLONG 178date: after date adjustment (+0 years, -1 months, +0 days), 179date: new date/time = '(Y-M-D) 2016-10-01 00:00:00' 180date: warning: month/year adjustment resulted in shifted dates: 181date: adjusted Y M D: 2016 09 31 182date: normalized Y M D: 2016 10 01 183date: '(Y-M-D) 2016-10-01 00:00:00' = 1475280000 epoch-seconds 184date: timezone: Universal Time 185date: final: 1475280000.000000000 (epoch-seconds) 186date: final: (Y-M-D) 2016-10-01 00:00:00 (UTC) 187date: final: (Y-M-D) 2016-10-01 00:00:00 (UTC+00) 188date: output format: '$d_t_fmt' 189Sat Oct 1 00:00:00 UTC 2016 190EOF 191 192date -u --debug -d '2016-10-31 - 1 month' >out6 2>&1 || fail=1 193compare exp6 out6 || fail=1 194 195 196## 197## Explicitly warn about crossing DST boundaries. 198## added in gnulib v0.1-1102-g30a55dd 199## https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=30a55dd72dad2 200TOOLONG2='it is recommended to specify the 15th of the months' 201cat<<EOF>exp7 202date: parsed date part: (Y-M-D) 2016-06-01 203date: parsed local_zone part: isdst=1 204date: parsed relative part: +6 month(s) 205date: input timezone: TZ="America/New_York" environment value, dst 206date: warning: using midnight as starting time: 00:00:00 207date: starting date/time: '(Y-M-D) 2016-06-01 00:00:00' 208date: warning: when adding relative months/years, $TOOLONG2 209date: after date adjustment (+0 years, +6 months, +0 days), 210date: new date/time = '(Y-M-D) 2016-11-30 23:00:00' 211date: warning: daylight saving time changed after date adjustment 212date: warning: month/year adjustment resulted in shifted dates: 213date: adjusted Y M D: 2016 12 01 214date: normalized Y M D: 2016 11 30 215date: '(Y-M-D) 2016-11-30 23:00:00' = 1480564800 epoch-seconds 216date: timezone: TZ="America/New_York" environment value 217date: final: 1480564800.000000000 (epoch-seconds) 218date: final: (Y-M-D) 2016-12-01 04:00:00 (UTC) 219date: final: (Y-M-D) 2016-11-30 23:00:00 (UTC-05) 220date: output format: '%F' 2212016-11-30 222EOF 223 224in7='2016-06-01 EDT + 6 months' 225TZ=America/New_York date --debug -d "$in7" +%F >out7 2>&1 || fail=1 226compare exp7 out7 || fail=1 227 228 229## fix local timezone debug messages. 230## fixed in git v0.1-1103-gc56e7fb 231## https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=c56e7fbb032 232 233cat<<EOF>exp8_1 234date: parsed date part: (Y-M-D) 2011-12-11 235date: parsed local_zone part: isdst=0 236date: input timezone: TZ="Europe/Helsinki" environment value 237date: warning: using midnight as starting time: 00:00:00 238date: starting date/time: '(Y-M-D) 2011-12-11 00:00:00' 239date: '(Y-M-D) 2011-12-11 00:00:00' = 1323554400 epoch-seconds 240date: timezone: TZ="Europe/Helsinki" environment value 241date: final: 1323554400.000000000 (epoch-seconds) 242date: final: (Y-M-D) 2011-12-10 22:00:00 (UTC) 243date: final: (Y-M-D) 2011-12-11 00:00:00 (UTC+02) 244date: output format: '$d_t_fmt' 245Sun Dec 11 00:00:00 EET 2011 246EOF 247 248TZ=Europe/Helsinki date --debug -d '2011-12-11 EET' >out8_1 2>&1 || fail=1 249compare exp8_1 out8_1 || fail=1 250 251cat<<EOF>exp8_2 252date: parsed date part: (Y-M-D) 2011-06-11 253date: parsed local_zone part: isdst=1 254date: input timezone: TZ="Europe/Helsinki" environment value, dst 255date: warning: using midnight as starting time: 00:00:00 256date: starting date/time: '(Y-M-D) 2011-06-11 00:00:00' 257date: '(Y-M-D) 2011-06-11 00:00:00' = 1307739600 epoch-seconds 258date: timezone: TZ="Europe/Helsinki" environment value 259date: final: 1307739600.000000000 (epoch-seconds) 260date: final: (Y-M-D) 2011-06-10 21:00:00 (UTC) 261date: final: (Y-M-D) 2011-06-11 00:00:00 (UTC+03) 262date: output format: '$d_t_fmt' 263Sat Jun 11 00:00:00 EEST 2011 264EOF 265 266TZ=Europe/Helsinki date --debug -d '2011-06-11 EEST' >out8_2 2>&1 || fail=1 267compare exp8_2 out8_2 || fail=1 268 269 270 271## fix debug message on lone year number (The "2011" part). 272## fixed in gnulib v0.1-1104-g15b8f30 273## https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=15b8f3046a25 274## 275## NOTE: 276## When the date 'Apr 11' is parsed, the year part will be the 277## current year. The expected output thus depends on the year 278## the test is being run. We'll use sed to change it to XXXX. 279cat<<EOF>exp9 280date: parsed date part: (Y-M-D) XXXX-04-11 281date: parsed time part: 22:59:00 282date: parsed number part: year: 2011 283date: input timezone: TZ="UTC0" environment value or -u 284date: using specified time as starting value: '22:59:00' 285date: starting date/time: '(Y-M-D) 2011-04-11 22:59:00' 286date: '(Y-M-D) 2011-04-11 22:59:00' = 1302562740 epoch-seconds 287date: timezone: Universal Time 288date: final: 1302562740.000000000 (epoch-seconds) 289date: final: (Y-M-D) 2011-04-11 22:59:00 (UTC) 290date: final: (Y-M-D) 2011-04-11 22:59:00 (UTC+00) 291date: output format: '$d_t_fmt' 292Mon Apr 11 22:59:00 UTC 2011 293EOF 294 295date -u --debug -d 'Apr 11 22:59:00 2011' >out9_t 2>&1 || fail=1 296sed '1s/(Y-M-D) [0-9][0-9][0-9][0-9]-/(Y-M-D) XXXX-/' out9_t > out9 \ 297 || framework_failure_ 298compare exp9 out9 || fail=1 299 300 301# Diagnose discarded -d arguments 302echo 'date: only using last of multiple -d options' > exp10 \ 303 || framework_failure_ 304cat exp9 >> exp10 || framework_failure_ 305date -u --debug -d 'discard' -d 'Apr 11 22:59:00 2011' > out10_t 2>&1 || fail=1 306sed '2s/(Y-M-D) [0-9][0-9][0-9][0-9]-/(Y-M-D) XXXX-/' out10_t >> out10 \ 307 || framework_failure_ 308compare exp10 out10 || fail=1 309 310 311Exit $fail 312