xref: /netbsd-src/external/gpl2/xcvs/dist/lib/test-getdate.sh (revision a7c918477dd5f12c1da816ba05caf44eab2d06d6)
1*a7c91847Schristos#! /bin/sh
2*a7c91847Schristos
3*a7c91847Schristos# Test that a getdate executable meets its specification.
4*a7c91847Schristos#
5*a7c91847Schristos# Copyright (C) 2004 Free Software Foundation, Inc.
6*a7c91847Schristos#
7*a7c91847Schristos# This program is free software; you can redistribute it and/or modify
8*a7c91847Schristos# it under the terms of the GNU General Public License as published by
9*a7c91847Schristos# the Free Software Foundation; either version 2, or (at your option)
10*a7c91847Schristos# any later version.
11*a7c91847Schristos#
12*a7c91847Schristos# This program is distributed in the hope that it will be useful,
13*a7c91847Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
14*a7c91847Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*a7c91847Schristos# GNU General Public License for more details.
16*a7c91847Schristos#
17*a7c91847Schristos# You should have received a copy of the GNU General Public License
18*a7c91847Schristos# along with this program; if not, write to the Free Software Foundation,
19*a7c91847Schristos# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20*a7c91847Schristos
21*a7c91847Schristos
22*a7c91847Schristos
23*a7c91847Schristos###
24*a7c91847Schristos### Globals
25*a7c91847Schristos###
26*a7c91847SchristosLOGFILE=`pwd`/getdate.log
27*a7c91847Schristosif test -f "$LOGFILE"; then
28*a7c91847Schristos	mv $LOGFILE $LOGFILE~
29*a7c91847Schristosfi
30*a7c91847Schristos
31*a7c91847Schristos
32*a7c91847Schristos
33*a7c91847Schristos###
34*a7c91847Schristos### Functions
35*a7c91847Schristos###
36*a7c91847Schristosverify ()
37*a7c91847Schristos{
38*a7c91847Schristos	echo >>getdate-got
39*a7c91847Schristos	if cmp getdate-expected getdate-got >getdate.cmp; then
40*a7c91847Schristos		echo "PASS: $1" >>$LOGFILE
41*a7c91847Schristos	else
42*a7c91847Schristos		cat getdate.cmp >>$LOGFILE
43*a7c91847Schristos		echo "** expected: " >>$LOGFILE
44*a7c91847Schristos		cat getdate-expected >>$LOGFILE
45*a7c91847Schristos		echo "** got: " >>$LOGFILE
46*a7c91847Schristos		cat getdate-got >>$LOGFILE
47*a7c91847Schristos		echo "FAIL: $1" | tee -a $LOGFILE >&2
48*a7c91847Schristos		echo "Failed!  See $LOGFILE for more!" >&2
49*a7c91847Schristos		exit 1
50*a7c91847Schristos	fi
51*a7c91847Schristos}
52*a7c91847Schristos
53*a7c91847Schristos
54*a7c91847Schristos
55*a7c91847Schristosskip ()
56*a7c91847Schristos{
57*a7c91847Schristos	echo "SKIP: $1"${2+" ($2)"} >>$LOGFILE
58*a7c91847Schristos}
59*a7c91847Schristos
60*a7c91847Schristos
61*a7c91847Schristos
62*a7c91847Schristos# Prep for future calls to valid_timezone().
63*a7c91847Schristos#
64*a7c91847Schristos# This should set $UTZ to three spaces, `GMT', `Unrecognized/Unrecognized', or
65*a7c91847Schristos# possibly the empty string, depending on what system we are running on.  With
66*a7c91847Schristos# any luck, this will catch any other existing variations as well.  The way it
67*a7c91847Schristos# is used later does have the disadvantage of rejecting at least the
68*a7c91847Schristos# `Europe/London' timezone for half the year when $UTZ gets set to `GMT', like
69*a7c91847Schristos# happens on NetBSD, but, since I haven't come up with any better ideas and
70*a7c91847Schristos# since rejecting a timezone just causes a few tests to be skipped, this will
71*a7c91847Schristos# have to do for now.
72*a7c91847Schristos#
73*a7c91847Schristos# UTZ stands for Unrecognized Time Zone.
74*a7c91847SchristosUTZ=`TZ=Unrecognized/Unrecognized date +%Z`
75*a7c91847Schristos
76*a7c91847Schristos# The following function will return true if $1 is a valid timezone.  It will
77*a7c91847Schristos# return false and set $skipreason, otherwise.
78*a7c91847Schristos#
79*a7c91847Schristos# Clobbers $NTZ & $skipreason.
80*a7c91847Schristos#
81*a7c91847Schristos# SUS2 says `date +%Z' will return `no characters' if `no timezone is
82*a7c91847Schristos# determinable'.  It is, unfortunately, not very specific about what
83*a7c91847Schristos# `determinable' means.  On GNU/Linux, `date +%Z' returns $TZ when $TZ is not
84*a7c91847Schristos# recognized.  NetBSD 1.6.1 "determines" that an unrecognizable value in $TZ
85*a7c91847Schristos# really means `GMT'.  On Cray, the standard is ignored and `date +%Z' returns
86*a7c91847Schristos# three spaces when $TZ is not recognized.  We test for all three cases, plus
87*a7c91847Schristos# the empty string for good measure, though I know of no set of conditions
88*a7c91847Schristos# which will actually cause `date +%Z' to return the empty string SUS2
89*a7c91847Schristos# specifies.
90*a7c91847Schristos#
91*a7c91847Schristos# Due to the current nature of this test, this will not work for the
92*a7c91847Schristos# three-letter zone codes on some systems.  e.g.:
93*a7c91847Schristos#
94*a7c91847Schristos#	test `TZ=EST date +%Z` = "EST"
95*a7c91847Schristos#
96*a7c91847Schristos# should, quite correctly, evaluate to true on most systems, but:
97*a7c91847Schristos#
98*a7c91847Schristos#	TZ=Asia/Calcutta date +%Z
99*a7c91847Schristos#
100*a7c91847Schristos# would return `IST' on GNU/Linux, and hopefully any system which understands
101*a7c91847Schristos# the `Asia/Calcutta' timezone, and `   ' on Cray.  Similarly:
102*a7c91847Schristos#
103*a7c91847Schristos#	TZ=Doesnt_Exist/Doesnt_Exist date +%Z
104*a7c91847Schristos#
105*a7c91847Schristos# returns `Doesnt_Exist/Doesnt_Exist' on GNU/Linux and `   ' on Cray.
106*a7c91847Schristos#
107*a7c91847Schristos# Unfortunately, the %z date format string (-HHMM format time zone) supported
108*a7c91847Schristos# by the GNU `date' command is not part of any standard I know of and,
109*a7c91847Schristos# therefore, is probably not portable.
110*a7c91847Schristos#
111*a7c91847Schristosvalid_timezone ()
112*a7c91847Schristos{
113*a7c91847Schristos	NTZ=`TZ=$1 date +%Z`
114*a7c91847Schristos	if test "$NTZ" = "$UTZ" || test "$NTZ" = "$1"; then
115*a7c91847Schristos		skipreason="$1 is not a recognized timezone on this system"
116*a7c91847Schristos		return `false`
117*a7c91847Schristos	else
118*a7c91847Schristos		return `:`
119*a7c91847Schristos	fi
120*a7c91847Schristos}
121*a7c91847Schristos
122*a7c91847Schristos
123*a7c91847Schristos
124*a7c91847Schristos###
125*a7c91847Schristos### Tests
126*a7c91847Schristos###
127*a7c91847Schristos
128*a7c91847Schristos# Why are these dates tested?
129*a7c91847Schristos#
130*a7c91847Schristos# February 29, 2003
131*a7c91847Schristos#   Is not a leap year - should be invalid.
132*a7c91847Schristos#
133*a7c91847Schristos# 2004-12-40
134*a7c91847Schristos#   Make sure get_date does not "roll" date forward to January 9th.  Some
135*a7c91847Schristos#   versions have been known to do this.
136*a7c91847Schristos#
137*a7c91847Schristos# Dec-5-1972
138*a7c91847Schristos#   This is my birthday.  :)
139*a7c91847Schristos#
140*a7c91847Schristos# 3/29/1974
141*a7c91847Schristos# 1996/05/12 13:57:45
142*a7c91847Schristos#   Because.
143*a7c91847Schristos#
144*a7c91847Schristos# 12-05-12
145*a7c91847Schristos#   This will be my 40th birthday.  Ouch.  :)
146*a7c91847Schristos#
147*a7c91847Schristos# 05/12/96
148*a7c91847Schristos#   Because.
149*a7c91847Schristos#
150*a7c91847Schristos# third tuesday in March, 2078
151*a7c91847Schristos#   Wanted this to work.
152*a7c91847Schristos#
153*a7c91847Schristos# 1969-12-32 2:00:00 UTC
154*a7c91847Schristos# 1970-01-01 2:00:00 UTC
155*a7c91847Schristos# 1969-12-32 2:00:00 +0400
156*a7c91847Schristos# 1970-01-01 2:00:00 +0400
157*a7c91847Schristos# 1969-12-32 2:00:00 -0400
158*a7c91847Schristos# 1970-01-01 2:00:00 -0400
159*a7c91847Schristos#   Playing near the UNIX Epoch boundry condition to make sure date rolling
160*a7c91847Schristos#   is also disabled there.
161*a7c91847Schristos#
162*a7c91847Schristos# 1996-12-12 1 month
163*a7c91847Schristos#   Test a relative date.
164*a7c91847Schristos
165*a7c91847Schristos
166*a7c91847Schristos
167*a7c91847Schristos# The following tests are currently being skipped for being unportable:
168*a7c91847Schristos#
169*a7c91847Schristos# Tue Jan 19 03:14:07 2038 +0000
170*a7c91847Schristos#   For machines with 31-bit time_t, any date past this date will be an
171*a7c91847Schristos#   invalid date. So, any test date with a value greater than this
172*a7c91847Schristos#   time is not portable.
173*a7c91847Schristos#
174*a7c91847Schristos# Feb. 29, 2096 4 years
175*a7c91847Schristos#   4 years from this date is _not_ a leap year, so Feb. 29th does not exist.
176*a7c91847Schristos#
177*a7c91847Schristos# Feb. 29, 2096 8 years
178*a7c91847Schristos#   8 years from this date is a leap year, so Feb. 29th does exist,
179*a7c91847Schristos#   but on many hosts with 32-bit time_t types time, this test will
180*a7c91847Schristos#   fail. So, this is not a portable test.
181*a7c91847Schristos#
182*a7c91847Schristos
183*a7c91847SchristosTZ=UTC0; export TZ
184*a7c91847Schristos
185*a7c91847Schristoscat >getdate-expected <<EOF
186*a7c91847SchristosEnter date, or blank line to exit.
187*a7c91847Schristos	> Bad format - couldn't convert.
188*a7c91847Schristos	> Bad format - couldn't convert.
189*a7c91847Schristos	> 1972-12-05 00:00:00.000000000
190*a7c91847Schristos	> 1974-03-29 00:00:00.000000000
191*a7c91847Schristos	> 1996-05-12 13:57:45.000000000
192*a7c91847Schristos	> 2012-05-12 00:00:00.000000000
193*a7c91847Schristos	> 1996-05-12 00:00:00.000000000
194*a7c91847Schristos	> Bad format - couldn't convert.
195*a7c91847Schristos	> Bad format - couldn't convert.
196*a7c91847Schristos	> 1970-01-01 02:00:00.000000000
197*a7c91847Schristos	> Bad format - couldn't convert.
198*a7c91847Schristos	> 1969-12-31 22:00:00.000000000
199*a7c91847Schristos	> Bad format - couldn't convert.
200*a7c91847Schristos	> 1970-01-01 06:00:00.000000000
201*a7c91847Schristos	> 1997-01-12 00:00:00.000000000
202*a7c91847Schristos	> 
203*a7c91847SchristosEOF
204*a7c91847Schristos
205*a7c91847Schristos./getdate >getdate-got <<EOF
206*a7c91847SchristosFebruary 29, 2003
207*a7c91847Schristos2004-12-40
208*a7c91847SchristosDec-5-1972
209*a7c91847Schristos3/29/1974
210*a7c91847Schristos1996/05/12 13:57:45
211*a7c91847Schristos12-05-12
212*a7c91847Schristos05/12/96
213*a7c91847Schristosthird tuesday in March, 2078
214*a7c91847Schristos1969-12-32 2:00:00 UTC
215*a7c91847Schristos1970-01-01 2:00:00 UTC
216*a7c91847Schristos1969-12-32 2:00:00 +0400
217*a7c91847Schristos1970-01-01 2:00:00 +0400
218*a7c91847Schristos1969-12-32 2:00:00 -0400
219*a7c91847Schristos1970-01-01 2:00:00 -0400
220*a7c91847Schristos1996-12-12 1 month
221*a7c91847SchristosEOF
222*a7c91847Schristos
223*a7c91847Schristosverify getdate-1
224*a7c91847Schristos
225*a7c91847Schristos
226*a7c91847Schristos
227*a7c91847Schristos# Why are these dates tested?
228*a7c91847Schristos#
229*a7c91847Schristos# Ian Abbot reported these odd boundry cases.  After daylight savings time went
230*a7c91847Schristos# into effect, non-daylight time zones would cause
231*a7c91847Schristos# "Bad format - couldn't convert." errors, even when the non-daylight zone
232*a7c91847Schristos# happened to be a universal one, like GMT.
233*a7c91847Schristos
234*a7c91847SchristosTZ=Europe/London; export TZ
235*a7c91847Schristosif valid_timezone $TZ; then
236*a7c91847Schristos	cat >getdate-expected <<EOF
237*a7c91847SchristosEnter date, or blank line to exit.
238*a7c91847Schristos	> 2005-03-01 00:00:00.000000000
239*a7c91847Schristos	> 2005-03-27 00:00:00.000000000
240*a7c91847Schristos	> 2005-03-28 01:00:00.000000000
241*a7c91847Schristos	> 2005-03-28 01:00:00.000000000
242*a7c91847Schristos	> 2005-03-29 01:00:00.000000000
243*a7c91847Schristos	> 2005-03-29 01:00:00.000000000
244*a7c91847Schristos	> 2005-03-30 01:00:00.000000000
245*a7c91847Schristos	> 2005-03-30 01:00:00.000000000
246*a7c91847Schristos	> 2005-03-31 01:00:00.000000000
247*a7c91847Schristos	> 2005-03-31 01:00:00.000000000
248*a7c91847Schristos	> 2005-04-01 01:00:00.000000000
249*a7c91847Schristos	> 2005-04-01 01:00:00.000000000
250*a7c91847Schristos	> 2005-04-10 01:00:00.000000000
251*a7c91847Schristos	> 2005-04-10 01:00:00.000000000
252*a7c91847Schristos	> 2005-04-01 00:00:00.000000000
253*a7c91847Schristos	> 
254*a7c91847SchristosEOF
255*a7c91847Schristos
256*a7c91847Schristos	./getdate >getdate-got <<EOF
257*a7c91847Schristos2005-3-1 GMT
258*a7c91847Schristos2005-3-27 GMT
259*a7c91847Schristos2005-3-28 GMT
260*a7c91847Schristos2005-3-28 UTC0
261*a7c91847Schristos2005-3-29 GMT
262*a7c91847Schristos2005-3-29 UTC0
263*a7c91847Schristos2005-3-30 GMT
264*a7c91847Schristos2005-3-30 UTC0
265*a7c91847Schristos2005-3-31 GMT
266*a7c91847Schristos2005-3-31 UTC0
267*a7c91847Schristos2005-4-1 GMT
268*a7c91847Schristos2005-4-1 UTC0
269*a7c91847Schristos2005-4-10 GMT
270*a7c91847Schristos2005-4-10 UTC0
271*a7c91847Schristos2005-4-1 BST
272*a7c91847SchristosEOF
273*a7c91847Schristos
274*a7c91847Schristos	verify getdate-2
275*a7c91847Schristoselse
276*a7c91847Schristos	skip getdate-2 "$skipreason"
277*a7c91847Schristosfi
278*a7c91847Schristos
279*a7c91847Schristos
280*a7c91847Schristos
281*a7c91847Schristos# Many of the following cases were also submitted by Ian Abbott, but the same
282*a7c91847Schristos# errors are not exhibited.  The original problem had a similar root, but
283*a7c91847Schristos# managed to produce errors with GMT, which is considered a "Universal Zone".
284*a7c91847Schristos# This was fixed.
285*a7c91847Schristos#
286*a7c91847Schristos# The deeper problem has to do with "local zone" processing in getdate.y
287*a7c91847Schristos# that causes local daylight zones to be excluded when local standard time is
288*a7c91847Schristos# in effect and vice versa.  This used to cause trouble with GMT in Britian
289*a7c91847Schristos# when British Summer Time was in effect, but this was overridden for the
290*a7c91847Schristos# "Universal Timezones" (GMT, UTC, & UT), that might double as a local zone in
291*a7c91847Schristos# some locales.  We still see in these tests the local daylight/standard zone
292*a7c91847Schristos# exclusion in EST/EDT.  According to Paul Eggert in a message to
293*a7c91847Schristos# bug-gnulib@gnu.org on 2005-04-12, this is considered a bug but may not be
294*a7c91847Schristos# fixed soon due to its complexity.
295*a7c91847Schristos
296*a7c91847SchristosTZ=America/New_York; export TZ
297*a7c91847Schristosif valid_timezone $TZ; then
298*a7c91847Schristos	cat >getdate-expected <<EOF
299*a7c91847SchristosEnter date, or blank line to exit.
300*a7c91847Schristos	> 2005-03-01 00:00:00.000000000
301*a7c91847Schristos	> 2005-02-28 18:00:00.000000000
302*a7c91847Schristos	> 2005-04-01 00:00:00.000000000
303*a7c91847Schristos	> Bad format - couldn't convert.
304*a7c91847Schristos	> 2005-04-30 19:00:00.000000000
305*a7c91847Schristos	> 2005-04-30 20:00:00.000000000
306*a7c91847Schristos	> 2005-05-01 00:00:00.000000000
307*a7c91847Schristos	> 2005-04-30 20:00:00.000000000
308*a7c91847Schristos	> Bad format - couldn't convert.
309*a7c91847Schristos	> 2005-05-31 19:00:00.000000000
310*a7c91847Schristos	> 2005-05-31 20:00:00.000000000
311*a7c91847Schristos	> 2005-06-01 00:00:00.000000000
312*a7c91847Schristos	> 2005-05-31 20:00:00.000000000
313*a7c91847Schristos	> 
314*a7c91847SchristosEOF
315*a7c91847Schristos
316*a7c91847Schristos	./getdate >getdate-got <<EOF
317*a7c91847Schristos2005-3-1 EST
318*a7c91847Schristos2005-3-1 BST
319*a7c91847Schristos2005-4-1 EST
320*a7c91847Schristos2005-5-1 EST
321*a7c91847Schristos2005-5-1 BST
322*a7c91847Schristos2005-5-1 GMT
323*a7c91847Schristos2005-5-1 EDT
324*a7c91847Schristos2005-5-1 UTC0
325*a7c91847Schristos2005-6-1 EST
326*a7c91847Schristos2005-6-1 BST
327*a7c91847Schristos2005-6-1 GMT
328*a7c91847Schristos2005-6-1 EDT
329*a7c91847Schristos2005-6-1 UTC0
330*a7c91847SchristosEOF
331*a7c91847Schristos
332*a7c91847Schristos	verify getdate-3
333*a7c91847Schristoselse
334*a7c91847Schristos	skip getdate-3 "$skipreason"
335*a7c91847Schristosfi
336*a7c91847Schristos
337*a7c91847Schristos
338*a7c91847Schristos
339*a7c91847Schristosrm getdate-expected getdate-got getdate.cmp
340*a7c91847Schristosexit 0
341