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