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