GnuCash 2.4.99
test-date.c
00001 /*
00002  * -- fix borken timezone test -- linas May 2004
00003  */
00004 
00005 #include "config.h"
00006 #include <ctype.h>
00007 #include <glib.h>
00008 #include <time.h>
00009 
00010 #include "gnc-date.h"
00011 #include "gnc-module.h"
00012 #include "test-stuff.h"
00013 #include "test-engine-stuff.h"
00014 
00015 
00016 static gboolean
00017 check_time (Timespec ts, gboolean always_print)
00018 {
00019     Timespec ts_2;
00020     char str[128];
00021     gboolean ok;
00022 
00023     ts.tv_nsec = MIN (ts.tv_nsec, 999999999);
00024     ts.tv_nsec /= 1000;
00025     ts.tv_nsec *= 1000;
00026 
00027     /* We just can't handle dates whose time_t doesn't fit in int - skip those
00028      * cases. */
00029     if (ts.tv_sec > (0x7fffffff - 3600 * 25))
00030         return TRUE;
00031 
00032     /* If we are east of UTC, we also can't handle dates whose tv_sec member
00033      * falls in the range [0, -gnc_timezone(tm)) - make sure were are at least 12
00034      * hours past the epoch to skip those cases too */
00035     if (ts.tv_sec < 3600 * 12)
00036         return TRUE;
00037 
00038     gnc_timespec_to_iso8601_buff (ts, str);
00039 
00040     /* The time, in seconds, everywhere on the planet, is always
00041      * the same, and is independent of location.  In particular,
00042      * the time, in seconds, is identical to the local time in
00043      * Greenwich (GMT).
00044      */
00045     ts_2 = gnc_iso8601_to_timespec_gmt (str);
00046 
00047     ok = timespec_equal (&ts, &ts_2);
00048 
00049     if (!ok || always_print)
00050     {
00051         fprintf (stderr,
00052                  "\n%" G_GINT64_FORMAT ":%ld -> %s ->\n"
00053                  "\t%" G_GINT64_FORMAT ":%ld"
00054                  " (diff of %" G_GINT64_FORMAT " secs %ld nsecs)\n",
00055                  ts.tv_sec, ts.tv_nsec, str,
00056                  ts_2.tv_sec, ts_2.tv_nsec,
00057                  ts.tv_sec - ts_2.tv_sec, ts.tv_nsec - ts_2.tv_nsec);
00058 
00059         if (!ok)
00060         {
00061             failure ("timespec to iso8601 string conversion failed");
00062             return FALSE;
00063         }
00064     }
00065 
00066     success ("timespec to iso8601 string conversion passes");
00067 
00068     return TRUE;
00069 }
00070 
00071 static gboolean
00072 check_conversion (const char * str, Timespec expected_ts)
00073 {
00074     Timespec ts;
00075     int day, month, year;
00076     GDate d1, d2;
00077 
00078     ts = gnc_iso8601_to_timespec_gmt (str);
00079 
00080     // We test the conversion to GDate against the timespec2dmy
00081     // conversion, and also the conversion back to timespec and again
00082     // to GDate so that it is still the original GDate
00083     gnc_timespec2dmy(ts, &day, &month, &year);
00084     d1 = timespec_to_gdate(ts);
00085     d2 = timespec_to_gdate(gdate_to_timespec(d1));
00086     if ((g_date_compare(&d1, &d2) != 0)
00087             || (g_date_get_day(&d1) != day)
00088             || (g_date_get_month(&d1) != month)
00089             || (g_date_get_year(&d1) != year))
00090     {
00091         fprintf (stderr,
00092                  "\nmis-converted \"%s\" to GDate\n",
00093                  str);
00094         failure ("misconverted timespec");
00095         return FALSE;
00096     }
00097 
00098     if ((expected_ts.tv_sec != ts.tv_sec) || (expected_ts.tv_nsec != ts.tv_nsec))
00099     {
00100         fprintf (stderr,
00101                  "\nmis-converted \"%s\" to %" G_GUINT64_FORMAT ".%09ld seconds\n"
00102                  "\twas expecting %" G_GUINT64_FORMAT ".%09ld seconds\n",
00103                  str, ts.tv_sec, ts.tv_nsec,
00104                  expected_ts.tv_sec, expected_ts.tv_nsec);
00105         failure ("misconverted timespec");
00106         return FALSE;
00107     }
00108     success ("good conversion");
00109     return TRUE;
00110 }
00111 
00112 static void
00113 run_test (void)
00114 {
00115     Timespec ts;
00116     int i;
00117     gboolean do_print = FALSE;
00118 
00119     /* Now leaving the 60's:
00120      *
00121      * Black Panthers
00122      * Weather Underground
00123      * Kent State
00124      * Evacuation of Vietnam
00125      * Impeachment
00126      * Gas Crisis
00127      * New York Garbage Crisis
00128      * Stagflation
00129      * Delapidated Bicentennial
00130      * Sex Pistols
00131      * Punk Rock
00132      *
00133      * Of course, anything had to be better than the miserable 70's,
00134      * which explains why Reagan was elected.  Food for thought.
00135      */
00136     ts.tv_sec = 10 * 365 * 24 * 3600 + 2 * 24 * 3600;
00137     ts.tv_nsec = 0;
00138     check_conversion ("1979-12-31 15:00:00.000000 -0900", ts);
00139     check_conversion ("1979-12-31 16:00:00.000000 -0800", ts);
00140     check_conversion ("1979-12-31 17:00:00.000000 -0700", ts);
00141     check_conversion ("1979-12-31 18:00:00.000000 -0600", ts);
00142     check_conversion ("1979-12-31 19:00:00.000000 -0500", ts);
00143     check_conversion ("1979-12-31 20:00:00.000000 -0400", ts);
00144     check_conversion ("1979-12-31 21:00:00.000000 -0300", ts);
00145     check_conversion ("1979-12-31 22:00:00.000000 -0200", ts);
00146     check_conversion ("1979-12-31 23:00:00.000000 -0100", ts);
00147 
00148     check_conversion ("1980-01-01 00:00:00.000000 -0000", ts);
00149     check_conversion ("1980-01-01 00:00:00.000000 +0000", ts);
00150 
00151     check_conversion ("1980-01-01 01:00:00.000000 +0100", ts);
00152     check_conversion ("1980-01-01 02:00:00.000000 +0200", ts);
00153     check_conversion ("1980-01-01 03:00:00.000000 +0300", ts);
00154     check_conversion ("1980-01-01 04:00:00.000000 +0400", ts);
00155     check_conversion ("1980-01-01 05:00:00.000000 +0500", ts);
00156     check_conversion ("1980-01-01 06:00:00.000000 +0600", ts);
00157     check_conversion ("1980-01-01 07:00:00.000000 +0700", ts);
00158     check_conversion ("1980-01-01 08:00:00.000000 +0800", ts);
00159 
00160     /* check minute-offsets as well */
00161     check_conversion ("1980-01-01 08:01:00.000000 +0801", ts);
00162     check_conversion ("1980-01-01 08:02:00.000000 +0802", ts);
00163     check_conversion ("1980-01-01 08:03:00.000000 +0803", ts);
00164     check_conversion ("1980-01-01 08:23:00.000000 +0823", ts);
00165     check_conversion ("1980-01-01 08:35:00.000000 +0835", ts);
00166     check_conversion ("1980-01-01 08:47:00.000000 +0847", ts);
00167     check_conversion ("1980-01-01 08:59:00.000000 +0859", ts);
00168 
00169     check_conversion ("1979-12-31 15:01:00.000000 -0859", ts);
00170     check_conversion ("1979-12-31 15:02:00.000000 -0858", ts);
00171     check_conversion ("1979-12-31 15:03:00.000000 -0857", ts);
00172     check_conversion ("1979-12-31 15:23:00.000000 -0837", ts);
00173     check_conversion ("1979-12-31 15:45:00.000000 -0815", ts);
00174 
00175 
00176     /* The 90's */
00177     ts.tv_sec = 20 * 365 * 24 * 3600 + 5 * 24 * 3600;
00178     ts.tv_nsec = 0;
00179     check_conversion ("1989-12-31 15:00:00.000000 -0900", ts);
00180     check_conversion ("1989-12-31 16:00:00.000000 -0800", ts);
00181     check_conversion ("1989-12-31 17:00:00.000000 -0700", ts);
00182     check_conversion ("1989-12-31 18:00:00.000000 -0600", ts);
00183     check_conversion ("1989-12-31 19:00:00.000000 -0500", ts);
00184     check_conversion ("1989-12-31 20:00:00.000000 -0400", ts);
00185     check_conversion ("1989-12-31 21:00:00.000000 -0300", ts);
00186     check_conversion ("1989-12-31 22:00:00.000000 -0200", ts);
00187     check_conversion ("1989-12-31 23:00:00.000000 -0100", ts);
00188 
00189     check_conversion ("1990-01-01 00:00:00.000000 -0000", ts);
00190     check_conversion ("1990-01-01 00:00:00.000000 +0000", ts);
00191 
00192     check_conversion ("1990-01-01 01:00:00.000000 +0100", ts);
00193     check_conversion ("1990-01-01 02:00:00.000000 +0200", ts);
00194     check_conversion ("1990-01-01 03:00:00.000000 +0300", ts);
00195     check_conversion ("1990-01-01 04:00:00.000000 +0400", ts);
00196     check_conversion ("1990-01-01 05:00:00.000000 +0500", ts);
00197     check_conversion ("1990-01-01 06:00:00.000000 +0600", ts);
00198     check_conversion ("1990-01-01 07:00:00.000000 +0700", ts);
00199     check_conversion ("1990-01-01 08:00:00.000000 +0800", ts);
00200 
00201     /* check minute-offsets as well */
00202     check_conversion ("1990-01-01 08:01:00.000000 +0801", ts);
00203     check_conversion ("1990-01-01 08:02:00.000000 +0802", ts);
00204     check_conversion ("1990-01-01 08:03:00.000000 +0803", ts);
00205     check_conversion ("1990-01-01 08:23:00.000000 +0823", ts);
00206     check_conversion ("1990-01-01 08:35:00.000000 +0835", ts);
00207     check_conversion ("1990-01-01 08:47:00.000000 +0847", ts);
00208     check_conversion ("1990-01-01 08:59:00.000000 +0859", ts);
00209 
00210     check_conversion ("1989-12-31 15:01:00.000000 -0859", ts);
00211     check_conversion ("1989-12-31 15:02:00.000000 -0858", ts);
00212     check_conversion ("1989-12-31 15:03:00.000000 -0857", ts);
00213     check_conversion ("1989-12-31 15:23:00.000000 -0837", ts);
00214     check_conversion ("1989-12-31 15:45:00.000000 -0815", ts);
00215 
00216 
00217     /* The naughties */
00218     ts.tv_sec = 30 * 365 * 24 * 3600 + 7 * 24 * 3600;
00219     ts.tv_nsec = 0;
00220     check_conversion ("1999-12-31 15:00:00.000000 -0900", ts);
00221     check_conversion ("1999-12-31 16:00:00.000000 -0800", ts);
00222     check_conversion ("1999-12-31 17:00:00.000000 -0700", ts);
00223     check_conversion ("1999-12-31 18:00:00.000000 -0600", ts);
00224     check_conversion ("1999-12-31 19:00:00.000000 -0500", ts);
00225     check_conversion ("1999-12-31 20:00:00.000000 -0400", ts);
00226     check_conversion ("1999-12-31 21:00:00.000000 -0300", ts);
00227     check_conversion ("1999-12-31 22:00:00.000000 -0200", ts);
00228     check_conversion ("1999-12-31 23:00:00.000000 -0100", ts);
00229 
00230     check_conversion ("2000-01-01 00:00:00.000000 -0000", ts);
00231     check_conversion ("2000-01-01 00:00:00.000000 +0000", ts);
00232 
00233     check_conversion ("2000-01-01 01:00:00.000000 +0100", ts);
00234     check_conversion ("2000-01-01 02:00:00.000000 +0200", ts);
00235     check_conversion ("2000-01-01 03:00:00.000000 +0300", ts);
00236     check_conversion ("2000-01-01 04:00:00.000000 +0400", ts);
00237     check_conversion ("2000-01-01 05:00:00.000000 +0500", ts);
00238     check_conversion ("2000-01-01 06:00:00.000000 +0600", ts);
00239     check_conversion ("2000-01-01 07:00:00.000000 +0700", ts);
00240     check_conversion ("2000-01-01 08:00:00.000000 +0800", ts);
00241 
00242     /* check minute-offsets as well */
00243     check_conversion ("2000-01-01 08:01:00.000000 +0801", ts);
00244     check_conversion ("2000-01-01 08:02:00.000000 +0802", ts);
00245     check_conversion ("2000-01-01 08:03:00.000000 +0803", ts);
00246     check_conversion ("2000-01-01 08:23:00.000000 +0823", ts);
00247     check_conversion ("2000-01-01 08:35:00.000000 +0835", ts);
00248     check_conversion ("2000-01-01 08:47:00.000000 +0847", ts);
00249     check_conversion ("2000-01-01 08:59:00.000000 +0859", ts);
00250 
00251     check_conversion ("1999-12-31 15:01:00.000000 -0859", ts);
00252     check_conversion ("1999-12-31 15:02:00.000000 -0858", ts);
00253     check_conversion ("1999-12-31 15:03:00.000000 -0857", ts);
00254     check_conversion ("1999-12-31 15:23:00.000000 -0837", ts);
00255     check_conversion ("1999-12-31 15:45:00.000000 -0815", ts);
00256 
00257 
00258     /* The nows */
00259     ts.tv_sec = 35 * 365 * 24 * 3600 + 9 * 24 * 3600;
00260     ts.tv_nsec = 0;
00261     check_conversion ("2004-12-31 15:00:00.000000 -0900", ts);
00262     check_conversion ("2004-12-31 16:00:00.000000 -0800", ts);
00263     check_conversion ("2004-12-31 17:00:00.000000 -0700", ts);
00264     check_conversion ("2004-12-31 18:00:00.000000 -0600", ts);
00265     check_conversion ("2004-12-31 19:00:00.000000 -0500", ts);
00266     check_conversion ("2004-12-31 20:00:00.000000 -0400", ts);
00267     check_conversion ("2004-12-31 21:00:00.000000 -0300", ts);
00268     check_conversion ("2004-12-31 22:00:00.000000 -0200", ts);
00269     check_conversion ("2004-12-31 23:00:00.000000 -0100", ts);
00270 
00271     check_conversion ("2005-01-01 00:00:00.000000 -0000", ts);
00272     check_conversion ("2005-01-01 00:00:00.000000 +0000", ts);
00273 
00274     check_conversion ("2005-01-01 01:00:00.000000 +0100", ts);
00275     check_conversion ("2005-01-01 02:00:00.000000 +0200", ts);
00276     check_conversion ("2005-01-01 03:00:00.000000 +0300", ts);
00277     check_conversion ("2005-01-01 04:00:00.000000 +0400", ts);
00278     check_conversion ("2005-01-01 05:00:00.000000 +0500", ts);
00279     check_conversion ("2005-01-01 06:00:00.000000 +0600", ts);
00280     check_conversion ("2005-01-01 07:00:00.000000 +0700", ts);
00281     check_conversion ("2005-01-01 08:00:00.000000 +0800", ts);
00282 
00283     /* check minute-offsets as well */
00284     check_conversion ("2005-01-01 08:01:00.000000 +0801", ts);
00285     check_conversion ("2005-01-01 08:02:00.000000 +0802", ts);
00286     check_conversion ("2005-01-01 08:03:00.000000 +0803", ts);
00287     check_conversion ("2005-01-01 08:23:00.000000 +0823", ts);
00288     check_conversion ("2005-01-01 08:35:00.000000 +0835", ts);
00289     check_conversion ("2005-01-01 08:47:00.000000 +0847", ts);
00290     check_conversion ("2005-01-01 08:59:00.000000 +0859", ts);
00291 
00292     check_conversion ("2004-12-31 15:01:00.000000 -0859", ts);
00293     check_conversion ("2004-12-31 15:02:00.000000 -0858", ts);
00294     check_conversion ("2004-12-31 15:03:00.000000 -0857", ts);
00295     check_conversion ("2004-12-31 15:23:00.000000 -0837", ts);
00296     check_conversion ("2004-12-31 15:45:00.000000 -0815", ts);
00297 
00298 
00299     /* Various leap-year days and near-leap times. */
00300     ts = gnc_iso8601_to_timespec_gmt ("1980-02-29 00:00:00.000000 -0000");
00301     check_time (ts, do_print);
00302 
00303     ts = gnc_iso8601_to_timespec_gmt ("1979-02-28 00:00:00.000000 -0000");
00304     check_time (ts, do_print);
00305 
00306     ts = gnc_iso8601_to_timespec_gmt ("1990-02-28 00:00:00.000000 -0000");
00307     check_time (ts, do_print);
00308 
00309     ts = gnc_iso8601_to_timespec_gmt ("2000-02-29 00:00:00.000000 -0000");
00310     check_time (ts, do_print);
00311 
00312     ts = gnc_iso8601_to_timespec_gmt ("2004-02-29 00:00:00.000000 -0000");
00313     check_time (ts, do_print);
00314 
00315     ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:00:00.000000 -0000");
00316     check_time (ts, do_print);
00317 
00318     ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:01:00.000000 -0000");
00319     check_time (ts, do_print);
00320 
00321     ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 02:02:00.000000 -0000");
00322     check_time (ts, do_print);
00323 
00324     ts = gnc_iso8601_to_timespec_gmt ("2008-02-28 23:23:23.000000 -0000");
00325     check_time (ts, do_print);
00326 
00327     /* Here's a date ten days after the 2038 rollover that should work
00328        if/when we support it. */
00329     ts.tv_nsec = 0;
00330     ts.tv_sec = (long long int) 0x7fffffff + 3600 * 24 * 10;
00331     //check_time(ts, do_print);
00332 
00333     /* Various 'special' times. What makes these so special? */
00334     ts.tv_sec = 152098136;
00335     ts.tv_nsec = 0;
00336     check_time (ts, do_print);
00337 
00338     ts.tv_sec = 1162088421;
00339     ts.tv_nsec = 12548000;
00340     check_time (ts, do_print);
00341 
00342     ts.tv_sec = 325659000 - 6500;
00343     ts.tv_nsec = 0;
00344     check_time (ts, do_print);
00345 
00346     ts.tv_sec = 1143943200;
00347     ts.tv_nsec = 0;
00348     check_time (ts, do_print);
00349 
00350     ts.tv_sec = 1603591171;
00351     ts.tv_nsec = 595311000;
00352     check_time (ts, do_print);
00353 
00354     ts.tv_sec = 1738909365;
00355     ts.tv_nsec = 204102000;
00356     check_time (ts, do_print);
00357 
00358     ts.tv_sec = 1603591171;
00359     ts.tv_nsec = 595311000;
00360     check_time (ts, do_print);
00361 
00362     ts.tv_sec = 1143943200 - 1;
00363     ts.tv_nsec = 0;
00364     check_time (ts, do_print);
00365 
00366     ts.tv_sec = 1143943200;
00367     ts.tv_nsec = 0;
00368     check_time (ts, do_print);
00369 
00370     ts.tv_sec = 1143943200 + (7 * 60 * 60);
00371     ts.tv_nsec = 0;
00372     check_time (ts, do_print);
00373 
00374     ts.tv_sec = 1143943200 + (8 * 60 * 60);
00375     ts.tv_nsec = 0;
00376     check_time (ts, do_print);
00377 
00378     ts = *get_random_timespec ();
00379 
00380     for (i = 0; i < 10000; i++)
00381     {
00382         ts.tv_sec += 10800;
00383         if (!check_time (ts, FALSE))
00384             return;
00385     }
00386 
00387     for (i = 0; i < 5000; i++)
00388     {
00389         ts = *get_random_timespec ();
00390 
00391         if (!check_time (ts, FALSE))
00392             return;
00393     }
00394 }
00395 
00396 int
00397 main (int argc, char **argv)
00398 {
00399     run_test ();
00400 
00401     success ("dates seem to work");
00402 
00403     print_test_results();
00404     exit(get_rv());
00405 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines