1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 dnl GNU General Public License for more details.
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
17 AT_BANNER([data input (data-in)])
19 AT_SETUP([numeric input formats])
20 AT_KEYWORDS([data-in slow])
28 # This random number generator and the test for it below are drawn
29 # from Park and Miller, "Random Number Generators: Good Ones are Hard
30 # to Come By", Communications of the ACM 31:10 (October 1988). It is
31 # documented to function properly on systems with a 46-bit or longer
32 # real significand, which includes systems that have 64-bit IEEE reals
33 # (with 53-bit significand). The test should catch any systems for
34 # which this is not true, in any case.
40 seed = tmp - m * (tmp // m)
43 # Test the random number generator for reproducibility,
46 for i in range(10000):
48 assert seed == 1043618065
51 def permute_zeros(fraction, exponent):
52 frac_rep = "%f" % fraction
53 leading_zeros = len(frac_rep) - len(frac_rep.lstrip('0'))
54 trailing_zeros = len(re.search(r'(\.?0*)$', frac_rep).group(1))
55 for i in range(leading_zeros + 1):
56 for j in range(trailing_zeros + 1):
57 trimmed = frac_rep[i:len(frac_rep) - j]
58 if trimmed == '.' or not trimmed:
61 permute_commas(trimmed, exponent)
63 def permute_commas(frac_rep, exponent):
64 permute_dot_comma(frac_rep, exponent)
65 pos = my_rand(len(frac_rep) + 1)
66 frac_rep = "%s,%s" % (frac_rep[:pos], frac_rep[pos:])
67 permute_dot_comma(frac_rep, exponent)
69 def permute_dot_comma(frac_rep, exponent):
70 permute_exponent_syntax(frac_rep, exponent)
71 if ',' in frac_rep or '.' in frac_rep:
72 frac_rep = frac_rep.translate(str.maketrans('.,', ',.'))
73 permute_exponent_syntax(frac_rep, exponent)
75 def permute_exponent_syntax(frac_rep, exponent):
77 e = pick(('', 'e0', 'e-0', 'e+0', '-0', '+0'))
79 e = pick(("e%s" % exponent, "e+%s" % exponent, "+%s" % exponent))
82 e = pick(("e-%s" % abs_exp, "e-%s" % abs_exp, "-%s" % abs_exp))
83 permute_sign_and_affix(frac_rep, e)
85 def permute_sign_and_affix(frac_rep, exp_rep):
86 for prefix in (pick(('', '$')),
87 pick(('-', '-$', '$-', '$-$')),
88 pick(('+', '+$', '$+', '$+$'))):
89 for suffix in ('', '%'):
90 permute_spaces(prefix + frac_rep + exp_rep + suffix)
92 def permute_spaces(s):
93 fields = re.sub(r'([-+\$e%])', r' \1 ', s).split()
94 print(''.join(fields))
97 pos = my_rand(len(fields) - 1) + 1
98 print("%s %s" % (''.join(fields[:pos]),
99 ''.join(fields[pos:])))
102 return choices[my_rand(len(choices))]
104 for number in (0, 1, .5, .015625, 123):
105 base_exp = math.floor(math.log10(number)) if number else 0
106 for offset in range(-3, 4):
107 exponent = base_exp + offset
108 fraction = number / 10**offset
110 permute_zeros(fraction, exponent)
113 AT_CHECK([$PYTHON3 num-in.py > num-in.data])
114 AT_DATA([num-in.sps], [dnl
117 SET MXWARNS=10000000.
118 DATA LIST FILE='num-in.data' NOTABLE/
125 PRINT OUTFILE='num-in.out'/all (6f10.4).
128 AT_CHECK([pspp -O format=csv num-in.sps])
129 AT_CHECK([gzip -cd < $top_srcdir/tests/data/num-in.expected.gz > expout])
130 AT_CHECK([cat num-in.out], [0], [expout])
133 dnl Some very old version of PSPP crashed reading big numbers,
134 dnl so this checks for regressions.
135 AT_SETUP([reading big numbers])
136 AT_KEYWORDS([data-in])
137 AT_DATA([bignum.txt], [dnl
168 199999999999999999999
169 1234567890123456789012
170 19999999999999999999999
171 123456789012345678901234
172 1999999999999999999999999
173 12345678901234567890123456
174 199999999999999999999999999
175 1234567890123456789012345678
176 19999999999999999999999999999
177 123456789012345678901234567890
178 1999999999999999999999999999999
179 12345678901234567890123456789012
180 199999999999999999999999999999999
181 1234567890123456789012345678901234
182 19999999999999999999999999999999999
183 123456789012345678901234567890123456
184 1999999999999999999999999999999999999
185 12345678901234567890123456789012345678
186 199999999999999999999999999999999999999
187 1234567890123456789012345678901234567890
188 1999999999999999999999999999999999999999
202 AT_DATA([bignum.sps], [dnl
203 title 'Test use of big numbers'.
205 *** Do the portable output.
206 data list file='bignum.txt'/BIGNUM 1-40.
209 *** Do the nonportable output for fun.
212 AT_CHECK([pspp -o pspp.csv bignum.sps], [0], [ignore])
215 AT_SETUP([DATE input format])
216 AT_KEYWORDS([data-in])
217 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py date d-m-y])
218 AT_FAIL_IF([test ! -s date.sps || test ! -s date.input || test ! -s expout])
219 AT_CHECK([pspp -O format=csv date.sps])
220 AT_CHECK([cat date.output], [0], [expout])
223 AT_SETUP([ADATE input format])
224 AT_KEYWORDS([data-in])
225 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py adate m-d-y])
226 AT_FAIL_IF([test ! -s adate.sps || test ! -s adate.input || test ! -s expout])
227 AT_CHECK([pspp -O format=csv adate.sps])
228 AT_CHECK([cat adate.output], [0], [expout])
231 AT_SETUP([EDATE input format])
232 AT_KEYWORDS([data-in])
233 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py edate d-m-y])
234 AT_FAIL_IF([test ! -s edate.sps || test ! -s edate.input || test ! -s expout])
235 AT_CHECK([pspp -O format=csv edate.sps])
236 AT_CHECK([cat edate.output], [0], [expout])
239 AT_SETUP([JDATE input format])
240 AT_KEYWORDS([data-in])
241 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py jdate j])
242 AT_FAIL_IF([test ! -s jdate.sps || test ! -s jdate.input || test ! -s expout])
243 AT_CHECK([pspp -O format=csv jdate.sps])
244 AT_CHECK([cat jdate.output], [0], [expout])
247 AT_SETUP([SDATE input format])
248 AT_KEYWORDS([data-in])
249 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py sdate y-m-d])
250 AT_FAIL_IF([test ! -s sdate.sps || test ! -s sdate.input || test ! -s expout])
251 AT_CHECK([pspp -O format=csv sdate.sps])
252 AT_CHECK([cat sdate.output], [0], [expout])
255 AT_SETUP([QYR input format])
256 AT_KEYWORDS([data-in])
257 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py qyr qQy])
258 AT_FAIL_IF([test ! -s qyr.sps || test ! -s qyr.input || test ! -s expout])
259 AT_CHECK([pspp -O format=csv qyr.sps])
260 AT_CHECK([cat qyr.output], [0], [expout])
263 AT_SETUP([MOYR input format])
264 AT_KEYWORDS([data-in])
265 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py moyr m-y])
266 AT_FAIL_IF([test ! -s moyr.sps || test ! -s moyr.input || test ! -s expout])
267 AT_CHECK([pspp -O format=csv moyr.sps])
268 AT_CHECK([cat moyr.output], [0], [expout])
271 AT_SETUP([WKYR input format])
272 AT_KEYWORDS([data-in])
273 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py wkyr wWy])
274 AT_FAIL_IF([test ! -s wkyr.sps || test ! -s wkyr.input || test ! -s expout])
275 AT_CHECK([pspp -O format=csv wkyr.sps])
276 AT_CHECK([cat wkyr.output], [0], [expout])
279 AT_SETUP([DATETIME input format])
280 AT_KEYWORDS([data-in slow])
281 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py datetime "d-m-y +H:M" "d-m-y +H:M:S"])
282 AT_FAIL_IF([test ! -s datetime.sps || test ! -s datetime.input || \
284 AT_CHECK([pspp -O format=csv datetime.sps])
285 AT_CHECK([cat datetime.output], [0], [expout])
288 AT_SETUP([YMDHMS input format])
289 AT_KEYWORDS([data-in slow])
290 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-date-input.py ymdhms "y-m-d +H:M" "y-m-d +H:M:S"])
291 AT_FAIL_IF([test ! -s ymdhms.sps || test ! -s ymdhms.input || \
293 AT_CHECK([pspp -O format=csv ymdhms.sps])
294 AT_CHECK([cat ymdhms.output], [0], [expout])
297 AT_SETUP([MTIME input format])
298 AT_KEYWORDS([data-in])
299 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-time-input.py mtime +M:S])
300 AT_FAIL_IF([test ! -s mtime.sps || test ! -s mtime.input || test ! -s expout])
301 AT_CHECK([pspp -O format=csv mtime.sps])
302 AT_CHECK([cat mtime.output], [0], [expout])
305 AT_SETUP([TIME input format])
306 AT_KEYWORDS([data-in])
307 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-time-input.py time +H:M +H:M:S])
308 AT_FAIL_IF([test ! -s time.sps || test ! -s time.input || test ! -s expout])
309 AT_CHECK([pspp -O format=csv time.sps])
310 AT_CHECK([cat time.output], [0], [expout])
313 AT_SETUP([DTIME input format])
314 AT_KEYWORDS([data-in])
315 AT_CHECK([$PYTHON3 $top_srcdir/tests/data/test-time-input.py dtime '+D H:M' '+D H:M:S'])
316 AT_FAIL_IF([test ! -s dtime.sps || test ! -s dtime.input || test ! -s expout])
317 AT_CHECK([pspp -O format=csv dtime.sps])
318 AT_CHECK([cat dtime.output], [0], [expout])
321 m4_divert_push([PREPARE_TESTS])
322 [number_lines_in_hex () {
325 for i, line in enumerate(sys.stdin):
326 sys.stdout.write(" %04X %s" % (i, line))
329 m4_divert_pop([PREPARE_TESTS])
332 AT_SETUP([binary and hexadecimal input (IB, PIB, and PIBHEX formats)])
334 AT_CHECK([$PYTHON3 -c '
337 for i in range(65536):
338 sys.stdout.buffer.write(struct.pack(">H", i))' > binhex-in.data])
339 AT_CHECK([[wc -c < binhex-in.data | sed 's/[ ]//g']], [0], [131072
341 AT_DATA([binhex-in.sps], [dnl
344 SET MXWARNS=10000000.
346 FILE HANDLE data/NAME='binhex-in.data'/MODE=IMAGE/LRECL=2.
347 DATA LIST FILE=data NOTABLE/ib 1-2 (IB) pib 1-2 (PIB) pibhex 1-2 (PIBHEX).
348 COMPUTE x=$CASENUM - 1.
349 PRINT OUTFILE='binhex-in.out'/x (PIBHEX4) ' ' ib pib pibhex.
352 AT_CHECK([gzip -cd < $top_srcdir/tests/data/binhex-in.expected.cmp.gz | \
353 number_lines_in_hex > expout])
354 AT_CHECK([pspp -O format=csv binhex-in.sps], [0])
355 AT_CHECK([cat binhex-in.out], [0], [expout])
358 AT_SETUP([BCD input (P and PK formats)])
360 AT_CHECK([$PYTHON3 -c '
363 for i in range(65536):
364 sys.stdout.buffer.write(struct.pack(">H", i))' > bcd-in.data])
365 AT_CHECK([[wc -c < bcd-in.data | sed 's/[ ]//g']], [0], [131072
367 AT_DATA([bcd-in.sps], [dnl
369 SET MXWARNS=10000000.
371 FILE HANDLE data/NAME='bcd-in.data'/MODE=IMAGE/LRECL=2.
372 DATA LIST FILE=data NOTABLE/p 1-2 (P) pk 1-2 (PK).
373 COMPUTE x=$CASENUM - 1.
374 PRINT OUTFILE='bcd-in.out'/x (PIBHEX4) ' ' P PK.
377 AT_CHECK([gzip -cd < $top_srcdir/tests/data/bcd-in.expected.cmp.gz | \
378 number_lines_in_hex > expout])
379 AT_CHECK([pspp -O format=csv bcd-in.sps])
380 AT_CHECK([cat bcd-in.out], [0], [expout])
383 AT_SETUP([legacy input (N and Z formats)])
385 AT_CHECK([$PYTHON3 -c '
388 for i in range(65536):
389 sys.stdout.buffer.write(struct.pack(">H", i))' > legacy-in.data])
390 AT_CHECK([[wc -c < legacy-in.data | sed 's/[ ]//g']], [0], [131072
392 AT_DATA([legacy-in.sps], [dnl
394 SET MXWARNS=10000000.
396 FILE HANDLE data/NAME='legacy-in.data'/MODE=IMAGE/LRECL=2.
397 DATA LIST NOTABLE FILE=data/n 1-2 (N) z 1-2 (z).
398 COMPUTE x=$CASENUM - 1.
399 PRINT OUTFILE='legacy-in.out'/x (PIBHEX4) ' ' N Z.
402 AT_CHECK([gzip -cd < $top_srcdir/tests/data/legacy-in.expected.cmp.gz | \
403 number_lines_in_hex > expout])
404 AT_CHECK([pspp -O format=csv legacy-in.sps])
405 AT_CHECK([cat legacy-in.out], [0], [expout])
408 AT_SETUP([WKDAY input format])
409 AT_DATA([wkday.sps], [dnl
410 DATA LIST NOTABLE /wkday2 1-2 (wkday)
418 wkday10 1-10 (wkday).
431 FORMATS ALL (WKDAY2).
432 PRINT OUTFILE='wkday.out'/ALL.
435 AT_CHECK([pspp -O format=csv wkday.sps], [0], [dnl
436 wkday.sps:20.1-20.2: warning: Data for variable wkday2 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
438 wkday.sps:20.1-20.3: warning: Data for variable wkday3 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
440 wkday.sps:20.1-20.4: warning: Data for variable wkday4 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
442 wkday.sps:20.1-20.5: warning: Data for variable wkday5 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
444 wkday.sps:20.1-20.6: warning: Data for variable wkday6 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
446 wkday.sps:20.1-20.7: warning: Data for variable wkday7 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
448 wkday.sps:20.1-20.8: warning: Data for variable wkday8 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
450 wkday.sps:20.1-20.9: warning: Data for variable wkday9 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
452 wkday.sps:20.1-20.10: warning: Data for variable wkday10 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
454 AT_CHECK([cat wkday.out], [0], [dnl
455 . . . . . . . . . @&t@
456 . . . . . . . . . @&t@
457 MO MO MO MO MO MO MO MO MO @&t@
458 TU TU TU TU TU TU TU TU TU @&t@
459 WE WE WE WE WE WE WE WE WE @&t@
460 TH TH TH TH TH TH TH TH TH @&t@
461 FR FR FR FR FR FR FR FR FR @&t@
462 SA SA SA SA SA SA SA SA SA @&t@
463 SU SU SU SU SU SU SU SU SU @&t@
464 . . . . . . . . . @&t@
468 AT_SETUP([MONTH input format])
469 AT_DATA([month.sps], [dnl
470 DATA LIST NOTABLE /month3 1-3 (MONTH)
477 month10 1-10 (MONTH).
526 FORMATS ALL (MONTH3).
527 PRINT OUTFILE='month.out'/ALL.
530 AT_CHECK([pspp -O format=csv month.sps], [0], [dnl
531 month.sps:15.1-15.4: warning: Data for variable month4 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
533 month.sps:15.1-15.5: warning: Data for variable month5 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
535 month.sps:15.1-15.6: warning: Data for variable month6 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
537 month.sps:15.1-15.7: warning: Data for variable month7 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
539 month.sps:15.1-15.8: warning: Data for variable month8 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
541 month.sps:15.1-15.9: warning: Data for variable month9 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
543 month.sps:15.1-15.10: warning: Data for variable month10 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
545 month.sps:26.1-26.3: warning: Data for variable month3 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
547 month.sps:26.1-26.4: warning: Data for variable month4 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
549 month.sps:26.1-26.5: warning: Data for variable month5 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
551 month.sps:26.1-26.6: warning: Data for variable month6 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
553 month.sps:26.1-26.7: warning: Data for variable month7 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
555 month.sps:26.1-26.8: warning: Data for variable month8 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
557 month.sps:26.1-26.9: warning: Data for variable month9 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
559 month.sps:26.1-26.10: warning: Data for variable month10 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
561 month.sps:39.1-39.3: warning: Data for variable month3 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
563 month.sps:39.1-39.4: warning: Data for variable month4 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
565 month.sps:39.1-39.5: warning: Data for variable month5 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
567 month.sps:39.1-39.6: warning: Data for variable month6 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
569 month.sps:39.1-39.7: warning: Data for variable month7 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
571 month.sps:39.1-39.8: warning: Data for variable month8 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
573 month.sps:39.1-39.9: warning: Data for variable month9 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
575 month.sps:39.1-39.10: warning: Data for variable month10 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
577 AT_CHECK([cat month.out], [0], [dnl
580 JAN JAN JAN JAN JAN JAN JAN JAN @&t@
581 FEB FEB FEB FEB FEB FEB FEB FEB @&t@
582 MAR MAR MAR MAR MAR MAR MAR MAR @&t@
583 MAR . . . . . . . @&t@
584 APR APR APR APR APR APR APR APR @&t@
585 MAY MAY MAY MAY MAY MAY MAY MAY @&t@
586 JUN JUN JUN JUN JUN JUN JUN JUN @&t@
587 JUL JUL JUL JUL JUL JUL JUL JUL @&t@
588 JUL AUG AUG AUG AUG AUG AUG AUG @&t@
589 SEP SEP SEP SEP SEP SEP SEP SEP @&t@
590 JUL AUG AUG AUG AUG AUG AUG AUG @&t@
591 OCT OCT OCT OCT OCT OCT OCT OCT @&t@
592 NOV NOV NOV NOV NOV NOV NOV NOV @&t@
593 DEC DEC DEC DEC DEC DEC DEC DEC @&t@
595 JAN JAN JAN JAN JAN JAN JAN JAN @&t@
596 FEB FEB FEB FEB FEB FEB FEB FEB @&t@
597 MAR MAR MAR MAR MAR MAR MAR MAR @&t@
598 APR APR APR APR APR APR APR APR @&t@
599 MAY MAY MAY MAY MAY MAY MAY MAY @&t@
600 JUN JUN JUN JUN JUN JUN JUN JUN @&t@
601 JUL JUL JUL JUL JUL JUL JUL JUL @&t@
602 AUG AUG AUG AUG AUG AUG AUG AUG @&t@
603 SEP SEP SEP SEP SEP SEP SEP SEP @&t@
604 OCT OCT OCT OCT OCT OCT OCT OCT @&t@
605 NOV NOV NOV NOV NOV NOV NOV NOV @&t@
606 DEC DEC DEC DEC DEC DEC DEC DEC @&t@
608 JAN JAN JAN JAN JAN JAN JAN JAN @&t@
609 JAN JAN JAN JAN JAN JAN JAN JAN @&t@
610 FEB FEB FEB FEB FEB FEB FEB FEB @&t@
611 FEB FEB FEB FEB FEB FEB FEB FEB @&t@
612 MAR MAR MAR MAR MAR MAR MAR MAR @&t@
613 MAR MAR MAR MAR MAR MAR MAR MAR @&t@
614 APR APR APR APR APR APR APR APR @&t@
615 MAY MAY MAY MAY MAY MAY MAY MAY @&t@
616 JUN JUN JUN JUN JUN JUN JUN JUN @&t@
617 JUL JUL JUL JUL JUL JUL JUL JUL @&t@
618 AUG AUG AUG AUG AUG AUG AUG AUG @&t@
619 SEP SEP SEP SEP SEP SEP SEP SEP @&t@
620 OCT OCT OCT OCT OCT OCT OCT OCT @&t@
621 NOV NOV NOV NOV NOV NOV NOV NOV @&t@
622 DEC DEC DEC DEC DEC DEC DEC DEC @&t@
623 DEC DEC DEC DEC DEC DEC DEC DEC @&t@