output: Introduce pivot tables.
[pspp] / tests / language / expressions / evaluate.at
index 4a8324ed661436e833ec6f295b990b6620f50714..76e11d885eb256b35ebd450f2c5b1d7059fbf8f5 100644 (file)
@@ -1,16 +1,37 @@
-m4_define([CHECK_EXPR_EVAL],
+dnl PSPP - a program for statistical analysis.
+dnl Copyright (C) 2017 Free Software Foundation, Inc.
+dnl 
+dnl This program is free software: you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, either version 3 of the License, or
+dnl (at your option) any later version.
+dnl 
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
+dnl m4_define([CHECK_EXPR_EVAL],
   [AT_SETUP([expressions - $1])
    AT_DATA([evaluate.sps],
      [set mxwarn 1000.
 set mxerr 1000.
+set epoch 1940.
 m4_foreach([check], [m4_shift($@)],
                  [DEBUG EVALUATE NOOPT m4_argn(4, check)/[]m4_car(check).
 DEBUG EVALUATE m4_argn(4, check)/[]m4_car(check).
 ])])
    AT_CAPTURE_FILE([evaluate.sps])
-   m4_pushdef([i], [2])
+   m4_pushdef([i], [3])
    AT_CHECK([pspp --testing-mode --error-file=- --no-output evaluate.sps], 
-     [m4_if(m4_bregexp([m4_foreach([check], [m4_shift($@)], [m4_argn(3, check)])], [error:]), [-1], [0], [1])],
+     [m4_if(m4_bregexp([m4_foreach([check], [m4_shift($@)], [m4_argn(3, check)])], [error:]), [-1], [0], [1])], 
+     [stdout])
+   # Use sed to transform "file:line.column:" into plain "file:line:",
+   # because column numbers change between opt and noopt versions.
+   AT_CHECK([[sed 's/\(evaluate.sps:[0-9]\{1,\}\)\.[0-9]\{1,\}:/\1:/' stdout]],
+     [0],
      [m4_foreach([check], [m4_shift($@)],
         [m4_define([i], m4_incr(i))dnl
 m4_if(m4_argn(3, check), [], [], [evaluate.sps:[]i[]: m4_argn(3, check)
@@ -281,10 +302,10 @@ dnl Make sure >= token can't be split:
   [['asdfj   ' ne 'asdf'], [true]],
 dnl <> token can't be split:
   [[1 < > 1], [error],
-   [error: DEBUG EVALUATE: Syntax error at `GT'.]],
+   [error: DEBUG EVALUATE: Syntax error at `>'.]],
 dnl # ~= token can't be split:
   [[1 ~ = 1], [error],
-   [error: DEBUG EVALUATE: Syntax error at `NOT': expecting end of command.]])
+   [error: DEBUG EVALUATE: Syntax error at `~': expecting end of command.]])
 
 CHECK_EXPR_EVAL([exp lg10 ln sqrt abs mod mod10 rnd trunc],
   [[exp(10)], [22026.47]],
@@ -328,15 +349,37 @@ CHECK_EXPR_EVAL([exp lg10 ln sqrt abs mod mod10 rnd trunc],
   [[rnd(5.6)], [6.00]],
   [[rnd(-5.4)], [-5.00]],
   [[rnd(-5.6)], [-6.00]],
+  [[rnd(5.56, .1)], [5.60]],
+  [[rnd(-5.56, .1)], [-5.60]],
+  [[rnd(.5)], [1.00]],
+  [[rnd(.5 - 2**-53)], [1.00]],
+  [[rnd(.5 - 2**-52)], [1.00]],
+  [[rnd(.5 - 2**-51)], [1.00]],
+  [[rnd(.5 - 2**-45)], [0.00]],
+  [[rnd(.5 - 2**-45, 1, 10)], [1.00]],
   [[rnd('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking RND(number) as rnd(string).]],
+   [error: DEBUG EVALUATE: Function invocation rnd(string) does not match any known function.  Candidates are:
+RND(number)
+RND(number, number)
+RND(number, number, number).]],
 
   [[trunc(1.2)], [1.00]],
   [[trunc(1.9)], [1.00]],
   [[trunc(-1.2)], [-1.00]],
   [[trunc(-1.9)], [-1.00]],
+  [[trunc(5.06, .1)], [5.00]],
+  [[trunc(-5.06, .1)], [-5.00]],
+  [[trunc(1)], [1.00]],
+  [[trunc(1 - 2**-53)], [1.00]],
+  [[trunc(1 - 2**-52)], [1.00]],
+  [[trunc(1 - 2**-51)], [1.00]],
+  [[trunc(1 - 2**-45)], [0.00]],
+  [[trunc(1 - 2**-45, 1, 10)], [1.00]],
   [[trunc('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking TRUNC(number) as trunc(string).]])
+   [error: DEBUG EVALUATE: Function invocation trunc(string) does not match any known function.  Candidates are:
+TRUNC(number)
+TRUNC(number, number)
+TRUNC(number, number, number).]])
 
 CHECK_EXPR_EVAL([acos arsin artan cos sin tan],
   [[acos(.5) / 3.14159 * 180], [60.00]],
@@ -482,7 +525,7 @@ ANY(string, string[, string]...).]],
   [[any('a', 'a  ', 'b', 'c')], [true]],
   [[any('b   ', 'a', 'b', 'c')], [true]],
   [[any('c   ', 'a', 'b', 'c     ')], [true]],
-  [[any(a, 'b', 'c', 'd')], [error],
+  [[any(a10, 'b', 'c', 'd')], [error],
    [error: DEBUG EVALUATE: Function invocation any(format, string, string, string) does not match any known function.  Candidates are:
 ANY(number, number[, number]...)
 ANY(string, string[, string]...).]],
@@ -616,7 +659,7 @@ MIN(string[, string]...).]],
   [[min("1", "2")], ["1"]],
   [[min("1")], ["1"]])
 
-CHECK_EXPR_EVAL([cfvar mean sd sum variance],
+CHECK_EXPR_EVAL([cfvar mean median sd sum variance],
   [[cfvar(1, 2, 3, 4, 5)], [0.53]],
   [[cfvar(1, $sysmis, 2, 3, $sysmis, 4, 5)], [0.53]],
   [[cfvar(1, 2)], [0.47]],
@@ -644,6 +687,25 @@ CHECK_EXPR_EVAL([cfvar mean sd sum variance],
   [[mean.4(1, 2, 3)], [error],
    [error: DEBUG EVALUATE: With MEAN(number[, number]...), using minimum valid argument count of 4 does not make sense when passing only 3 arguments in list.]],
 
+  [[median(1, 2, 3, 4, 5)], [3.00]],
+  [[median(2, 3, 4, 5, 1)], [3.00]],
+  [[median(2, 3, 4, 1, 5)], [3.00]],
+  [[median(2, 1, 4, 5, 3)], [3.00]],
+  [[median(1, 2, 3, 4)], [2.50]],
+  [[median(2, 3, 1, 4)], [2.50]],
+  [[median(2, 3, 4, 1)], [2.50]],
+  [[median(2, 1, 4, 3)], [2.50]],
+  [[median(1, $sysmis, 3, 4, 5)], [3.50]],
+  [[median(2, 3, 4, 5, $sysmis, 1)], [3.00]],
+  [[median($sysmis, $sysmis, $sysmis, 2, 3, 4, 1, 5)], [3.00]],
+  [[median(1, 2, 3)], [2.00]],
+  [[median(1)], [1.00]],
+  [[median(1, 2)], [1.50]],
+  [[median(1, 2, $sysmis)], [1.50]],
+  [[median(1, $sysmis, $sysmis)], [1.00]],
+  [[median($sysmis, $sysmis, $sysmis)], [sysmis]],
+  [[median.3(1, 2, $sysmis)], [sysmis]],
+  [[median.2(1, $sysmis)], [sysmis]],
 
   [[sd(1, 2, 3, 4, 5)], [1.58]],
   [[sd(1, $sysmis, 2, 3, $sysmis, 4, 5)], [1.58]],
@@ -753,6 +815,7 @@ CHECK_EXPR_EVAL([concat index rindex length lower],
   [[rindex('abcbcde', 'abc', 1)], [5.00]],
   [[rindex('abcbcde', 'bccb', 2)], [4.00]],
   [[rindex('abcbcde', 'bcbc', 2)], [4.00]],
+  [[rindex('abcbcde', 'bcbc', 0)], [sysmis]],
   [[rindex('abcbcde', 'bcbc', $sysmis)], [sysmis]],
   [[rindex('abcbcde', 'bcbcg', 2)], [sysmis]],
   [[rindex('abcbcde', 'bcbcg', $sysmis)], [sysmis]],
@@ -792,7 +855,22 @@ RINDEX(string, string, number).]],
   [[lower(1)], [error],
    [error: DEBUG EVALUATE: Type mismatch invoking LOWER(string) as lower(number).]])
 
-CHECK_EXPR_EVAL([lpad number ltrim lpad rtrim rpad string substr upcase],
+CHECK_EXPR_EVAL([replace],
+  [[replace('banana', 'an', 'AN')], ["bANANa"]],
+  [[replace('banana', 'an', 'a')], ["baaa"]],
+  [[replace('banana', 'an', '')], ["ba"]],
+  [[replace('banana', 'na', '')], ["ba"]],
+  [[replace('banana', 'ba', 'BA')], ["BAnana"]],
+  [[replace('banana', 'na', 'xyzzy')], ["baxyzzyxyzzy"]],
+  [[replace('banana', 'an', 'xyzzy', 1)], ["bxyzzyana"]],
+  [[replace('banana', 'an', 'xyzzy', 1.5)], ["bxyzzyana"]],
+  [[replace('banana', 'bananana', 'xyzzy')], ["banana"]],
+  [[replace('banana', '', 'xyzzy')], ["banana"]],
+  [[replace('banana', 'ba', '', 0)], ["banana"]],
+  [[replace('banana', 'ba', '', -1)], ["banana"]],
+  [[replace('banana', 'ba', '', $sysmis)], ["banana"]])
+
+CHECK_EXPR_EVAL([lpad number ltrim lpad rtrim rpad string strunc substr upcase],
   [[lpad('abc', -1)], [""]],
   [[lpad('abc', 0)], ["abc"]],
   [[lpad('abc', 2)], ["abc"]],
@@ -948,6 +1026,29 @@ dnl E has a minimum width of 6 on output:
    [error: DEBUG EVALUATE: Type mismatch invoking STRING(number, num_output_format) as string(number, format).]],
   [[string(123, e6.0)], ["1E+002"]],
 
+  [[strunc('a c   ', 9)], ["a c"]],
+  [[strunc('a c   ', 7)], ["a c"]],
+  [[strunc('a c   ', 6)], ["a c"]],
+  [[strunc('a c   ', 5)], ["a c"]],
+  [[strunc('a c   ', 4)], ["a c"]],
+  [[strunc('a c   ', 3)], ["a c"]],
+  [[strunc('a c   ', 2)], ["a"]],
+  [[strunc('a c   ', 1)], ["a"]],
+  [[strunc('a c   ', 0)], [""]],
+  [[strunc('a c   ', -1)], [""]],
+  [[strunc('a c   ', $sysmis)], [""]],
+  [[strunc('  abc  ', 9)], ["  abc"]],
+  [[strunc('  abc  ', 8)], ["  abc"]],
+  [[strunc('  abc  ', 7)], ["  abc"]],
+  [[strunc('  abc  ', 6)], ["  abc"]],
+  [[strunc('  abc  ', 5)], ["  abc"]],
+  [[strunc('  abc  ', 4)], ["  ab"]],
+  [[strunc('  abc  ', 3)], ["  a"]],
+  [[strunc('  abc  ', 2)], [""]],
+  [[strunc('  abc  ', 1)], [""]],
+  [[strunc('  abc  ', -1)], [""]],
+  [[strunc('  abc  ', $sysmis)], [""]],
+
   [[substr('abcdefgh', -5)], [""]],
   [[substr('abcdefgh', 0)], [""]],
   [[substr('abcdefgh', 1)], ["abcdefgh"]],
@@ -1281,7 +1382,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.date(date.mdy(10,7,1943) + time.hms(2,57,52)) / 86400], [131845.00]],
   [[xdate.date(date.mdy(3,17,1992) + time.hms(16,45,44)) / 86400], [149539.00]],
   [[xdate.date(date.mdy(2,25,1996) + time.hms(21,30,57)) / 86400], [150979.00]],
-  [[xdate.date(date.mdy(9,29,41) + time.hms(4,25,9)) / 86400], [131107.00]],
+  [[xdate.date(date.mdy(9,29,1941) + time.hms(4,25,9)) / 86400], [131107.00]],
   [[xdate.date(date.mdy(4,19,43) + time.hms(6,49,27)) / 86400], [131674.00]],
   [[xdate.date(date.mdy(10,7,43) + time.hms(2,57,52)) / 86400], [131845.00]],
   [[xdate.date(date.mdy(3,17,92) + time.hms(16,45,44)) / 86400], [149539.00]],
@@ -1305,7 +1406,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.hour(date.mdy(10,7,1943) + time.hms(2,57,52))], [2.00]],
   [[xdate.hour(date.mdy(3,17,1992) + time.hms(16,45,44))], [16.00]],
   [[xdate.hour(date.mdy(2,25,1996) + time.hms(21,30,57))], [21.00]],
-  [[xdate.hour(date.mdy(9,29,41) + time.hms(4,25,9))], [4.00]],
+  [[xdate.hour(date.mdy(9,29,1941) + time.hms(4,25,9))], [4.00]],
   [[xdate.hour(date.mdy(4,19,43) + time.hms(6,49,27))], [6.00]],
   [[xdate.hour(date.mdy(10,7,43) + time.hms(2,57,52))], [2.00]],
   [[xdate.hour(date.mdy(3,17,92) + time.hms(16,45,44))], [16.00]],
@@ -1331,7 +1432,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.jday(date.mdy(10,7,1943) + time.hms(2,57,52))], [280.00]],
   [[xdate.jday(date.mdy(3,17,1992) + time.hms(16,45,44))], [77.00]],
   [[xdate.jday(date.mdy(2,25,1996) + time.hms(21,30,57))], [56.00]],
-  [[xdate.jday(date.mdy(9,29,41) + time.hms(4,25,9))], [272.00]],
+  [[xdate.jday(date.mdy(9,29,1941) + time.hms(4,25,9))], [272.00]],
   [[xdate.jday(date.mdy(4,19,43) + time.hms(6,49,27))], [109.00]],
   [[xdate.jday(date.mdy(10,7,43) + time.hms(2,57,52))], [280.00]],
   [[xdate.jday(date.mdy(3,17,92) + time.hms(16,45,44))], [77.00]],
@@ -1355,7 +1456,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.mday(date.mdy(10,7,1943) + time.hms(2,57,52))], [7.00]],
   [[xdate.mday(date.mdy(3,17,1992) + time.hms(16,45,44))], [17.00]],
   [[xdate.mday(date.mdy(2,25,1996) + time.hms(21,30,57))], [25.00]],
-  [[xdate.mday(date.mdy(9,29,41) + time.hms(4,25,9))], [29.00]],
+  [[xdate.mday(date.mdy(9,29,1941) + time.hms(4,25,9))], [29.00]],
   [[xdate.mday(date.mdy(4,19,43) + time.hms(6,49,27))], [19.00]],
   [[xdate.mday(date.mdy(10,7,43) + time.hms(2,57,52))], [7.00]],
   [[xdate.mday(date.mdy(3,17,92) + time.hms(16,45,44))], [17.00]],
@@ -1376,7 +1477,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.minute(date.mdy(10,7,1943) + time.hms(2,57,52))], [57.00]],
   [[xdate.minute(date.mdy(3,17,1992) + time.hms(16,45,44))], [45.00]],
   [[xdate.minute(date.mdy(2,25,1996) + time.hms(21,30,57))], [30.00]],
-  [[xdate.minute(date.mdy(9,29,41) + time.hms(4,25,9))], [25.00]],
+  [[xdate.minute(date.mdy(9,29,1941) + time.hms(4,25,9))], [25.00]],
   [[xdate.minute(date.mdy(4,19,43) + time.hms(6,49,27))], [49.00]],
   [[xdate.minute(date.mdy(10,7,43) + time.hms(2,57,52))], [57.00]],
   [[xdate.minute(date.mdy(3,17,92) + time.hms(16,45,44))], [45.00]],
@@ -1397,7 +1498,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.month(date.mdy(10,7,1943) + time.hms(2,57,52))], [10.00]],
   [[xdate.month(date.mdy(3,17,1992) + time.hms(16,45,44))], [3.00]],
   [[xdate.month(date.mdy(2,25,1996) + time.hms(21,30,57))], [2.00]],
-  [[xdate.month(date.mdy(9,29,41) + time.hms(4,25,9))], [9.00]],
+  [[xdate.month(date.mdy(9,29,1941) + time.hms(4,25,9))], [9.00]],
   [[xdate.month(date.mdy(4,19,43) + time.hms(6,49,27))], [4.00]],
   [[xdate.month(date.mdy(10,7,43) + time.hms(2,57,52))], [10.00]],
   [[xdate.month(date.mdy(3,17,92) + time.hms(16,45,44))], [3.00]],
@@ -1418,7 +1519,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.quarter(date.mdy(10,7,1943) + time.hms(2,57,52))], [4.00]],
   [[xdate.quarter(date.mdy(3,17,1992) + time.hms(16,45,44))], [1.00]],
   [[xdate.quarter(date.mdy(2,25,1996) + time.hms(21,30,57))], [1.00]],
-  [[xdate.quarter(date.mdy(9,29,41) + time.hms(4,25,9))], [3.00]],
+  [[xdate.quarter(date.mdy(9,29,1941) + time.hms(4,25,9))], [3.00]],
   [[xdate.quarter(date.mdy(4,19,43) + time.hms(6,49,27))], [2.00]],
   [[xdate.quarter(date.mdy(10,7,43) + time.hms(2,57,52))], [4.00]],
   [[xdate.quarter(date.mdy(3,17,92) + time.hms(16,45,44))], [1.00]],
@@ -1439,7 +1540,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.second(date.mdy(10,7,1943) + time.hms(2,57,52))], [52.00]],
   [[xdate.second(date.mdy(3,17,1992) + time.hms(16,45,44))], [44.00]],
   [[xdate.second(date.mdy(2,25,1996) + time.hms(21,30,57))], [57.00]],
-  [[xdate.second(date.mdy(9,29,41) + time.hms(4,25,9))], [9.00]],
+  [[xdate.second(date.mdy(9,29,1941) + time.hms(4,25,9))], [9.00]],
   [[xdate.second(date.mdy(4,19,43) + time.hms(6,49,27))], [27.00]],
   [[xdate.second(date.mdy(10,7,43) + time.hms(2,57,52))], [52.00]],
   [[xdate.second(date.mdy(3,17,92) + time.hms(16,45,44))], [44.00]],
@@ -1460,7 +1561,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.tday(date.mdy(10,7,1943) + time.hms(2,57,52))], [131845.00]],
   [[xdate.tday(date.mdy(3,17,1992) + time.hms(16,45,44))], [149539.00]],
   [[xdate.tday(date.mdy(2,25,1996) + time.hms(21,30,57))], [150979.00]],
-  [[xdate.tday(date.mdy(9,29,41) + time.hms(4,25,9))], [131107.00]],
+  [[xdate.tday(date.mdy(9,29,1941) + time.hms(4,25,9))], [131107.00]],
   [[xdate.tday(date.mdy(4,19,43) + time.hms(6,49,27))], [131674.00]],
   [[xdate.tday(date.mdy(10,7,43) + time.hms(2,57,52))], [131845.00]],
   [[xdate.tday(date.mdy(3,17,92) + time.hms(16,45,44))], [149539.00]],
@@ -1481,7 +1582,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.time(date.mdy(10,7,1943) + time.hms(2,57,52))], [10672.00]],
   [[xdate.time(date.mdy(3,17,1992) + time.hms(16,45,44))], [60344.00]],
   [[xdate.time(date.mdy(2,25,1996) + time.hms(21,30,57))], [77457.00]],
-  [[xdate.time(date.mdy(9,29,41) + time.hms(4,25,9))], [15909.00]],
+  [[xdate.time(date.mdy(9,29,1941) + time.hms(4,25,9))], [15909.00]],
   [[xdate.time(date.mdy(4,19,43) + time.hms(6,49,27))], [24567.00]],
   [[xdate.time(date.mdy(10,7,43) + time.hms(2,57,52))], [10672.00]],
   [[xdate.time(date.mdy(3,17,92) + time.hms(16,45,44))], [60344.00]],
@@ -1502,7 +1603,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.week(date.mdy(10,7,1943) + time.hms(2,57,52))], [40.00]],
   [[xdate.week(date.mdy(3,17,1992) + time.hms(16,45,44))], [11.00]],
   [[xdate.week(date.mdy(2,25,1996) + time.hms(21,30,57))], [8.00]],
-  [[xdate.week(date.mdy(9,29,41) + time.hms(4,25,9))], [39.00]],
+  [[xdate.week(date.mdy(9,29,1941) + time.hms(4,25,9))], [39.00]],
   [[xdate.week(date.mdy(4,19,43) + time.hms(6,49,27))], [16.00]],
   [[xdate.week(date.mdy(10,7,43) + time.hms(2,57,52))], [40.00]],
   [[xdate.week(date.mdy(3,17,92) + time.hms(16,45,44))], [11.00]],
@@ -1523,7 +1624,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.wkday(date.mdy(10,7,1943))], [5.00]],
   [[xdate.wkday(date.mdy(3,17,1992))], [3.00]],
   [[xdate.wkday(date.mdy(2,25,1996))], [1.00]],
-  [[xdate.wkday(date.mdy(9,29,41))], [2.00]],
+  [[xdate.wkday(date.mdy(9,29,1941))], [2.00]],
   [[xdate.wkday(date.mdy(4,19,43))], [2.00]],
   [[xdate.wkday(date.mdy(10,7,43))], [5.00]],
   [[xdate.wkday(date.mdy(3,17,92))], [3.00]],
