46 #define MJD_1970    40587 
   55     setenv( 
"TZ", 
"", 1 );
 
   59         setenv( 
"TZ", tz, 1 );
 
   66 int testlib_broken_down_time( 
int year, 
int month, 
int day, 
int hour, 
int min, 
double sec, 
int forceJulian, 
int inner_test_choice, 
int verbose )
 
   69     int       year1, month1, day1, hour1, min1;
 
   74     struct tm *ptm1 = &tm1;
 
   75     time_t    secs_past_epoch, secs_past_epoch1, delta_secs;
 
   79     int       ifleapyear, ifleapday, iffeb29, ifsamedate, ifsametime;
 
   80     ptm->tm_year = year - 1900;
 
   85     ptm->tm_sec  = (int) sec;
 
   90             printf( 
"Start of Julian proleptic inner test\n" );
 
   91             printf( 
"input and output (strfMJD) date/time\n" );
 
   95             printf( 
"Start of Gregorian proleptic inner test\n" );
 
   96             printf( 
"input and output (strftime), and output (strfMJD) date/time\n" );
 
   98         printf( 
"%.4d-%02d-%02dT%02d:%02d:%018.15fZ\n", year, month + 1, day, hour, min, sec );
 
  101     setFromUT( year, month, day, hour, min, sec, pMJD1, forceJulian );
 
  104     if ( !forceJulian && ( inner_test_choice & 
TEST01 ) )
 
  108         delta_secs       = abs( secs_past_epoch1 - secs_past_epoch );
 
  109         if ( delta_secs != 0 )
 
  111             printf( 
"setFromUT secs_past_epoch = %lld seconds\n", (
long long) secs_past_epoch1 );
 
  112             printf( 
"my_timegm secs_past_epoch = %lld seconds\n", (
long long) secs_past_epoch );
 
  113             printf( 
"delta secs_past_epoch = %lld seconds\n", (
long long) ( secs_past_epoch1 - secs_past_epoch ) );
 
  114             printf( 
"test failed with inconsistency between setFromUT and my_timegm\n" );
 
  121     if ( inner_test_choice & 
TEST02 )
 
  125             strftime( &( buf[0] ), 360, 
"%Y-%m-%dT%H:%M:%SZ\n", ptm );
 
  129         strfMJD( &( buf[0] ), 360, 
"%Y-%m-%dT%H:%M:%S%.Z\n", pMJD1, forceJulian, 0 );
 
  137         printf( 
"setFromUT JD = %25.16f days\n", jd );
 
  141         ifleapyear = ( year % 4 == 0 );
 
  143         ifleapyear = ( ( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 );
 
  144     iffeb29   = month == 1 && day == 29;
 
  145     ifleapday = ( ifleapyear && iffeb29 );
 
  148     if ( inner_test_choice & 
TEST03 )
 
  150         breakDownMJD( &year1, &month1, &day1, &hour1, &min1, &sec1, pMJD1, forceJulian );
 
  151         ifsamedate = ( year1 - year == 0 && ( ( ( !iffeb29 || ifleapday ) && ( month1 - month == 0 && day1 - day == 0 ) ) || ( ( iffeb29 && !ifleapday ) && ( month1 == 2 && day1 == 1 ) ) ) );
 
  152         ifsametime = ( hour1 - hour == 0 && min1 - min == 0 && fabs( sec1 - sec ) < 1.e-10 );
 
  154         if ( !( ifsamedate && ifsametime ) )
 
  156             printf( 
"output date calculated with breakDownMJD = %d-%02d-%02dT%02d:%02d:%018.15fZ\n", year1, month1 + 1, day1, hour1, min1, sec1 );
 
  157             printf( 
"test failed with inconsistency between setFromUT and breakDownMJD\n" );
 
  163     if ( !forceJulian && ( inner_test_choice & 
TEST04 ) )
 
  165         ptm1       = gmtime( &secs_past_epoch );
 
  166         ifsamedate = ( ptm1->tm_year == ptm->tm_year && ( ( ( !iffeb29 || ifleapday ) && ( ptm1->tm_mon == ptm->tm_mon && ptm1->tm_mday == ptm->tm_mday ) ) || ( ( iffeb29 && !ifleapday ) && ( ptm1->tm_mon == 2 && ptm1->tm_mday == 1 ) ) ) );
 
  167         ifsametime = ( ptm1->tm_hour == ptm->tm_hour && ptm1->tm_min == ptm->tm_min && ptm1->tm_sec == ptm->tm_sec );
 
  169         if ( !( ifsamedate && ifsametime ) )
 
  171             printf( 
"test failed with inconsistency between my_timegm and its C library inverse gmtime" );
 
  180     int       year, month, day, hour, 
min;
 
  183     int       year1, month1, day1, hour1, min1;
 
  186     struct tm *ptm = &tm;
 
  188     struct tm *ptm1 = &tm1;
 
  189     time_t    secs_past_epoch, secs_past_epoch1;
 
  191     MJDtime   MJD1_value, *MJD1 = &MJD1_value;
 
  192     MJDtime   MJD2_value, *MJD2 = &MJD2_value;
 
  194     int       ifleapyear, ifleapday, iffeb29, ifsamedate, ifsametime;
 
  199     breakDownMJD( &year, &month, &day, &hour, &min, &sec, MJD1, forceJulian );
 
  201     ptm->tm_year = year - 1900;
 
  206     ptm->tm_sec  = (int) sec;
 
  211             printf( 
"Start of Julian proleptic inner test\n" );
 
  212             printf( 
"input and output (strfMJD) date/time\n" );
 
  216             printf( 
"Start of Gregorian proleptic inner test\n" );
 
  217             printf( 
"input and output (strftime), and output (strfMJD) date/time\n" );
 
  219         printf( 
"%.4d-%02d-%02dT%02d:%02d:%018.15fZ\n", year, month + 1, day, hour, min, sec );
 
  223     if ( !forceJulian && ( inner_test_choice & 
TEST01 ) )
 
  225         ptm1 = gmtime( &secs_past_epoch );
 
  226         if ( !( ( ptm1->tm_year + 1900 ) == year && ptm1->tm_mon == month && ptm1->tm_mday == day && ptm1->tm_hour == hour && ptm1->tm_min == min && ptm1->tm_sec == (
int) sec ) )
 
  228             printf( 
"date calculated with breakDownMJD = %d-%02d-%02dT%02d:%02d:%018.15fZ\n", year, month + 1, day, hour, min, sec );
 
  229             printf( 
"date calculated with gmtime = %d-%02d-%02dT%02d:%02d:%02dZ\n", ptm1->tm_year + 1900, ptm1->tm_mon + 1, ptm1->tm_mday, ptm1->tm_hour, ptm1->tm_min, ptm1->tm_sec );
 
  230             printf( 
"test failed with inconsistency between breakDownMJD and gmtime\n" );
 
  237     if ( inner_test_choice & 
TEST02 )
 
  241             strftime( &( buf[0] ), 360, 
"%Y-%m-%dT%H:%M:%SZ\n", ptm );
 
  245         strfMJD( &( buf[0] ), 360, 
"%Y-%m-%dT%H:%M:%S%.Z\n", MJD1, forceJulian, 0 );
 
  253         printf( 
"JD = %25.16f days\n", jd );
 
  257         ifleapyear = ( year % 4 == 0 );
 
  259         ifleapyear = ( ( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 );
 
  260     iffeb29   = month == 1 && day == 29;
 
  261     ifleapday = ( ifleapyear && iffeb29 );
 
  264     if ( inner_test_choice & 
TEST03 )
 
  266         setFromUT( year, month, day, hour, min, sec, MJD2, forceJulian );
 
  269             printf( 
"(normalized) input MJD components are = %d, %f\n", MJD1->
base_day, MJD1->
time_sec );
 
  270             printf( 
"(output MJD2 components generated by setFromUT are = %d, %f\n", MJD2->
base_day, MJD2->
time_sec );
 
  271             printf( 
"test failed with inconsistency between breakDownMJD and setFromUT\n" );
 
  277     if ( !forceJulian && ( inner_test_choice & 
TEST04 ) )
 
  280         if ( !( secs_past_epoch == secs_past_epoch1 ) )
 
  282             printf( 
"secs_past_epoch calculated from input = %lld\n", (
long long) secs_past_epoch );
 
  283             printf( 
"secs_past_epoch calculated from my_timegm = %lld\n", (
long long) secs_past_epoch1 );
 
  284             printf( 
"delta secs_past_epoch = %lld seconds\n", (
long long) ( secs_past_epoch1 - secs_past_epoch ) );
 
  285             printf( 
"test failed with inconsistency between breakDownMJD and its C library based inverse, my_timegm\n" );
 
  300     int       year, month, day, hour, 
min;
 
  302     int       year1, month1, day1, hour1, min1;
 
  305     struct tm *ptm = &tm;
 
  307     struct tm *ptm1 = &tm1;
 
  310     MJDtime   MJD1_value, *MJD1 = &MJD1_value;
 
  312     int       test_choice, date_choice, ret;
 
  316     scanf( 
"%i", &test_choice );
 
  318     printf( 
"sizeof(time_t) = %d\n", (
int) 
sizeof ( time_t ) );
 
  319     if ( 
sizeof ( time_t ) < 8 )
 
  321         printf( 
"tests abandoned because time_t is too small on this platform to represent the extremely large date range used for many of these tests.  Note, the limitation is in the C library routines (gmtime and mktime) used for these test comparisons and not libqsastime itself.\n" );
 
  325     printf( 
"sizeof(int) = %d\n", (
int) 
sizeof ( 
int ) );
 
  326     if ( 
sizeof ( 
int ) != 4 )
 
  328         printf( 
"tests abandoned because int must be 32-bits to test this library properly for how well it will potentially perform on 32-bit platforms\n" );
 
  332     setenv( 
"TZ", 
"", 1 );
 
  335     if ( test_choice & 
TEST01 )
 
  337         printf( 
"Test 01 of calendar dates in the vicinity of the JD epoch \n" );
 
  339         for ( date_choice = 0; date_choice < 5; date_choice++ )
 
  341             if ( date_choice == 0 )
 
  346             else if ( date_choice == 1 )
 
  351             else if ( date_choice == 2 )
 
  356             else if ( date_choice == 3 )
 
  361             else if ( date_choice == 4 )
 
  370             for ( year = -4717; year <= -4707; year++ )
 
  383     if ( test_choice & 
TEST02 )
 
  385         printf( 
"Test 02 of calendar dates in the vicinity of the year epoch. \n" );
 
  387         for ( date_choice = 0; date_choice < 5; date_choice++ )
 
  389             if ( date_choice == 0 )
 
  394             else if ( date_choice == 1 )
 
  399             else if ( date_choice == 2 )
 
  404             else if ( date_choice == 3 )
 
  409             else if ( date_choice == 4 )
 
  418             for ( year = -5; year <= 5; year++ )
 
  431     if ( test_choice & 
TEST03 )
 
  433         printf( 
"Test 03 of calendar dates in the vicinity of the MJD epoch. \n" );
 
  435         for ( date_choice = 0; date_choice < 6; date_choice++ )
 
  437             if ( date_choice == 0 )
 
  442             else if ( date_choice == 1 )
 
  447             else if ( date_choice == 2 )
 
  452             else if ( date_choice == 3 )
 
  457             else if ( date_choice == 4 )
 
  462             else if ( date_choice == 5 )
 
  471             for ( year = 1853; year <= 1863; year++ )
 
  484     if ( test_choice & 
TEST04 )
 
  486         printf( 
"Test 04 of small second range near Year 0 (Julian)\n" );
 
  488         ret = 
setFromUT( 0, 0, 1, 0, 0, 0., MJD1, 1 );
 
  491             printf( 
"Test 04 cannot even start for Year 0 (Julian)" );
 
  495         for ( seconds = -5; seconds < 5; seconds++ )
 
  504         printf( 
"Test 04 of small second range near Year 0 (Gregorian)\n" );
 
  507         ret = 
setFromUT( 0, 0, 1, 0, 0, 0., MJD1, 0 );
 
  510             printf( 
"Test 04 cannot even start for Year 0 (Gregorian)" );
 
  514         for ( seconds = -5; seconds < 5; seconds++ )
 
  523         printf( 
"Test 04 of small second range near 2009-01-01 (Gregorian) when a leap second was inserted\n" );
 
  526         ret = 
setFromUT( 2009, 0, 1, 0, 0, 0.1234567890123456 - 5., MJD1, 0 );
 
  529             printf( 
"Test 04 cannot even start for Year 0 (Gregorian)" );
 
  533         for ( seconds = -5; seconds < 5; seconds++ )
 
  543     if ( test_choice & 
TEST05 )
 
  545         printf( 
"Test 05 of normalization of breakDownMJD result and strfMJD results near the hour.\n" );
 
  549         for ( iepsilon = -1; iepsilon < 2; iepsilon++ )
 
  551             MJD1->
time_sec = 3600. + 1.e-8 * (double) iepsilon;
 
  552             breakDownMJD( &year, &month, &day, &hour, &min, &sec, MJD1, 0 );
 
  554             printf( 
"breakDownMJD result is year, month, day, hour, min, sec = %d, %d, %d, %d, %d, %20.15f\n", year, month, day, hour, min, sec );
 
  555             strfMJD( &( buf[0] ), 360, 
"%Y-%m-%dT%H:%M:%S%9Z\n", MJD1, 0, 0 );
 
  556             printf( 
"strfMJD %%S%%9 result is %s", buf );
 
  557             strfMJD( &( buf[0] ), 360, 
"%Y-%m-%dT%H:%M:%S%.Z\n", MJD1, 0, 0 );
 
  558             printf( 
"strfMJD %%S%%. result is %s", buf );
 
  559             strfMJD( &( buf[0] ), 360, 
"%H:%M:%S, %H:%M:%S%0, %H:%M:%S%1, %H:%M:%S%2, %H:%M:%S%3, %H:%M:%S%4\n          %H:%M:%S %0,%H:%M:%S %1,%H:%M:%S %2,%H:%M:%S %3,%H:%M:%S %4\n", MJD1, 0, 0 );
 
  560             printf( 
"strfMJD more heavily rounded results (the latter ones with a blank before the\ndecimal point to prove separated formatting works) for H:M:S are the following:\n%s", buf );
 
  564     if ( test_choice & 
TEST06 )
 
  566         printf( 
"Test 06 (non-verbose) of calendar dates for every year from -5000000 to 5000000\n" );
 
  568         for ( date_choice = 0; date_choice < 5; date_choice++ )
 
  570             if ( date_choice == 0 )
 
  575             else if ( date_choice == 1 )
 
  580             else if ( date_choice == 2 )
 
  585             else if ( date_choice == 3 )
 
  590             else if ( date_choice == 4 )
 
  601             for ( year = -5000000; year <= 5000000; year += 1 )
 
  613     if ( test_choice & 
TEST07 )
 
  615         printf( 
"Test 07 (non-verbose) of all seconds from late 2007 to early 2009\n" );
 
  616         ret = 
setFromUT( 2007, 11, 30, 0, 0, 0., MJD1, 0 );
 
  619             printf( 
"Test 06 cannot even start" );
 
  624         for ( seconds = 0; seconds < 430 * 86400; seconds++ )
 
size_t strfMJD(char *buf, size_t len, const char *format, const MJDtime *MJD, int forceJulian, int inleap)
 
int setFromUT(int year, int month, int day, int hour, int min, double sec, MJDtime *MJD, int forceJulian)
 
time_t my_timegm(struct tm *tm)
 
int testlib_MJD(const MJDtime *MJD, int forceJulian, int inner_test_choice, int verbose)
 
int testlib_broken_down_time(int year, int month, int day, int hour, int min, double sec, int forceJulian, int inner_test_choice, int verbose)
 
void normalize_MJD(MJDtime *MJD)
 
void breakDownMJD(int *year, int *month, int *day, int *hour, int *min, double *sec, const MJDtime *MJD, int forceJulian)