test-date.c

00001 /***************************************************************************
00002  *            test-date.c
00003  *
00004  *  May 2004
00005  *  Copyright  2004  Linas Vepstas
00006  *
00007  ****************************************************************************/
00008 /*
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU Library General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00022  */
00023  
00024 /* this test produces random failures on Mac OSX. */
00025 /*
00026  * -- fix broken timezone test -- linas May 2004
00027  */
00028 #define _GNU_SOURCE
00029 
00030 #include <stdio.h>
00031 #include <ctype.h>
00032 #include <glib.h>
00033 #include <time.h>
00034 
00035 #include "gnc-date.h"
00036 #include "test-stuff.h"
00037 #include "test-engine-stuff.h"
00038 
00039 static gboolean
00040 check_time (Timespec ts, gboolean always_print)
00041 {
00042   Timespec ts_2;
00043   char str[128];
00044   gboolean ok;
00045 
00046   ts.tv_nsec = MIN (ts.tv_nsec, 999999999);
00047   ts.tv_nsec /= 1000;
00048   ts.tv_nsec *= 1000;
00049 
00050   gnc_timespec_to_iso8601_buff (ts, str);
00051 
00052   /* The time, in seconds, everywhere on the planet, is always
00053    * the same, and is independent of location.  In particular,
00054    * the time, in seconds, is identical to the local time in 
00055    * Greewich (GMT).
00056    */
00057   ts_2 = gnc_iso8601_to_timespec_gmt (str);
00058 
00059   ok = timespec_equal (&ts, &ts_2);
00060 
00061   if (!ok || always_print)
00062   {
00063     fprintf (stderr,
00064              "\n%lld:%lld -> %s ->\n%lld:%lld "
00065              "(diff of %lld secs %lld nsecs)\n",
00066              (long long int) ts.tv_sec,
00067              (long long int) ts.tv_nsec,
00068              str,
00069              (long long int) ts_2.tv_sec,
00070              (long long int) ts_2.tv_nsec,
00071              (long long int) (ts.tv_sec - ts_2.tv_sec),
00072              (long long int) (ts.tv_nsec - ts_2.tv_nsec));
00073 
00074     if (!ok)
00075     {
00076       failure ("timespec to iso8601 string conversion failed");
00077       return FALSE;
00078     }
00079   }
00080 
00081   success ("timespec to iso8601 string conversion passes");
00082 
00083   return TRUE;
00084 }
00085 
00086 static gboolean
00087 check_conversion (const char * str, Timespec expected_ts)
00088 {
00089   Timespec ts;
00090 
00091   ts = gnc_iso8601_to_timespec_gmt (str);
00092 
00093   if ((expected_ts.tv_sec != ts.tv_sec) || (expected_ts.tv_nsec != ts.tv_nsec)) 
00094   {
00095     fprintf (stderr, 
00096              "\nmis-converted \"%s\" to %" G_GUINT64_FORMAT ".%09ld seconds\n"
00097              "\twas expecting %" G_GUINT64_FORMAT ".%09ld seconds\n", 
00098              str, ts.tv_sec, ts.tv_nsec, 
00099              expected_ts.tv_sec, expected_ts.tv_nsec); 
00100     failure ("misconverted timespec");
00101     return FALSE;
00102   }
00103   success ("good conversion");
00104   return TRUE;
00105 }
00106 
00107 static void
00108 run_test (void)
00109 {
00110   Timespec ts;
00111   int i;
00112   gboolean do_print = FALSE;
00113 
00114   /* All of the following strings are equivalent 
00115    * representations of zero seconds.  Note, zero seconds
00116    * is the same world-wide, independent of timezone.
00117    */
00118   ts.tv_sec = 0;
00119   ts.tv_nsec = 0;
00120 /* hack alert -- gnc_iso8601_to_timespec_gmt
00121  * returns incorrect values for dates before 1970 */
00122 
00123   ts.tv_sec = 10*365*24*3600 + 2*24*3600;
00124   ts.tv_nsec = 0;
00125   check_conversion ("1979-12-31 15:00:00.000000 -0900", ts);
00126   check_conversion ("1979-12-31 16:00:00.000000 -0800", ts);
00127   check_conversion ("1979-12-31 17:00:00.000000 -0700", ts);
00128   check_conversion ("1979-12-31 18:00:00.000000 -0600", ts);
00129   check_conversion ("1979-12-31 19:00:00.000000 -0500", ts);
00130   check_conversion ("1979-12-31 20:00:00.000000 -0400", ts);
00131   check_conversion ("1979-12-31 21:00:00.000000 -0300", ts);
00132   check_conversion ("1979-12-31 22:00:00.000000 -0200", ts);
00133   check_conversion ("1979-12-31 23:00:00.000000 -0100", ts);
00134 
00135   check_conversion ("1980-01-01 00:00:00.000000 -0000", ts);
00136   check_conversion ("1980-01-01 00:00:00.000000 +0000", ts);
00137 
00138   check_conversion ("1980-01-01 01:00:00.000000 +0100", ts);
00139   check_conversion ("1980-01-01 02:00:00.000000 +0200", ts);
00140   check_conversion ("1980-01-01 03:00:00.000000 +0300", ts);
00141   check_conversion ("1980-01-01 04:00:00.000000 +0400", ts);
00142   check_conversion ("1980-01-01 05:00:00.000000 +0500", ts);
00143   check_conversion ("1980-01-01 06:00:00.000000 +0600", ts);
00144   check_conversion ("1980-01-01 07:00:00.000000 +0700", ts);
00145   check_conversion ("1980-01-01 08:00:00.000000 +0800", ts);
00146 
00147   /* check minute-offsets as well */
00148   check_conversion ("1980-01-01 08:01:00.000000 +0801", ts);
00149   check_conversion ("1980-01-01 08:02:00.000000 +0802", ts);
00150   check_conversion ("1980-01-01 08:03:00.000000 +0803", ts);
00151   check_conversion ("1980-01-01 08:23:00.000000 +0823", ts);
00152   check_conversion ("1980-01-01 08:35:00.000000 +0835", ts);
00153   check_conversion ("1980-01-01 08:47:00.000000 +0847", ts);
00154   check_conversion ("1980-01-01 08:59:00.000000 +0859", ts);
00155 
00156   check_conversion ("1979-12-31 15:01:00.000000 -0859", ts);
00157   check_conversion ("1979-12-31 15:02:00.000000 -0858", ts);
00158   check_conversion ("1979-12-31 15:03:00.000000 -0857", ts);
00159   check_conversion ("1979-12-31 15:23:00.000000 -0837", ts);
00160   check_conversion ("1979-12-31 15:45:00.000000 -0815", ts);
00161 
00162 
00163   /* The 90's */
00164   ts.tv_sec = 20*365*24*3600 + 5*24*3600;
00165   ts.tv_nsec = 0;
00166   check_conversion ("1989-12-31 15:00:00.000000 -0900", ts);
00167   check_conversion ("1989-12-31 16:00:00.000000 -0800", ts);
00168   check_conversion ("1989-12-31 17:00:00.000000 -0700", ts);
00169   check_conversion ("1989-12-31 18:00:00.000000 -0600", ts);
00170   check_conversion ("1989-12-31 19:00:00.000000 -0500", ts);
00171   check_conversion ("1989-12-31 20:00:00.000000 -0400", ts);
00172   check_conversion ("1989-12-31 21:00:00.000000 -0300", ts);
00173   check_conversion ("1989-12-31 22:00:00.000000 -0200", ts);
00174   check_conversion ("1989-12-31 23:00:00.000000 -0100", ts);
00175 
00176   check_conversion ("1990-01-01 00:00:00.000000 -0000", ts);
00177   check_conversion ("1990-01-01 00:00:00.000000 +0000", ts);
00178 
00179   check_conversion ("1990-01-01 01:00:00.000000 +0100", ts);
00180   check_conversion ("1990-01-01 02:00:00.000000 +0200", ts);
00181   check_conversion ("1990-01-01 03:00:00.000000 +0300", ts);
00182   check_conversion ("1990-01-01 04:00:00.000000 +0400", ts);
00183   check_conversion ("1990-01-01 05:00:00.000000 +0500", ts);
00184   check_conversion ("1990-01-01 06:00:00.000000 +0600", ts);
00185   check_conversion ("1990-01-01 07:00:00.000000 +0700", ts);
00186   check_conversion ("1990-01-01 08:00:00.000000 +0800", ts);
00187 
00188   /* check minute-offsets as well */
00189   check_conversion ("1990-01-01 08:01:00.000000 +0801", ts);
00190   check_conversion ("1990-01-01 08:02:00.000000 +0802", ts);
00191   check_conversion ("1990-01-01 08:03:00.000000 +0803", ts);
00192   check_conversion ("1990-01-01 08:23:00.000000 +0823", ts);
00193   check_conversion ("1990-01-01 08:35:00.000000 +0835", ts);
00194   check_conversion ("1990-01-01 08:47:00.000000 +0847", ts);
00195   check_conversion ("1990-01-01 08:59:00.000000 +0859", ts);
00196 
00197   check_conversion ("1989-12-31 15:01:00.000000 -0859", ts);
00198   check_conversion ("1989-12-31 15:02:00.000000 -0858", ts);
00199   check_conversion ("1989-12-31 15:03:00.000000 -0857", ts);
00200   check_conversion ("1989-12-31 15:23:00.000000 -0837", ts);
00201   check_conversion ("1989-12-31 15:45:00.000000 -0815", ts);
00202 
00203 
00204   /* The naughties */
00205   ts.tv_sec = 30*365*24*3600 + 7*24*3600;
00206   ts.tv_nsec = 0;
00207   check_conversion ("1999-12-31 15:00:00.000000 -0900", ts);
00208   check_conversion ("1999-12-31 16:00:00.000000 -0800", ts);
00209   check_conversion ("1999-12-31 17:00:00.000000 -0700", ts);
00210   check_conversion ("1999-12-31 18:00:00.000000 -0600", ts);
00211   check_conversion ("1999-12-31 19:00:00.000000 -0500", ts);
00212   check_conversion ("1999-12-31 20:00:00.000000 -0400", ts);
00213   check_conversion ("1999-12-31 21:00:00.000000 -0300", ts);
00214   check_conversion ("1999-12-31 22:00:00.000000 -0200", ts);
00215   check_conversion ("1999-12-31 23:00:00.000000 -0100", ts);
00216 
00217   check_conversion ("2000-01-01 00:00:00.000000 -0000", ts);
00218   check_conversion ("2000-01-01 00:00:00.000000 +0000", ts);
00219 
00220   check_conversion ("2000-01-01 01:00:00.000000 +0100", ts);
00221   check_conversion ("2000-01-01 02:00:00.000000 +0200", ts);
00222   check_conversion ("2000-01-01 03:00:00.000000 +0300", ts);
00223   check_conversion ("2000-01-01 04:00:00.000000 +0400", ts);
00224   check_conversion ("2000-01-01 05:00:00.000000 +0500", ts);
00225   check_conversion ("2000-01-01 06:00:00.000000 +0600", ts);
00226   check_conversion ("2000-01-01 07:00:00.000000 +0700", ts);
00227   check_conversion ("2000-01-01 08:00:00.000000 +0800", ts);
00228 
00229   /* check minute-offsets as well */
00230   check_conversion ("2000-01-01 08:01:00.000000 +0801", ts);
00231   check_conversion ("2000-01-01 08:02:00.000000 +0802", ts);
00232   check_conversion ("2000-01-01 08:03:00.000000 +0803", ts);
00233   check_conversion ("2000-01-01 08:23:00.000000 +0823", ts);
00234   check_conversion ("2000-01-01 08:35:00.000000 +0835", ts);
00235   check_conversion ("2000-01-01 08:47:00.000000 +0847", ts);
00236   check_conversion ("2000-01-01 08:59:00.000000 +0859", ts);
00237 
00238   check_conversion ("1999-12-31 15:01:00.000000 -0859", ts);
00239   check_conversion ("1999-12-31 15:02:00.000000 -0858", ts);
00240   check_conversion ("1999-12-31 15:03:00.000000 -0857", ts);
00241   check_conversion ("1999-12-31 15:23:00.000000 -0837", ts);
00242   check_conversion ("1999-12-31 15:45:00.000000 -0815", ts);
00243 
00244 
00245   /* The nows */
00246   ts.tv_sec = 35*365*24*3600 + 9*24*3600;
00247   ts.tv_nsec = 0;
00248   check_conversion ("2004-12-31 15:00:00.000000 -0900", ts);
00249   check_conversion ("2004-12-31 16:00:00.000000 -0800", ts);
00250   check_conversion ("2004-12-31 17:00:00.000000 -0700", ts);
00251   check_conversion ("2004-12-31 18:00:00.000000 -0600", ts);
00252   check_conversion ("2004-12-31 19:00:00.000000 -0500", ts);
00253   check_conversion ("2004-12-31 20:00:00.000000 -0400", ts);
00254   check_conversion ("2004-12-31 21:00:00.000000 -0300", ts);
00255   check_conversion ("2004-12-31 22:00:00.000000 -0200", ts);
00256   check_conversion ("2004-12-31 23:00:00.000000 -0100", ts);
00257 
00258   check_conversion ("2005-01-01 00:00:00.000000 -0000", ts);
00259   check_conversion ("2005-01-01 00:00:00.000000 +0000", ts);
00260 
00261   check_conversion ("2005-01-01 01:00:00.000000 +0100", ts);
00262   check_conversion ("2005-01-01 02:00:00.000000 +0200", ts);
00263   check_conversion ("2005-01-01 03:00:00.000000 +0300", ts);
00264   check_conversion ("2005-01-01 04:00:00.000000 +0400", ts);
00265   check_conversion ("2005-01-01 05:00:00.000000 +0500", ts);
00266   check_conversion ("2005-01-01 06:00:00.000000 +0600", ts);
00267   check_conversion ("2005-01-01 07:00:00.000000 +0700", ts);
00268   check_conversion ("2005-01-01 08:00:00.000000 +0800", ts);
00269 
00270   /* check minute-offsets as well */
00271   check_conversion ("2005-01-01 08:01:00.000000 +0801", ts);
00272   check_conversion ("2005-01-01 08:02:00.000000 +0802", ts);
00273   check_conversion ("2005-01-01 08:03:00.000000 +0803", ts);
00274   check_conversion ("2005-01-01 08:23:00.000000 +0823", ts);
00275   check_conversion ("2005-01-01 08:35:00.000000 +0835", ts);
00276   check_conversion ("2005-01-01 08:47:00.000000 +0847", ts);
00277   check_conversion ("2005-01-01 08:59:00.000000 +0859", ts);
00278 
00279   check_conversion ("2004-12-31 15:01:00.000000 -0859", ts);
00280   check_conversion ("2004-12-31 15:02:00.000000 -0858", ts);
00281   check_conversion ("2004-12-31 15:03:00.000000 -0857", ts);
00282   check_conversion ("2004-12-31 15:23:00.000000 -0837", ts);
00283   check_conversion ("2004-12-31 15:45:00.000000 -0815", ts);
00284 
00285   /* Various leap-year days and near-leap times. */
00286   ts = gnc_iso8601_to_timespec_gmt ("1980-02-29 00:00:00.000000 -0000");
00287   check_time (ts, do_print);
00288 
00289   ts = gnc_iso8601_to_timespec_gmt ("1979-02-28 00:00:00.000000 -0000");
00290   check_time (ts, do_print);
00291 
00292   ts = gnc_iso8601_to_timespec_gmt ("1990-02-28 00:00:00.000000 -0000");
00293   check_time (ts, do_print);
00294 
00295   ts = gnc_iso8601_to_timespec_gmt ("2000-02-29 00:00:00.000000 -0000");
00296   check_time (ts, do_print);
00297 
00298   ts = gnc_iso8601_to_timespec_gmt ("2004-02-29 00:00:00.000000 -0000");
00299   check_time (ts, do_print);
00300 
00301   ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:00:00.000000 -0000");
00302   check_time (ts, do_print);
00303 
00304   ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:01:00.000000 -0000");
00305   check_time (ts, do_print);
00306 
00307   ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 02:02:00.000000 -0000");
00308   check_time (ts, do_print);
00309 
00310   ts = gnc_iso8601_to_timespec_gmt ("2008-02-28 23:23:23.000000 -0000");
00311   check_time (ts, do_print);
00312 
00313   /* Various 'special' times e.g. times before and after daylight saving */
00314 
00315   ts.tv_sec = 796179600;
00316   ts.tv_nsec = 0;
00317   check_time (ts, do_print);
00318 
00319   ts.tv_sec = 796179500;
00320   ts.tv_nsec = 72000;
00321   check_time (ts, do_print);
00322 
00323   ts.tv_sec = 152098136;
00324   ts.tv_nsec = 0;
00325   check_time (ts, do_print);
00326 
00327   ts.tv_sec = 1964049931;
00328   ts.tv_nsec = 0;
00329   check_time (ts, do_print);
00330 
00331   ts.tv_sec = 1162088421;
00332   ts.tv_nsec = 12548000;
00333   check_time (ts, do_print);
00334 
00335   ts.tv_sec = 325659000 - 6500;
00336   ts.tv_nsec = 0;
00337   check_time (ts, do_print);
00338 
00339   ts.tv_sec = 1143943200;
00340   ts.tv_nsec = 0;
00341   check_time (ts, do_print);
00342 
00343   ts.tv_sec = 1603591171;
00344   ts.tv_nsec = 595311000;
00345   check_time (ts, do_print);
00346 
00347   ts.tv_sec = 1738909365;
00348   ts.tv_nsec = 204102000;
00349   check_time (ts, do_print);
00350 
00351   ts.tv_sec = 1603591171;
00352   ts.tv_nsec = 595311000;
00353   check_time (ts, do_print);
00354 
00355   ts.tv_sec = 1143943200 - 1;
00356   ts.tv_nsec = 0;
00357   check_time (ts, do_print);
00358 
00359   ts.tv_sec = 1143943200;
00360   ts.tv_nsec = 0;
00361   check_time (ts, do_print);
00362 
00363   ts.tv_sec = 1143943200 + (7 * 60 * 60);
00364   ts.tv_nsec = 0;
00365   check_time (ts, do_print);
00366 
00367   ts.tv_sec = 1143943200 + (8 * 60 * 60);
00368   ts.tv_nsec = 0;
00369   check_time (ts, do_print);
00370 
00371   srand(time(0));
00372 
00373   /* Get a random time that won't overflow a signed 32bit int durng testing */
00374   ts = *get_random_timespec ();
00375   while (ts.tv_sec >= ((2^31) - (10000*10800))) {
00376     ts = *get_random_timespec();  
00377   };
00378 
00379   for (i = 0; i < 10000; i++)
00380   {
00381     ts.tv_sec += 10800;
00382     check_time (ts, FALSE);
00383   }
00384 
00385   for (i = 0; i < 5000; i++)
00386   {
00387     ts = *get_random_timespec ();
00388 
00389     ts.tv_nsec = MIN (ts.tv_nsec, 999999999);
00390     ts.tv_nsec /= 1000;
00391     ts.tv_nsec *= 1000;
00392 
00393     if (!check_time (ts, FALSE)) { printf("%d : %ld\n", i, ts.tv_nsec); }
00394 //      return;
00395   }
00396 }
00397 
00398 int
00399 main (int argc, char **argv)
00400 {
00401   run_test ();
00402 
00403   success ("dates seem to work");
00404 
00405   print_test_results();
00406   exit(get_rv());
00407 }

Generated on Fri May 12 18:00:33 2006 for QOF by  doxygen 1.4.4