@@ -1544,7 +1645,7 @@ CHECK_EXPR_EVAL([xdate],
   [[xdate.year(date.mdy(10,7,1943) + time.hms(2,57,52))], [1943.00]],
   [[xdate.year(date.mdy(3,17,1992) + time.hms(16,45,44))], [1992.00]],
   [[xdate.year(date.mdy(2,25,1996) + time.hms(21,30,57))], [1996.00]],
-  [[xdate.year(date.mdy(9,29,41) + time.hms(4,25,9))], [1941.00]],
+  [[xdate.year(date.mdy(9,29,1941) + time.hms(4,25,9))], [1941.00]],
   [[xdate.year(date.mdy(4,19,43) + time.hms(6,49,27))], [1943.00]],
   [[xdate.year(date.mdy(10,7,43) + time.hms(2,57,52))], [1943.00]],
   [[xdate.year(date.mdy(3,17,92) + time.hms(16,45,44))], [1992.00]],
@@ -1565,8 +1666,8 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'years')], [0.00]],
   [[datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'years')], [-48.00]],
   [[datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'years')], [-3.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(2,25,1996), 'years')], [-54.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(4,19,43), 'years')], [-1.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'years')], [-54.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'years')], [-1.00]],
   [[datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'years')], [0.00]],
   [[datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'years')], [-48.00]],
   [[datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'years')], [-3.00]],
