Line 0
Link Here
|
|
|
1 |
/* Beginning of modification history */ |
2 |
/* Written 09-07-27 by Paul Green. */ |
3 |
/* End of modification history */ |
4 |
|
5 |
#define _XOPEN_SOURCE 600 |
6 |
#pragma longmap_check, no_default_mapping, system_programming; |
7 |
|
8 |
#include <stdio.h> |
9 |
#include <stddef.h> |
10 |
#include <string.h> |
11 |
#include <sys/types.h> |
12 |
#include "time.h" |
13 |
|
14 |
static int failures = 0; |
15 |
|
16 |
static void explain (char *title, char *fmt, char *src) |
17 |
{ |
18 |
printf ("Testing: %s\n", title); |
19 |
printf ("Format: %s\n", fmt); |
20 |
printf ("Source: %s\n", src); |
21 |
} |
22 |
|
23 |
static void try1 (char *title, char *fmt, char *src, off_t off, int answer) |
24 |
{ |
25 |
struct tm r; |
26 |
int value; |
27 |
|
28 |
explain (title, fmt, src); |
29 |
memset (&r, 0, sizeof (r)); |
30 |
strptime (src, fmt, &r); |
31 |
|
32 |
value = * (int *) ((char *)&r + off); |
33 |
|
34 |
if (value == answer) |
35 |
printf ("Result: %d (ok)\n", answer); |
36 |
else |
37 |
{ |
38 |
printf ("Result: %d instead of %d (bad)\n", value, answer); |
39 |
failures++; |
40 |
} |
41 |
printf ("\n"); |
42 |
} |
43 |
|
44 |
/* Special test for the %c format string. Try to convert |
45 |
"Mon Mday HH:MM:SS YYYY". */ |
46 |
|
47 |
static void try2 (char *title, char *fmt, char *src) |
48 |
{ |
49 |
struct tm r; |
50 |
|
51 |
explain (title, fmt, src); |
52 |
memset (&r, 0, sizeof (r)); |
53 |
strptime (src, fmt, &r); |
54 |
|
55 |
if (r.tm_mon == 11 && |
56 |
r.tm_mday == 31 && |
57 |
r.tm_year == 109 && |
58 |
r.tm_hour == 23 && |
59 |
r.tm_min == 59 && |
60 |
r.tm_sec == 59) |
61 |
printf ("Result: December 31 23:59:59 2009 (ok)\n"); |
62 |
else |
63 |
{ |
64 |
failures++; |
65 |
printf ("Result: failed. %d/%d/%d %02d:%02d:%02d %2d %2d\n", |
66 |
r.tm_mon+1, r.tm_mday, r.tm_year+1900, r.tm_hour, |
67 |
r.tm_min, r.tm_sec, r.tm_wday, r.tm_yday); |
68 |
} |
69 |
printf ("\n"); |
70 |
} |
71 |
|
72 |
/* Special test for the %D format string. Try to convert |
73 |
"MM/DD/YY". */ |
74 |
|
75 |
static void try3 (char *title, char *fmt, char *src) |
76 |
{ |
77 |
struct tm r; |
78 |
|
79 |
explain (title, fmt, src); |
80 |
memset (&r, 0, sizeof (r)); |
81 |
strptime (src, fmt, &r); |
82 |
|
83 |
if (r.tm_mon == 11 && |
84 |
r.tm_mday == 31 && |
85 |
r.tm_year == 109) |
86 |
printf ("Result: 12/31/2009 (ok)\n"); |
87 |
else |
88 |
{ |
89 |
failures++; |
90 |
printf ("Result: failed. %02d/%02d/%4d\n", |
91 |
r.tm_mon+1, r.tm_mday, r.tm_year+1900); |
92 |
} |
93 |
printf ("\n"); |
94 |
} |
95 |
|
96 |
/* Special test for the %r format string. Try to convert |
97 |
"HH:MM:SS XM". */ |
98 |
|
99 |
static void try4 (char *title, char *fmt, char *src) |
100 |
{ |
101 |
struct tm r; |
102 |
|
103 |
explain (title, fmt, src); |
104 |
memset (&r, 0, sizeof (r)); |
105 |
strptime (src, fmt, &r); |
106 |
|
107 |
if (r.tm_hour == 23 && |
108 |
r.tm_min == 59 && |
109 |
r.tm_sec == 59) |
110 |
printf ("Result: 11:59:59 pm (ok)\n"); |
111 |
else |
112 |
{ |
113 |
failures++; |
114 |
printf ("Result: failed. %02d:%02d:%02d\n", |
115 |
r.tm_hour, r.tm_min, r.tm_sec); |
116 |
} |
117 |
printf ("\n"); |
118 |
} |
119 |
|
120 |
/* Special test for the %R format string. Try to convert |
121 |
"HH:MM". */ |
122 |
|
123 |
static void try5 (char *title, char *fmt, char *src) |
124 |
{ |
125 |
struct tm r; |
126 |
|
127 |
explain (title, fmt, src); |
128 |
memset (&r, 0, sizeof (r)); |
129 |
strptime (src, fmt, &r); |
130 |
|
131 |
if (r.tm_hour == 23 && |
132 |
r.tm_min == 59) |
133 |
printf ("Result: 23:59 (ok)\n"); |
134 |
else |
135 |
{ |
136 |
failures++; |
137 |
printf ("Result: failed. %02d:%02d\n", |
138 |
r.tm_hour, r.tm_min); |
139 |
} |
140 |
printf ("\n"); |
141 |
} |
142 |
|
143 |
/* Special test for the %T format string. Try to convert |
144 |
"HH:MM:SS". */ |
145 |
|
146 |
static void try6 (char *title, char *fmt, char *src) |
147 |
{ |
148 |
struct tm r; |
149 |
|
150 |
explain (title, fmt, src); |
151 |
memset (&r, 0, sizeof (r)); |
152 |
strptime (src, fmt, &r); |
153 |
|
154 |
if (r.tm_hour == 23 && |
155 |
r.tm_min == 59 && |
156 |
r.tm_sec == 59) |
157 |
printf ("Result: 23:59:59 (ok)\n"); |
158 |
else |
159 |
{ |
160 |
failures++; |
161 |
printf ("Result: failed. %02d:%02d:%02d\n", |
162 |
r.tm_hour, r.tm_min, r.tm_sec); |
163 |
} |
164 |
printf ("\n"); |
165 |
} |
166 |
|
167 |
/* Special test for the %U format string. Try to convert |
168 |
"2009 21", which is 5/31/2009 */ |
169 |
|
170 |
static void try7 (char *title, char *fmt, char *src) |
171 |
{ |
172 |
struct tm r; |
173 |
|
174 |
explain (title, fmt, src); |
175 |
memset (&r, 0, sizeof (r)); |
176 |
strptime (src, fmt, &r); |
177 |
|
178 |
if (r.tm_mon == 4 && |
179 |
r.tm_mday == 31 && |
180 |
r.tm_year == 109 && |
181 |
r.tm_wday == 0 && |
182 |
r.tm_yday == 151) |
183 |
printf ("Result: Sunday May 31 2009, yday 151 [week 21] (ok)\n"); |
184 |
else |
185 |
{ |
186 |
failures++; |
187 |
printf ("Result: failed. %02d/%02d/%04d wday=%d yday=%d\n", |
188 |
r.tm_mon+1, r.tm_mday, r.tm_year+1900, r.tm_wday, r.tm_yday); |
189 |
printf ("Expected 05/31/2009 wday=0 yday=151\n"); |
190 |
} |
191 |
printf ("\n"); |
192 |
} |
193 |
|
194 |
/* Special test for the %W format string. Try to convert |
195 |
"2009 21", which is 6/1/2009 */ |
196 |
|
197 |
static void try8 (char *title, char *fmt, char *src) |
198 |
{ |
199 |
struct tm r; |
200 |
|
201 |
explain (title, fmt, src); |
202 |
memset (&r, 0, sizeof (r)); |
203 |
strptime (src, fmt, &r); |
204 |
|
205 |
if (r.tm_mon == 5 && |
206 |
r.tm_mday == 1 && |
207 |
r.tm_year == 109 && |
208 |
r.tm_wday == 1 && |
209 |
r.tm_yday == 152) |
210 |
printf ("Result: Monday June 1 2009, yday 152 [week 21] (ok)\n"); |
211 |
else |
212 |
{ |
213 |
failures++; |
214 |
printf ("Result: failed. %02d/%02d/%04d wday=%d yday=%d\n", |
215 |
r.tm_mon+1, r.tm_mday, r.tm_year+1900, r.tm_wday, r.tm_yday); |
216 |
printf ("Expected: 06/01/2009 wday=1 yday=152\n"); |
217 |
} |
218 |
printf ("\n"); |
219 |
} |
220 |
|
221 |
/* Special test for the %U format string. Try to convert |
222 |
a range of values. */ |
223 |
|
224 |
static void tryU (char *title, char *fmt, char *range) |
225 |
{ |
226 |
/* automatic */ |
227 |
|
228 |
int mon, mday, w, yday, year, yr; |
229 |
char *p; |
230 |
char src[32]; |
231 |
struct tm r; |
232 |
|
233 |
/* static */ |
234 |
|
235 |
/* The date in January of the first Sunday, for 1998-2004. */ |
236 |
static int first_sunday [7] = {4, 3, 2, 7, 6, 5, 4}; |
237 |
|
238 |
/* The month*100 + the date of Sunday, for 1998-2004. */ |
239 |
static int known_answer [7][54] = { |
240 |
{0,104,111,118,125,201,208,215,222,301,308,315,322,329,405,412,419,426,503,510,517,524,531,607,614,621,628,705,712,719,726,802,809,816,823,830,906,913,920,927,1004,1011,1018,1025,1101,1108,1115,1122,1129,1206,1213,1220,1227,103}, /* 1998 */ |
241 |
{0,103,110,117,124,131,207,214,221,228,307,314,321,328,404,411,418,425,502,509,516,523,530,606,613,620,627,704,711,718,725,801,808,815,822,829,905,912,919,926,1003,1010,1017,1024,1031,1107,1114,1121,1128,1205,1212,1219,1226,102}, /* 1999 */ |
242 |
{0,102,109,116,123,130,206,213,220,227,305,312,319,326,402,409,416,423,430,507,514,521,528,604,611,618,625,702,709,716,723,730,806,813,820,827,903,910,917,924,1001,1008,1015,1022,1029,1105,1112,1119,1126,1203,1210,1217,1224,1231}, /* 2000 */ |
243 |
{0,107,114,121,128,204,211,218,225,304,311,318,325,401,408,415,422,429,506,513,520,527,603,610,617,624,701,708,715,722,729,805,812,819,826,902,909,916,923,930,1007,1014,1021,1028,1104,1111,1118,1125,1202,1209,1216,1223,1230,106}, /* 2001 */ |
244 |
{0,106,113,120,127,203,210,217,224,303,310,317,324,331,407,414,421,428,505,512,519,526,602,609,616,623,630,707,714,721,728,804,811,818,825,901,908,915,922,929,1006,1013,1020,1027,1103,1110,1117,1124,1201,1208,1215,1222,1229,105}, /* 2002 */ |
245 |
{0,105,112,119,126,202,209,216,223,302,309,316,323,330,406,413,420,427,504,511,518,525,601,608,615,622,629,706,713,720,727,803,810,817,824,831,907,914,921,928,1005,1012,1019,1026,1102,1109,1116,1123,1130,1207,1214,1221,1228,104}, /* 2003 */ |
246 |
{0,104,111,118,125,201,208,215,222,229,307,314,321,328,404,411,418,425,502,509,516,523,530,606,613,620,627,704,711,718,725,801,808,815,822,829,905,912,919,926,1003,1010,1017,1024,1031,1107,1114,1121,1128,1205,1212,1219,1226,102}}; /* 2004 */ |
247 |
|
248 |
/* execution */ |
249 |
|
250 |
explain (title, fmt, range); |
251 |
memset (&r, 0, sizeof (r)); |
252 |
|
253 |
for (year=1998; year<2005; year++) |
254 |
{ |
255 |
mday = first_sunday[year-1998]; |
256 |
yday = mday; |
257 |
printf ("The first Sunday of %4d is Jan %d.\n", year, mday); |
258 |
|
259 |
for (w=1; w<54; w++) |
260 |
{ |
261 |
sprintf (src, "%4d %d", year, w); |
262 |
p = strptime (src, fmt, &r); |
263 |
mon = (known_answer[year-1998][w] / 100) - 1; |
264 |
mday = (known_answer[year-1998][w] % 100); |
265 |
|
266 |
if (w == 53 && mon == 0) |
267 |
{ |
268 |
yr = year + 1; |
269 |
yday = mday; |
270 |
} |
271 |
else yr = year; |
272 |
|
273 |
if (p == NULL || |
274 |
r.tm_mon != mon || |
275 |
r.tm_mday != mday || |
276 |
r.tm_year != yr - 1900 || |
277 |
r.tm_wday != 0 || |
278 |
r.tm_yday != yday) |
279 |
{ |
280 |
failures++; |
281 |
printf ("%4d week %d failed.\n", year, w); |
282 |
printf (" got: %02d/%02d/%04d wday=%d yday=%d\n", |
283 |
r.tm_mon+1, r.tm_mday, r.tm_year+1900, r.tm_wday, r.tm_yday); |
284 |
printf (" expected: %02d/%02d/%04d wday=%d yday=%d\n", |
285 |
mon+1, mday, yr, 0, yday); |
286 |
printf ("\n"); |
287 |
} |
288 |
yday += 7; |
289 |
} |
290 |
} |
291 |
printf ("\n"); |
292 |
} |
293 |
|
294 |
/* Special test for the %W format string. */ |
295 |
|
296 |
int main (int argc, char **argv) |
297 |
{ |
298 |
struct tm t; |
299 |
|
300 |
t.tm_sec = 59; |
301 |
t.tm_min = 59; |
302 |
t.tm_hour = 23; |
303 |
t.tm_mday = 31; |
304 |
t.tm_mon = 12; |
305 |
t.tm_year = 2009; |
306 |
t.tm_wday = 6; |
307 |
t.tm_yday = 364; |
308 |
t.tm_isdst = 0; |
309 |
|
310 |
try1 ("Day of the week", "%a", "Sat", offsetof (struct tm, tm_wday), 6); |
311 |
try1 ("Day of the week", "%A", "Saturday", offsetof (struct tm, tm_wday), 6); |
312 |
try1 ("Month name", "%b", "Dec", offsetof (struct tm, tm_mon), 11); |
313 |
try1 ("Month name", "%B", "December", offsetof (struct tm, tm_mon), 11); |
314 |
try2 ("Date and time", "%c", "December 31 23:59:59 2009"); |
315 |
try1 ("Century", "%C", "2009", offsetof (struct tm, tm_year), 100); |
316 |
try1 ("Date of month", "%d", "31", offsetof (struct tm, tm_mday), 31); |
317 |
try3 ("MM/DD/YY", "%D", "12/31/09"); |
318 |
/* skip E codes */ |
319 |
/* skip O codes */ |
320 |
try1 ("Date of month", "%e", "31", offsetof (struct tm, tm_mday), 31); |
321 |
try1 ("Month name", "%h", "Dec", offsetof (struct tm, tm_mon), 11); |
322 |
try1 ("Hours, 24-hr", "%H", "23", offsetof (struct tm, tm_hour), 23); |
323 |
try1 ("Hours, 12-hr", "%I", "12", offsetof (struct tm, tm_hour), 12); |
324 |
try1 ("Day of year", "%j", "365", offsetof (struct tm, tm_yday), 364); |
325 |
try1 ("Month number", "%m", "12", offsetof (struct tm, tm_mon), 11); |
326 |
try1 ("Minute number", "%M", "59", offsetof (struct tm, tm_min), 59); |
327 |
try1 ("AM/PM 12-hr", "%I %p", "11 AM", offsetof (struct tm, tm_hour), 11); |
328 |
try1 ("AM/PM 12-hr", "%I %p", "11 PM", offsetof (struct tm, tm_hour), 23); |
329 |
try1 ("AM/PM 24-hr", "%H", "11", offsetof (struct tm, tm_hour), 11); |
330 |
try1 ("AM/PM 24-hr", "%H", "23", offsetof (struct tm, tm_hour), 23); |
331 |
try4 ("Time of day H:M:S XM", "%r", "11:59:59 pm"); |
332 |
try5 ("Time of day H:M", "%R", "23:59"); |
333 |
try1 ("Second number", "%S", "59", offsetof (struct tm, tm_sec), 59); |
334 |
try6 ("Time of day H:M:S", "%T", "23:59:59"); |
335 |
try7 ("Week number Sun=0", "%Y %U", "2009 22"); |
336 |
try1 ("Week day number", "%w", "4", offsetof (struct tm, tm_wday), 4); |
337 |
try8 ("Week number Mon=0", "%Y %W", "2009 22"); |
338 |
try1 ("Year in century", "%y", "9", offsetof (struct tm, tm_year), 109); |
339 |
try1 ("Year in century", "%Y", "2009", offsetof (struct tm, tm_year), 109); |
340 |
|
341 |
tryU ("U conversion", "%Y %U", "range"); |
342 |
|
343 |
if (failures) |
344 |
printf ("%d tests failed.\n", failures); |
345 |
else printf ("All tests passed.\n"); |
346 |
|
347 |
return failures; |
348 |
} |
349 |
|