|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 /* |
|
7 * file: timetest.c |
|
8 * description: test time and date routines |
|
9 */ |
|
10 /*********************************************************************** |
|
11 ** Includes |
|
12 ***********************************************************************/ |
|
13 /* Used to get the command line option */ |
|
14 #include "plgetopt.h" |
|
15 |
|
16 #include "prinit.h" |
|
17 #include "prtime.h" |
|
18 #include "prprf.h" |
|
19 |
|
20 #include <stdio.h> |
|
21 #include <stdlib.h> |
|
22 #include <string.h> |
|
23 |
|
24 int failed_already=0; |
|
25 PRBool debug_mode = PR_FALSE; |
|
26 |
|
27 static char *dayOfWeek[] = |
|
28 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; |
|
29 static char *month[] = |
|
30 { "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
|
31 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; |
|
32 |
|
33 static void PrintExplodedTime(const PRExplodedTime *et) { |
|
34 PRInt32 totalOffset; |
|
35 PRInt32 hourOffset, minOffset; |
|
36 const char *sign; |
|
37 |
|
38 /* Print day of the week, month, day, hour, minute, and second */ |
|
39 if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ", |
|
40 dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, |
|
41 et->tm_hour, et->tm_min, et->tm_sec); |
|
42 |
|
43 /* Print time zone */ |
|
44 totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; |
|
45 if (totalOffset == 0) { |
|
46 if (debug_mode) printf("UTC "); |
|
47 } else { |
|
48 sign = "+"; |
|
49 if (totalOffset < 0) { |
|
50 totalOffset = -totalOffset; |
|
51 sign = "-"; |
|
52 } |
|
53 hourOffset = totalOffset / 3600; |
|
54 minOffset = (totalOffset % 3600) / 60; |
|
55 if (debug_mode) |
|
56 printf("%s%02ld%02ld ", sign, hourOffset, minOffset); |
|
57 } |
|
58 |
|
59 /* Print year */ |
|
60 if (debug_mode) printf("%hd", et->tm_year); |
|
61 } |
|
62 |
|
63 static int ExplodedTimeIsEqual(const PRExplodedTime *et1, |
|
64 const PRExplodedTime *et2) |
|
65 { |
|
66 if (et1->tm_usec == et2->tm_usec && |
|
67 et1->tm_sec == et2->tm_sec && |
|
68 et1->tm_min == et2->tm_min && |
|
69 et1->tm_hour == et2->tm_hour && |
|
70 et1->tm_mday == et2->tm_mday && |
|
71 et1->tm_month == et2->tm_month && |
|
72 et1->tm_year == et2->tm_year && |
|
73 et1->tm_wday == et2->tm_wday && |
|
74 et1->tm_yday == et2->tm_yday && |
|
75 et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset && |
|
76 et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) { |
|
77 return 1; |
|
78 } else { |
|
79 return 0; |
|
80 } |
|
81 } |
|
82 |
|
83 static void |
|
84 testParseTimeString(PRTime t) |
|
85 { |
|
86 PRExplodedTime et; |
|
87 PRTime t2; |
|
88 char timeString[128]; |
|
89 char buf[128]; |
|
90 PRInt32 totalOffset; |
|
91 PRInt32 hourOffset, minOffset; |
|
92 const char *sign; |
|
93 PRInt64 usec_per_sec; |
|
94 |
|
95 /* Truncate the microsecond part of PRTime */ |
|
96 LL_I2L(usec_per_sec, PR_USEC_PER_SEC); |
|
97 LL_DIV(t, t, usec_per_sec); |
|
98 LL_MUL(t, t, usec_per_sec); |
|
99 |
|
100 PR_ExplodeTime(t, PR_LocalTimeParameters, &et); |
|
101 |
|
102 /* Print day of the week, month, day, hour, minute, and second */ |
|
103 PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ", |
|
104 dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday, |
|
105 et.tm_hour, et.tm_min, et.tm_sec); |
|
106 /* Print time zone */ |
|
107 totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset; |
|
108 if (totalOffset == 0) { |
|
109 strcat(timeString, "GMT "); /* I wanted to use "UTC" here, but |
|
110 * PR_ParseTimeString doesn't |
|
111 * understand "UTC". */ |
|
112 } else { |
|
113 sign = "+"; |
|
114 if (totalOffset < 0) { |
|
115 totalOffset = -totalOffset; |
|
116 sign = "-"; |
|
117 } |
|
118 hourOffset = totalOffset / 3600; |
|
119 minOffset = (totalOffset % 3600) / 60; |
|
120 PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset); |
|
121 strcat(timeString, buf); |
|
122 } |
|
123 /* Print year */ |
|
124 PR_snprintf(buf, 128, "%hd", et.tm_year); |
|
125 strcat(timeString, buf); |
|
126 |
|
127 if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) { |
|
128 fprintf(stderr, "PR_ParseTimeString() failed\n"); |
|
129 exit(1); |
|
130 } |
|
131 if (LL_NE(t, t2)) { |
|
132 fprintf(stderr, "PR_ParseTimeString() incorrect\n"); |
|
133 PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n", |
|
134 t, t2, timeString); |
|
135 fprintf(stderr, "%s\n", buf); |
|
136 exit(1); |
|
137 } |
|
138 } |
|
139 |
|
140 int main(int argc, char** argv) |
|
141 { |
|
142 /* The command line argument: -d is used to determine if the test is being run |
|
143 in debug mode. The regress tool requires only one line output:PASS or FAIL. |
|
144 All of the printfs associated with this test has been handled with a if (debug_mode) |
|
145 test. |
|
146 Usage: test_name -d |
|
147 */ |
|
148 PLOptStatus os; |
|
149 PLOptState *opt; |
|
150 |
|
151 PR_STDIO_INIT(); |
|
152 opt = PL_CreateOptState(argc, argv, "d"); |
|
153 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) |
|
154 { |
|
155 if (PL_OPT_BAD == os) continue; |
|
156 switch (opt->option) |
|
157 { |
|
158 case 'd': /* debug mode */ |
|
159 debug_mode = PR_TRUE; |
|
160 break; |
|
161 default: |
|
162 break; |
|
163 } |
|
164 } |
|
165 PL_DestroyOptState(opt); |
|
166 |
|
167 /* main test */ |
|
168 |
|
169 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); |
|
170 |
|
171 /* Testing zero PRTime (the epoch) */ |
|
172 { |
|
173 PRTime t; |
|
174 PRExplodedTime et; |
|
175 |
|
176 LL_I2L(t, 0); |
|
177 if (debug_mode) printf("The NSPR epoch is:\n"); |
|
178 PR_ExplodeTime(t, PR_LocalTimeParameters, &et); |
|
179 PrintExplodedTime(&et); |
|
180 if (debug_mode) printf("\n"); |
|
181 PR_ExplodeTime(t, PR_GMTParameters, &et); |
|
182 PrintExplodedTime(&et); |
|
183 if (debug_mode) printf("\n\n"); |
|
184 testParseTimeString(t); |
|
185 } |
|
186 |
|
187 /* |
|
188 ************************************************************* |
|
189 ** |
|
190 ** Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime |
|
191 ** on the current time |
|
192 ** |
|
193 ************************************************************* |
|
194 */ |
|
195 |
|
196 { |
|
197 PRTime t1, t2; |
|
198 PRExplodedTime et; |
|
199 |
|
200 if (debug_mode) { |
|
201 printf("*********************************************\n"); |
|
202 printf("** **\n"); |
|
203 printf("** Testing PR_Now(), PR_ExplodeTime, and **\n"); |
|
204 printf("** PR_ImplodeTime on the current time **\n"); |
|
205 printf("** **\n"); |
|
206 printf("*********************************************\n\n"); |
|
207 } |
|
208 t1 = PR_Now(); |
|
209 |
|
210 /* First try converting to UTC */ |
|
211 |
|
212 PR_ExplodeTime(t1, PR_GMTParameters, &et); |
|
213 if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) { |
|
214 if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n"); |
|
215 else failed_already=1; |
|
216 return 1; |
|
217 } |
|
218 if (debug_mode) printf("Current UTC is "); |
|
219 PrintExplodedTime(&et); |
|
220 if (debug_mode) printf("\n"); |
|
221 |
|
222 t2 = PR_ImplodeTime(&et); |
|
223 if (LL_NE(t1, t2)) { |
|
224 if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n"); |
|
225 else printf("FAIL\n"); |
|
226 return 1; |
|
227 } |
|
228 |
|
229 /* Next, try converting to local (US Pacific) time */ |
|
230 |
|
231 PR_ExplodeTime(t1, PR_LocalTimeParameters, &et); |
|
232 if (debug_mode) printf("Current local time is "); |
|
233 PrintExplodedTime(&et); |
|
234 if (debug_mode) printf("\n"); |
|
235 if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n", |
|
236 et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset); |
|
237 t2 = PR_ImplodeTime(&et); |
|
238 if (LL_NE(t1, t2)) { |
|
239 if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n"); |
|
240 return 1; |
|
241 } |
|
242 |
|
243 if (debug_mode) printf("Please examine the results\n"); |
|
244 testParseTimeString(t1); |
|
245 } |
|
246 |
|
247 |
|
248 /* |
|
249 ******************************************* |
|
250 ** |
|
251 ** Testing PR_NormalizeTime() |
|
252 ** |
|
253 ******************************************* |
|
254 */ |
|
255 |
|
256 /* July 4, 2001 is Wednesday */ |
|
257 { |
|
258 PRExplodedTime et; |
|
259 |
|
260 if (debug_mode) { |
|
261 printf("\n"); |
|
262 printf("**********************************\n"); |
|
263 printf("** **\n"); |
|
264 printf("** Testing PR_NormalizeTime() **\n"); |
|
265 printf("** **\n"); |
|
266 printf("**********************************\n\n"); |
|
267 } |
|
268 et.tm_year = 2001; |
|
269 et.tm_month = 7 - 1; |
|
270 et.tm_mday = 4; |
|
271 et.tm_hour = 0; |
|
272 et.tm_min = 0; |
|
273 et.tm_sec = 0; |
|
274 et.tm_usec = 0; |
|
275 et.tm_params = PR_GMTParameters(&et); |
|
276 |
|
277 PR_NormalizeTime(&et, PR_GMTParameters); |
|
278 |
|
279 if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]); |
|
280 if (et.tm_wday == 3) { |
|
281 if (debug_mode) printf("PASS\n"); |
|
282 } else { |
|
283 if (debug_mode) printf("ERROR: It should be Wednesday\n"); |
|
284 else failed_already=1; |
|
285 return 1; |
|
286 } |
|
287 testParseTimeString(PR_ImplodeTime(&et)); |
|
288 |
|
289 /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */ |
|
290 et.tm_year = 1997; |
|
291 et.tm_month = 6 - 1; |
|
292 et.tm_mday = 12; |
|
293 et.tm_hour = 23; |
|
294 et.tm_min = 0; |
|
295 et.tm_sec = 0; |
|
296 et.tm_usec = 0; |
|
297 et.tm_params.tp_gmt_offset = -8 * 3600; |
|
298 et.tm_params.tp_dst_offset = 0; |
|
299 |
|
300 PR_NormalizeTime(&et, PR_USPacificTimeParameters); |
|
301 |
|
302 if (debug_mode) { |
|
303 printf("Thu Jun 12, 1997 23:00:00 PST is "); |
|
304 } |
|
305 PrintExplodedTime(&et); |
|
306 if (debug_mode) printf(".\n"); |
|
307 if (et.tm_wday == 5) { |
|
308 if (debug_mode) printf("PASS\n"); |
|
309 } else { |
|
310 if (debug_mode) printf("ERROR: It should be Friday\n"); |
|
311 else failed_already=1; |
|
312 return 1; |
|
313 } |
|
314 testParseTimeString(PR_ImplodeTime(&et)); |
|
315 |
|
316 /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */ |
|
317 et.tm_year = 1997; |
|
318 et.tm_month = 2 - 1; |
|
319 et.tm_mday = 14; |
|
320 et.tm_hour = 0; |
|
321 et.tm_min = 0; |
|
322 et.tm_sec = 0; |
|
323 et.tm_usec = 0; |
|
324 et.tm_params.tp_gmt_offset = -8 * 3600; |
|
325 et.tm_params.tp_dst_offset = 3600; |
|
326 |
|
327 PR_NormalizeTime(&et, PR_USPacificTimeParameters); |
|
328 |
|
329 if (debug_mode) { |
|
330 printf("Fri Feb 14, 1997 00:00:00 PDT is "); |
|
331 } |
|
332 PrintExplodedTime(&et); |
|
333 if (debug_mode) printf(".\n"); |
|
334 if (et.tm_wday == 4) { |
|
335 if (debug_mode) printf("PASS\n"); |
|
336 } else { |
|
337 if (debug_mode) printf("ERROR: It should be Thursday\n"); |
|
338 else failed_already=1; |
|
339 return 1; |
|
340 } |
|
341 testParseTimeString(PR_ImplodeTime(&et)); |
|
342 |
|
343 /* What time is Nov. 7, 1996, 18:29:23 PDT? */ |
|
344 et.tm_year = 1996; |
|
345 et.tm_month = 11 - 1; |
|
346 et.tm_mday = 7; |
|
347 et.tm_hour = 18; |
|
348 et.tm_min = 29; |
|
349 et.tm_sec = 23; |
|
350 et.tm_usec = 0; |
|
351 et.tm_params.tp_gmt_offset = -8 * 3600; /* PDT */ |
|
352 et.tm_params.tp_dst_offset = 3600; |
|
353 |
|
354 PR_NormalizeTime(&et, PR_LocalTimeParameters); |
|
355 if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is "); |
|
356 PrintExplodedTime(&et); |
|
357 if (debug_mode) printf(".\n"); |
|
358 testParseTimeString(PR_ImplodeTime(&et)); |
|
359 |
|
360 /* What time is Oct. 7, 1995, 18:29:23 PST? */ |
|
361 et.tm_year = 1995; |
|
362 et.tm_month = 10 - 1; |
|
363 et.tm_mday = 7; |
|
364 et.tm_hour = 18; |
|
365 et.tm_min = 29; |
|
366 et.tm_sec = 23; |
|
367 et.tm_params.tp_gmt_offset = -8 * 3600; /* PST */ |
|
368 et.tm_params.tp_dst_offset = 0; |
|
369 |
|
370 PR_NormalizeTime(&et, PR_LocalTimeParameters); |
|
371 if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is "); |
|
372 PrintExplodedTime(&et); |
|
373 if (debug_mode) printf(".\n"); |
|
374 testParseTimeString(PR_ImplodeTime(&et)); |
|
375 |
|
376 if (debug_mode) printf("Please examine the results\n"); |
|
377 } |
|
378 |
|
379 /* |
|
380 ************************************************************** |
|
381 ** |
|
382 ** Testing range of years |
|
383 ** |
|
384 ************************************************************** |
|
385 */ |
|
386 |
|
387 { |
|
388 PRExplodedTime et1, et2; |
|
389 PRTime ttt; |
|
390 PRTime secs; |
|
391 |
|
392 if (debug_mode) { |
|
393 printf("\n"); |
|
394 printf("***************************************\n"); |
|
395 printf("** **\n"); |
|
396 printf("** Testing range of years **\n"); |
|
397 printf("** **\n"); |
|
398 printf("***************************************\n\n"); |
|
399 } |
|
400 /* April 4, 1917 GMT */ |
|
401 et1.tm_usec = 0; |
|
402 et1.tm_sec = 0; |
|
403 et1.tm_min = 0; |
|
404 et1.tm_hour = 0; |
|
405 et1.tm_mday = 4; |
|
406 et1.tm_month = 4 - 1; |
|
407 et1.tm_year = 1917; |
|
408 et1.tm_params = PR_GMTParameters(&et1); |
|
409 PR_NormalizeTime(&et1, PR_LocalTimeParameters); |
|
410 secs = PR_ImplodeTime(&et1); |
|
411 if (LL_GE_ZERO(secs)) { |
|
412 if (debug_mode) |
|
413 printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n"); |
|
414 failed_already = 1; |
|
415 return 1; |
|
416 } |
|
417 PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2); |
|
418 if (!ExplodedTimeIsEqual(&et1, &et2)) { |
|
419 if (debug_mode) |
|
420 printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n"); |
|
421 failed_already=1; |
|
422 return 1; |
|
423 } |
|
424 ttt = PR_ImplodeTime(&et1); |
|
425 testParseTimeString( ttt ); |
|
426 |
|
427 if (debug_mode) printf("Test passed for April 4, 1917\n"); |
|
428 |
|
429 /* July 4, 2050 */ |
|
430 et1.tm_usec = 0; |
|
431 et1.tm_sec = 0; |
|
432 et1.tm_min = 0; |
|
433 et1.tm_hour = 0; |
|
434 et1.tm_mday = 4; |
|
435 et1.tm_month = 7 - 1; |
|
436 et1.tm_year = 2050; |
|
437 et1.tm_params = PR_GMTParameters(&et1); |
|
438 PR_NormalizeTime(&et1, PR_LocalTimeParameters); |
|
439 secs = PR_ImplodeTime(&et1); |
|
440 if (!LL_GE_ZERO(secs)) { |
|
441 if (debug_mode) |
|
442 printf("ERROR: July 4, 2050 GMT returns a negative second count\n"); |
|
443 failed_already = 1; |
|
444 return 1; |
|
445 } |
|
446 PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2); |
|
447 if (!ExplodedTimeIsEqual(&et1, &et2)) { |
|
448 if (debug_mode) |
|
449 printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n"); |
|
450 failed_already=1; |
|
451 return 1; |
|
452 } |
|
453 testParseTimeString(PR_ImplodeTime(&et1)); |
|
454 |
|
455 if (debug_mode) printf("Test passed for July 4, 2050\n"); |
|
456 |
|
457 } |
|
458 |
|
459 /* |
|
460 ************************************************************** |
|
461 ** |
|
462 ** Stress test |
|
463 * |
|
464 ** Go through four years, starting from |
|
465 ** 00:00:00 PST Jan. 1, 2005, incrementing |
|
466 ** every 10 minutes. |
|
467 ** |
|
468 ************************************************************** |
|
469 */ |
|
470 |
|
471 { |
|
472 PRExplodedTime et, et1, et2; |
|
473 PRInt64 usecPer10Min; |
|
474 int day, hour, min; |
|
475 PRTime usecs; |
|
476 int dstInEffect = 0; |
|
477 |
|
478 if (debug_mode) { |
|
479 printf("\n"); |
|
480 printf("*******************************************************\n"); |
|
481 printf("** **\n"); |
|
482 printf("** Stress test Pacific Time **\n"); |
|
483 printf("** Starting from midnight Jan. 1, 2005 PST, **\n"); |
|
484 printf("** going through four years in 10-minute increment **\n"); |
|
485 printf("** **\n"); |
|
486 printf("*******************************************************\n\n"); |
|
487 } |
|
488 LL_I2L(usecPer10Min, 600000000L); |
|
489 |
|
490 /* 00:00:00 PST Jan. 1, 2005 */ |
|
491 et.tm_usec = 0; |
|
492 et.tm_sec = 0; |
|
493 et.tm_min = 0; |
|
494 et.tm_hour = 0; |
|
495 et.tm_mday = 1; |
|
496 et.tm_month = 0; |
|
497 et.tm_year = 2005; |
|
498 et.tm_params.tp_gmt_offset = -8 * 3600; |
|
499 et.tm_params.tp_dst_offset = 0; |
|
500 usecs = PR_ImplodeTime(&et); |
|
501 |
|
502 for (day = 0; day < 4 * 365 + 1; day++) { |
|
503 for (hour = 0; hour < 24; hour++) { |
|
504 for (min = 0; min < 60; min += 10) { |
|
505 LL_ADD(usecs, usecs, usecPer10Min); |
|
506 PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1); |
|
507 |
|
508 et2 = et; |
|
509 et2.tm_usec += 600000000L; |
|
510 PR_NormalizeTime(&et2, PR_USPacificTimeParameters); |
|
511 |
|
512 if (!ExplodedTimeIsEqual(&et1, &et2)) { |
|
513 printf("ERROR: componentwise comparison failed\n"); |
|
514 PrintExplodedTime(&et1); |
|
515 printf("\n"); |
|
516 PrintExplodedTime(&et2); |
|
517 printf("\n"); |
|
518 failed_already=1; |
|
519 return 1; |
|
520 } |
|
521 |
|
522 if (LL_NE(usecs, PR_ImplodeTime(&et1))) { |
|
523 printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); |
|
524 PrintExplodedTime(&et1); |
|
525 printf("\n"); |
|
526 failed_already=1; |
|
527 return 1; |
|
528 } |
|
529 testParseTimeString(usecs); |
|
530 |
|
531 if (!dstInEffect && et1.tm_params.tp_dst_offset) { |
|
532 dstInEffect = 1; |
|
533 if (debug_mode) { |
|
534 printf("DST changeover from "); |
|
535 PrintExplodedTime(&et); |
|
536 printf(" to "); |
|
537 PrintExplodedTime(&et1); |
|
538 printf(".\n"); |
|
539 } |
|
540 } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { |
|
541 dstInEffect = 0; |
|
542 if (debug_mode) { |
|
543 printf("DST changeover from "); |
|
544 PrintExplodedTime(&et); |
|
545 printf(" to "); |
|
546 PrintExplodedTime(&et1); |
|
547 printf(".\n"); |
|
548 } |
|
549 } |
|
550 |
|
551 et = et1; |
|
552 } |
|
553 } |
|
554 } |
|
555 if (debug_mode) printf("Test passed\n"); |
|
556 } |
|
557 |
|
558 |
|
559 /* Same stress test, but with PR_LocalTimeParameters */ |
|
560 |
|
561 { |
|
562 PRExplodedTime et, et1, et2; |
|
563 PRInt64 usecPer10Min; |
|
564 int day, hour, min; |
|
565 PRTime usecs; |
|
566 int dstInEffect = 0; |
|
567 |
|
568 if (debug_mode) { |
|
569 printf("\n"); |
|
570 printf("*******************************************************\n"); |
|
571 printf("** **\n"); |
|
572 printf("** Stress test Local Time **\n"); |
|
573 printf("** Starting from midnight Jan. 1, 2005 PST, **\n"); |
|
574 printf("** going through four years in 10-minute increment **\n"); |
|
575 printf("** **\n"); |
|
576 printf("*******************************************************\n\n"); |
|
577 } |
|
578 |
|
579 LL_I2L(usecPer10Min, 600000000L); |
|
580 |
|
581 /* 00:00:00 PST Jan. 1, 2005 */ |
|
582 et.tm_usec = 0; |
|
583 et.tm_sec = 0; |
|
584 et.tm_min = 0; |
|
585 et.tm_hour = 0; |
|
586 et.tm_mday = 1; |
|
587 et.tm_month = 0; |
|
588 et.tm_year = 2005; |
|
589 et.tm_params.tp_gmt_offset = -8 * 3600; |
|
590 et.tm_params.tp_dst_offset = 0; |
|
591 usecs = PR_ImplodeTime(&et); |
|
592 |
|
593 for (day = 0; day < 4 * 365 + 1; day++) { |
|
594 for (hour = 0; hour < 24; hour++) { |
|
595 for (min = 0; min < 60; min += 10) { |
|
596 LL_ADD(usecs, usecs, usecPer10Min); |
|
597 PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1); |
|
598 |
|
599 et2 = et; |
|
600 et2.tm_usec += 600000000L; |
|
601 PR_NormalizeTime(&et2, PR_LocalTimeParameters); |
|
602 |
|
603 if (!ExplodedTimeIsEqual(&et1, &et2)) { |
|
604 printf("ERROR: componentwise comparison failed\n"); |
|
605 PrintExplodedTime(&et1); |
|
606 printf("\n"); |
|
607 PrintExplodedTime(&et2); |
|
608 printf("\n"); |
|
609 return 1; |
|
610 } |
|
611 |
|
612 if (LL_NE(usecs, PR_ImplodeTime(&et1))) { |
|
613 printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); |
|
614 PrintExplodedTime(&et1); |
|
615 printf("\n"); |
|
616 failed_already=1; |
|
617 return 1; |
|
618 } |
|
619 testParseTimeString(usecs); |
|
620 |
|
621 if (!dstInEffect && et1.tm_params.tp_dst_offset) { |
|
622 dstInEffect = 1; |
|
623 if (debug_mode) { |
|
624 printf("DST changeover from "); |
|
625 PrintExplodedTime(&et); |
|
626 printf(" to "); |
|
627 PrintExplodedTime(&et1); |
|
628 printf(".\n"); |
|
629 } |
|
630 } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { |
|
631 dstInEffect = 0; |
|
632 if (debug_mode) { |
|
633 printf("DST changeover from "); |
|
634 PrintExplodedTime(&et); |
|
635 printf(" to "); |
|
636 PrintExplodedTime(&et1); |
|
637 printf(".\n"); |
|
638 } |
|
639 } |
|
640 |
|
641 et = et1; |
|
642 } |
|
643 } |
|
644 } |
|
645 if (debug_mode) printf("Test passed\n"); |
|
646 } |
|
647 |
|
648 /* Same stress test, but with PR_LocalTimeParameters and going backward */ |
|
649 |
|
650 { |
|
651 PRExplodedTime et, et1, et2; |
|
652 PRInt64 usecPer10Min; |
|
653 int day, hour, min; |
|
654 PRTime usecs; |
|
655 int dstInEffect = 0; |
|
656 |
|
657 if (debug_mode) { |
|
658 printf("\n"); |
|
659 printf("*******************************************************\n"); |
|
660 printf("** **\n"); |
|
661 printf("** Stress test Local Time **\n"); |
|
662 printf("** Starting from midnight Jan. 1, 2009 PST, **\n"); |
|
663 printf("** going back four years in 10-minute increment **\n"); |
|
664 printf("** **\n"); |
|
665 printf("*******************************************************\n\n"); |
|
666 } |
|
667 |
|
668 LL_I2L(usecPer10Min, 600000000L); |
|
669 |
|
670 /* 00:00:00 PST Jan. 1, 2009 */ |
|
671 et.tm_usec = 0; |
|
672 et.tm_sec = 0; |
|
673 et.tm_min = 0; |
|
674 et.tm_hour = 0; |
|
675 et.tm_mday = 1; |
|
676 et.tm_month = 0; |
|
677 et.tm_year = 2009; |
|
678 et.tm_params.tp_gmt_offset = -8 * 3600; |
|
679 et.tm_params.tp_dst_offset = 0; |
|
680 usecs = PR_ImplodeTime(&et); |
|
681 |
|
682 for (day = 0; day < 4 * 365 + 1; day++) { |
|
683 for (hour = 0; hour < 24; hour++) { |
|
684 for (min = 0; min < 60; min += 10) { |
|
685 LL_SUB(usecs, usecs, usecPer10Min); |
|
686 PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1); |
|
687 |
|
688 et2 = et; |
|
689 et2.tm_usec -= 600000000L; |
|
690 PR_NormalizeTime(&et2, PR_LocalTimeParameters); |
|
691 |
|
692 if (!ExplodedTimeIsEqual(&et1, &et2)) { |
|
693 printf("ERROR: componentwise comparison failed\n"); |
|
694 PrintExplodedTime(&et1); |
|
695 printf("\n"); |
|
696 PrintExplodedTime(&et2); |
|
697 printf("\n"); |
|
698 return 1; |
|
699 } |
|
700 |
|
701 if (LL_NE(usecs, PR_ImplodeTime(&et1))) { |
|
702 printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); |
|
703 PrintExplodedTime(&et1); |
|
704 printf("\n"); |
|
705 failed_already=1; |
|
706 return 1; |
|
707 } |
|
708 testParseTimeString(usecs); |
|
709 |
|
710 if (!dstInEffect && et1.tm_params.tp_dst_offset) { |
|
711 dstInEffect = 1; |
|
712 if (debug_mode) { |
|
713 printf("DST changeover from "); |
|
714 PrintExplodedTime(&et); |
|
715 printf(" to "); |
|
716 PrintExplodedTime(&et1); |
|
717 printf(".\n"); |
|
718 } |
|
719 } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { |
|
720 dstInEffect = 0; |
|
721 if (debug_mode) { |
|
722 printf("DST changeover from "); |
|
723 PrintExplodedTime(&et); |
|
724 printf(" to "); |
|
725 PrintExplodedTime(&et1); |
|
726 printf(".\n"); |
|
727 } |
|
728 } |
|
729 |
|
730 et = et1; |
|
731 } |
|
732 } |
|
733 } |
|
734 } |
|
735 |
|
736 if (failed_already) return 1; |
|
737 else return 0; |
|
738 |
|
739 } |