@@ -1588,8 +1689,8 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'quarters')], [-1.00]],
   [[datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'quarters')], [-193.00]],
   [[datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'quarters')], [-15.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(2,25,1996), 'quarters')], [-217.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(4,19,43), 'quarters')], [-6.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'quarters')], [-217.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'quarters')], [-6.00]],
   [[datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'quarters')], [-1.00]],
   [[datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'quarters')], [-193.00]],
   [[datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'quarters')], [-15.00]],
@@ -1611,8 +1712,8 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'months')], [-5.00]],
   [[datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'months')], [-581.00]],
   [[datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'months')], [-47.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(2,25,1996), 'months')], [-652.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(4,19,43), 'months')], [-18.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'months')], [-652.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'months')], [-18.00]],
   [[datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'months')], [-5.00]],
   [[datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'months')], [-581.00]],
   [[datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'months')], [-47.00]],
@@ -1634,8 +1735,8 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'weeks')], [-24.00]],
   [[datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'weeks')], [-2527.00]],
   [[datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'weeks')], [-205.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(2,25,1996), 'weeks')], [-2838.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(4,19,43), 'weeks')], [-81.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'weeks')], [-2838.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'weeks')], [-81.00]],
   [[datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'weeks')], [-24.00]],
   [[datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'weeks')], [-2527.00]],
   [[datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'weeks')], [-205.00]],
