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