Add support for reading and writing SPV files.
[pspp] / tests / data / test-date-input.py
1 #! /usr/bin/env python
2
3 import re
4 import sys
5
6 fmt_name = sys.argv[1]
7 templates = sys.argv[2:]
8
9 dates = (#yyyy  mm  dd  jjj  HH  MM  SS
10          (1648,  6, 10, 162,  0,  0,  0),
11          (1680,  6, 30, 182,  4, 50, 38),
12          (1716,  7, 24, 206, 12, 31, 35),
13          (1768,  6, 19, 171, 12, 47, 53),
14          (1819,  8,  2, 214,  1, 26,  0),
15          (1839,  3, 27,  86, 20, 58, 11),
16          (1903,  4, 19, 109,  7, 36,  5),
17          (1929,  8, 25, 237, 15, 43, 49),
18          (1941,  9, 29, 272,  4, 25,  9),
19          (1943,  4, 19, 109,  6, 49, 27),
20          (1943, 10,  7, 280,  2, 57, 52),
21          (1992,  3, 17,  77, 16, 45, 44),
22          (1996,  2, 25,  56, 21, 30, 57),
23          (1941,  9, 29, 272,  4, 25,  9),
24          (1943,  4, 19, 109,  6, 49, 27),
25          (1943, 10,  7, 280,  2, 57, 52),
26          (1992,  3, 17,  77, 16, 45, 44),
27          (1996,  2, 25,  56, 21, 30, 57),
28          (2038, 11, 10, 314, 22, 30,  4),
29          (2094,  7, 18, 199,  1, 56, 51))
30
31 syntax_file = open('%s.sps' % fmt_name, 'w')
32 syntax_file.write('''\
33 SET EPOCH 1930.
34 DATA LIST NOTABLE FILE='%(fmt_name)s.input'/%(fmt_name)s 1-40 (%(fmt_name)s).
35 PRINT OUTFILE='%(fmt_name)s.output'/%(fmt_name)s (F16.2).
36 EXECUTE.
37 ''' % {'fmt_name': fmt_name})
38 syntax_file.close()
39
40 expout_file = open('expout', 'w')
41 input_file = open('%s.input' % fmt_name, 'w')
42
43 def is_leap_year(y):
44     return y % 4 == 0 and (y % 100 != 0 or y % 400 == 0)
45
46 n = 0
47 def print_all_formats(date, template, formatted, exp_y, exp_m, exp_d,
48                       exp_time, exp_sign):
49     if template != '':
50         global n
51         n += 1
52         year, month, day, julian, hour, minute, second = date
53         quarter = (month - 1) // 3 + 1
54         week = (julian - 1) // 7 + 1
55         if year >= 1930 and year < 2030:
56             years = ('%d' % year, '%d' % (year % 100))
57         else:
58             years = ('%d' % year,)
59
60         c = template[0]
61         template = template[1:]
62         if c == 'd':
63             for f in ('%d', '%02d'):
64                 print_all_formats(date, template, formatted + (f % day),
65                                   exp_y, exp_m, day, exp_time, exp_sign)
66         elif c == 'm':
67             for f in ('%d' % month,
68                       '%02d' % month,
69                       ('i', 'ii', 'iii', 'iv', 'v', 'vi',
70                        'vii', 'viii', 'ix', 'x', 'xi', 'xii')[month - 1],
71                       ('I', 'II', 'III', 'IV', 'V', 'VI',
72                        'VII', 'VIII', 'IX', 'X', 'XI', 'XII')[month - 1],
73                       ('jan', 'feb', 'mar', 'apr', 'may', 'jun',
74                        'jul', 'aug', 'sep', 'oct', 'nov', 'dec')[month - 1],
75                       ('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN',
76                        'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC')[month - 1],
77                       ('january', 'february', 'march',
78                        'april', 'may', 'june',
79                        'july', 'august', 'september',
80                        'october', 'november', 'december')[month - 1],
81                       ('JANUARY', 'FEBRUARY', 'MARCH',
82                        'APRIL', 'MAY', 'JUNE',
83                        'JULY', 'AUGUST', 'SEPTEMBER',
84                        'OCTOBER', 'NOVEMBER', 'DECEMBER')[month - 1]):
85                 print_all_formats(date, template, formatted + f,
86                                   exp_y, month, exp_d, exp_time, exp_sign)
87         elif c == 'y':
88             for f in years:
89                 print_all_formats(date, template, formatted + f,
90                                   year, exp_m, exp_d, exp_time, exp_sign)
91         elif c == 'j':
92             for f in years:
93                 print_all_formats(date, template,
94                                   formatted + f + ('%03d' % julian),
95                                   year, month, day, exp_time, exp_sign)
96         elif c == 'q':
97             print_all_formats(date, template, formatted + ('%d' % quarter),
98                               exp_y, (quarter - 1) * 3 + 1, 1,
99                               exp_time, exp_sign)
100         elif c == 'w':
101             exp_m = month
102             exp_d = day - (julian - 1) % 7
103             if exp_d < 1:
104                 exp_m -= 1
105                 exp_d += (31, 29 if is_leap_year(year) else 28, 31,
106                           30, 31, 30, 31, 31, 30, 31, 30, 31)[exp_m]
107             print_all_formats(date, template, formatted + ('%d' % week),
108                               exp_y, exp_m, exp_d, exp_time, exp_sign)
109             
110         elif c == 'H':
111             for f in ('%d', '%02d'):
112                 print_all_formats(date, template, formatted + (f % hour),
113                                   exp_y, exp_m, exp_d, exp_time + hour * 3600,
114                                   exp_sign)
115         elif c == 'M':
116             for f in ('%d', '%02d'):
117                 print_all_formats(date, template, formatted + (f % minute),
118                                   exp_y, exp_m, exp_d, exp_time + minute * 60,
119                                   exp_sign)
120         elif c == 'S':
121             for f in ('%d', '%02d'):
122                 print_all_formats(date, template, formatted + (f % second),
123                                   exp_y, exp_m, exp_d, exp_time + second,
124                                   exp_sign)
125         elif c == '-':
126             for f in ' -.,/':
127                 print_all_formats(date, template, formatted + f,
128                                   exp_y, exp_m, exp_d, exp_time,
129                                   exp_sign)
130         elif c == ':':
131             for f in ' :':
132                 print_all_formats(date, template, formatted + f,
133                                   exp_y, exp_m, exp_d, exp_time,
134                                   exp_sign)
135         elif c == ' ':
136             print_all_formats(date, template, formatted + ' ',
137                               exp_y, exp_m, exp_d, exp_time,
138                               exp_sign)
139         elif c == 'Q' or c == 'W':
140             infix = 'q' if c == 'Q' else 'wk'
141             for before in (' ', ''):
142                 for middle in (infix, infix.upper()):
143                     for after in (' ', ''):
144                         print_all_formats(date, template,
145                                           formatted + before + middle + after,
146                                           exp_y, exp_m, exp_d, exp_time,
147                                           exp_sign)
148         elif c == '+':
149             for f in ('', '+', '-'):
150                 print_all_formats(date, template, formatted + f,
151                                   exp_y, exp_m, exp_d, exp_time,
152                                   f)
153         else:
154             assert False    
155     else:
156         # Write the formatted value to fmt_name.input.
157         input_file.write('%s\n' % formatted)
158
159         # Write the expected value to 'expout'.
160         assert exp_y >= 1582 and exp_y <= 2100
161         assert exp_m >= 1 and exp_m <= 12
162         assert exp_d >= 1 and exp_d <= 31
163         EPOCH = -577734         # 14 Oct 1582
164         expected = (EPOCH - 1
165                     + 365 * (exp_y - 1)
166                     + (exp_y - 1) // 4
167                     - (exp_y - 1) // 100
168                     + (exp_y - 1) // 400
169                     + (367 * exp_m - 362) // 12
170                     + (0 if exp_m <= 2
171                        else -1 if exp_m >= 2 and is_leap_year(exp_y)
172                        else -2)
173                     + exp_d) * 86400
174         if exp_sign == '-' and expected > 0:
175             expected -= exp_time
176         else:
177             expected += exp_time
178         expected_s = '%17.2f\n' % expected
179         expected_s = expected_s.replace(' 0.', '  .')
180         expout_file.write(expected_s)
181         
182
183 for template in templates:
184     for date in dates:
185         print_all_formats(date, template, '', 0, 0, 1, 0, '')
186