@@ -1657,8 +1758,8 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'days')], [-171.00]],
   [[datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'days')], [-17694.00]],
   [[datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'days')], [-1440.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(2,25,1996), 'days')], [-19872.00]],
-  [[datediff(date.mdy(9,29,41), date.mdy(4,19,43), 'days')], [-567.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'days')], [-19872.00]],
+  [[datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'days')], [-567.00]],
   [[datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'days')], [-171.00]],
   [[datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'days')], [-17694.00]],
   [[datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'days')], [-1440.00]],
@@ -1680,8 +1781,8 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'years')], [0.00]],
   [[datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'years')], [48.00]],
   [[datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'years')], [3.00]],
-  [[datediff(date.mdy(2,25,1996), date.mdy(9,29,41), 'years')], [54.00]],
-  [[datediff(date.mdy(4,19,43), date.mdy(9,29,41), 'years')], [1.00]],
+  [[datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'years')], [54.00]],
+  [[datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'years')], [1.00]],
   [[datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'years')], [0.00]],
   [[datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'years')], [48.00]],
   [[datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'years')], [3.00]],
@@ -1703,8 +1804,8 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'months')], [5.00]],
   [[datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'months')], [581.00]],
   [[datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'months')], [47.00]],
