y2k.c (33951B)
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: y2k.c 8 * description: Test for y2k compliance for NSPR. 9 * 10 * Sep 1999. lth. Added "Sun" specified dates to the test data. 11 */ 12 /*********************************************************************** 13 ** Includes 14 ***********************************************************************/ 15 /* Used to get the command line option */ 16 #include "plgetopt.h" 17 18 #include "prinit.h" 19 #include "prtime.h" 20 #include "prprf.h" 21 #include "prlog.h" 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 27 #define PRINT_DETAILS 28 29 int failed_already = 0; 30 PRBool debug_mode = PR_FALSE; 31 32 static char* dayOfWeek[] = {"Sun", "Mon", "Tue", "Wed", 33 "Thu", "Fri", "Sat", "???"}; 34 static char* month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", 35 "Aug", "Sep", "Oct", "Nov", "Dec", "???"}; 36 37 PRLogModuleInfo* lm; 38 39 static void PrintExplodedTime(const PRExplodedTime* et) { 40 PRInt32 totalOffset; 41 PRInt32 hourOffset, minOffset; 42 const char* sign; 43 44 /* Print day of the week, month, day, hour, minute, and second */ 45 printf("%s %s %2ld %02ld:%02ld:%02ld ", dayOfWeek[et->tm_wday], 46 month[et->tm_month], et->tm_mday, et->tm_hour, et->tm_min, et->tm_sec); 47 48 /* Print year */ 49 printf("%hd ", et->tm_year); 50 51 /* Print time zone */ 52 totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; 53 if (totalOffset == 0) { 54 printf("UTC "); 55 } else { 56 sign = "+"; 57 if (totalOffset < 0) { 58 totalOffset = -totalOffset; 59 sign = "-"; 60 } 61 hourOffset = totalOffset / 3600; 62 minOffset = (totalOffset % 3600) / 60; 63 printf("%s%02ld%02ld ", sign, hourOffset, minOffset); 64 } 65 #ifdef PRINT_DETAILS 66 printf("{%d, %d, %d, %d, %d, %d, %d, %d, %d, { %d, %d}}\n", et->tm_usec, 67 et->tm_sec, et->tm_min, et->tm_hour, et->tm_mday, et->tm_month, 68 et->tm_year, et->tm_wday, et->tm_yday, et->tm_params.tp_gmt_offset, 69 et->tm_params.tp_dst_offset); 70 #endif 71 } 72 73 static int ExplodedTimeIsEqual(const PRExplodedTime* et1, 74 const PRExplodedTime* et2) { 75 if (et1->tm_usec == et2->tm_usec && et1->tm_sec == et2->tm_sec && 76 et1->tm_min == et2->tm_min && et1->tm_hour == et2->tm_hour && 77 et1->tm_mday == et2->tm_mday && et1->tm_month == et2->tm_month && 78 et1->tm_year == et2->tm_year && et1->tm_wday == et2->tm_wday && 79 et1->tm_yday == et2->tm_yday && 80 et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset && 81 et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) { 82 return 1; 83 } else { 84 return 0; 85 } 86 } 87 88 /* 89 * TEST 1: TestExplodeImplodeTime 90 * Description: 91 * For each given timestamp T (a PRTime value), call PR_ExplodeTime 92 * with GMT, US Pacific, and local time parameters. Compare the 93 * resulting calendar (exploded) time values with the expected 94 * values. 95 * 96 * Note: the expected local time values depend on the local time 97 * zone. The local time values stored in this test are for the US 98 * Pacific Time Zone. If you are running this test in a different 99 * time zone, you need to modify the values in the localt array. 100 * An example is provided below. 101 * 102 * Call PR_ImplodeTime for each of the exploded values and compare 103 * the resulting PRTime values with the original input. 104 * 105 * This test is run for the values of time T corresponding to the 106 * following dates: 107 * - 12/31/99 - before 2000 108 * - 01/01/00 - after 2000 109 * - Leap year - Feb 29, 2000 110 * - March 1st, 2001 (after 1 year) 111 * - March 1st, 2005 (after second leap year) 112 * - 09/09/99 (used by some programs as an end of file marker) 113 * 114 * Call PR_Now, convert to calendar time using PR_ExplodeTime and 115 * manually check the result for correctness. The time should match 116 * the system clock. 117 * 118 * Tested functions: PR_Now, PR_ExplodeTime, PR_ImplodeTime, 119 * PR_LocalTimeParameters, PR_GMTParameters. 120 */ 121 122 static PRTime prt[] = { 123 LL_INIT(220405, 2133125120), /* 946634400000000 */ 124 LL_INIT(220425, 2633779200), /* 946720800000000 */ 125 LL_INIT(221612, 2107598848), /* 951818400000000 */ 126 LL_INIT(228975, 663398400), /* 983440800000000 */ 127 LL_INIT(258365, 1974568960), /* 1109671200000000 */ 128 LL_INIT(218132, 1393788928), /* 936871200000000 */ 129 /* Sun's dates follow */ 130 LL_INIT(213062, 4077979648), /* Dec 31 1998 10:00:00 */ 131 LL_INIT(218152, 1894443008), /* Sep 10 1999 10:00:00 */ 132 LL_INIT(221592, 1606944768), /* Feb 28 2000 10:00:00 */ 133 LL_INIT(227768, 688924672), /* Dec 31 2000 10:00:00 */ 134 LL_INIT(227788, 1189578752), /* Jan 1 2001 10:00:00 */ 135 }; 136 137 static PRExplodedTime gmt[] = { 138 {0, 0, 0, 10, 31, 11, 1999, 5, 364, {0, 0}}, /* 1999/12/31 10:00:00 GMT */ 139 {0, 0, 0, 10, 1, 0, 2000, 6, 0, {0, 0}}, /* 2000/01/01 10:00:00 GMT */ 140 {0, 0, 0, 10, 29, 1, 2000, 2, 59, {0, 0}}, /* 2000/02/29 10:00:00 GMT */ 141 {0, 0, 0, 10, 1, 2, 2001, 4, 59, {0, 0}}, /* 2001/3/1 10:00:00 GMT */ 142 {0, 0, 0, 10, 1, 2, 2005, 2, 59, {0, 0}}, /* 2005/3/1 10:00:00 GMT */ 143 {0, 0, 0, 10, 9, 8, 1999, 4, 251, {0, 0}}, /* 1999/9/9 10:00:00 GMT */ 144 /* Sun's dates follow */ 145 {0, 0, 0, 10, 31, 11, 1998, 4, 364, {0, 0}}, /* 12/31/1998 10:00:00 GMT */ 146 {0, 0, 0, 10, 10, 8, 1999, 5, 252, {0, 0}}, /* 9/10/1999 10:00:00 GMT */ 147 {0, 0, 0, 10, 28, 1, 2000, 1, 58, {0, 0}}, /* 2/28/2000 10:00:00 GMT */ 148 {0, 0, 0, 10, 31, 11, 2000, 0, 365, {0, 0}}, /* 12/31/2000 10:00:00 GMT */ 149 {0, 0, 0, 10, 1, 0, 2001, 1, 0, {0, 0}} /* 1/1/2001 10:00:00 GMT */ 150 }; 151 152 static PRExplodedTime uspt[] = { 153 {0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST 154 */ 155 {0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */ 156 {0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */ 157 {0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */ 158 {0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */ 159 {0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}}, /* 1999/9/9 3:00:00 PDT */ 160 /* Sun's dates follow */ 161 {0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}}, /* 12/31/1998 00:00:00 GMT 162 */ 163 {0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}}, /* 9/10/1999 00:00:00 GMT 164 */ 165 {0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}}, /* 2/28/2000 00:00:00 GMT */ 166 {0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}}, /* 12/31/2000 00:00:00 GMT 167 */ 168 {0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}} /* 1/1/2001 00:00:00 GMT */ 169 }; 170 171 /* 172 * This test assumes that we are in US Pacific Time Zone. 173 * If you are running this test in a different time zone, 174 * you need to modify the localt array and fill in the 175 * expected results. The localt array for US Eastern Time 176 * Zone is provided as an example. 177 */ 178 static PRExplodedTime localt[] = { 179 {0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST 180 */ 181 {0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */ 182 {0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */ 183 {0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */ 184 {0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */ 185 {0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}}, /* 1999/9/9 3:00:00 PDT */ 186 /* Sun's dates follow */ 187 {0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}}, /* 12/31/1998 00:00:00 GMT 188 */ 189 {0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}}, /* 9/10/1999 00:00:00 GMT 190 */ 191 {0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}}, /* 2/28/2000 00:00:00 GMT */ 192 {0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}}, /* 12/31/2000 00:00:00 GMT 193 */ 194 {0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}} /* 1/1/2001 00:00:00 GMT */ 195 }; 196 197 #ifdef US_EASTERN_TIME 198 static PRExplodedTime localt[] = { 199 {0, 0, 0, 5, 31, 11, 1999, 5, 364, {-18000, 0}}, /* 1999/12/31 2:00:00 EST 200 */ 201 {0, 0, 0, 5, 1, 0, 2000, 6, 0, {-18000, 0}}, /* 2000/01/01 2:00:00 EST */ 202 {0, 0, 0, 5, 29, 1, 2000, 2, 59, {-18000, 0}}, /* 2000/02/29 2:00:00 EST */ 203 {0, 0, 0, 5, 1, 2, 2001, 4, 59, {-18000, 0}}, /* 2001/3/1 2:00:00 EST */ 204 {0, 0, 0, 5, 1, 2, 2005, 2, 59, {-18000, 0}}, /* 2005/3/1 2:00:00 EST */ 205 {0, 0, 0, 6, 9, 8, 1999, 4, 251, {-18000, 3600}}, /* 1999/9/9 3:00:00 EDT */ 206 /* Sun's dates follow */ 207 {0, 0, 0, 5, 31, 11, 1998, 4, 364, {-18000 0}}, /* 12/31/1998 00:00:00 GMT 208 */ 209 {0, 0, 0, 6, 10, 8, 1999, 5, 252, {-18000 3600}}, /* 9/10/1999 00:00:00 GMT 210 */ 211 {0, 0, 0, 5, 28, 1, 2000, 1, 58, {-18000 0}}, /* 2/28/2000 00:00:00 GMT */ 212 {0, 0, 0, 5, 31, 11, 2000, 0, 365, {-18000 0}}, /* 12/31/2000 00:00:00 GMT 213 */ 214 {0, 0, 0, 5, 1, 0, 2001, 1, 0, {-18000 0}} /* 1/1/2001 00:00:00 GMT */ 215 }; 216 #endif 217 218 static PRStatus TestExplodeImplodeTime(void) { 219 PRTime prt_tmp; 220 PRTime now; 221 int idx; 222 int array_size = sizeof(prt) / sizeof(PRTime); 223 PRExplodedTime et_tmp; 224 char buf[1024]; 225 226 for (idx = 0; idx < array_size; idx++) { 227 PR_snprintf(buf, sizeof(buf), "%lld", prt[idx]); 228 if (debug_mode) { 229 printf("Time stamp %s\n", buf); 230 } 231 PR_ExplodeTime(prt[idx], PR_GMTParameters, &et_tmp); 232 if (!ExplodedTimeIsEqual(&et_tmp, &gmt[idx])) { 233 fprintf(stderr, "GMT not equal\n"); 234 PrintExplodedTime(&et_tmp); 235 PrintExplodedTime(&gmt[idx]); 236 exit(1); 237 } 238 prt_tmp = PR_ImplodeTime(&et_tmp); 239 if (LL_NE(prt_tmp, prt[idx])) { 240 fprintf(stderr, "PRTime not equal\n"); 241 exit(1); 242 } 243 if (debug_mode) { 244 printf("GMT: "); 245 PrintExplodedTime(&et_tmp); 246 printf("\n"); 247 } 248 249 PR_ExplodeTime(prt[idx], PR_USPacificTimeParameters, &et_tmp); 250 if (!ExplodedTimeIsEqual(&et_tmp, &uspt[idx])) { 251 fprintf(stderr, "US Pacific Time not equal\n"); 252 PrintExplodedTime(&et_tmp); 253 PrintExplodedTime(&uspt[idx]); 254 exit(1); 255 } 256 prt_tmp = PR_ImplodeTime(&et_tmp); 257 if (LL_NE(prt_tmp, prt[idx])) { 258 fprintf(stderr, "PRTime not equal\n"); 259 exit(1); 260 } 261 if (debug_mode) { 262 printf("US Pacific Time: "); 263 PrintExplodedTime(&et_tmp); 264 printf("\n"); 265 } 266 267 PR_ExplodeTime(prt[idx], PR_LocalTimeParameters, &et_tmp); 268 if (!ExplodedTimeIsEqual(&et_tmp, &localt[idx])) { 269 fprintf(stderr, "not equal\n"); 270 PrintExplodedTime(&et_tmp); 271 PrintExplodedTime(&localt[idx]); 272 exit(1); 273 } 274 prt_tmp = PR_ImplodeTime(&et_tmp); 275 if (LL_NE(prt_tmp, prt[idx])) { 276 fprintf(stderr, "not equal\n"); 277 exit(1); 278 } 279 if (debug_mode) { 280 printf("Local time:"); 281 PrintExplodedTime(&et_tmp); 282 printf("\n\n"); 283 } 284 } 285 286 now = PR_Now(); 287 PR_ExplodeTime(now, PR_GMTParameters, &et_tmp); 288 printf("Current GMT is "); 289 PrintExplodedTime(&et_tmp); 290 printf("\n"); 291 prt_tmp = PR_ImplodeTime(&et_tmp); 292 if (LL_NE(prt_tmp, now)) { 293 fprintf(stderr, "not equal\n"); 294 exit(1); 295 } 296 PR_ExplodeTime(now, PR_USPacificTimeParameters, &et_tmp); 297 printf("Current US Pacific Time is "); 298 PrintExplodedTime(&et_tmp); 299 printf("\n"); 300 prt_tmp = PR_ImplodeTime(&et_tmp); 301 if (LL_NE(prt_tmp, now)) { 302 fprintf(stderr, "not equal\n"); 303 exit(1); 304 } 305 PR_ExplodeTime(now, PR_LocalTimeParameters, &et_tmp); 306 printf("Current local time is "); 307 PrintExplodedTime(&et_tmp); 308 printf("\n"); 309 prt_tmp = PR_ImplodeTime(&et_tmp); 310 if (LL_NE(prt_tmp, now)) { 311 fprintf(stderr, "not equal\n"); 312 exit(1); 313 } 314 printf("Please verify the results\n\n"); 315 316 if (debug_mode) { 317 printf("Test 1 passed\n"); 318 } 319 return PR_SUCCESS; 320 } 321 /* End of Test 1: TestExplodeImplodeTime */ 322 323 /* 324 * Test 2: Normalize Time 325 */ 326 327 /* 328 * time increment for addition to PRExplodeTime 329 */ 330 typedef struct time_increment { 331 PRInt32 ti_usec; 332 PRInt32 ti_sec; 333 PRInt32 ti_min; 334 PRInt32 ti_hour; 335 } time_increment_t; 336 337 /* 338 * Data for testing PR_Normalize 339 * Add the increment to base_time, normalize it to GMT and US Pacific 340 * Time zone. 341 */ 342 typedef struct normalize_test_data { 343 PRExplodedTime base_time; 344 time_increment_t increment; 345 PRExplodedTime expected_gmt_time; 346 PRExplodedTime expected_uspt_time; 347 } normalize_test_data_t; 348 349 /* 350 * Test data - the base time values cover dates of interest including y2k - 1, 351 * y2k + 1, y2k leap year, y2k leap date + 1year, 352 * y2k leap date + 4 years 353 */ 354 normalize_test_data_t normalize_test_array[] = { 355 /*usec sec min hour mday mo year wday yday {gmtoff, dstoff }*/ 356 357 /* Fri 12/31/1999 19:32:48 PST */ 358 { 359 {0, 48, 32, 19, 31, 11, 1999, 5, 364, {-28800, 0}}, 360 {0, 0, 30, 20}, 361 {0, 48, 2, 0, 2, 0, 2000, 0, 1, {0, 0}}, /*Sun Jan 2 00:02:48 UTC 2000*/ 362 {0, 48, 2, 16, 1, 0, 2000, 6, 0, {-28800, 0}}, /* Sat Jan 1 16:02:48 363 PST 2000*/ 364 }, 365 /* Fri 99-12-31 23:59:02 GMT */ 366 { 367 {0, 2, 59, 23, 31, 11, 1999, 5, 364, {0, 0}}, 368 {0, 0, 45, 0}, 369 {0, 2, 44, 0, 1, 0, 2000, 6, 0, {0, 0}}, /* Sat Jan 1 00:44:02 UTC 370 2000*/ 371 {0, 2, 44, 16, 31, 11, 1999, 5, 364, {-28800, 0}} /*Fri Dec 31 16:44:02 372 PST 1999*/ 373 }, 374 /* 99-12-25 12:00:00 GMT */ 375 { 376 {0, 0, 0, 12, 25, 11, 1999, 6, 358, {0, 0}}, 377 {0, 0, 0, 364 * 24}, 378 {0, 0, 0, 12, 23, 11, 2000, 6, 357, {0, 0}}, /*Sat Dec 23 12:00:00 379 2000 UTC*/ 380 {0, 0, 0, 4, 23, 11, 2000, 6, 357, {-28800, 0}} /*Sat Dec 23 04:00:00 381 2000 -0800*/ 382 }, 383 /* 00-01-1 00:00:00 PST */ 384 { 385 {0, 0, 0, 0, 1, 0, 2000, 6, 0, {-28800, 0}}, 386 {0, 0, 0, 48}, 387 {0, 0, 0, 8, 3, 0, 2000, 1, 2, {0, 0}}, /*Mon Jan 3 08:00:00 2000 UTC*/ 388 {0, 0, 0, 0, 3, 0, 2000, 1, 2, {-28800, 0}} /*Mon Jan 3 00:00:00 2000 389 -0800*/ 390 }, 391 /* 00-01-10 12:00:00 PST */ 392 { 393 {0, 0, 0, 12, 10, 0, 2000, 1, 9, {-28800, 0}}, 394 {0, 0, 0, 364 * 5 * 24}, 395 {0, 0, 0, 20, 3, 0, 2005, 1, 2, {0, 0}}, /*Mon Jan 3 20:00:00 2005 UTC 396 */ 397 {0, 0, 0, 12, 3, 0, 2005, 1, 2, {-28800, 0}} /*Mon Jan 3 12:00:00 398 2005 -0800*/ 399 }, 400 /* 00-02-28 15:39 GMT */ 401 { 402 {0, 0, 39, 15, 28, 1, 2000, 1, 58, {0, 0}}, 403 {0, 0, 0, 24}, 404 {0, 0, 39, 15, 29, 1, 2000, 2, 59, {0, 0}}, /*Tue Feb 29 15:39:00 2000 405 UTC*/ 406 {0, 0, 39, 7, 29, 1, 2000, 2, 59, {-28800, 0}} /*Tue Feb 29 07:39:00 407 2000 -0800*/ 408 }, 409 /* 01-03-01 12:00 PST */ 410 { 411 {0, 0, 0, 12, 3, 0, 2001, 3, 2, {-28800, 0}}, /*Wed Jan 3 12:00:00 412 -0800 2001*/ 413 {0, 30, 30, 45}, 414 {0, 30, 30, 17, 5, 0, 2001, 5, 4, {0, 0}}, /*Fri Jan 5 17:30:30 2001 415 UTC*/ 416 {0, 30, 30, 9, 5, 0, 2001, 5, 4, {-28800, 0}} /*Fri Jan 5 09:30:30 417 2001 -0800*/ 418 }, 419 /* 2004-04-26 12:00 GMT */ 420 { 421 {0, 0, 0, 20, 3, 0, 2001, 3, 2, {0, 0}}, 422 {0, 0, 30, 0}, 423 {0, 0, 30, 20, 3, 0, 2001, 3, 2, {0, 0}}, /*Wed Jan 3 20:30:00 2001 424 UTC*/ 425 {0, 0, 30, 12, 3, 0, 2001, 3, 2, {-28800, 0}} /*Wed Jan 3 12:30:00 426 2001 -0800*/ 427 }, 428 /* 99-09-09 00:00 GMT */ 429 { 430 {0, 0, 0, 0, 9, 8, 1999, 4, 251, {0, 0}}, 431 {0, 0, 0, 12}, 432 {0, 0, 0, 12, 9, 8, 1999, 4, 251, {0, 0}}, /*Thu Sep 9 12:00:00 1999 433 UTC*/ 434 {0, 0, 0, 5, 9, 8, 1999, 4, 251, {-28800, 3600}} /*Thu Sep 9 05:00:00 435 1999 -0700*/ 436 }}; 437 438 void add_time_increment(PRExplodedTime* et1, time_increment_t* it) { 439 et1->tm_usec += it->ti_usec; 440 et1->tm_sec += it->ti_sec; 441 et1->tm_min += it->ti_min; 442 et1->tm_hour += it->ti_hour; 443 } 444 445 /* 446 ** TestNormalizeTime() -- Test PR_NormalizeTime() 447 ** For each data item, add the time increment to the base_time and then 448 ** normalize it for GMT and local time zones. This test assumes that 449 ** the local time zone is the Pacific Time Zone. The normalized values 450 ** should match the expected values in the data item. 451 ** 452 */ 453 PRStatus TestNormalizeTime(void) { 454 int idx, count; 455 normalize_test_data_t* itemp; 456 time_increment_t* itp; 457 458 count = sizeof(normalize_test_array) / sizeof(normalize_test_array[0]); 459 for (idx = 0; idx < count; idx++) { 460 itemp = &normalize_test_array[idx]; 461 if (debug_mode) { 462 printf("%2d. %15s", idx + 1, "Base time: "); 463 PrintExplodedTime(&itemp->base_time); 464 printf("\n"); 465 } 466 itp = &itemp->increment; 467 if (debug_mode) { 468 printf("%20s %2d hrs %2d min %3d sec\n", "Add", itp->ti_hour, itp->ti_min, 469 itp->ti_sec); 470 } 471 add_time_increment(&itemp->base_time, &itemp->increment); 472 PR_NormalizeTime(&itemp->base_time, PR_LocalTimeParameters); 473 if (debug_mode) { 474 printf("%19s", "PST time: "); 475 PrintExplodedTime(&itemp->base_time); 476 printf("\n"); 477 } 478 if (!ExplodedTimeIsEqual(&itemp->base_time, &itemp->expected_uspt_time)) { 479 printf("PR_NormalizeTime failed\n"); 480 if (debug_mode) { 481 PrintExplodedTime(&itemp->expected_uspt_time); 482 } 483 return PR_FAILURE; 484 } 485 PR_NormalizeTime(&itemp->base_time, PR_GMTParameters); 486 if (debug_mode) { 487 printf("%19s", "GMT time: "); 488 PrintExplodedTime(&itemp->base_time); 489 printf("\n"); 490 } 491 492 if (!ExplodedTimeIsEqual(&itemp->base_time, &itemp->expected_gmt_time)) { 493 printf("PR_NormalizeTime failed\n"); 494 return PR_FAILURE; 495 } 496 } 497 return PR_SUCCESS; 498 } 499 500 /* 501 ** ParseTest. Structure defining a string time and a matching exploded time 502 ** 503 */ 504 typedef struct ParseTest { 505 char* sDate; /* string to be converted using PR_ParseTimeString() */ 506 PRExplodedTime et; /* expected result of the conversion */ 507 } ParseTest; 508 509 static ParseTest parseArray[] = { 510 /* |<----- expected result 511 ------------------------------------------->| */ 512 /* "string to test" usec sec min hour day mo year 513 wday julian {gmtoff, dstoff }*/ 514 {"Thursday 1 Jan 1970 00:00:00", 515 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 516 {"1 Jan 1970 00:00:00", 517 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 518 {"1-Jan-1970 00:00:00", 519 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 520 {"01-Jan-1970 00:00:00", 521 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 522 {"January 1, 1970", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 523 {"January 1, 1970 00:00", 524 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 525 {"January 01, 1970 00:00", 526 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 527 {"January 01 1970 00:00", 528 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 529 {"January 01 1970 00:00:00", 530 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 531 {"01-01-1970", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 532 {"01/01/1970", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 533 {"01/01/70", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 534 {"01/01/70 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 535 {"70/01/01 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 536 {"70/1/1 00:00:", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 537 {"00:00 Thursday, January 1, 1970", 538 {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 539 {"1-Jan-70 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 540 {"70-01-01 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 541 {"70/01/01 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}}, 542 543 /* 31-Dec-1969 */ 544 {"Wed 31 Dec 1969 00:00:00", 545 {000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0}}}, 546 {"31 Dec 1969 00:00:00", 547 {000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0}}}, 548 {"12/31/69 00:00:00", 549 {000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0}}}, 550 {"12/31/1969 00:00:00", 551 {000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0}}}, 552 {"12-31-69 00:00:00", 553 {000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0}}}, 554 {"12-31-1969 00:00:00", 555 {000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0}}}, 556 {"69-12-31 00:00:00", 557 {000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0}}}, 558 {"69/12/31 00:00:00", 559 {000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0}}}, 560 561 /* "Sun". 31-Dec-1998 (?) */ 562 {"Thu 31 Dec 1998 00:00:00", 563 {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}}, 564 {"12/31/98 00:00:00", 565 {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}}, 566 {"12/31/1998 00:00:00", 567 {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}}, 568 {"12-31-98 00:00:00", 569 {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}}, 570 {"12-31-1998 00:00:00", 571 {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}}, 572 {"98-12-31 00:00:00", 573 {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}}, 574 {"98/12/31 00:00:00", 575 {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}}, 576 577 /* 09-Sep-1999. Interesting because of its use as an eof marker? */ 578 {"09 Sep 1999 00:00:00", 579 {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}}, 580 {"9/9/99 00:00:00", 581 {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}}, 582 {"9/9/1999 00:00:00", 583 {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}}, 584 {"9-9-99 00:00:00", 585 {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}}, 586 {"9-9-1999 00:00:00", 587 {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}}, 588 {"09-09-99 00:00:00", 589 {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}}, 590 {"09-09-1999 00:00:00", 591 {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}}, 592 {"99-09-09 00:00:00", 593 {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}}, 594 595 /* "Sun". 10-Sep-1999. Because Sun said so. */ 596 {"10 Sep 1999 00:00:00", 597 {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}}, 598 {"9/10/99 00:00:00", 599 {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}}, 600 {"9/10/1999 00:00:00", 601 {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}}, 602 {"9-10-99 00:00:00", 603 {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}}, 604 {"9-10-1999 00:00:00", 605 {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}}, 606 {"09-10-99 00:00:00", 607 {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}}, 608 {"09-10-1999 00:00:00", 609 {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}}, 610 {"99-09-10 00:00:00", 611 {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}}, 612 613 /* 31-Dec-1999 */ 614 {"31 Dec 1999 00:00:00", 615 {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}}, 616 {"12/31/99 00:00:00", 617 {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}}, 618 {"12/31/1999 00:00:00", 619 {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}}, 620 {"12-31-99 00:00:00", 621 {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}}, 622 {"12-31-1999 00:00:00", 623 {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}}, 624 {"99-12-31 00:00:00", 625 {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}}, 626 {"99/12/31 00:00:00", 627 {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}}, 628 629 /* 01-Jan-2000 */ 630 {"01 Jan 2000 00:00:00", 631 {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}}, 632 {"1/1/00 00:00:00", 633 {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}}, 634 {"1/1/2000 00:00:00", 635 {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}}, 636 {"1-1-00 00:00:00", 637 {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}}, 638 {"1-1-2000 00:00:00", 639 {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}}, 640 {"01-01-00 00:00:00", 641 {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}}, 642 {"Saturday 01-01-2000 00:00:00", 643 {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}}, 644 645 /* "Sun". 28-Feb-2000 */ 646 {"28 Feb 2000 00:00:00", 647 {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}}, 648 {"2/28/00 00:00:00", 649 {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}}, 650 {"2/28/2000 00:00:00", 651 {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}}, 652 {"2-28-00 00:00:00", 653 {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}}, 654 {"2-28-2000 00:00:00", 655 {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}}, 656 {"02-28-00 00:00:00", 657 {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}}, 658 {"02-28-2000 00:00:00", 659 {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}}, 660 661 /* 29-Feb-2000 */ 662 {"29 Feb 2000 00:00:00", 663 {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}}, 664 {"2/29/00 00:00:00", 665 {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}}, 666 {"2/29/2000 00:00:00", 667 {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}}, 668 {"2-29-00 00:00:00", 669 {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}}, 670 {"2-29-2000 00:00:00", 671 {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}}, 672 {"02-29-00 00:00:00", 673 {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}}, 674 {"02-29-2000 00:00:00", 675 {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}}, 676 677 /* 01-Mar-2000 */ 678 {"01 Mar 2000 00:00:00", 679 {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}}, 680 {"3/1/00 00:00:00", 681 {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}}, 682 {"3/1/2000 00:00:00", 683 {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}}, 684 {"3-1-00 00:00:00", 685 {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}}, 686 {"03-01-00 00:00:00", 687 {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}}, 688 {"03-01-2000 00:00:00", 689 {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}}, 690 691 /* "Sun". 31-Dec-2000 */ 692 {"31 Dec 2000 00:00:00", 693 {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}}, 694 {"12/31/00 00:00:00", 695 {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}}, 696 {"12/31/2000 00:00:00", 697 {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}}, 698 {"12-31-00 00:00:00", 699 {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}}, 700 {"12-31-2000 00:00:00", 701 {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}}, 702 {"00-12-31 00:00:00", 703 {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}}, 704 {"00/12/31 00:00:00", 705 {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}}, 706 707 /* "Sun". 01-Jan-2001 */ 708 {"01 Jan 2001 00:00:00", 709 {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}}, 710 {"1/1/01 00:00:00", 711 {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}}, 712 {"1/1/2001 00:00:00", 713 {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}}, 714 {"1-1-01 00:00:00", 715 {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}}, 716 {"1-1-2001 00:00:00", 717 {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}}, 718 {"01-01-01 00:00:00", 719 {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}}, 720 {"Saturday 01-01-2001 00:00:00", 721 {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}}, 722 723 /* 01-Mar-2001 */ 724 {"01 Mar 2001 00:00:00", 725 {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}}, 726 {"3/1/01 00:00:00", 727 {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}}, 728 {"3/1/2001 00:00:00", 729 {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}}, 730 {"3-1-01 00:00:00", 731 {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}}, 732 {"3-1-2001 00:00:00", 733 {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}}, 734 {"03-01-01 00:00:00", 735 {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}}, 736 {"03-01-2001 00:00:00", 737 {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}}, 738 739 /* 29-Feb-2004 */ 740 {"29 Feb 2004 00:00:00", 741 {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}}, 742 {"2/29/04 00:00:00", 743 {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}}, 744 {"2/29/2004 00:00:00", 745 {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}}, 746 {"2-29-04 00:00:00", 747 {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}}, 748 {"2-29-2004 00:00:00", 749 {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}}, 750 751 /* 01-Mar-2004 */ 752 {"01 Mar 2004 00:00:00", 753 {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}}, 754 {"3/1/04 00:00:00", 755 {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}}, 756 {"3/1/2004 00:00:00", 757 {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}}, 758 {"3-1-04 00:00:00", 759 {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}}, 760 {"3-1-2004 00:00:00", 761 {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}}, 762 {"03-01-04 00:00:00", 763 {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}}, 764 {"03-01-2004 00:00:00", 765 {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}}, 766 767 /* 01-Mar-2005 */ 768 {"01 Mar 2005 00:00:00", 769 {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}}, 770 {"3/1/05 00:00:00", 771 {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}}, 772 {"3/1/2005 00:00:00", 773 {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}}, 774 {"3-1-05 00:00:00", 775 {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}}, 776 {"3-1-2005 00:00:00", 777 {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}}, 778 {"03-01-05 00:00:00", 779 {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}}, 780 {"03-01-2005 00:00:00", 781 {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}}, 782 783 /* last element. string must be null */ 784 {NULL}}; /* end array of ParseTest */ 785 786 /* 787 ** TestParseTime() -- Test PR_ParseTimeString() for y2k compliance 788 ** 789 ** TestParseTime() loops thru the array parseArray. For each element in 790 ** the array, he calls PR_ParseTimeString() with sDate as the conversion 791 ** argument. The result (ct) is then converted to a PRExplodedTime structure 792 ** and compared with the exploded time value (parseArray[n].et) in the 793 ** array element; if equal, the element passes the test. 794 ** 795 ** The array parseArray[] contains entries that are interesting to the 796 ** y2k problem. 797 ** 798 ** 799 */ 800 static PRStatus TestParseTime(void) { 801 ParseTest* ptp = parseArray; 802 PRTime ct; 803 PRExplodedTime cet; 804 char* sp = ptp->sDate; 805 PRStatus rc; 806 PRStatus rv = PR_SUCCESS; 807 808 while (sp != NULL) { 809 rc = PR_ParseTimeString(sp, PR_FALSE, &ct); 810 if (PR_FAILURE == rc) { 811 printf("TestParseTime(): PR_ParseTimeString() failed to convert: %s\n", 812 sp); 813 rv = PR_FAILURE; 814 failed_already = 1; 815 } else { 816 PR_ExplodeTime(ct, PR_LocalTimeParameters, &cet); 817 818 if (!ExplodedTimeIsEqual(&cet, &ptp->et)) { 819 printf("TestParseTime(): Exploded time compare failed: %s\n", sp); 820 if (debug_mode) { 821 PrintExplodedTime(&cet); 822 printf("\n"); 823 PrintExplodedTime(&ptp->et); 824 printf("\n"); 825 } 826 827 rv = PR_FAILURE; 828 failed_already = 1; 829 } 830 } 831 832 /* point to next element in array, keep going */ 833 ptp++; 834 sp = ptp->sDate; 835 } /* end while() */ 836 837 return (rv); 838 } /* end TestParseTime() */ 839 840 int main(int argc, char** argv) { 841 /* The command line argument: -d is used to determine if the test is being run 842 in debug mode. The regress tool requires only one line output:PASS or FAIL. 843 All of the printfs associated with this test has been handled with a if 844 (debug_mode) test. Usage: test_name -d 845 */ 846 PLOptStatus os; 847 PLOptState* opt; 848 849 opt = PL_CreateOptState(argc, argv, "d"); 850 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { 851 if (PL_OPT_BAD == os) { 852 continue; 853 } 854 switch (opt->option) { 855 case 'd': /* debug mode */ 856 debug_mode = PR_TRUE; 857 break; 858 default: 859 break; 860 } 861 } 862 PL_DestroyOptState(opt); 863 864 /* main test */ 865 866 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 867 lm = PR_NewLogModule("test"); 868 869 if (PR_FAILURE == TestExplodeImplodeTime()) { 870 PR_LOG(lm, PR_LOG_ERROR, ("TestExplodeImplodeTime() failed")); 871 } else { 872 printf("Test 1: Calendar Time Test passed\n"); 873 } 874 875 if (PR_FAILURE == TestNormalizeTime()) { 876 PR_LOG(lm, PR_LOG_ERROR, ("TestNormalizeTime() failed")); 877 } else { 878 printf("Test 2: Normalize Time Test passed\n"); 879 } 880 881 if (PR_FAILURE == TestParseTime()) { 882 PR_LOG(lm, PR_LOG_ERROR, ("TestParseTime() failed")); 883 } else { 884 printf("Test 3: Parse Time Test passed\n"); 885 } 886 887 if (failed_already) { 888 return 1; 889 } else { 890 return 0; 891 } 892 } /* end main() y2k.c */