michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * file: timetest.c michael@0: * description: test time and date routines michael@0: */ michael@0: /*********************************************************************** michael@0: ** Includes michael@0: ***********************************************************************/ michael@0: /* Used to get the command line option */ michael@0: #include "plgetopt.h" michael@0: michael@0: #include "prinit.h" michael@0: #include "prtime.h" michael@0: #include "prprf.h" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: int failed_already=0; michael@0: PRBool debug_mode = PR_FALSE; michael@0: michael@0: static char *dayOfWeek[] = michael@0: { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; michael@0: static char *month[] = michael@0: { "Jan", "Feb", "Mar", "Apr", "May", "Jun", michael@0: "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; michael@0: michael@0: static void PrintExplodedTime(const PRExplodedTime *et) { michael@0: PRInt32 totalOffset; michael@0: PRInt32 hourOffset, minOffset; michael@0: const char *sign; michael@0: michael@0: /* Print day of the week, month, day, hour, minute, and second */ michael@0: if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ", michael@0: dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, michael@0: et->tm_hour, et->tm_min, et->tm_sec); michael@0: michael@0: /* Print time zone */ michael@0: totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; michael@0: if (totalOffset == 0) { michael@0: if (debug_mode) printf("UTC "); michael@0: } else { michael@0: sign = "+"; michael@0: if (totalOffset < 0) { michael@0: totalOffset = -totalOffset; michael@0: sign = "-"; michael@0: } michael@0: hourOffset = totalOffset / 3600; michael@0: minOffset = (totalOffset % 3600) / 60; michael@0: if (debug_mode) michael@0: printf("%s%02ld%02ld ", sign, hourOffset, minOffset); michael@0: } michael@0: michael@0: /* Print year */ michael@0: if (debug_mode) printf("%hd", et->tm_year); michael@0: } michael@0: michael@0: static int ExplodedTimeIsEqual(const PRExplodedTime *et1, michael@0: const PRExplodedTime *et2) michael@0: { michael@0: if (et1->tm_usec == et2->tm_usec && michael@0: et1->tm_sec == et2->tm_sec && michael@0: et1->tm_min == et2->tm_min && michael@0: et1->tm_hour == et2->tm_hour && michael@0: et1->tm_mday == et2->tm_mday && michael@0: et1->tm_month == et2->tm_month && michael@0: et1->tm_year == et2->tm_year && michael@0: et1->tm_wday == et2->tm_wday && michael@0: et1->tm_yday == et2->tm_yday && michael@0: et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset && michael@0: et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) { michael@0: return 1; michael@0: } else { michael@0: return 0; michael@0: } michael@0: } michael@0: michael@0: static void michael@0: testParseTimeString(PRTime t) michael@0: { michael@0: PRExplodedTime et; michael@0: PRTime t2; michael@0: char timeString[128]; michael@0: char buf[128]; michael@0: PRInt32 totalOffset; michael@0: PRInt32 hourOffset, minOffset; michael@0: const char *sign; michael@0: PRInt64 usec_per_sec; michael@0: michael@0: /* Truncate the microsecond part of PRTime */ michael@0: LL_I2L(usec_per_sec, PR_USEC_PER_SEC); michael@0: LL_DIV(t, t, usec_per_sec); michael@0: LL_MUL(t, t, usec_per_sec); michael@0: michael@0: PR_ExplodeTime(t, PR_LocalTimeParameters, &et); michael@0: michael@0: /* Print day of the week, month, day, hour, minute, and second */ michael@0: PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ", michael@0: dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday, michael@0: et.tm_hour, et.tm_min, et.tm_sec); michael@0: /* Print time zone */ michael@0: totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset; michael@0: if (totalOffset == 0) { michael@0: strcat(timeString, "GMT "); /* I wanted to use "UTC" here, but michael@0: * PR_ParseTimeString doesn't michael@0: * understand "UTC". */ michael@0: } else { michael@0: sign = "+"; michael@0: if (totalOffset < 0) { michael@0: totalOffset = -totalOffset; michael@0: sign = "-"; michael@0: } michael@0: hourOffset = totalOffset / 3600; michael@0: minOffset = (totalOffset % 3600) / 60; michael@0: PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset); michael@0: strcat(timeString, buf); michael@0: } michael@0: /* Print year */ michael@0: PR_snprintf(buf, 128, "%hd", et.tm_year); michael@0: strcat(timeString, buf); michael@0: michael@0: if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_ParseTimeString() failed\n"); michael@0: exit(1); michael@0: } michael@0: if (LL_NE(t, t2)) { michael@0: fprintf(stderr, "PR_ParseTimeString() incorrect\n"); michael@0: PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n", michael@0: t, t2, timeString); michael@0: fprintf(stderr, "%s\n", buf); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: int main(int argc, char** argv) michael@0: { michael@0: /* The command line argument: -d is used to determine if the test is being run michael@0: in debug mode. The regress tool requires only one line output:PASS or FAIL. michael@0: All of the printfs associated with this test has been handled with a if (debug_mode) michael@0: test. michael@0: Usage: test_name -d michael@0: */ michael@0: PLOptStatus os; michael@0: PLOptState *opt; michael@0: michael@0: PR_STDIO_INIT(); michael@0: opt = PL_CreateOptState(argc, argv, "d"); michael@0: while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) michael@0: { michael@0: if (PL_OPT_BAD == os) continue; michael@0: switch (opt->option) michael@0: { michael@0: case 'd': /* debug mode */ michael@0: debug_mode = PR_TRUE; michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: } michael@0: PL_DestroyOptState(opt); michael@0: michael@0: /* main test */ michael@0: michael@0: PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); michael@0: michael@0: /* Testing zero PRTime (the epoch) */ michael@0: { michael@0: PRTime t; michael@0: PRExplodedTime et; michael@0: michael@0: LL_I2L(t, 0); michael@0: if (debug_mode) printf("The NSPR epoch is:\n"); michael@0: PR_ExplodeTime(t, PR_LocalTimeParameters, &et); michael@0: PrintExplodedTime(&et); michael@0: if (debug_mode) printf("\n"); michael@0: PR_ExplodeTime(t, PR_GMTParameters, &et); michael@0: PrintExplodedTime(&et); michael@0: if (debug_mode) printf("\n\n"); michael@0: testParseTimeString(t); michael@0: } michael@0: michael@0: /* michael@0: ************************************************************* michael@0: ** michael@0: ** Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime michael@0: ** on the current time michael@0: ** michael@0: ************************************************************* michael@0: */ michael@0: michael@0: { michael@0: PRTime t1, t2; michael@0: PRExplodedTime et; michael@0: michael@0: if (debug_mode) { michael@0: printf("*********************************************\n"); michael@0: printf("** **\n"); michael@0: printf("** Testing PR_Now(), PR_ExplodeTime, and **\n"); michael@0: printf("** PR_ImplodeTime on the current time **\n"); michael@0: printf("** **\n"); michael@0: printf("*********************************************\n\n"); michael@0: } michael@0: t1 = PR_Now(); michael@0: michael@0: /* First try converting to UTC */ michael@0: michael@0: PR_ExplodeTime(t1, PR_GMTParameters, &et); michael@0: if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) { michael@0: if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n"); michael@0: else failed_already=1; michael@0: return 1; michael@0: } michael@0: if (debug_mode) printf("Current UTC is "); michael@0: PrintExplodedTime(&et); michael@0: if (debug_mode) printf("\n"); michael@0: michael@0: t2 = PR_ImplodeTime(&et); michael@0: if (LL_NE(t1, t2)) { michael@0: if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n"); michael@0: else printf("FAIL\n"); michael@0: return 1; michael@0: } michael@0: michael@0: /* Next, try converting to local (US Pacific) time */ michael@0: michael@0: PR_ExplodeTime(t1, PR_LocalTimeParameters, &et); michael@0: if (debug_mode) printf("Current local time is "); michael@0: PrintExplodedTime(&et); michael@0: if (debug_mode) printf("\n"); michael@0: if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n", michael@0: et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset); michael@0: t2 = PR_ImplodeTime(&et); michael@0: if (LL_NE(t1, t2)) { michael@0: if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n"); michael@0: return 1; michael@0: } michael@0: michael@0: if (debug_mode) printf("Please examine the results\n"); michael@0: testParseTimeString(t1); michael@0: } michael@0: michael@0: michael@0: /* michael@0: ******************************************* michael@0: ** michael@0: ** Testing PR_NormalizeTime() michael@0: ** michael@0: ******************************************* michael@0: */ michael@0: michael@0: /* July 4, 2001 is Wednesday */ michael@0: { michael@0: PRExplodedTime et; michael@0: michael@0: if (debug_mode) { michael@0: printf("\n"); michael@0: printf("**********************************\n"); michael@0: printf("** **\n"); michael@0: printf("** Testing PR_NormalizeTime() **\n"); michael@0: printf("** **\n"); michael@0: printf("**********************************\n\n"); michael@0: } michael@0: et.tm_year = 2001; michael@0: et.tm_month = 7 - 1; michael@0: et.tm_mday = 4; michael@0: et.tm_hour = 0; michael@0: et.tm_min = 0; michael@0: et.tm_sec = 0; michael@0: et.tm_usec = 0; michael@0: et.tm_params = PR_GMTParameters(&et); michael@0: michael@0: PR_NormalizeTime(&et, PR_GMTParameters); michael@0: michael@0: if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]); michael@0: if (et.tm_wday == 3) { michael@0: if (debug_mode) printf("PASS\n"); michael@0: } else { michael@0: if (debug_mode) printf("ERROR: It should be Wednesday\n"); michael@0: else failed_already=1; michael@0: return 1; michael@0: } michael@0: testParseTimeString(PR_ImplodeTime(&et)); michael@0: michael@0: /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */ michael@0: et.tm_year = 1997; michael@0: et.tm_month = 6 - 1; michael@0: et.tm_mday = 12; michael@0: et.tm_hour = 23; michael@0: et.tm_min = 0; michael@0: et.tm_sec = 0; michael@0: et.tm_usec = 0; michael@0: et.tm_params.tp_gmt_offset = -8 * 3600; michael@0: et.tm_params.tp_dst_offset = 0; michael@0: michael@0: PR_NormalizeTime(&et, PR_USPacificTimeParameters); michael@0: michael@0: if (debug_mode) { michael@0: printf("Thu Jun 12, 1997 23:00:00 PST is "); michael@0: } michael@0: PrintExplodedTime(&et); michael@0: if (debug_mode) printf(".\n"); michael@0: if (et.tm_wday == 5) { michael@0: if (debug_mode) printf("PASS\n"); michael@0: } else { michael@0: if (debug_mode) printf("ERROR: It should be Friday\n"); michael@0: else failed_already=1; michael@0: return 1; michael@0: } michael@0: testParseTimeString(PR_ImplodeTime(&et)); michael@0: michael@0: /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */ michael@0: et.tm_year = 1997; michael@0: et.tm_month = 2 - 1; michael@0: et.tm_mday = 14; michael@0: et.tm_hour = 0; michael@0: et.tm_min = 0; michael@0: et.tm_sec = 0; michael@0: et.tm_usec = 0; michael@0: et.tm_params.tp_gmt_offset = -8 * 3600; michael@0: et.tm_params.tp_dst_offset = 3600; michael@0: michael@0: PR_NormalizeTime(&et, PR_USPacificTimeParameters); michael@0: michael@0: if (debug_mode) { michael@0: printf("Fri Feb 14, 1997 00:00:00 PDT is "); michael@0: } michael@0: PrintExplodedTime(&et); michael@0: if (debug_mode) printf(".\n"); michael@0: if (et.tm_wday == 4) { michael@0: if (debug_mode) printf("PASS\n"); michael@0: } else { michael@0: if (debug_mode) printf("ERROR: It should be Thursday\n"); michael@0: else failed_already=1; michael@0: return 1; michael@0: } michael@0: testParseTimeString(PR_ImplodeTime(&et)); michael@0: michael@0: /* What time is Nov. 7, 1996, 18:29:23 PDT? */ michael@0: et.tm_year = 1996; michael@0: et.tm_month = 11 - 1; michael@0: et.tm_mday = 7; michael@0: et.tm_hour = 18; michael@0: et.tm_min = 29; michael@0: et.tm_sec = 23; michael@0: et.tm_usec = 0; michael@0: et.tm_params.tp_gmt_offset = -8 * 3600; /* PDT */ michael@0: et.tm_params.tp_dst_offset = 3600; michael@0: michael@0: PR_NormalizeTime(&et, PR_LocalTimeParameters); michael@0: if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is "); michael@0: PrintExplodedTime(&et); michael@0: if (debug_mode) printf(".\n"); michael@0: testParseTimeString(PR_ImplodeTime(&et)); michael@0: michael@0: /* What time is Oct. 7, 1995, 18:29:23 PST? */ michael@0: et.tm_year = 1995; michael@0: et.tm_month = 10 - 1; michael@0: et.tm_mday = 7; michael@0: et.tm_hour = 18; michael@0: et.tm_min = 29; michael@0: et.tm_sec = 23; michael@0: et.tm_params.tp_gmt_offset = -8 * 3600; /* PST */ michael@0: et.tm_params.tp_dst_offset = 0; michael@0: michael@0: PR_NormalizeTime(&et, PR_LocalTimeParameters); michael@0: if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is "); michael@0: PrintExplodedTime(&et); michael@0: if (debug_mode) printf(".\n"); michael@0: testParseTimeString(PR_ImplodeTime(&et)); michael@0: michael@0: if (debug_mode) printf("Please examine the results\n"); michael@0: } michael@0: michael@0: /* michael@0: ************************************************************** michael@0: ** michael@0: ** Testing range of years michael@0: ** michael@0: ************************************************************** michael@0: */ michael@0: michael@0: { michael@0: PRExplodedTime et1, et2; michael@0: PRTime ttt; michael@0: PRTime secs; michael@0: michael@0: if (debug_mode) { michael@0: printf("\n"); michael@0: printf("***************************************\n"); michael@0: printf("** **\n"); michael@0: printf("** Testing range of years **\n"); michael@0: printf("** **\n"); michael@0: printf("***************************************\n\n"); michael@0: } michael@0: /* April 4, 1917 GMT */ michael@0: et1.tm_usec = 0; michael@0: et1.tm_sec = 0; michael@0: et1.tm_min = 0; michael@0: et1.tm_hour = 0; michael@0: et1.tm_mday = 4; michael@0: et1.tm_month = 4 - 1; michael@0: et1.tm_year = 1917; michael@0: et1.tm_params = PR_GMTParameters(&et1); michael@0: PR_NormalizeTime(&et1, PR_LocalTimeParameters); michael@0: secs = PR_ImplodeTime(&et1); michael@0: if (LL_GE_ZERO(secs)) { michael@0: if (debug_mode) michael@0: printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n"); michael@0: failed_already = 1; michael@0: return 1; michael@0: } michael@0: PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2); michael@0: if (!ExplodedTimeIsEqual(&et1, &et2)) { michael@0: if (debug_mode) michael@0: printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n"); michael@0: failed_already=1; michael@0: return 1; michael@0: } michael@0: ttt = PR_ImplodeTime(&et1); michael@0: testParseTimeString( ttt ); michael@0: michael@0: if (debug_mode) printf("Test passed for April 4, 1917\n"); michael@0: michael@0: /* July 4, 2050 */ michael@0: et1.tm_usec = 0; michael@0: et1.tm_sec = 0; michael@0: et1.tm_min = 0; michael@0: et1.tm_hour = 0; michael@0: et1.tm_mday = 4; michael@0: et1.tm_month = 7 - 1; michael@0: et1.tm_year = 2050; michael@0: et1.tm_params = PR_GMTParameters(&et1); michael@0: PR_NormalizeTime(&et1, PR_LocalTimeParameters); michael@0: secs = PR_ImplodeTime(&et1); michael@0: if (!LL_GE_ZERO(secs)) { michael@0: if (debug_mode) michael@0: printf("ERROR: July 4, 2050 GMT returns a negative second count\n"); michael@0: failed_already = 1; michael@0: return 1; michael@0: } michael@0: PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2); michael@0: if (!ExplodedTimeIsEqual(&et1, &et2)) { michael@0: if (debug_mode) michael@0: printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n"); michael@0: failed_already=1; michael@0: return 1; michael@0: } michael@0: testParseTimeString(PR_ImplodeTime(&et1)); michael@0: michael@0: if (debug_mode) printf("Test passed for July 4, 2050\n"); michael@0: michael@0: } michael@0: michael@0: /* michael@0: ************************************************************** michael@0: ** michael@0: ** Stress test michael@0: * michael@0: ** Go through four years, starting from michael@0: ** 00:00:00 PST Jan. 1, 2005, incrementing michael@0: ** every 10 minutes. michael@0: ** michael@0: ************************************************************** michael@0: */ michael@0: michael@0: { michael@0: PRExplodedTime et, et1, et2; michael@0: PRInt64 usecPer10Min; michael@0: int day, hour, min; michael@0: PRTime usecs; michael@0: int dstInEffect = 0; michael@0: michael@0: if (debug_mode) { michael@0: printf("\n"); michael@0: printf("*******************************************************\n"); michael@0: printf("** **\n"); michael@0: printf("** Stress test Pacific Time **\n"); michael@0: printf("** Starting from midnight Jan. 1, 2005 PST, **\n"); michael@0: printf("** going through four years in 10-minute increment **\n"); michael@0: printf("** **\n"); michael@0: printf("*******************************************************\n\n"); michael@0: } michael@0: LL_I2L(usecPer10Min, 600000000L); michael@0: michael@0: /* 00:00:00 PST Jan. 1, 2005 */ michael@0: et.tm_usec = 0; michael@0: et.tm_sec = 0; michael@0: et.tm_min = 0; michael@0: et.tm_hour = 0; michael@0: et.tm_mday = 1; michael@0: et.tm_month = 0; michael@0: et.tm_year = 2005; michael@0: et.tm_params.tp_gmt_offset = -8 * 3600; michael@0: et.tm_params.tp_dst_offset = 0; michael@0: usecs = PR_ImplodeTime(&et); michael@0: michael@0: for (day = 0; day < 4 * 365 + 1; day++) { michael@0: for (hour = 0; hour < 24; hour++) { michael@0: for (min = 0; min < 60; min += 10) { michael@0: LL_ADD(usecs, usecs, usecPer10Min); michael@0: PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1); michael@0: michael@0: et2 = et; michael@0: et2.tm_usec += 600000000L; michael@0: PR_NormalizeTime(&et2, PR_USPacificTimeParameters); michael@0: michael@0: if (!ExplodedTimeIsEqual(&et1, &et2)) { michael@0: printf("ERROR: componentwise comparison failed\n"); michael@0: PrintExplodedTime(&et1); michael@0: printf("\n"); michael@0: PrintExplodedTime(&et2); michael@0: printf("\n"); michael@0: failed_already=1; michael@0: return 1; michael@0: } michael@0: michael@0: if (LL_NE(usecs, PR_ImplodeTime(&et1))) { michael@0: printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); michael@0: PrintExplodedTime(&et1); michael@0: printf("\n"); michael@0: failed_already=1; michael@0: return 1; michael@0: } michael@0: testParseTimeString(usecs); michael@0: michael@0: if (!dstInEffect && et1.tm_params.tp_dst_offset) { michael@0: dstInEffect = 1; michael@0: if (debug_mode) { michael@0: printf("DST changeover from "); michael@0: PrintExplodedTime(&et); michael@0: printf(" to "); michael@0: PrintExplodedTime(&et1); michael@0: printf(".\n"); michael@0: } michael@0: } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { michael@0: dstInEffect = 0; michael@0: if (debug_mode) { michael@0: printf("DST changeover from "); michael@0: PrintExplodedTime(&et); michael@0: printf(" to "); michael@0: PrintExplodedTime(&et1); michael@0: printf(".\n"); michael@0: } michael@0: } michael@0: michael@0: et = et1; michael@0: } michael@0: } michael@0: } michael@0: if (debug_mode) printf("Test passed\n"); michael@0: } michael@0: michael@0: michael@0: /* Same stress test, but with PR_LocalTimeParameters */ michael@0: michael@0: { michael@0: PRExplodedTime et, et1, et2; michael@0: PRInt64 usecPer10Min; michael@0: int day, hour, min; michael@0: PRTime usecs; michael@0: int dstInEffect = 0; michael@0: michael@0: if (debug_mode) { michael@0: printf("\n"); michael@0: printf("*******************************************************\n"); michael@0: printf("** **\n"); michael@0: printf("** Stress test Local Time **\n"); michael@0: printf("** Starting from midnight Jan. 1, 2005 PST, **\n"); michael@0: printf("** going through four years in 10-minute increment **\n"); michael@0: printf("** **\n"); michael@0: printf("*******************************************************\n\n"); michael@0: } michael@0: michael@0: LL_I2L(usecPer10Min, 600000000L); michael@0: michael@0: /* 00:00:00 PST Jan. 1, 2005 */ michael@0: et.tm_usec = 0; michael@0: et.tm_sec = 0; michael@0: et.tm_min = 0; michael@0: et.tm_hour = 0; michael@0: et.tm_mday = 1; michael@0: et.tm_month = 0; michael@0: et.tm_year = 2005; michael@0: et.tm_params.tp_gmt_offset = -8 * 3600; michael@0: et.tm_params.tp_dst_offset = 0; michael@0: usecs = PR_ImplodeTime(&et); michael@0: michael@0: for (day = 0; day < 4 * 365 + 1; day++) { michael@0: for (hour = 0; hour < 24; hour++) { michael@0: for (min = 0; min < 60; min += 10) { michael@0: LL_ADD(usecs, usecs, usecPer10Min); michael@0: PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1); michael@0: michael@0: et2 = et; michael@0: et2.tm_usec += 600000000L; michael@0: PR_NormalizeTime(&et2, PR_LocalTimeParameters); michael@0: michael@0: if (!ExplodedTimeIsEqual(&et1, &et2)) { michael@0: printf("ERROR: componentwise comparison failed\n"); michael@0: PrintExplodedTime(&et1); michael@0: printf("\n"); michael@0: PrintExplodedTime(&et2); michael@0: printf("\n"); michael@0: return 1; michael@0: } michael@0: michael@0: if (LL_NE(usecs, PR_ImplodeTime(&et1))) { michael@0: printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); michael@0: PrintExplodedTime(&et1); michael@0: printf("\n"); michael@0: failed_already=1; michael@0: return 1; michael@0: } michael@0: testParseTimeString(usecs); michael@0: michael@0: if (!dstInEffect && et1.tm_params.tp_dst_offset) { michael@0: dstInEffect = 1; michael@0: if (debug_mode) { michael@0: printf("DST changeover from "); michael@0: PrintExplodedTime(&et); michael@0: printf(" to "); michael@0: PrintExplodedTime(&et1); michael@0: printf(".\n"); michael@0: } michael@0: } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { michael@0: dstInEffect = 0; michael@0: if (debug_mode) { michael@0: printf("DST changeover from "); michael@0: PrintExplodedTime(&et); michael@0: printf(" to "); michael@0: PrintExplodedTime(&et1); michael@0: printf(".\n"); michael@0: } michael@0: } michael@0: michael@0: et = et1; michael@0: } michael@0: } michael@0: } michael@0: if (debug_mode) printf("Test passed\n"); michael@0: } michael@0: michael@0: /* Same stress test, but with PR_LocalTimeParameters and going backward */ michael@0: michael@0: { michael@0: PRExplodedTime et, et1, et2; michael@0: PRInt64 usecPer10Min; michael@0: int day, hour, min; michael@0: PRTime usecs; michael@0: int dstInEffect = 0; michael@0: michael@0: if (debug_mode) { michael@0: printf("\n"); michael@0: printf("*******************************************************\n"); michael@0: printf("** **\n"); michael@0: printf("** Stress test Local Time **\n"); michael@0: printf("** Starting from midnight Jan. 1, 2009 PST, **\n"); michael@0: printf("** going back four years in 10-minute increment **\n"); michael@0: printf("** **\n"); michael@0: printf("*******************************************************\n\n"); michael@0: } michael@0: michael@0: LL_I2L(usecPer10Min, 600000000L); michael@0: michael@0: /* 00:00:00 PST Jan. 1, 2009 */ michael@0: et.tm_usec = 0; michael@0: et.tm_sec = 0; michael@0: et.tm_min = 0; michael@0: et.tm_hour = 0; michael@0: et.tm_mday = 1; michael@0: et.tm_month = 0; michael@0: et.tm_year = 2009; michael@0: et.tm_params.tp_gmt_offset = -8 * 3600; michael@0: et.tm_params.tp_dst_offset = 0; michael@0: usecs = PR_ImplodeTime(&et); michael@0: michael@0: for (day = 0; day < 4 * 365 + 1; day++) { michael@0: for (hour = 0; hour < 24; hour++) { michael@0: for (min = 0; min < 60; min += 10) { michael@0: LL_SUB(usecs, usecs, usecPer10Min); michael@0: PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1); michael@0: michael@0: et2 = et; michael@0: et2.tm_usec -= 600000000L; michael@0: PR_NormalizeTime(&et2, PR_LocalTimeParameters); michael@0: michael@0: if (!ExplodedTimeIsEqual(&et1, &et2)) { michael@0: printf("ERROR: componentwise comparison failed\n"); michael@0: PrintExplodedTime(&et1); michael@0: printf("\n"); michael@0: PrintExplodedTime(&et2); michael@0: printf("\n"); michael@0: return 1; michael@0: } michael@0: michael@0: if (LL_NE(usecs, PR_ImplodeTime(&et1))) { michael@0: printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); michael@0: PrintExplodedTime(&et1); michael@0: printf("\n"); michael@0: failed_already=1; michael@0: return 1; michael@0: } michael@0: testParseTimeString(usecs); michael@0: michael@0: if (!dstInEffect && et1.tm_params.tp_dst_offset) { michael@0: dstInEffect = 1; michael@0: if (debug_mode) { michael@0: printf("DST changeover from "); michael@0: PrintExplodedTime(&et); michael@0: printf(" to "); michael@0: PrintExplodedTime(&et1); michael@0: printf(".\n"); michael@0: } michael@0: } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { michael@0: dstInEffect = 0; michael@0: if (debug_mode) { michael@0: printf("DST changeover from "); michael@0: PrintExplodedTime(&et); michael@0: printf(" to "); michael@0: PrintExplodedTime(&et1); michael@0: printf(".\n"); michael@0: } michael@0: } michael@0: michael@0: et = et1; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (failed_already) return 1; michael@0: else return 0; michael@0: michael@0: }