-  [[datediff(date.mdy(2,25,1996), date.mdy(9,29,41), 'months')], [652.00]],
-  [[datediff(date.mdy(4,19,43), date.mdy(9,29,41), 'months')], [18.00]],
+  [[datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'months')], [652.00]],
+  [[datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'months')], [18.00]],
   [[datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'months')], [5.00]],
   [[datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'months')], [581.00]],
   [[datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'months')], [47.00]],
@@ -1726,8 +1827,8 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'quarters')], [1.00]],
   [[datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'quarters')], [193.00]],
   [[datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'quarters')], [15.00]],
-  [[datediff(date.mdy(2,25,1996), date.mdy(9,29,41), 'quarters')], [217.00]],
-  [[datediff(date.mdy(4,19,43), date.mdy(9,29,41), 'quarters')], [6.00]],
+  [[datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'quarters')], [217.00]],
+  [[datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'quarters')], [6.00]],
   [[datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'quarters')], [1.00]],
   [[datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'quarters')], [193.00]],
   [[datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'quarters')], [15.00]],
@@ -1735,7 +1836,42 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(7,18,2094), date.mdy(11,10,2038), 'quarters')], [222.00]],
   [[datediff(date.mdy(2,29,1904), date.mdy(2,29,1900), 'quarters')], [15.00]],
   [[datediff(date.mdy(2,29,1908), date.mdy(2,29,1904), 'quarters')], [16.00]],
