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