Back to index

lightning-sunbird  0.9+nobinonly
timetest.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*
00039  * file: timetest.c
00040  * description: test time and date routines
00041  */
00042 /***********************************************************************
00043 ** Includes
00044 ***********************************************************************/
00045 /* Used to get the command line option */
00046 #include "plgetopt.h"
00047 
00048 #include "prinit.h"
00049 #include "prtime.h"
00050 #include "prprf.h"
00051 
00052 #include <stdio.h>
00053 #include <stdlib.h>
00054 #include <string.h>
00055 
00056 #ifdef XP_MAC
00057 #include "prlog.h"
00058 #include "macstdlibextras.h"
00059 extern void SetupMacPrintfLog(char *logFile);
00060 #endif
00061 
00062 int failed_already=0;
00063 PRBool debug_mode = PR_FALSE;
00064 
00065 static char *dayOfWeek[] =
00066        { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
00067 static char *month[] =
00068        { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00069          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
00070 
00071 static void PrintExplodedTime(const PRExplodedTime *et) {
00072     PRInt32 totalOffset;
00073     PRInt32 hourOffset, minOffset;
00074     const char *sign;
00075 
00076     /* Print day of the week, month, day, hour, minute, and second */
00077     if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ",
00078            dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
00079            et->tm_hour, et->tm_min, et->tm_sec);
00080 
00081     /* Print time zone */
00082     totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
00083     if (totalOffset == 0) {
00084        if (debug_mode) printf("UTC ");
00085     } else {
00086         sign = "+";
00087         if (totalOffset < 0) {
00088            totalOffset = -totalOffset;
00089            sign = "-";
00090         }
00091         hourOffset = totalOffset / 3600;
00092         minOffset = (totalOffset % 3600) / 60;
00093         if (debug_mode) 
00094             printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
00095     }
00096 
00097     /* Print year */
00098     if (debug_mode) printf("%hd", et->tm_year);
00099 }
00100 
00101 static int ExplodedTimeIsEqual(const PRExplodedTime *et1,
00102        const PRExplodedTime *et2)
00103 {
00104     if (et1->tm_usec == et2->tm_usec &&
00105            et1->tm_sec == et2->tm_sec &&
00106            et1->tm_min == et2->tm_min &&
00107            et1->tm_hour == et2->tm_hour &&
00108            et1->tm_mday == et2->tm_mday &&
00109            et1->tm_month == et2->tm_month &&
00110            et1->tm_year == et2->tm_year &&
00111            et1->tm_wday == et2->tm_wday &&
00112            et1->tm_yday == et2->tm_yday &&
00113            et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset &&
00114            et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) {
00115         return 1;
00116     } else {
00117        return 0;
00118     }
00119 }
00120 
00121 static void
00122 testParseTimeString(PRTime t)
00123 {
00124     PRExplodedTime et;
00125     PRTime t2;
00126     char timeString[128];
00127     char buf[128];
00128     PRInt32 totalOffset;
00129     PRInt32 hourOffset, minOffset;
00130     const char *sign;
00131     PRInt64 usec_per_sec;
00132 
00133     /* Truncate the microsecond part of PRTime */
00134     LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
00135     LL_DIV(t, t, usec_per_sec);
00136     LL_MUL(t, t, usec_per_sec);
00137 
00138     PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
00139 
00140     /* Print day of the week, month, day, hour, minute, and second */
00141     PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ",
00142            dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday,
00143            et.tm_hour, et.tm_min, et.tm_sec);
00144     /* Print time zone */
00145     totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset;
00146     if (totalOffset == 0) {
00147        strcat(timeString, "GMT ");  /* I wanted to use "UTC" here, but
00148                                       * PR_ParseTimeString doesn't 
00149                                       * understand "UTC".  */
00150     } else {
00151         sign = "+";
00152         if (totalOffset < 0) {
00153            totalOffset = -totalOffset;
00154            sign = "-";
00155         }
00156         hourOffset = totalOffset / 3600;
00157         minOffset = (totalOffset % 3600) / 60;
00158         PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset);
00159        strcat(timeString, buf);
00160     }
00161     /* Print year */
00162     PR_snprintf(buf, 128, "%hd", et.tm_year);
00163     strcat(timeString, buf);
00164 
00165     if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) {
00166        fprintf(stderr, "PR_ParseTimeString() failed\n");
00167        exit(1);
00168     }
00169     if (LL_NE(t, t2)) {
00170        fprintf(stderr, "PR_ParseTimeString() incorrect\n");
00171        PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n",
00172                 t, t2, timeString);
00173        fprintf(stderr, "%s\n", buf);
00174        exit(1);
00175     }
00176 }
00177 
00178 int main(int argc, char** argv)
00179 {
00180        /* The command line argument: -d is used to determine if the test is being run
00181        in debug mode. The regress tool requires only one line output:PASS or FAIL.
00182        All of the printfs associated with this test has been handled with a if (debug_mode)
00183        test.
00184        Usage: test_name -d
00185        */
00186        PLOptStatus os;
00187        PLOptState *opt;
00188     
00189     PR_STDIO_INIT();
00190        opt = PL_CreateOptState(argc, argv, "d");
00191        while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
00192     {
00193               if (PL_OPT_BAD == os) continue;
00194         switch (opt->option)
00195         {
00196         case 'd':  /* debug mode */
00197                      debug_mode = PR_TRUE;
00198             break;
00199          default:
00200             break;
00201         }
00202     }
00203        PL_DestroyOptState(opt);
00204 
00205  /* main test */
00206        
00207     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
00208 
00209 #ifdef XP_MAC
00210        /* Set up the console */
00211        InitializeSIOUX(true);
00212        debug_mode = PR_TRUE;
00213 #endif
00214     /* Testing zero PRTime (the epoch) */
00215     {
00216        PRTime t;
00217        PRExplodedTime et;
00218 
00219        LL_I2L(t, 0);
00220        if (debug_mode) printf("The NSPR epoch is:\n");
00221         PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
00222        PrintExplodedTime(&et);
00223        if (debug_mode) printf("\n");
00224        PR_ExplodeTime(t, PR_GMTParameters, &et);
00225        PrintExplodedTime(&et);
00226        if (debug_mode) printf("\n\n");
00227        testParseTimeString(t);
00228     }
00229 
00230     /*
00231      *************************************************************
00232      **
00233      **  Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime
00234      **  on the current time
00235      **
00236      *************************************************************
00237      */
00238 
00239     {
00240        PRTime t1, t2;
00241        PRExplodedTime et;
00242 
00243        if (debug_mode) {
00244        printf("*********************************************\n");
00245        printf("**                                         **\n");
00246     printf("** Testing PR_Now(), PR_ExplodeTime, and   **\n");
00247        printf("** PR_ImplodeTime on the current time      **\n");
00248        printf("**                                         **\n");
00249        printf("*********************************************\n\n");
00250        }
00251        t1 = PR_Now();
00252 
00253         /* First try converting to UTC */
00254 
00255         PR_ExplodeTime(t1, PR_GMTParameters, &et);
00256         if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) {
00257            if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n");
00258               else failed_already=1;
00259            return 1;
00260         }
00261         if (debug_mode) printf("Current UTC is ");
00262        PrintExplodedTime(&et);
00263        if (debug_mode) printf("\n");
00264 
00265         t2 = PR_ImplodeTime(&et);
00266         if (LL_NE(t1, t2)) {
00267            if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
00268               else printf("FAIL\n");
00269            return 1;
00270         }
00271 
00272         /* Next, try converting to local (US Pacific) time */
00273 
00274         PR_ExplodeTime(t1, PR_LocalTimeParameters, &et);
00275         if (debug_mode) printf("Current local time is ");
00276        PrintExplodedTime(&et);
00277        if (debug_mode) printf("\n");
00278        if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n",
00279               et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset);
00280         t2 = PR_ImplodeTime(&et);
00281         if (LL_NE(t1, t2)) {
00282            if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
00283            return 1;
00284        }
00285 
00286        if (debug_mode) printf("Please examine the results\n");
00287        testParseTimeString(t1);
00288     }
00289 
00290 
00291     /*
00292      *******************************************
00293      **
00294      ** Testing PR_NormalizeTime()
00295      **
00296      *******************************************
00297      */
00298 
00299     /* July 4, 2001 is Wednesday */
00300     {
00301        PRExplodedTime et;
00302 
00303        if (debug_mode)  {
00304        printf("\n");
00305        printf("**********************************\n");
00306        printf("**                              **\n");
00307        printf("** Testing PR_NormalizeTime()   **\n");
00308        printf("**                              **\n");
00309        printf("**********************************\n\n");
00310        }
00311         et.tm_year    = 2001;
00312         et.tm_month   = 7 - 1;
00313         et.tm_mday    = 4;
00314         et.tm_hour    = 0;
00315         et.tm_min     = 0;
00316         et.tm_sec     = 0;
00317        et.tm_usec    = 0;
00318         et.tm_params  = PR_GMTParameters(&et);
00319 
00320        PR_NormalizeTime(&et, PR_GMTParameters);
00321 
00322        if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]);
00323        if (et.tm_wday == 3) {
00324            if (debug_mode) printf("PASS\n");
00325         } else {
00326             if (debug_mode) printf("ERROR: It should be Wednesday\n");
00327                      else failed_already=1;
00328            return 1;
00329        }
00330        testParseTimeString(PR_ImplodeTime(&et));
00331 
00332         /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */
00333         et.tm_year    = 1997;
00334         et.tm_month   = 6 - 1;
00335         et.tm_mday    = 12;
00336         et.tm_hour    = 23;
00337         et.tm_min     = 0;
00338         et.tm_sec     = 0;
00339        et.tm_usec    = 0;
00340         et.tm_params.tp_gmt_offset = -8 * 3600;
00341        et.tm_params.tp_dst_offset = 0;
00342 
00343        PR_NormalizeTime(&et, PR_USPacificTimeParameters);
00344 
00345        if (debug_mode) {
00346            printf("Thu Jun 12, 1997 23:00:00 PST is ");
00347        }
00348        PrintExplodedTime(&et);
00349        if (debug_mode) printf(".\n");
00350        if (et.tm_wday == 5) {
00351            if (debug_mode) printf("PASS\n");
00352         } else {
00353             if (debug_mode) printf("ERROR: It should be Friday\n");
00354                      else failed_already=1;
00355            return 1;
00356        }
00357        testParseTimeString(PR_ImplodeTime(&et));
00358 
00359         /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */
00360         et.tm_year    = 1997;
00361         et.tm_month   = 2 - 1;
00362         et.tm_mday    = 14;
00363         et.tm_hour    = 0;
00364         et.tm_min     = 0;
00365         et.tm_sec     = 0;
00366        et.tm_usec    = 0;
00367         et.tm_params.tp_gmt_offset = -8 * 3600;
00368        et.tm_params.tp_dst_offset = 3600;
00369 
00370        PR_NormalizeTime(&et, PR_USPacificTimeParameters);
00371 
00372        if (debug_mode) {
00373            printf("Fri Feb 14, 1997 00:00:00 PDT is ");
00374        }
00375        PrintExplodedTime(&et);
00376        if (debug_mode) printf(".\n");
00377        if (et.tm_wday == 4) {
00378            if (debug_mode) printf("PASS\n");
00379         } else {
00380             if (debug_mode) printf("ERROR: It should be Thursday\n");
00381                      else failed_already=1;
00382            return 1;
00383        }
00384        testParseTimeString(PR_ImplodeTime(&et));
00385 
00386         /* What time is Nov. 7, 1996, 18:29:23 PDT? */
00387         et.tm_year    = 1996;
00388         et.tm_month   = 11 - 1;
00389         et.tm_mday    = 7;
00390         et.tm_hour    = 18;
00391         et.tm_min     = 29;
00392         et.tm_sec     = 23;
00393        et.tm_usec    = 0;
00394         et.tm_params.tp_gmt_offset = -8 * 3600;  /* PDT */
00395        et.tm_params.tp_dst_offset = 3600; 
00396 
00397        PR_NormalizeTime(&et, PR_LocalTimeParameters);
00398         if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is ");
00399        PrintExplodedTime(&et);
00400        if (debug_mode) printf(".\n");
00401        testParseTimeString(PR_ImplodeTime(&et));
00402 
00403         /* What time is Oct. 7, 1995, 18:29:23 PST? */
00404         et.tm_year    = 1995;
00405         et.tm_month   = 10 - 1;
00406         et.tm_mday    = 7;
00407         et.tm_hour    = 18;
00408         et.tm_min     = 29;
00409         et.tm_sec     = 23;
00410         et.tm_params.tp_gmt_offset = -8 * 3600;  /* PST */
00411        et.tm_params.tp_dst_offset = 0;
00412 
00413        PR_NormalizeTime(&et, PR_LocalTimeParameters);
00414         if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is ");
00415        PrintExplodedTime(&et);
00416        if (debug_mode) printf(".\n");
00417        testParseTimeString(PR_ImplodeTime(&et));
00418 
00419        if (debug_mode) printf("Please examine the results\n");
00420     }
00421 
00422     /*
00423      **************************************************************
00424      **
00425      ** Testing range of years
00426      **
00427      **************************************************************
00428      */
00429 
00430     {
00431        PRExplodedTime et1, et2;
00432     PRTime  ttt;
00433        PRTime secs;
00434 
00435        if (debug_mode) {
00436        printf("\n");
00437        printf("***************************************\n");
00438        printf("**                                   **\n");
00439        printf("**  Testing range of years           **\n");
00440        printf("**                                   **\n");
00441        printf("***************************************\n\n");
00442        }
00443        /* April 4, 1917 GMT */
00444        et1.tm_usec = 0;
00445        et1.tm_sec = 0;
00446        et1.tm_min = 0;
00447        et1.tm_hour = 0;
00448        et1.tm_mday = 4;
00449        et1.tm_month = 4 - 1;
00450        et1.tm_year = 1917;
00451        et1.tm_params = PR_GMTParameters(&et1);
00452        PR_NormalizeTime(&et1, PR_LocalTimeParameters);
00453        secs = PR_ImplodeTime(&et1);
00454        if (LL_GE_ZERO(secs)) {
00455            if (debug_mode)
00456               printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n");
00457               failed_already = 1;
00458            return 1;
00459         }
00460        PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
00461        if (!ExplodedTimeIsEqual(&et1, &et2)) {
00462               if (debug_mode)
00463               printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n");
00464               failed_already=1;
00465            return 1;
00466         }
00467     ttt = PR_ImplodeTime(&et1);
00468        testParseTimeString( ttt );
00469 
00470        if (debug_mode) printf("Test passed for April 4, 1917\n");
00471 
00472        /* July 4, 2050 */
00473        et1.tm_usec = 0;
00474        et1.tm_sec = 0;
00475        et1.tm_min = 0;
00476        et1.tm_hour = 0;
00477        et1.tm_mday = 4;
00478        et1.tm_month = 7 - 1;
00479        et1.tm_year = 2050;
00480        et1.tm_params = PR_GMTParameters(&et1);
00481        PR_NormalizeTime(&et1, PR_LocalTimeParameters);
00482        secs = PR_ImplodeTime(&et1);
00483        if (!LL_GE_ZERO(secs)) {
00484            if (debug_mode)
00485                      printf("ERROR: July 4, 2050 GMT returns a negative second count\n");
00486               failed_already = 1;
00487            return 1;
00488         }
00489        PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
00490        if (!ExplodedTimeIsEqual(&et1, &et2)) {
00491            if (debug_mode)
00492               printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n");
00493               failed_already=1;
00494            return 1;
00495         }
00496        testParseTimeString(PR_ImplodeTime(&et1));
00497 
00498        if (debug_mode) printf("Test passed for July 4, 2050\n");
00499 
00500     }
00501 
00502     /*
00503      **************************************************************
00504      **
00505      **  Stress test
00506      *
00507      **      Go through four years, starting from
00508      **      00:00:00 PST Jan. 1, 2005, incrementing
00509      **      every 10 minutes.
00510      **
00511      **************************************************************
00512      */
00513 
00514     {
00515        PRExplodedTime et, et1, et2;
00516        PRInt64 usecPer10Min;
00517        int day, hour, min;
00518        PRTime usecs;
00519        int dstInEffect = 0;
00520 
00521        if (debug_mode) {
00522        printf("\n");
00523        printf("*******************************************************\n");
00524        printf("**                                                   **\n");
00525        printf("**        Stress test  Pacific Time                  **\n");
00526        printf("**  Starting from midnight Jan. 1, 2005 PST,         **\n");
00527        printf("**  going through four years in 10-minute increment  **\n");
00528        printf("**                                                   **\n");
00529        printf("*******************************************************\n\n");
00530        }
00531        LL_I2L(usecPer10Min, 600000000L);
00532 
00533        /* 00:00:00 PST Jan. 1, 2005 */
00534        et.tm_usec = 0;
00535        et.tm_sec = 0;
00536        et.tm_min = 0;
00537        et.tm_hour = 0;
00538        et.tm_mday = 1;
00539        et.tm_month = 0;
00540        et.tm_year = 2005;
00541        et.tm_params.tp_gmt_offset = -8 * 3600;
00542        et.tm_params.tp_dst_offset = 0;
00543        usecs = PR_ImplodeTime(&et);
00544 
00545         for (day = 0; day < 4 * 365 + 1; day++) {
00546            for (hour = 0; hour < 24; hour++) {
00547               for (min = 0; min < 60; min += 10) {
00548                    LL_ADD(usecs, usecs, usecPer10Min);
00549                   PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1);
00550 
00551                   et2 = et;
00552                   et2.tm_usec += 600000000L;
00553                   PR_NormalizeTime(&et2, PR_USPacificTimeParameters);
00554 
00555                   if (!ExplodedTimeIsEqual(&et1, &et2)) {
00556                      printf("ERROR: componentwise comparison failed\n");
00557                      PrintExplodedTime(&et1);
00558                      printf("\n");
00559                      PrintExplodedTime(&et2);
00560                      printf("\n");
00561                      failed_already=1;
00562                       return 1;
00563                   }
00564 
00565                   if (LL_NE(usecs, PR_ImplodeTime(&et1))) { 
00566                      printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
00567                      PrintExplodedTime(&et1);
00568                      printf("\n");
00569                      failed_already=1;
00570                       return 1;
00571                   }
00572                   testParseTimeString(usecs);
00573 
00574                   if (!dstInEffect && et1.tm_params.tp_dst_offset) {
00575                       dstInEffect = 1;
00576                       if (debug_mode) {
00577                          printf("DST changeover from ");
00578                          PrintExplodedTime(&et);
00579                          printf(" to ");
00580                          PrintExplodedTime(&et1);
00581                          printf(".\n");
00582                      }
00583                     } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
00584                       dstInEffect = 0;
00585                      if (debug_mode) {
00586                          printf("DST changeover from ");
00587                          PrintExplodedTime(&et);
00588                          printf(" to ");
00589                          PrintExplodedTime(&et1);
00590                          printf(".\n");
00591                      }
00592                     }
00593 
00594                   et = et1;
00595               }
00596            }
00597         }
00598        if (debug_mode) printf("Test passed\n");
00599     }
00600 
00601 
00602     /* Same stress test, but with PR_LocalTimeParameters */
00603 
00604     {
00605        PRExplodedTime et, et1, et2;
00606        PRInt64 usecPer10Min;
00607        int day, hour, min;
00608        PRTime usecs;
00609        int dstInEffect = 0;
00610 
00611        if (debug_mode) {
00612        printf("\n");
00613        printf("*******************************************************\n");
00614        printf("**                                                   **\n");
00615        printf("**         Stress test    Local Time                 **\n");
00616        printf("**  Starting from midnight Jan. 1, 2005 PST,         **\n");
00617        printf("**  going through four years in 10-minute increment  **\n");
00618        printf("**                                                   **\n");
00619        printf("*******************************************************\n\n");
00620        }
00621        
00622        LL_I2L(usecPer10Min, 600000000L);
00623 
00624        /* 00:00:00 PST Jan. 1, 2005 */
00625        et.tm_usec = 0;
00626        et.tm_sec = 0;
00627        et.tm_min = 0;
00628        et.tm_hour = 0;
00629        et.tm_mday = 1;
00630        et.tm_month = 0;
00631        et.tm_year = 2005;
00632        et.tm_params.tp_gmt_offset = -8 * 3600;
00633        et.tm_params.tp_dst_offset = 0;
00634        usecs = PR_ImplodeTime(&et);
00635 
00636         for (day = 0; day < 4 * 365 + 1; day++) {
00637            for (hour = 0; hour < 24; hour++) {
00638               for (min = 0; min < 60; min += 10) {
00639                    LL_ADD(usecs, usecs, usecPer10Min);
00640                   PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
00641 
00642                   et2 = et;
00643                   et2.tm_usec += 600000000L;
00644                   PR_NormalizeTime(&et2, PR_LocalTimeParameters);
00645 
00646                   if (!ExplodedTimeIsEqual(&et1, &et2)) {
00647                      printf("ERROR: componentwise comparison failed\n");
00648                      PrintExplodedTime(&et1);
00649                      printf("\n");
00650                      PrintExplodedTime(&et2);
00651                      printf("\n");
00652                       return 1;
00653                   }
00654 
00655                   if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
00656                         printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
00657                      PrintExplodedTime(&et1);
00658                      printf("\n");
00659                      failed_already=1;
00660                       return 1;
00661                   }
00662                   testParseTimeString(usecs);
00663 
00664                   if (!dstInEffect && et1.tm_params.tp_dst_offset) {
00665                       dstInEffect = 1;
00666                       if (debug_mode) {
00667                          printf("DST changeover from ");
00668                          PrintExplodedTime(&et);
00669                          printf(" to ");
00670                          PrintExplodedTime(&et1);
00671                          printf(".\n");
00672                      }
00673                     } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
00674                       dstInEffect = 0;
00675                      if (debug_mode) {
00676                          printf("DST changeover from ");
00677                          PrintExplodedTime(&et);
00678                          printf(" to ");
00679                          PrintExplodedTime(&et1);
00680                          printf(".\n");
00681                      }
00682                     }
00683 
00684                   et = et1;
00685               }
00686            }
00687         }
00688        if (debug_mode) printf("Test passed\n");
00689     }
00690 
00691     /* Same stress test, but with PR_LocalTimeParameters and going backward */
00692 
00693     {
00694        PRExplodedTime et, et1, et2;
00695        PRInt64 usecPer10Min;
00696        int day, hour, min;
00697        PRTime usecs;
00698        int dstInEffect = 0;
00699 
00700        if (debug_mode) {
00701        printf("\n");
00702        printf("*******************************************************\n");
00703        printf("**                                                   **\n");
00704        printf("**           Stress test    Local Time               **\n");
00705        printf("**  Starting from midnight Jan. 1, 2009 PST,         **\n");
00706        printf("**  going back four years in 10-minute increment     **\n");
00707        printf("**                                                   **\n");
00708        printf("*******************************************************\n\n");
00709        }
00710 
00711        LL_I2L(usecPer10Min, 600000000L);
00712 
00713        /* 00:00:00 PST Jan. 1, 2009 */
00714        et.tm_usec = 0;
00715        et.tm_sec = 0;
00716        et.tm_min = 0;
00717        et.tm_hour = 0;
00718        et.tm_mday = 1;
00719        et.tm_month = 0;
00720        et.tm_year = 2009;
00721        et.tm_params.tp_gmt_offset = -8 * 3600;
00722        et.tm_params.tp_dst_offset = 0;
00723        usecs = PR_ImplodeTime(&et);
00724 
00725         for (day = 0; day < 4 * 365 + 1; day++) {
00726            for (hour = 0; hour < 24; hour++) {
00727               for (min = 0; min < 60; min += 10) {
00728                    LL_SUB(usecs, usecs, usecPer10Min);
00729                   PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
00730 
00731                   et2 = et;
00732                   et2.tm_usec -= 600000000L;
00733                   PR_NormalizeTime(&et2, PR_LocalTimeParameters);
00734 
00735                   if (!ExplodedTimeIsEqual(&et1, &et2)) {
00736                       printf("ERROR: componentwise comparison failed\n");
00737                      PrintExplodedTime(&et1);
00738                      printf("\n");
00739                      PrintExplodedTime(&et2);
00740                      printf("\n");
00741                       return 1;
00742                   }
00743 
00744                   if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
00745                      printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
00746                      PrintExplodedTime(&et1);
00747                      printf("\n");
00748                      failed_already=1;
00749                       return 1;
00750                   }
00751                   testParseTimeString(usecs);
00752 
00753                   if (!dstInEffect && et1.tm_params.tp_dst_offset) {
00754                       dstInEffect = 1;
00755                       if (debug_mode) {
00756                          printf("DST changeover from ");
00757                          PrintExplodedTime(&et);
00758                          printf(" to ");
00759                          PrintExplodedTime(&et1);
00760                          printf(".\n");
00761                      }
00762                     } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
00763                       dstInEffect = 0;
00764                      if (debug_mode) {
00765                          printf("DST changeover from ");
00766                          PrintExplodedTime(&et);
00767                          printf(" to ");
00768                          PrintExplodedTime(&et1);
00769                          printf(".\n");
00770                      }
00771                     }
00772 
00773                   et = et1;
00774               }
00775            }
00776         }
00777     }
00778 
00779 #ifdef XP_MAC
00780        if (1)
00781        {
00782               char dummyChar;
00783               
00784               printf("Press return to exit\n\n");
00785               scanf("%c", &dummyChar);
00786        }
00787 #endif
00788 
00789        if (failed_already) return 1;
00790        else return 0;
00791 
00792 }