-  [[datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'quarters')], [11.00]])
+  [[datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'quarters')], [11.00]],
+
+dnl time of day is significant for DATEDIFF
+  [[datediff(date.mdy(10,15,1910) + 234, date.mdy(10,10,1910) + 123, 'days')],
+    [5.00]],
+  [[datediff(date.mdy(10,15,1910) + 123, date.mdy(10,10,1910) + 234, 'days')],
+    [4.00]],
+  [[datediff(date.mdy(10,24,1910) + 234, date.mdy(10,10,1910) + 123, 'weeks')],
+    [2.00]],
+  [[datediff(date.mdy(10,24,1910) + 123, date.mdy(10,10,1910) + 234, 'weeks')],
+    [1.00]],
+  [[datediff(date.mdy(10,10,1910) + 234, date.mdy(5,10,1910) + 123, 'months')],
+    [5.00]],
+  [[datediff(date.mdy(10,10,1910) + 123, date.mdy(5,10,1910) + 234, 'months')],
+    [4.00]],
+  [[datediff(date.mdy(5,10,1919) + 234, date.mdy(5,10,1910) + 123, 'years')],
+    [9.00]],
+  [[datediff(date.mdy(5,10,1919) + 123, date.mdy(5,10,1910) + 234, 'years')],
+    [8.00]],
+
+  [[datediff(date.mdy(10,10,1910) + 123, date.mdy(10,15,1910) + 234, 'days')],
+    [-5.00]],
+  [[datediff(date.mdy(10,10,1910) + 234, date.mdy(10,15,1910) + 123, 'days')],
+    [-4.00]],
+  [[datediff(date.mdy(10,10,1910) + 123, date.mdy(10,24,1910) + 234, 'weeks')],
+    [-2.00]],
+  [[datediff(date.mdy(10,10,1910) + 234, date.mdy(10,24,1910) + 123, 'weeks')],
+    [-1.00]],
+  [[datediff(date.mdy(5,10,1910) + 123, date.mdy(10,10,1910) + 234, 'months')],
+    [-5.00]],
+  [[datediff(date.mdy(5,10,1910) + 234, date.mdy(10,10,1910) + 123, 'months')],
+    [-4.00]],
+  [[datediff(date.mdy(5,10,1910) + 123, date.mdy(5,10,1919) + 234, 'years')],
+    [-9.00]],
+  [[datediff(date.mdy(5,10,1910) + 234, date.mdy(5,10,1919) + 123, 'years')],
+    [-8.00]])
 
 CHECK_EXPR_EVAL([datesum],
 dnl DATESUM with non-leap year
@@ -1808,7 +1944,13 @@ dnl DATESUM with leap year
   [[ctime.days(datesum(date.mdy(6,10,1648), 1, 'hours') - date.mdy(6,10,1648))], [0.04]],
   [[ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'hours') - date.mdy(6,30,1680))], [0.10]],
   [[ctime.days(datesum(date.mdy(6,19,1768), -4, 'hours') - date.mdy(6,19,1768))], [-0.17]],
-  [[ctime.days(datesum(date.mdy(8,2,1819), 5, 'hours') - date.mdy(8,2,1819))], [0.21]])
+  [[ctime.days(datesum(date.mdy(8,2,1819), 5, 'hours') - date.mdy(8,2,1819))], [0.21]],
+
+dnl DATESUM preserves time-of-day for units of days and longer.
+  [[ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'days') - (date.mdy(8,2,1819) + time.hms(1,2,3)))], [5.00]],
+  [[ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'weeks') - (date.mdy(8,2,1819) + time.hms(1,2,3)))], [35.00]],
+  [[ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'months') - (date.mdy(8,2,1819) + time.hms(1,2,3)))], [153.00]],
+  [[ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'years') - (date.mdy(8,2,1819) + time.hms(1,2,3)))], [1827.00]])
 
 CHECK_EXPR_EVAL([miscellaneous],
 dnl These test values are from Applied Statistics, Algorithm AS 310.
@@ -1978,10 +2120,10 @@ Table: Data List
 n,s,nlabel,slabel
 .,,,
 0,a,Very dissa,Wouldn't b
-1,b,Dissatisfi,Unhappy   @&t@
-2,c,Neutral   ,Bored     @&t@
-3,d,Satisfied ,Satiated  @&t@
-4,e,Very satis,Elated    @&t@
+1,b,Dissatisfi,Unhappy
+2,c,Neutral,Bored
+3,d,Satisfied,Satiated
+4,e,Very satis,Elated
 5,f,,
 6,g,,
 ])