timetest.c 26 KB

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