4 # Copyright (C) 2005-2016 Free Software Foundation, Inc.
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.
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.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 (my $ME = $0) =~ s
|.*/||;
23 # Turn off localization of executable's output.
24 @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x
3;
26 # Export TZ=UTC0 so that zone-dependent strings match.
30 my $d0 = '1997-01-19';
31 my $d1 = "$d0 $t0 +0";
32 my $dT = "${d0}T$t0+0"; # ISO 8601 with "T" separator
34 my $ts = '08:17:49'; # next second
35 my $tm = '08:18:48'; # next minute
36 my $th = '09:17:48'; # next hour
38 my $dd = '1997-01-20'; # next day
39 my $dw = '1997-01-26'; # next week
40 my $dm = '1997-02-19'; # next month
41 my $dy = '1998-01-19'; # next month
43 my $fmt = "'+%Y-%m-%d %T'";
47 # test-name, [option, option, ...] {OUT=>"expected-output"}
49 ['1', "-d '$d1' +'%% %a %A %b %B'", {OUT
=>"% Sun Sunday Jan January"}],
51 # [Actually, skip it on *all* systems. -- this Perl code is run at
52 # distribution-build-time, not at configure/test time. ]
54 # Skip the test of %c on SunOS4 systems. Such systems would fail this
55 # test because their underlying strftime doesn't handle the %c format
56 # properly. GNU strftime must rely on the underlying host library
57 # function to get locale-dependent behavior, as strftime is the only
58 # portable interface to that behavior.
59 # ['2', "-d '$d1' +'%c'", {OUT=>"Sun Jan 19 $t0 1997"}],
61 ['3', "-d '$d1' +'%d_%D_%e_%h_%H'", {OUT
=>"19_01/19/97_19_Jan_08"}],
62 ['3T',"-d '$dT' +'%d_%D_%e_%h_%H'", {OUT
=>"19_01/19/97_19_Jan_08"}],
64 ['4', "-d '$d1' +'%I_%j_%k_%l_%m'", {OUT
=>"08_019_ 8_ 8_01"}],
65 ['5', "-d '$d1' +'%M_%n_%p_%r'", {OUT
=>"17_\n_AM_$t0 AM"}],
66 ['6', "-d '$d1' +'%s_%S_%t_%T'", {OUT
=>"853661868_48_\t_$t0"}],
67 ['7', "-d '$d1' +'%U_%V_%w_%W'", {OUT
=>"03_03_0_02"}],
68 ['8', "-d '$d1' +'%x_%X_%y_%Y'", {OUT
=>"01/19/97_${t0}_97_1997"}],
69 ['9', "-d '$d1' +'%z'", {OUT
=>"+0000"}],
71 ['leap-1', "--date '02/29/1996 1 year' +%Y-%m-%d", {OUT
=>"1997-03-01"}],
73 ['U95-1', "--date '1995-1-1' +%U", {OUT
=>"01"}],
74 ['U95-2', "--date '1995-1-7' +%U", {OUT
=>"01"}],
75 ['U95-3', "--date '1995-1-8' +%U", {OUT
=>"02"}],
77 ['U92-1', "--date '1992-1-1' +%U", {OUT
=>"00"}],
78 ['U92-2', "--date '1992-1-4' +%U", {OUT
=>"00"}],
79 ['U92-3', "--date '1992-1-5' +%U", {OUT
=>"01"}],
81 ['V92-1', "--date '1992-1-1' +%V", {OUT
=>"01"}],
82 ['V92-2', "--date '1992-1-5' +%V", {OUT
=>"01"}],
83 ['V92-3', "--date '1992-1-6' +%V", {OUT
=>"02"}],
85 ['W92-1', "--date '1992-1-1' +%W", {OUT
=>"00"}],
86 ['W92-2', "--date '1992-1-5' +%W", {OUT
=>"00"}],
87 ['W92-3', "--date '1992-1-6' +%W", {OUT
=>"01"}],
89 ['millen-1', "--date '1998-1-1 3 years' +%Y", {OUT
=>"2001"}],
91 ['rel-0', "-d '$d1 now' '+%Y-%m-%d %T'", {OUT
=>"$d0 $t0"}],
93 ['rel-1a', "-d '$d1 yesterday' $fmt", {OUT
=>"1997-01-18 $t0"}],
94 ['rel-1b', "-d '$d1 tomorrow' $fmt", {OUT
=>"1997-01-20 $t0"}],
96 ['rel-2a', "-d '$d1 6 years ago' $fmt", {OUT
=>"1991-01-19 $t0"}],
97 ['rel-2b', "-d '$d1 7 months ago' $fmt", {OUT
=>"1996-06-19 $t0"}],
98 ['rel-2c', "-d '$d1 8 weeks ago' $fmt", {OUT
=>"1996-11-24 $t0"}],
99 ['rel-2d', "-d '$d1 1 day ago' $fmt", {OUT
=>"1997-01-18 $t0"}],
100 ['rel-2e', "-d '$d1 2 hours ago' $fmt", {OUT
=>"$d0 06:17:48"}],
101 ['rel-2f', "-d '$d1 3 minutes ago' $fmt", {OUT
=>"$d0 08:14:48"}],
102 ['rel-2g', "-d '$d1 4 seconds ago' $fmt", {OUT
=>"$d0 08:17:44"}],
104 ['rel-3a', "-d '$d1 4 seconds ago' $fmt", {OUT
=>"$d0 08:17:44"}],
106 # This has always worked, ...
107 ['rel-1day', "-d '20050101 1 day' +%F", {OUT
=>"2005-01-02"}],
108 # ...but up to coreutils-6.9, this was rejected due to the "+".
109 ['rel-plus1', "-d '20050101 +1 day' +%F", {OUT
=>"2005-01-02"}],
111 ['next-s', "-d '$d1 next second' '+%Y-%m-%d %T'", {OUT
=>"$d0 $ts"}],
112 ['next-m', "-d '$d1 next minute' '+%Y-%m-%d %T'", {OUT
=>"$d0 $tm"}],
113 ['next-h', "-d '$d1 next hour' '+%Y-%m-%d %T'", {OUT
=>"$d0 $th"}],
114 ['next-d', "-d '$d1 next day' '+%Y-%m-%d %T'", {OUT
=>"$dd $t0"}],
115 ['next-w', "-d '$d1 next week' '+%Y-%m-%d %T'", {OUT
=>"$dw $t0"}],
116 ['next-mo', "-d '$d1 next month' '+%Y-%m-%d %T'", {OUT
=>"$dm $t0"}],
117 ['next-y', "-d '$d1 next year' '+%Y-%m-%d %T'", {OUT
=>"$dy $t0"}],
119 ['utc-0', "-u -d '08/01/97 6:00' '+%D,%H:%M'", {OUT
=>"08/01/97,06:00"},
120 {ENV
=> 'TZ=UTC+4'}],
122 ['utc-0a', "-u -d '08/01/97 6:00 UTC +4 hours' '+%D,%H:%M'",
123 {OUT
=>"08/01/97,10:00"}],
124 # Make sure --file=FILE works with -u.
125 ['utc-1', "-u --file=f '+%Y-%m-%d %T'",
126 {AUX
=>{f
=>"$d0 $t0\n$d0 $t0"}},
127 {OUT
=>"$d0 $t0\n$d0 $t0"},
128 {ENV
=> 'TZ=UTC+1'}],
130 ['utc-1a', "-u --file=f '+%Y-%m-%d %T'",
131 {AUX
=>{f
=>"$d0 $t0 UTC +1 hour\n$d0 $t0 UTC +1 hour"}},
132 {OUT
=>"$d0 $th\n$d0 $th"}],
134 # From the examples in the documentation.
135 ['date2sec-0', "-d '1970-01-01 00:00:01' +%s", {OUT
=>"7201"},
136 {ENV
=> 'TZ=UTC+2'}],
138 # Same as above, but don't rely on TZ in environment.
139 ['date2sec-0a', "-d '1970-01-01 00:00:01 UTC +2 hours' +%s",
142 ['date2sec-1', "-d 2000-01-01 +%s", {OUT
=>"946684800"}],
143 ['sec2date-0', "-d '1970-01-01 UTC 946684800 sec' +'%Y-%m-%d %T %z'",
144 {OUT
=>"2000-01-01 00:00:00 +0000"}],
146 ['this-m', "-d '$d0 $t0 this minute' $fmt", {OUT
=>"$d0 $t0"}],
147 ['this-h', "-d '$d0 $t0 this hour' $fmt", {OUT
=>"$d0 $t0"}],
148 ['this-w', "-d '$d0 $t0 this week' $fmt", {OUT
=>"$d0 $t0"}],
149 ['this-mo', "-d '$d0 $t0 this month' $fmt", {OUT
=>"$d0 $t0"}],
150 ['this-y', "-d '$d0 $t0 this year' $fmt", {OUT
=>"$d0 $t0"}],
152 ['risks-1', "-d 'Nov 10 1996' $fmt", {OUT
=>"1996-11-10 00:00:00"}],
154 # This one would pass if TZ (with any, or even no, value) were in
156 ['regress-1', "-u -d '1996-11-10 0:00:00 +0' $fmt",
157 {OUT
=>"1996-11-10 00:00:00"},
161 ['datevtime-1', "-d 000909 $fmt", {OUT
=>"2000-09-09 00:00:00"}],
163 # test for RFC-822 conformance
164 ['rfc822-1', "-R -d '$d1'", {OUT
=>"Sun, 19 Jan 1997 08:17:48 +0000"},
165 # Solaris 5.9's /bin/sh emits this diagnostic to stderr
166 # if you don't have support for the named locale.
167 {ERR_SUBST
=> q
!s/^couldn't set locale correctly\n//!},
168 {ENV
=> 'LC_ALL=de_DE TZ=UTC0'}],
170 # Relative seconds, with time. fixed in 2.0j
171 ['relative-1', "--utc -d '1970-01-01 00:00:00 UTC +961062237 sec' $fmt",
172 {OUT
=>"2000-06-15 09:43:57"}],
174 # Relative seconds, no time.
175 ['relative-2', "--utc -d '1970-01-01 UTC +961062237 sec' $fmt",
176 {OUT
=>"2000-06-15 09:43:57"},
177 {ENV
=> 'TZ=UTC+1'}],
179 # Relative days, no time, across time zones.
180 ['relative-3', "-I -d '2006-04-23 21 days ago'", {OUT
=>"2006-04-02"},
181 {ENV
=>'TZ=PST8PDT,M4.1.0,M10.5.0'}],
183 # This would infloop (or appear to) prior to coreutils-4.5.5,
184 # due to a bug in strftime.c.
185 ['wide-fmt', "-d '1999-06-01'", '+%3004Y', {OUT
=>'0' x
3000 . "1999"}],
187 # Ensure that we can parse MONTHNAME-DAY-YEAR.
188 ['moname-d-y', '--iso -d May-23-2003', {OUT
=>"2003-05-23"}],
189 ['moname-d-y-r', '--rfc-3339=date -d May-23-2003', {OUT
=>"2003-05-23"}],
191 ['epoch', '--iso=sec -d @31536000',
192 {OUT
=>"1971-01-01T00:00:00+00:00"}],
193 ['epoch-r', '--rfc-3339=sec -d @31536000',
194 {OUT
=>"1971-01-01 00:00:00+00:00"}],
196 ['ns-10', '--iso=ns', '-d "1969-12-31 13:00:00.00000001-1100"',
197 {OUT
=>"1970-01-01T00:00:00,000000010+00:00"}],
198 ['ns-10-r', '--rfc-3339=ns', '-d "1969-12-31 13:00:00.00000001-1100"',
199 {OUT
=>"1970-01-01 00:00:00.000000010+00:00"}],
201 ['ns-max32', '--iso=ns', '-d "2038-01-19 03:14:07.999999999"',
202 {OUT
=>"2038-01-19T03:14:07,999999999+00:00"}],
203 ['ns-max32-r', '--rfc-3339=ns', '-d "2038-01-19 03:14:07.999999999"',
204 {OUT
=>"2038-01-19 03:14:07.999999999+00:00"}],
206 ['tz-1', '+%:::z', {OUT
=>"-12:34:56"}, {ENV
=>'TZ=XXX12:34:56'}],
208 ['tz-2', '+%:::z', {OUT
=>"+12:34:56"}, {ENV
=>'TZ=XXX-12:34:56'}],
210 ['tz-3', '+%::z', {OUT
=>"+01:02:03"}, {ENV
=>'TZ=XXX-1:02:03'}],
212 ['tz-4', '+%:::z', {OUT
=>"+12"}, {ENV
=>'TZ=XXX-12'}],
214 ['tz-5', '+%:z', {OUT
=>"-00:01"}, {ENV
=>'TZ=XXX0:01'}],
216 # Accept %:z with a field width before the ':'.
217 ['tz-5w','+%8:z', {OUT
=>"-0000:01"}, {ENV
=>'TZ=XXX0:01'}],
218 # Don't recognize %:z with a field width between the ':' and the 'z'.
219 ['tz-5wf', '+%:8z', {OUT
=>"%:8z"}, {ENV
=>'TZ=XXX0:01'}],
223 "-d'1970-01-01 00:00:00.1234567 UTC +961062237.987654321 sec'",
224 {OUT
=>"2000-06-15T09:43:58,111111021+00:00"}],
225 ['ns-relativer', '--rfc-3339=ns',
226 "-d'1970-01-01 00:00:00.1234567 UTC +961062237.987654321 sec'",
227 {OUT
=>"2000-06-15 09:43:58.111111021+00:00"}],
229 # Since coreutils/lib/getdate.y revision 1.96 (post-coreutils-5.3.0),
230 # a command like the following would mistakenly exit nonzero with an
231 # 'invalid date ...' diagnostic, but when run in a time zone for
232 # which daylight savings time is in effect for the starting date.
233 # Unfortunately (for ease of testing), if you set TZ at all, this
234 # failure is not triggered, hence the removal of TZ from the environment.
235 ['cross-dst', "-d'2005-03-27 +1 day'", '+%Y', {OUT
=>"2005"},
239 ['empty-fmt', '+', {OUT
=>""}],
241 ['neg-secs', '-d @-22 +%05s', {OUT
=>"-0022"}],
242 ['neg-secs2', '-d @-22 +%_5s', {OUT
=>" -22"}],
244 # FIXME: Ensure date doesn't print uninitialized data
245 # for an out-of-range date. This test is currently
246 # disabled as various systems have different limits
247 # for localtime(), and we can't use perl for example
248 # to determine those limits as it doesn't always call
249 # down to the system localtime() as it has configure
250 # time checks and settings itself for these limits.
251 #['uninit-64', "-d \@72057594037927935",
253 # # Use ERR_SUBST to get around fact that the diagnostic
254 # # you get on a system with 32-bit time_t is not the same as
255 # # the one you get for a system where it's 64 bits wide:
256 # # - date: time 72057594037927935 is out of range
257 # # + date: invalid date '@72057594037927935'
258 # {ERR_SUBST => 's/.*//'},
263 ['fill-1', '-d 1999-12-08 +%_3d', {OUT
=>' 8'}],
264 ['fill-2', '-d 1999-12-08 +%03d', {OUT
=>'008'}],
266 # Test the combination of the to-upper-case modifier (^) and a conversion
267 # specifier that expands to a string containing lower case characters.
268 ['subfmt-up1', '-d "1999-12-08 7:30" "+%^c"',
269 # Solaris 5.9 prints 'WED DEC 08 07:30:00 1999', while
270 # most others print 'WED DEC 8 07:30:00 1999'.
271 {OUT_SUBST
=> 's/ [ 0]8.*//'},
274 ['invalid-high-bit-set', "-d '\xb0'",
275 {ERR
=> "date: invalid date '\\260'\n"},
279 # From coreutils-5.3.0 to 8.22 inclusive
280 # this would either infinite loop or crash
281 ['invalid-TZ-crash', "-d 'TZ=\"\"\"'",
282 {ERR
=> "date: invalid date 'TZ=\"\"\"'\n"},
287 # Repeat the cross-dst test, using Jan 1, 2005 and every interval from 1..364.
288 foreach my $i (1..364)
290 push @Tests, ["cross-dst$i",
291 "-d'2005-01-01 +$i day'", '+%Y', {OUT
=>"2005"},
296 # Append "\n" to each OUT=> RHS if the expected exit value is either
297 # zero or not specified (defaults to zero).
298 foreach my $t (@Tests)
303 ref $e && ref $e eq 'HASH' && defined $e->{EXIT
}
304 and $exit_val = $e->{EXIT
};
308 ref $e && ref $e eq 'HASH' && defined $e->{OUT
} && ! $exit_val
309 and $e->{OUT
} .= "\n";
313 my $save_temps = $ENV{DEBUG
};
314 my $verbose = $ENV{VERBOSE
};
317 my $fail = run_tests
($ME, $prog, \
@Tests, $save_temps, $verbose);