diff -u at-3.1.8/Makefile.in.orig at-3.1.8/Makefile.in --- at-3.1.8/Makefile.in.orig Wed Feb 14 13:59:09 2001 +++ at-3.1.8/Makefile.in Mon Feb 19 14:48:42 2001 @@ -51,6 +51,8 @@ OTHERS = parsetime.l parsetime.y +TEST_VERBOSE = 0 + DOCS = Problems Copyright README ChangeLog timespec MISC = COPYING Makefile.in configure acconfig.h install-sh \ @@ -150,6 +152,9 @@ parsetest: lex.yy.c y.tab.c $(CC) -o parsetest $(CFLAGS) $(DEFS) -DTEST_PARSER -DNEED_YYWRAP lex.yy.c y.tab.c + +test: parsetest + PERL_DL_NONLAZY=1 perl -e 'use Test::Harness qw(&runtests $$verbose); $$verbose=$(TEST_VERBOSE); runtests @ARGV;' test.pl .depend: $(CSRCS) gcc $(CFLAGS) $(DEFS) -MM $(CSRCS) > .depend diff -u at-3.1.8/test.pl.orig at-3.1.8/test.pl --- at-3.1.8/test.pl.orig Mon Feb 19 14:51:37 2001 +++ at-3.1.8/test.pl Mon Feb 19 14:30:17 2001 @@ -0,0 +1,800 @@ +#!/usr/bin/perl -w +# +# test.pl - tests vailidity of lexer/parser for at(1) +# +# Copyright 2001 David D. Kilzer +# +# Licensed under the GNU Public License +# +# Environment variables: +# TEST_VERBOSE +# 0 - no verbosity +# 1 - verbose output only on failed tests, and all stderr output +# > 1 - verbose output on every test, and all stderr output +# + +use strict; + +use constant SECOND => 1; # seconds per second +use constant MINUTE => 60*SECOND; # seconds per minute +use constant HOUR => 60*MINUTE; # seconds per hour +use constant DAY => 24*HOUR; # seconds per day +use constant WEEK => 7*DAY; # seconds per week + +use vars qw($verbose); + +use POSIX; # strftime +use Time::Local; # timelocal() and timegm() + +BEGIN { $| = 1; } # no output buffering + + +# +# Subroutines +# +sub is_dst (;$); # is time in DST? +sub get_utc_offset (;$); # calculate hours offset from UTC + + +# +# Data structures containing test data +# +my @date_tests; # date strings +my @time_tests; # time strings +my @date_time_tests_time; # time + date strings (just times) +my @date_time_tests_date; # time + date strings (just dates) +my @inc_dec_tests; # increment and decrement strings +my @misc_tests; # miscellaneous strings (mostly for DST) + +my $num_tests; # number of tests +my $show_stderr; # set to "2> /dev/null" if (! $verbose) +my $utc_off; # timezone offset in minutes west of UTC + + +# +# Set variables before running tests +# +$verbose = $ENV{'TEST_VERBOSE'} || 0; + +$show_stderr = ($verbose > 0 ? "" : "2> /dev/null"); + +$utc_off = get_utc_offset(); + + +# +# Tests for dates only +# These tests include both relative and specific dates. +# They are not combined with any other tests. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@date_tests = +( +[ "dec 31", 12, 31, '$y', '$h', '$mi' ], +[ "Dec 31", 12, 31, '$y', '$h', '$mi' ], +[ "DEC 31", 12, 31, '$y', '$h', '$mi' ], +[ "december 31", 12, 31, '$y', '$h', '$mi' ], +[ "December 31", 12, 31, '$y', '$h', '$mi' ], +[ "DECEMBER 31", 12, 31, '$y', '$h', '$mi' ], +[ "Dec 31 10", 12, 31, 2010, '$h', '$mi' ], +[ "December 31 10", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31 2010", 12, 31, 2010, '$h', '$mi' ], +[ "December 31 2010", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31,10", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31, 10", 12, 31, 2010, '$h', '$mi' ], +[ "December 31,10", 12, 31, 2010, '$h', '$mi' ], +[ "December 31, 10", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31,2010", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31, 2010", 12, 31, 2010, '$h', '$mi' ], +[ "December 31,2010", 12, 31, 2010, '$h', '$mi' ], +[ "December 31, 2010", 12, 31, 2010, '$h', '$mi' ], +[ "sun", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "Sun", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "SUN", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "sunday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "Sunday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "SUNDAY", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 0 ? 7 : ((7 - $wd + 0) % 7)) * DAY)' ], +[ "Mon", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], +[ "Monday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], +[ "Tue", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 2 ? 7 : ((7 - $wd + 2) % 7)) * DAY)' ], +[ "Tuesday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 2 ? 7 : ((7 - $wd + 2) % 7)) * DAY)' ], +[ "Wed", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 3 ? 7 : ((7 - $wd + 3) % 7)) * DAY)' ], +[ "Wednesday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 3 ? 7 : ((7 - $wd + 3) % 7)) * DAY)' ], +[ "Thu", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 4 ? 7 : ((7 - $wd + 4) % 7)) * DAY)' ], +[ "Thursday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 4 ? 7 : ((7 - $wd + 4) % 7)) * DAY)' ], +[ "Fri", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 5 ? 7 : ((7 - $wd + 5) % 7)) * DAY)' ], +[ "Friday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 5 ? 7 : ((7 - $wd + 5) % 7)) * DAY)' ], +[ "Sat", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 6 ? 7 : ((7 - $wd + 6) % 7)) * DAY)' ], +[ "Saturday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 6 ? 7 : ((7 - $wd + 6) % 7)) * DAY)' ], +[ "now", '$mo', '$d', '$y', '$h', '$mi' ], +[ "Now", '$mo', '$d', '$y', '$h', '$mi' ], +[ "NOW", '$mo', '$d', '$y', '$h', '$mi' ], +[ "today", '$mo', '$d', '$y', '$h', '$mi' ], +[ "Today", '$mo', '$d', '$y', '$h', '$mi' ], +[ "TODAY", '$mo', '$d', '$y', '$h', '$mi' ], +[ "tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "Tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "TOMORROW", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "10-12-31", 12, 31, 2010, '$h', '$mi' ], +[ "2010-12-31", 12, 31, 2010, '$h', '$mi' ], +[ "31.12.10", 12, 31, 2010, '$h', '$mi' ], +[ "31.12.2010", 12, 31, 2010, '$h', '$mi' ], +[ "31 Dec", 12, 31, '$y', '$h', '$mi' ], +[ "31 December", 12, 31, '$y', '$h', '$mi' ], +[ "31 Dec 10", 12, 31, 2010, '$h', '$mi' ], +[ "31 Dec 2010", 12, 31, 2010, '$h', '$mi' ], +[ "31 December 10", 12, 31, 2010, '$h', '$mi' ], +[ "31 December 2010", 12, 31, 2010, '$h', '$mi' ], +[ "12/31/10", 12, 31, 2010, '$h', '$mi' ], +[ "12/31/2010", 12, 31, 2010, '$h', '$mi' ], +[ "13010", 01, 30, 2010, '$h', '$mi' ], +[ "1302010", 01, 30, 2010, '$h', '$mi' ], +[ "013010", 01, 30, 2010, '$h', '$mi' ], +[ "01302010", 01, 30, 2010, '$h', '$mi' ], +[ "123110", 12, 31, 2010, '$h', '$mi' ], +[ "12312010", 12, 31, 2010, '$h', '$mi' ], +[ "next minute", '$mo', '$d', '$y', '$h', '$mi', '1 * MINUTE' ], +[ "next hour", '$mo', '$d', '$y', '$h', '$mi', '1 * HOUR' ], +[ "next day", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "next week", '$mo', '$d', '$y', '$h', '$mi', '1 * WEEK' ], +[ "next month", '($mo == 12 ? 1 : $mo + 1)', '$d', '($mo == 12 ? $y + 1 : $y)', '$h', '$mi' ], +[ "next year", '$mo', '$d', '$y + 1', '$h', '$mi' ], +); + + +# +# Tests for times only +# These tests include specific times and time aliases. +# They are not combined with any other tests. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@time_tests = +( +[ "0800", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "2300", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8:00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08:00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23:00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8'00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08'00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23'00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8.00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08.00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23.00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8h00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08h00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23h00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8,00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08,00", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "23,00", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8:00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08:00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11:00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8'00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08'00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11'00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8.00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08.00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11.00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8h00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08h00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11h00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "8,00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "08,00 am", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi) < ( 8*60+0) ? 0 : 1 * DAY)' ], +[ "11,00 pm", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi) < (23*60+0) ? 0 : 1 * DAY)' ], +[ "0800 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "2300 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8:00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08:00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23:00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8'00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08'00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23'00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8.00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08.00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23.00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8h00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08h00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23h00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8,00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08,00 utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "23,00 utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8:00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08:00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11:00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8'00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08'00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11'00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8.00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08.00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11.00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8h00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08h00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11h00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "8,00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "08,00 am utc", '$mo', '$d', '$y', 8, 0, + '(($h*60+$mi+$utc_off) < ( 8*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "11,00 pm utc", '$mo', '$d', '$y', 23, 0, + '(($h*60+$mi+$utc_off) < (23*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "noon", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], +[ "Noon", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], +[ "NOON", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi) < (12*60+0) ? 0 : 1 * DAY)' ], +[ "midnight", '$mo', '$d', '$y', 0, 0, + '(($h*60+$mi) < ( 0*60+0) ? 1 * DAY : 1 * DAY)' ], +[ "teatime", '$mo', '$d', '$y', 16, 0, + '(($h*60+$mi) < (16*60+0) ? 0 : 1 * DAY)' ], +[ "noon utc", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi+$utc_off) < (12*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "noon UTC", '$mo', '$d', '$y', 12, 0, + '(($h*60+$mi+$utc_off) < (12*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +[ "midnight utc", '$mo', '$d', '$y', 0, 0, + '(($h*60+$mi+$utc_off) < ( 0*60+0) ? 1 * DAY : 1 * DAY) - $utc_off * MINUTE' ], +[ "teatime utc", '$mo', '$d', '$y', 16, 0, + '(($h*60+$mi+$utc_off) < (16*60+0) ? 0 : 1 * DAY) - $utc_off * MINUTE' ], +); + + +# +# Tests for combining times and dates and inc/dec +# These tests include specific times and time aliases that are +# combined with @date_time_tests_date and with @inc_dec_tests +# during testing. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@date_time_tests_time = +( +[ "0800", '$mo', '$d', '$y', 8, 0 ], +[ "2300", '$mo', '$d', '$y', 23, 0 ], +[ "8:00", '$mo', '$d', '$y', 8, 0 ], +[ "23:00", '$mo', '$d', '$y', 23, 0 ], +[ "8'00", '$mo', '$d', '$y', 8, 0 ], +[ "23'00", '$mo', '$d', '$y', 23, 0 ], +[ "8.00", '$mo', '$d', '$y', 8, 0 ], +[ "23.00", '$mo', '$d', '$y', 23, 0 ], +[ "8h00", '$mo', '$d', '$y', 8, 0 ], +[ "23h00", '$mo', '$d', '$y', 23, 0 ], +[ "8,00", '$mo', '$d', '$y', 8, 0 ], +[ "23,00", '$mo', '$d', '$y', 23, 0 ], +[ "8:00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11:00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "8'00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11'00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "8.00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11.00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "8h00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11h00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "8,00 am", '$mo', '$d', '$y', 8, 0 ], +[ "11,00 pm", '$mo', '$d', '$y', 23, 0 ], +[ "0800 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "2300 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8:00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23:00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8'00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23'00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8.00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23.00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8h00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23h00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8,00 utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "23,00 utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8:00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11:00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8'00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11'00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8.00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11.00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8h00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11h00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "8,00 am utc", '$mo', '$d', '$y', 8, 0, + '- $utc_off * MINUTE' ], +[ "11,00 pm utc", '$mo', '$d', '$y', 23, 0, + '- $utc_off * MINUTE' ], +[ "noon", '$mo', '$d', '$y', 12, 0 ], +[ "midnight", '$mo', '$d', '$y', 0, 0 ], +[ "teatime", '$mo', '$d', '$y', 16, 0 ], +[ "noon utc", '$mo', '$d', '$y', 12, 0, + '- $utc_off * MINUTE' ], +[ "midnight utc", '$mo', '$d', '$y', 0, 0, + '- $utc_off * MINUTE' ], +[ "teatime utc", '$mo', '$d', '$y', 16, 0, + '- $utc_off * MINUTE' ], +); + + +# +# Tests for combining times and dates and inc/dec +# These tests include both relative and specific dates that are +# combined with @date_time_tests_time and with @inc_dec_tests +# during testing. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@date_time_tests_date = +( +[ "Dec 31", 12, 31, '($mo==12 && $d==31 ? $y+1 : $y)', '$h', '$mi' ], +[ "Dec 31 10", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31 2010", 12, 31, 2010, '$h', '$mi' ], +[ "Dec 31, 10", 12, 31, 2010, '$h', '$mi' ], +[ "December 31, 2010", 12, 31, 2010, '$h', '$mi' ], +[ "Monday", '$mo', '$d', '$y', '$h', '$mi', + '(($wd == 1 ? 7 : ((7 - $wd + 1) % 7)) * DAY)' ], +[ "today", '$mo', '$d', '$y', '$h', '$mi' ], +[ "tomorrow", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "10-12-31", 12, 31, 2010, '$h', '$mi' ], +[ "2010-12-31", 12, 31, 2010, '$h', '$mi' ], +[ "31.12.10", 12, 31, 2010, '$h', '$mi' ], +[ "31.12.2010", 12, 31, 2010, '$h', '$mi' ], +[ "31 Dec", 12, 31, '($mo==12 && $d==31 ? $y+1 : $y)', '$h', '$mi' ], +[ "31 Dec 10", 12, 31, 2010, '$h', '$mi' ], +[ "31 Dec 2010", 12, 31, 2010, '$h', '$mi' ], +[ "12/31/10", 12, 31, 2010, '$h', '$mi' ], +[ "12/31/2010", 12, 31, 2010, '$h', '$mi' ], +[ "13010", 01, 30, 2010, '$h', '$mi' ], +[ "1302010", 01, 30, 2010, '$h', '$mi' ], +[ "123110", 12, 31, 2010, '$h', '$mi' ], +[ "12312010", 12, 31, 2010, '$h', '$mi' ], +[ "next minute", '$mo', '$d', '$y', '$h', '$mi', '1 * MINUTE' ], +[ "next hour", '$mo', '$d', '$y', '$h', '$mi', '1 * HOUR' ], +[ "next day", '$mo', '$d', '$y', '$h', '$mi', '1 * DAY' ], +[ "next week", '$mo', '$d', '$y', '$h', '$mi', '1 * WEEK' ], +[ "next month", '($mo == 12 ? 1 : $mo + 1)', '$d', '($mo == 12 ? $y + 1 : $y)', '$h', '$mi' ], +[ "next year", '$mo', '$d', '$y + 1', '$h', '$mi' ], +); + + +# +# Tests for combining times and dates and inc/dec +# These tests include both increments and decrements that are +# combined with @date_time_tests_time and with @date_time_tests_date +# during testing. Note how these tests refer to elements from +# the data structures that they will be combined with ($$i[N]). +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@inc_dec_tests = +( +[ "- 1 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * MINUTE' ], +[ "- 1 minute", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * MINUTE' ], +[ "- 1 hour", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * HOUR' ], +[ "- 1 day", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * DAY' ], +[ "- 1 week", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 1 * WEEK' ], +[ "- 1 month", '($$i[1] == 1 ? 12 : $$i[1] - 1)', '$$i[2]', '($$i[1] == 1 ? $$i[3] - 1 : $$i[3])', '$$i[4]', '$$i[5]' ], +[ "- 1 year", '$$i[1]', '$$i[2]', '$$i[3] - 1', '$$i[4]', '$$i[5]' ], +[ "- 10 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * MINUTE' ], +[ "- 10 minutes", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * MINUTE' ], +[ "- 10 hours", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * HOUR' ], +[ "- 10 days", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * DAY' ], +[ "- 10 weeks", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '- 10 * WEEK' ], +[ "- 10 months", '($$i[1] > 10 ? $$i[1] - 10 : $$i[1] + 2)', '$$i[2]', '($$i[1] > 10 ? $$i[3]: $$i[3] - 1)', '$$i[4]', '$$i[5]' ], +[ "- 10 years", '$$i[1]', '$$i[2]', '$$i[3] - 10', '$$i[4]', '$$i[5]' ], +[ "+ 1 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * MINUTE' ], +[ "+ 1 minute", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * MINUTE' ], +[ "+ 1 hour", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * HOUR' ], +[ "+ 1 day", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * DAY' ], +[ "+ 1 week", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 1 * WEEK' ], +[ "+ 1 month", '($$i[1] == 12 ? 1 : $$i[1] + 1)', '$$i[2]', '($$i[1] == 12 ? $$i[3] + 1 : $$i[3])', '$$i[4]', '$$i[5]' ], +[ "+ 1 year", '$$i[1]', '$$i[2]', '$$i[3] + 1', '$$i[4]', '$$i[5]' ], +[ "+ 10 min", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * MINUTE' ], +[ "+ 10 minutes", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * MINUTE' ], +[ "+ 10 hours", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * HOUR' ], +[ "+ 10 days", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * DAY' ], +[ "+ 10 weeks", '$$i[1]', '$$i[2]', '$$i[3]', '$$i[4]', '$$i[5]', '+ 10 * WEEK' ], +[ "+ 10 months", '($$i[1] < 3 ? $$i[1] + 10 : $$i[1] - 2)', '$$i[2]', '($$i[1] < 3 ? $$i[3] : $$i[3] + 1)', '$$i[4]', '$$i[5]' ], +[ "+ 10 years", '$$i[1]', '$$i[2]', '$$i[3] + 10', '$$i[4]', '$$i[5]' ], +); + + +# +# Miscellaneous tests +# These tests include any specific test cases that won't fit easily +# into the test data above. +# They are not combined with any other tests. +# +# Format: "string", month, day, year, hour, minute, [offset] +# +@misc_tests = +( +# Test moving back and forth across DST +[ "March 1 + 3 months", '6', '1', '$y', '$h', '$mi' ], +[ "June 1 - 3 months", '3', '1', '$y', '$h', '$mi' ], +[ "September 1 + 3 months", '12', '1', '$y', '$h', '$mi' ], +[ "December 1 - 3 months", '9', '1', '$y', '$h', '$mi' ], +[ "March 1 + 12 weeks", '3', '1', '$y', '$h', '$mi', '+12 * WEEK' ], +[ "June 1 - 12 weeks", '6', '1', '$y', '$h', '$mi', '-12 * WEEK' ], +[ "September 1 + 12 weeks", '9', '1', '$y', '$h', '$mi', '+12 * WEEK' ], +[ "December 1 - 12 weeks", '12', '1', '$y', '$h', '$mi', '-12 * WEEK' ], +); + + +$num_tests = ($#date_tests + 1) + + ($#time_tests + 1) + + ($#misc_tests + 1) + + ($#date_time_tests_time + 1) * ($#date_time_tests_date + 1) + + ($#date_time_tests_time + 1) * ($#inc_dec_tests + 1) + + ($#date_time_tests_date + 1) * ($#inc_dec_tests + 1) + ; + + +# +# Print out the number of tests to perform +# +print "1..$num_tests\n"; + + +# +# Run date, time and miscellaneous tests +# +foreach my $i (@date_tests, @time_tests, @misc_tests) +{ + my $s; # current second + my $mi; # current minute + my $h; # current hour + my $d; # current day + my $mo; # current month + my $y; # current year + my $wd; # current week day + my $yd; # current year day + my $dst; # is daylight savings time? + + my $epoch_time; # time string in epoch seconds + my $offset = 0; # offset for test in epoch seconds + my $t; # time string to test against + + my $o; # output of parsetest command + my $run_time; # internal timestamp used for comparison + + ## WARNING: Next two statements could run in different minutes! + $o = `./parsetest \"$$i[0]\" $show_stderr`; + $run_time = time(); + + ## Set variables for $run_time before calculating $offset + ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); + $mo += 1; + $y += 1900; + + $offset = eval "$$i[6]" if (defined $$i[6]); + + $epoch_time = strftime("%s", + 0, + eval "$$i[5]", + eval "$$i[4]", + eval "$$i[2]", + eval "$$i[1] - 1", + eval "$$i[3] - 1900", + -1, # wday + -1, # yday + -1, # isdst + ); + + ## Adjust +-1 hour when moving in or out of DST + if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) + { # DST to no DST + $epoch_time += 1 * HOUR; + } + elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) + { # no DST to DST + $epoch_time -= 1 * HOUR; + } + + $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); + + chomp $o; + + print $o eq $t ? "ok" : "not ok", "\n"; + + print "'", $$i[0], "': '$o' =? '$t'\n" + if ($verbose > 1 || ($verbose == 1 && $o ne $t)); +} + + +# +# Run time + date tests +# +foreach my $i (@date_time_tests_time) +{ + foreach my $j (@date_time_tests_date) + { + my $s; # current second + my $mi; # current minute + my $h; # current hour + my $d; # current day + my $mo; # current month + my $y; # current year + my $wd; # current week day + my $yd; # current year day + my $dst; # is daylight savings time? + + my $epoch_time; # time string in epoch seconds + my $offset = 0; # offset for test in epoch seconds + my $t; # time string to test against + + my $o; # output of parsetest command + my $run_time; # internal timestamp used for comparison + + ## WARNING: Next two statements could run in different minutes! + $o = `./parsetest \"$$i[0] $$j[0]\" $show_stderr`; + $run_time = time(); + + ## Set variables for $run_time before calculating $offset + ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); + $mo += 1; + $y += 1900; + + if (defined $$i[6]) + { + if (defined $$j[6]) + { + $offset = eval "($$i[6]) + ($$j[6])"; + } + else + { + $offset = eval "$$i[6]"; + } + } + elsif (defined $$j[6]) + { + $offset = eval "$$j[6]"; + } + + $epoch_time = strftime("%s", + 0, + eval "$$i[5]", + eval "$$i[4]", + eval "$$j[2]", + eval "$$j[1] - 1", + eval "$$j[3] - 1900", + -1, # wday + -1, # yday + -1, # isdst + ); + + ## Adjust +-1 hour when moving in or out of DST + if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) + { # DST to no DST + $epoch_time += 1 * HOUR; + } + elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) + { # no DST to DST + $epoch_time -= 1 * HOUR; + } + + $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); + + chomp $o; + + print $o eq $t ? "ok" : "not ok", "\n"; + + print "'$$i[0] $$j[0]': '$o' =? '$t'\n" + if ($verbose > 1 || ($verbose == 1 && $o ne $t)); + } +} + + +# +# Run time + inc_dec and date + inc_dec tests +# +foreach my $i (@date_time_tests_time, @date_time_tests_date) +{ + foreach my $j (@inc_dec_tests) + { + my $s; # current second + my $mi; # current minute + my $h; # current hour + my $d; # current day + my $mo; # current month + my $y; # current year + my $wd; # current week day + my $yd; # current year day + my $dst; # is daylight savings time? + + my $epoch_time; # time string in epoch seconds + my $offset = 0; # offset for test in epoch seconds + my $t; # time string to test against + + my $o; # output of parsetest command + my $run_time; # internal timestamp used for comparison + + ## WARNING: Next two statements could run in different minutes! + $o = `./parsetest \"$$i[0] $$j[0]\" $show_stderr`; + $run_time = time(); + + ## Set variables for $run_time before calculating $offset + ($s, $mi, $h, $d, $mo, $y, $wd, $yd, $dst) = localtime($run_time); + $mo += 1; + $y += 1900; + + if (defined $$i[6]) + { + if (defined $$j[6]) + { + $offset = eval "($$i[6]) + ($$j[6])"; + } + else + { + $offset = eval "$$i[6]"; + } + } + elsif (defined $$j[6]) + { + $offset = eval "$$j[6]"; + } + + $epoch_time = strftime("%s", + 0, + eval "$$i[5]", + eval "$$i[4]", + eval "eval \"$$j[2]\"", + eval "eval \"$$j[1] - 1\"", + eval "eval \"$$j[3] - 1900\"", + -1, # wday + -1, # yday + -1, # isdst + ); + + ## Adjust +-1 hour when moving in or out of DST + if ( is_dst($epoch_time) && ! is_dst($epoch_time + $offset)) + { # DST to no DST + $epoch_time += 1 * HOUR; + } + elsif (! is_dst($epoch_time) && is_dst($epoch_time + $offset)) + { # no DST to DST + $epoch_time -= 1 * HOUR; + } + + $t = strftime("%a %b %e %H:%M:00 %Y", localtime($epoch_time + $offset)); + + chomp $o; + + print $o eq $t ? "ok" : "not ok", "\n"; + + print "'$$i[0] $$j[0]': '$o' =? '$t'\n" + if ($verbose > 1 || ($verbose == 1 && $o ne $t)); + } +} + +exit 0; + + +# +# Subroutine: +# is_dst +# +# Description: +# returns true if the time passed in is in DST, else +# returns false if the time passed in is not in DST +# +# Arg 1: +# [Optional] time in epoch seconds; defaults to the current +# time if no argument is given +# +sub is_dst (;$) +{ + my $t = shift || time(); + return ((localtime($t))[8] > 0); +} + + +# +# Subroutine: +# get_utc_offset +# +# Description: +# returns the number of offest hours from UTC for the current timezone +# +# Arg 1: +# [Optional] time in epoch seconds; defaults to the current +# time if no argument is given +# +sub get_utc_offset (;$) +{ + my $t = shift || time(); + my @t = localtime($t); + my $is_dst = $t[8]; + return ((timelocal(@t) - timegm(@t) + ($is_dst > 0 ? HOUR : 0)) / MINUTE); +} +