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