QOF  0.8.7
test-date.c
00001 /***************************************************************************
00002  *            test-date.c
00003  *       Rewritten from scratch for QOF 0.8.0
00004  *
00005  *  Copyright (C) 2002-2008
00006  *  Free Software Foundation, Inc.
00007  *
00008  ****************************************************************************/
00009 /*
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA  02110-1301,  USA
00023  */
00024 
00025 #include "config.h"
00026 #include <stdio.h>
00027 #include <ctype.h>
00028 #include <glib.h>
00029 #include <time.h>
00030 #include "qof.h"
00031 #include "test-stuff.h"
00032 
00033 static gboolean test_data_is_init = FALSE;
00034 static GList *test_data = NULL;
00035 static QofLogModule log_module = QOF_MOD_DATE;
00036 
00037 typedef struct
00038 {
00039     /* time value of the date below */
00040     QofTime *time;
00041     /* date value of the above time. */
00042     QofDate *date;
00043     /* GList of the date in each QofDateFormat */
00044     GList   *string_list;
00045     /* unique ID for this date for error reports. */
00046     const gchar *id;
00047 }QTestDate;
00048 
00049 static void
00050 check_date_cycles (gpointer data, 
00051     gpointer user_data __attribute__ ((unused)))
00052 {
00053     QofDateFormat df;
00054     gchar *str, *cmp;
00055     QTestDate *d;
00056     gint i;
00057 
00058     d = (QTestDate*)data;
00059     df = qof_date_format_get_current ();
00060     /* test qof_date_to_qtime and qof_date_from_qtime */
00061     {
00062         do_test ((0 == qof_time_cmp (qof_date_to_qtime (d->date), 
00063             d->time)), d->id);
00064         do_test ((0 == qof_date_compare (qof_date_from_qtime (d->time), 
00065             d->date)), d->id);
00066     }
00067     /* don't test locale-sensitive formats, yet. */
00068     for (i = 1; i <= 6; i++)
00069     {
00070         str = qof_date_print (d->date, i);
00071         cmp = (gchar*)g_list_nth_data (d->string_list, (i - 1));
00072         if (0 != safe_strcasecmp (str, cmp))
00073             DEBUG (" str=%s cmp=%s", str, cmp);
00074         do_test ((0 == safe_strcasecmp (str, cmp)), d->id);
00075         /* now test qofstrptime */
00076         {
00077             QofDate *h, *j;
00078             const gchar * t;
00079             struct tm base;
00080 
00081             base.tm_year = base.tm_mday = base.tm_mon = 0;
00082             base.tm_min  = base.tm_hour = base.tm_gmtoff = 0;
00083             base.tm_sec  = base.tm_isdst = 0;
00085             if ((d->date->qd_year > 0) &&
00086                 (d->date->qd_year < 9999))
00087             {
00088                 h = qof_date_parse (cmp, i);
00089                 do_test ((h != NULL), "no date could be parsed");
00090                 if (!h)
00091                     PERR (" h failed for str=%s, "
00092                         "cmp=%s, %d\n", str, cmp, i);
00093                 t = qof_date_format_get_format (i);
00094                 strptime (cmp, t, &base);
00095                 j = qof_date_from_struct_tm (&base);
00096                 do_test ((j != NULL), "no value from struct tm");
00097                 if (h)
00098                 {
00099                     j->qd_nanosecs = h->qd_nanosecs;
00100                     qof_date_compare (h, j);
00101                     do_test ((0 == qof_date_compare (h, j)),
00102                         "compare with strptime");
00103                 }
00104             if (h)
00105                 qof_date_free (h);
00106             }
00107         }
00108     }
00109     qof_date_format_set_current (df);
00110 }
00111 
00112 static void
00113 test_date_init (void)
00114 {
00115     test_data_is_init = TRUE;
00116     test_data = NULL;
00117     /* A selection of current, old and future dates - all in UTC only. */
00118     {
00119         QTestDate *td = g_new0 (QTestDate, 1);
00120         td->time = qof_time_new ();
00121         qof_time_set_secs (td->time, 1147621550);
00122         qof_time_set_nanosecs (td->time, G_GINT64_CONSTANT(1000));
00123         td->date = qof_date_new ();
00124         td->date->qd_year = 2006;
00125         td->date->qd_mon  = 5;
00126         td->date->qd_mday = 14;
00127         td->date->qd_hour = 15;
00128         td->date->qd_min  = 45;
00129         td->date->qd_sec  = G_GINT64_CONSTANT(50);
00130         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00131         qof_date_valid (td->date);
00132         td->string_list = NULL;
00133         td->string_list = g_list_append (td->string_list, "05/14/2006");
00134         td->string_list = g_list_append (td->string_list, "14/05/2006");
00135         td->string_list = g_list_append (td->string_list, "14.05.2006");
00136         td->string_list = g_list_append (td->string_list, "2006-05-14");
00137         td->string_list = g_list_append (td->string_list, "2006-05-14T15:45:50Z");
00138         td->string_list = g_list_append (td->string_list,
00139             "2006-05-14 15:45:50.000001000 +0000");
00140         td->id = "a current time";
00141         test_data = g_list_prepend (test_data, td);
00142     }
00143     {
00144         QTestDate *td = g_new0 (QTestDate, 1);
00145         td->time = qof_time_new ();
00146         qof_time_set_secs (td->time, 1147132800);
00147         qof_time_set_nanosecs (td->time, 2);
00148         td->date = qof_date_new ();
00149         td->date->qd_year = 2006;
00150         td->date->qd_mon  = 5;
00151         td->date->qd_mday = 9;
00152         td->date->qd_hour = 0;
00153         td->date->qd_min  = 0;
00154         td->date->qd_sec  = G_GINT64_CONSTANT(0);
00155         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00156         qof_date_valid (td->date);
00157         td->string_list = NULL;
00158         td->string_list = g_list_prepend (td->string_list, "05/09/2006");
00159         td->string_list = g_list_prepend (td->string_list, "09/05/2006");
00160         td->string_list = g_list_prepend (td->string_list, "09.05.2006");
00161         td->string_list = g_list_prepend (td->string_list, "2006-05-09");
00162         td->string_list = g_list_prepend (td->string_list, "2006-05-09T00:00:00Z");
00163         td->string_list = g_list_prepend (td->string_list,
00164             "2006-05-09 00:00:00.000000002 +0000");
00165         td->string_list = g_list_reverse (td->string_list);
00166         td->id = "a recent time";
00167         test_data = g_list_prepend (test_data, td);
00168     }
00169     {
00170         QTestDate *td = g_new0 (QTestDate, 1);
00171         td->time = qof_time_new ();
00172         qof_time_set_secs (td->time, 1147186144);
00173         qof_time_set_nanosecs (td->time, 100);
00174         td->date = qof_date_new ();
00175         td->date->qd_year = 2006;
00176         td->date->qd_mon  = 5;
00177         td->date->qd_mday = 9;
00178         td->date->qd_hour = 14;
00179         td->date->qd_min  = 49;
00180         td->date->qd_sec  = G_GINT64_CONSTANT(4);
00181         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00182         qof_date_valid (td->date);
00183         td->string_list = NULL;
00184         td->string_list = g_list_prepend (td->string_list, "05/09/2006");
00185         td->string_list = g_list_prepend (td->string_list, "09/05/2006");
00186         td->string_list = g_list_prepend (td->string_list, "09.05.2006");
00187         td->string_list = g_list_prepend (td->string_list, "2006-05-09");
00188         td->string_list = g_list_prepend (td->string_list, "2006-05-09T14:49:04Z");
00189         td->string_list = g_list_prepend (td->string_list, 
00190             "2006-05-09 14:49:04.000000100 +0000");
00191         td->string_list = g_list_reverse (td->string_list);
00192         td->id = "second recent time";
00193         test_data = g_list_prepend (test_data, td);
00194     }
00195     {
00196         QTestDate *td = g_new0 (QTestDate, 1);
00197         td->time = qof_time_new ();
00198         qof_time_set_secs (td->time, 63039600);
00199         qof_time_set_nanosecs (td->time, 4);
00200         td->date = qof_date_new ();
00201         td->date->qd_year = 1971;
00202         td->date->qd_mon  = 12;
00203         td->date->qd_mday = 31;
00204         td->date->qd_hour = 15;
00205         td->date->qd_min  = 0;
00206         td->date->qd_sec  = G_GINT64_CONSTANT(0);
00207         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00208         qof_date_valid (td->date);
00209         td->string_list = NULL;
00210         td->string_list = g_list_prepend (td->string_list, "12/31/1971");
00211         td->string_list = g_list_prepend (td->string_list, "31/12/1971");
00212         td->string_list = g_list_prepend (td->string_list, "31.12.1971");
00213         td->string_list = g_list_prepend (td->string_list, "1971-12-31");
00214         td->string_list = g_list_prepend (td->string_list, "1971-12-31T15:00:00Z");
00215         td->string_list = g_list_prepend (td->string_list, 
00216             "1971-12-31 15:00:00.000000004 +0000");
00217         td->string_list = g_list_reverse (td->string_list);
00218         td->id = "New Year's Eve 1971";
00219         test_data = g_list_prepend (test_data, td);
00220     }
00221     {
00222         QTestDate *td = g_new0 (QTestDate, 1);
00223         td->time = qof_time_new ();
00224         qof_time_set_secs (td->time, 315532800);
00225         qof_time_set_nanosecs (td->time, 123456789);
00226         td->date = qof_date_new ();
00227         td->date->qd_year = 1980;
00228         td->date->qd_mon  = 1;
00229         td->date->qd_mday = 1;
00230         td->date->qd_hour = 0;
00231         td->date->qd_min  = 0;
00232         td->date->qd_sec  = G_GINT64_CONSTANT(0);
00233         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00234         qof_date_valid (td->date);
00235         td->string_list = NULL;
00236         td->string_list = g_list_prepend (td->string_list, "01/01/1980");
00237         td->string_list = g_list_prepend (td->string_list, "01/01/1980");
00238         td->string_list = g_list_prepend (td->string_list, "01.01.1980");
00239         td->string_list = g_list_prepend (td->string_list, "1980-01-01");
00240         td->string_list = g_list_prepend (td->string_list, "1980-01-01T00:00:00Z");
00241         td->string_list = g_list_prepend (td->string_list,
00242             "1980-01-01 00:00:00.123456789 +0000");
00243         td->string_list = g_list_reverse (td->string_list);
00244         td->id = "New Year's Day 1980";
00245         test_data = g_list_prepend (test_data, td);
00246     }
00247     {
00248         QTestDate *td = g_new0 (QTestDate, 1);
00249         td->time = qof_time_new ();
00250         qof_time_set_secs (td->time, 946684799);
00251         qof_time_set_nanosecs (td->time, 987654321);
00252         td->date = qof_date_new ();
00253         td->date->qd_year = 1999;
00254         td->date->qd_mon  = 12;
00255         td->date->qd_mday = 31;
00256         td->date->qd_hour = 23;
00257         td->date->qd_min  = 59;
00258         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00259         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00260         qof_date_valid (td->date);
00261         td->string_list = NULL;
00262         td->string_list = g_list_prepend (td->string_list, "12/31/1999");
00263         td->string_list = g_list_prepend (td->string_list, "31/12/1999");
00264         td->string_list = g_list_prepend (td->string_list, "31.12.1999");
00265         td->string_list = g_list_prepend (td->string_list, "1999-12-31");
00266         td->string_list = g_list_prepend (td->string_list, "1999-12-31T23:59:59Z");
00267         td->string_list = g_list_prepend (td->string_list,
00268             "1999-12-31 23:59:59.987654321 +0000");
00269         td->string_list = g_list_reverse (td->string_list);
00270         td->id = "Millenium Eve";
00271         test_data = g_list_prepend (test_data, td);
00272     }
00273     {
00274         QTestDate *td = g_new0 (QTestDate, 1);
00275         td->time = qof_time_new ();
00276         qof_time_set_secs (td->time, 699378323);
00277         qof_time_set_nanosecs (td->time, 90000);
00278         td->date = qof_date_new ();
00279         td->date->qd_year = 1992;
00280         td->date->qd_mon  = 2;
00281         td->date->qd_mday = 29;
00282         td->date->qd_hour = 15;
00283         td->date->qd_min  = 45;
00284         td->date->qd_sec  = G_GINT64_CONSTANT(23);
00285         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00286         qof_date_valid (td->date);
00287         td->string_list = NULL;
00288         td->string_list = g_list_prepend (td->string_list, "02/29/1992");
00289         td->string_list = g_list_prepend (td->string_list, "29/02/1992");
00290         td->string_list = g_list_prepend (td->string_list, "29.02.1992");
00291         td->string_list = g_list_prepend (td->string_list, "1992-02-29");
00292         td->string_list = g_list_prepend (td->string_list, "1992-02-29T15:45:23Z");
00293         td->string_list = g_list_prepend (td->string_list, 
00294             "1992-02-29 15:45:23.000090000 +0000");
00295         td->string_list = g_list_reverse (td->string_list);
00296         td->id = "29th February 1992";
00297         test_data = g_list_prepend (test_data, td);
00298     }
00299     {
00300 
00301         QTestDate *td = g_new0 (QTestDate, 1);
00302         td->time = qof_time_new ();
00303         qof_time_set_secs (td->time, -1);
00304         qof_time_set_nanosecs (td->time, 9);
00305         td->date = qof_date_new ();
00306         td->date->qd_year = 1969;
00307         td->date->qd_mon  = 12;
00308         td->date->qd_mday = 31;
00309         td->date->qd_hour = 23;
00310         td->date->qd_min  = 59;
00311         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00312         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00313         qof_date_valid (td->date);
00314         td->string_list = NULL;
00315         td->string_list = g_list_prepend (td->string_list, "12/31/1969");
00316         td->string_list = g_list_prepend (td->string_list, "31/12/1969");
00317         td->string_list = g_list_prepend (td->string_list, "31.12.1969");
00318         td->string_list = g_list_prepend (td->string_list, "1969-12-31");
00319         td->string_list = g_list_prepend (td->string_list, "1969-12-31T23:59:59Z");
00320         td->string_list = g_list_prepend (td->string_list, 
00321             "1969-12-31 23:59:59.000000009 +0000");
00322         td->string_list = g_list_reverse (td->string_list);
00323         td->id = "epoch eve";
00324         test_data = g_list_prepend (test_data, td);
00325     }
00326     {
00327         QTestDate *td = g_new0 (QTestDate, 1);
00328         td->time = qof_time_new ();
00329         qof_time_set_secs (td->time, -192776400);
00330         qof_time_set_nanosecs (td->time, 818818818);
00331         td->date = qof_date_new ();
00332         td->date->qd_year = 1963;
00333         td->date->qd_mon  = 11;
00334         td->date->qd_mday = 22;
00335         td->date->qd_hour = 19;
00336         td->date->qd_min  = 0;
00337         td->date->qd_sec  = G_GINT64_CONSTANT(0);
00338         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00339         qof_date_valid (td->date);
00340         td->string_list = NULL;
00341         td->string_list = g_list_prepend (td->string_list, "11/22/1963");
00342         td->string_list = g_list_prepend (td->string_list, "22/11/1963");
00343         td->string_list = g_list_prepend (td->string_list, "22.11.1963");
00344         td->string_list = g_list_prepend (td->string_list, "1963-11-22");
00345         td->string_list = g_list_prepend (td->string_list, "1963-11-22T19:00:00Z");
00346         td->string_list = g_list_prepend (td->string_list, 
00347             "1963-11-22 19:00:00.818818818 +0000");
00348         td->string_list = g_list_reverse (td->string_list);
00349         td->id = "approx JFK, 1963";
00350         test_data = g_list_prepend (test_data, td);
00351     }
00352     {
00353         QTestDate *td = g_new0 (QTestDate, 1);
00354         td->time = qof_time_new ();
00355         qof_time_set_secs (td->time, -767311080);
00356         qof_time_set_nanosecs (td->time, 0);
00357         td->date = qof_date_new ();
00358         td->date->qd_year = 1945;
00359         td->date->qd_mon  = 9;
00360         td->date->qd_mday = 8;
00361         td->date->qd_hour = 2;
00362         td->date->qd_min  = 2;
00363         td->date->qd_sec  = G_GINT64_CONSTANT(0);
00364         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00365         qof_date_valid (td->date);
00366         td->string_list = NULL;
00367         td->string_list = g_list_prepend (td->string_list, "09/08/1945");
00368         td->string_list = g_list_prepend (td->string_list, "08/09/1945");
00369         td->string_list = g_list_prepend (td->string_list, "08.09.1945");
00370         td->string_list = g_list_prepend (td->string_list, "1945-09-08");
00371         td->string_list = g_list_prepend (td->string_list, "1945-09-08T02:02:00Z");
00372         td->string_list = g_list_prepend (td->string_list, 
00373             "1945-09-08 02:02:00.000000000 +0000");
00374         td->string_list = g_list_reverse (td->string_list);
00375         td->id = "Nagasaki, 1945";
00376         test_data = g_list_prepend (test_data, td);
00377     }
00378     {
00379         QTestDate *td = g_new0 (QTestDate, 1);
00380         td->time = qof_time_new ();
00381         qof_time_set_secs (td->time, -1613826000);
00382         qof_time_set_nanosecs (td->time, 0);
00383         td->date = qof_date_new ();
00384         td->date->qd_year = 1918;
00385         td->date->qd_mon  = 11;
00386         td->date->qd_mday = 11;
00387         td->date->qd_hour = 11;
00388         td->date->qd_min  = 0;
00389         td->date->qd_sec  = G_GINT64_CONSTANT(0);
00390         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00391         qof_date_valid (td->date);
00392         td->string_list = NULL;
00393         td->string_list = g_list_prepend (td->string_list, "11/11/1918");
00394         td->string_list = g_list_prepend (td->string_list, "11/11/1918");
00395         td->string_list = g_list_prepend (td->string_list, "11.11.1918");
00396         td->string_list = g_list_prepend (td->string_list, "1918-11-11");
00397         td->string_list = g_list_prepend (td->string_list, "1918-11-11T11:00:00Z");
00398         td->string_list = g_list_prepend (td->string_list, 
00399             "1918-11-11 11:00:00.000000000 +0000");
00400         td->string_list = g_list_reverse (td->string_list);
00401         td->id = "Armistice 1918";
00402         test_data = g_list_prepend (test_data, td);
00403     }
00404     {
00405         QTestDate *td = g_new0 (QTestDate, 1);
00406         td->time = qof_time_new ();
00407         qof_time_set_secs (td->time, 
00408             G_GINT64_CONSTANT(-2208988801));
00409         qof_time_set_nanosecs (td->time, 0);
00410         td->date = qof_date_new ();
00411         td->date->qd_year = 1899;
00412         td->date->qd_mon  = 12;
00413         td->date->qd_mday = 31;
00414         td->date->qd_hour = 23;
00415         td->date->qd_min  = 59;
00416         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00417         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00418         qof_date_valid (td->date);
00419         td->string_list = NULL;
00420         td->string_list = g_list_prepend (td->string_list, "12/31/1899");
00421         td->string_list = g_list_prepend (td->string_list, "31/12/1899");
00422         td->string_list = g_list_prepend (td->string_list, "31.12.1899");
00423         td->string_list = g_list_prepend (td->string_list, "1899-12-31");
00424         td->string_list = g_list_prepend (td->string_list, "1899-12-31T23:59:59Z");
00425         td->string_list = g_list_prepend (td->string_list, 
00426             "1899-12-31 23:59:59.000000000 +0000");
00427         td->string_list = g_list_reverse (td->string_list);
00428         td->id = "19th century Millenium Eve";
00429         test_data = g_list_prepend (test_data, td);
00430     }
00431     {
00432         QTestDate *td = g_new0 (QTestDate, 1);
00433         td->time = qof_time_new ();
00434         qof_time_set_secs (td->time, 
00435             G_GINT64_CONSTANT(-13311993599));
00436         qof_time_set_nanosecs (td->time, 0);
00437         td->date = qof_date_new ();
00438         td->date->qd_year = 1548;
00439         td->date->qd_mon  = 2;
00440         td->date->qd_mday = 29;
00441         td->date->qd_hour = 0;
00442         td->date->qd_min  = 0;
00443         td->date->qd_sec  = G_GINT64_CONSTANT(1);
00444         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00445         qof_date_valid (td->date);
00446         td->string_list = NULL;
00447         td->string_list = g_list_prepend (td->string_list, "02/29/1548");
00448         td->string_list = g_list_prepend (td->string_list, "29/02/1548");
00449         td->string_list = g_list_prepend (td->string_list, "29.02.1548");
00450         td->string_list = g_list_prepend (td->string_list, "1548-02-29");
00451         td->string_list = g_list_prepend (td->string_list, "1548-02-29T00:00:01Z");
00452         td->string_list = g_list_prepend (td->string_list, 
00453             "1548-02-29 00:00:01.000000000 +0000");
00454         td->string_list = g_list_reverse (td->string_list);
00455         td->id = "16th century leap day";
00456         test_data = g_list_prepend (test_data, td);
00457     }
00458     {
00459         QTestDate *td = g_new0 (QTestDate, 1);
00460         td->time = qof_time_new ();
00461         qof_time_set_secs (td->time, G_GINT64_CONSTANT(-28502726400));
00462         qof_time_set_nanosecs (td->time, 0);
00463         td->date = qof_date_new ();
00464         td->date->qd_year = 1066;
00465         td->date->qd_mon  = 10;
00466         td->date->qd_mday = 14;
00467         td->date->qd_hour = 8;
00468         td->date->qd_min  = 0;
00469         td->date->qd_sec  = G_GINT64_CONSTANT(0);
00470         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00471         qof_date_valid (td->date);
00472         td->string_list = NULL;
00473         td->string_list = g_list_prepend (td->string_list, "10/14/1066");
00474         td->string_list = g_list_prepend (td->string_list, "14/10/1066");
00475         td->string_list = g_list_prepend (td->string_list, "14.10.1066");
00476         td->string_list = g_list_prepend (td->string_list, "1066-10-14");
00477         td->string_list = g_list_prepend (td->string_list, "1066-10-14T08:00:00Z");
00478         td->string_list = g_list_prepend (td->string_list, 
00479             "1066-10-14 08:00:00.000000000 +0000");
00480         td->string_list = g_list_reverse (td->string_list);
00481         td->id = "Battle of Hastings, 1066";
00482         test_data = g_list_prepend (test_data, td);
00483     }
00484     {
00485         QTestDate *td = g_new0 (QTestDate, 1);
00486         td->time = qof_time_new ();
00487         qof_time_set_secs (td->time, 
00488             G_GINT64_CONSTANT(-36417340799));
00489         qof_time_set_nanosecs (td->time, 0);
00490         td->date = qof_date_new ();
00491         td->date->qd_year = 815;
00492         td->date->qd_mon  = 12;
00493         td->date->qd_mday = 25;
00494         td->date->qd_hour = 0;
00495         td->date->qd_min  = 0;
00496         td->date->qd_sec  = G_GINT64_CONSTANT(1);
00497         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00498         qof_date_valid (td->date);
00499         td->string_list = NULL;
00500         td->string_list = g_list_prepend (td->string_list, "12/25/0815");
00501         td->string_list = g_list_prepend (td->string_list, "25/12/0815");
00502         td->string_list = g_list_prepend (td->string_list, "25.12.0815");
00503         td->string_list = g_list_prepend (td->string_list, "0815-12-25");
00504         td->string_list = g_list_prepend (td->string_list, "0815-12-25T00:00:01Z");
00505         td->string_list = g_list_prepend (td->string_list, 
00506             "0815-12-25 00:00:01.000000000 +0000");
00507         td->string_list = g_list_reverse (td->string_list);
00508         td->id = "9th century Christmas Day";
00509         test_data = g_list_prepend (test_data, td);
00510     }
00511     {
00512         QTestDate *td = g_new0 (QTestDate, 1);
00513         td->time = qof_time_new ();
00514         qof_time_set_secs (td->time, G_GINT64_CONSTANT(-60798160800));
00515         qof_time_set_nanosecs (td->time, 0);
00516         td->date = qof_date_new ();
00517         td->date->qd_year = 43;
00518         td->date->qd_mon  = 5;
00519         td->date->qd_mday = 20;
00520         td->date->qd_hour = 14;
00521         td->date->qd_min  = 0;
00522         td->date->qd_sec  = G_GINT64_CONSTANT(0);
00523         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00524         qof_date_valid (td->date);
00525         td->string_list = NULL;
00526         td->string_list = g_list_prepend (td->string_list, "05/20/0043");
00527         td->string_list = g_list_prepend (td->string_list, "20/05/0043");
00528         td->string_list = g_list_prepend (td->string_list, "20.05.0043");
00529         td->string_list = g_list_prepend (td->string_list, "0043-05-20");
00530         td->string_list = g_list_prepend (td->string_list, "0043-05-20T14:00:00Z");
00531         td->string_list = g_list_prepend (td->string_list, 
00532             "0043-05-20 14:00:00.000000000 +0000");
00533         td->string_list = g_list_reverse (td->string_list);
00534         td->id = "approx Roman invasion, 43AD";
00535         test_data = g_list_prepend (test_data, td);
00536     }
00541     {
00542         QTestDate *td = g_new0 (QTestDate, 1);
00543         td->time = qof_time_new ();
00544         qof_time_set_secs (td->time, G_GINT64_CONSTANT(-62167824001));
00545         qof_time_set_nanosecs (td->time, 0);
00546         td->date = qof_date_new ();
00547         td->date->qd_year = -1;
00548         td->date->qd_mon  = 12;
00549         td->date->qd_mday = 24;
00550         td->date->qd_hour = 23;
00551         td->date->qd_min  = 59;
00552         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00553         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00554         qof_date_valid (td->date);
00555         td->string_list = NULL;
00556         td->string_list = g_list_prepend (td->string_list, "12/24/-001");
00557         td->string_list = g_list_prepend (td->string_list, "24/12/-001");
00558         td->string_list = g_list_prepend (td->string_list, "24.12.-001");
00559         td->string_list = g_list_prepend (td->string_list, "-001-12-24");
00560         td->string_list = g_list_prepend (td->string_list, "-001-12-24T23:59:59Z");
00561         td->string_list = g_list_prepend (td->string_list, 
00562             "-001-12-24 23:59:59.000000000 +0000");
00563         td->string_list = g_list_reverse (td->string_list);
00564         td->id = "Xmas eve, 1BC";
00565         test_data = g_list_prepend (test_data, td);
00566     }
00567     {
00568         QTestDate *td = g_new0 (QTestDate, 1);
00569         td->time = qof_time_new ();
00570         qof_time_set_secs (td->time, 
00571             G_GINT64_CONSTANT(-204110409601));
00572         qof_time_set_nanosecs (td->time, 0);
00573         td->date = qof_date_new ();
00574         td->date->qd_year = -4499;
00575         td->date->qd_mon  = 12;
00576         td->date->qd_mday = 31;
00577         td->date->qd_hour = 23;
00578         td->date->qd_min  = 59;
00579         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00580         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00581         qof_date_valid (td->date);
00582         td->string_list = NULL;
00583         td->string_list = g_list_prepend (td->string_list, "12/31/-4499");
00584         td->string_list = g_list_prepend (td->string_list, "31/12/-4499");
00585         td->string_list = g_list_prepend (td->string_list, "31.12.-4499");
00586         td->string_list = g_list_prepend (td->string_list, "-4499-12-31");
00587         td->string_list = g_list_prepend (td->string_list, "-4499-12-31T23:59:59Z");
00588         td->string_list = g_list_prepend (td->string_list, 
00589             "-4499-12-31 23:59:59.000000000 +0000");
00590         td->string_list = g_list_reverse (td->string_list);
00591         td->id = "far past.";
00592         test_data = g_list_prepend (test_data, td);
00593     }
00594     {
00595         QTestDate *td = g_new0 (QTestDate, 1);
00596         td->time = qof_time_new ();
00597         qof_time_set_secs (td->time, 
00598             G_GINT64_CONSTANT(-2097527529601));
00599         qof_time_set_nanosecs (td->time, 0);
00600         td->date = qof_date_new ();
00601         td->date->qd_year = -64499;
00602         td->date->qd_mon  = 12;
00603         td->date->qd_mday = 31;
00604         td->date->qd_hour = 23;
00605         td->date->qd_min  = 59;
00606         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00607         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00608         qof_date_valid (td->date);
00609         td->string_list = NULL;
00610         td->string_list = g_list_prepend (td->string_list, "12/31/-64499");
00611         td->string_list = g_list_prepend (td->string_list, "31/12/-64499");
00612         td->string_list = g_list_prepend (td->string_list, "31.12.-64499");
00613         td->string_list = g_list_prepend (td->string_list, "-64499-12-31");
00614         td->string_list = g_list_prepend (td->string_list, "-64499-12-31T23:59:59Z");
00615         td->string_list = g_list_prepend (td->string_list, 
00616             "-64499-12-31 23:59:59.000000000 +0000");
00617         td->string_list = g_list_reverse (td->string_list);
00618         td->id = "far, far past.";
00619         test_data = g_list_prepend (test_data, td);
00620     }
00621     /* now test far future dates */
00622     {
00623         QTestDate *td = g_new0 (QTestDate, 1);
00624         td->time = qof_time_new ();
00625         qof_time_set_secs (td->time, G_GINT64_CONSTANT(32679095666));
00626         qof_time_set_nanosecs (td->time, 800);
00627         td->date = qof_date_new ();
00628         td->date->qd_year = 3005;
00629         td->date->qd_mon  = 7;
00630         td->date->qd_mday = 24;
00631         td->date->qd_hour = 6;
00632         td->date->qd_min  = 34;
00633         td->date->qd_sec  = G_GINT64_CONSTANT(26);
00634         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00635         qof_date_valid (td->date);
00636         td->string_list = NULL;
00637         td->string_list = g_list_prepend (td->string_list, "07/24/3005");
00638         td->string_list = g_list_prepend (td->string_list, "24/07/3005");
00639         td->string_list = g_list_prepend (td->string_list, "24.07.3005");
00640         td->string_list = g_list_prepend (td->string_list, "3005-07-24");
00641         td->string_list = g_list_prepend (td->string_list, "3005-07-24T06:34:26Z");
00642         td->string_list = g_list_prepend (td->string_list, 
00643             "3005-07-24 06:34:26.000000800 +0000");
00644         td->string_list = g_list_reverse (td->string_list);
00645         td->id = "24th July 3005";
00646         test_data = g_list_prepend (test_data, td);
00647     }
00648     {
00649         QTestDate *td = g_new0 (QTestDate, 1);
00650         td->time = qof_time_new ();
00651         qof_time_set_secs (td->time, 
00652             G_GINT64_CONSTANT(79839129599));
00653         qof_time_set_nanosecs (td->time, 50000);
00654         td->date = qof_date_new ();
00655         td->date->qd_year = 4499;
00656         td->date->qd_mon  = 12;
00657         td->date->qd_mday = 31;
00658         td->date->qd_hour = 23;
00659         td->date->qd_min  = 59;
00660         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00661         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00662         qof_date_valid (td->date);
00663         td->string_list = NULL;
00664         td->string_list = g_list_prepend (td->string_list, "12/31/4499");
00665         td->string_list = g_list_prepend (td->string_list, "31/12/4499");
00666         td->string_list = g_list_prepend (td->string_list, "31.12.4499");
00667         td->string_list = g_list_prepend (td->string_list, "4499-12-31");
00668         td->string_list = g_list_prepend (td->string_list, "4499-12-31T23:59:59Z");
00669         td->string_list = g_list_prepend (td->string_list, 
00670             "4499-12-31 23:59:59.000050000 +0000");
00671         td->string_list = g_list_reverse (td->string_list);
00672         td->id = "44th century Millenium Eve";
00673         test_data = g_list_prepend (test_data, td);
00674     }
00675     {
00676         QTestDate *td = g_new0 (QTestDate, 1);
00677         td->time = qof_time_new ();
00678         qof_time_set_secs (td->time, 
00679             G_GINT64_CONSTANT(395408649599));
00680         qof_time_set_nanosecs (td->time, 7000000);
00681         td->date = qof_date_new ();
00682         td->date->qd_year = 14499;
00683         td->date->qd_mon  = 12;
00684         td->date->qd_mday = 31;
00685         td->date->qd_hour = 23;
00686         td->date->qd_min  = 59;
00687         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00688         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00689         qof_date_valid (td->date);
00690         td->string_list = NULL;
00691         td->string_list = g_list_prepend (td->string_list, "12/31/14499");
00692         td->string_list = g_list_prepend (td->string_list, "31/12/14499");
00693         td->string_list = g_list_prepend (td->string_list, "31.12.14499");
00694         td->string_list = g_list_prepend (td->string_list, "14499-12-31");
00695         td->string_list = g_list_prepend (td->string_list, "14499-12-31T23:59:59Z");
00696         td->string_list = g_list_prepend (td->string_list, 
00697             "14499-12-31 23:59:59.007000000 +0000");
00698         td->string_list = g_list_reverse (td->string_list);
00699         td->id = "144th century Millenium Eve";
00700         test_data = g_list_prepend (test_data, td);
00701     }
00702     {
00703         QTestDate *td = g_new0 (QTestDate, 1);
00704         td->time = qof_time_new ();
00705         qof_time_set_secs (td->time, 
00706             G_GINT64_CONSTANT(74869815369599));
00707         qof_time_set_nanosecs (td->time, 45321545);
00708         td->date = qof_date_new ();
00709         td->date->qd_year = 2374499;
00710         td->date->qd_mon  = 12;
00711         td->date->qd_mday = 31;
00712         td->date->qd_hour = 23;
00713         td->date->qd_min  = 59;
00714         td->date->qd_sec  = G_GINT64_CONSTANT(59);
00715         td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
00716         qof_date_valid (td->date);
00717         td->string_list = NULL;
00718         td->string_list = g_list_prepend (td->string_list, "12/31/2374499");
00719         td->string_list = g_list_prepend (td->string_list, "31/12/2374499");
00720         td->string_list = g_list_prepend (td->string_list, "31.12.2374499");
00721         td->string_list = g_list_prepend (td->string_list, "2374499-12-31");
00722         td->string_list = g_list_prepend (td->string_list, "2374499-12-31T23:59:59Z");
00723         td->string_list = g_list_prepend (td->string_list,
00724             "2374499-12-31 23:59:59.045321545 +0000");
00725         td->string_list = g_list_reverse (td->string_list);
00726         td->id = "far, far future";
00727         test_data = g_list_prepend (test_data, td);
00728     }
00729 }
00730 
00731 static void
00732 free_test_data (gpointer data, gpointer user_data __attribute__ ((unused)))
00733 {
00734     QTestDate *td;
00735 
00736     td = (QTestDate*)data;
00737     qof_date_free (td->date);
00738     qof_time_free (td->time);
00739     td->string_list = NULL;
00740     g_free (td);
00741     td = NULL;
00742 }
00743 
00744 static void
00745 test_date_close (void)
00746 {
00747     g_list_foreach (test_data, free_test_data, NULL);
00748 }
00749 
00750 static void
00751 scan_and_stamp (const gchar * str, QofDateFormat df, QofTimeSecs check)
00752 {
00753     QofTime *scan;
00754     QofDate *qd;
00755     gchar *stamp;
00756 
00757     qd = qof_date_parse (str, df);
00758     scan = qof_date_to_qtime (qd);
00759     do_test ((scan != NULL), "scan failed");
00760     if (scan == NULL)
00761         return;
00762     do_test ((0 == safe_strcasecmp(qd->qd_zone, "GMT")),
00763         " timezone reset incorrect");
00764     do_test ((qof_time_get_secs (scan) == check), 
00765         "wrong time value");
00766     if (qof_time_get_secs (scan) != check)
00767         PERR (" wrong time value %"
00768             G_GINT64_FORMAT " %" G_GINT64_FORMAT " diff=%"
00769             G_GINT64_FORMAT " df=%d str=%s cmp=%s",
00770             qof_time_get_secs (scan), check,
00771             qof_time_get_secs (scan) - check, df, str,
00772             qof_date_print(qd, QOF_DATE_FORMAT_UTC));
00773     stamp = qof_date_print (qof_date_from_qtime(scan), df);
00774     do_test ((stamp != NULL), "stamp failed");
00775     /* timezone tests mean stamp cannot be compared to str */
00776     qof_time_free (scan);
00777 }
00778 
00779 static void
00780 stamp_and_scan (QofTimeSecs start, glong nanosecs, 
00781     QofDateFormat df)
00782 {
00783     gchar *str1, *str2;
00784     QofDate *check;
00785     QofTime *time, *scan;
00786 
00787     time = qof_time_new ();
00788     qof_time_set_secs (time, start);
00789     qof_time_set_nanosecs (time, nanosecs);
00790     str1 = qof_date_print (qof_date_from_qtime(time), df);
00791     do_test ((str1 != NULL), "stamp failed");
00792     if (!str1)
00793         return;
00794     check = qof_date_parse (str1, df);
00795     do_test ((check != NULL), "parse failed");
00796     if (!check)
00797         PERR (" tried to parse %s\n", str1);
00798     scan = qof_date_to_qtime (check);
00799     qof_date_free (check);
00800     do_test ((scan != NULL), "scan failed");
00801     if (!scan)
00802         return;
00803     /* depending on the format, data may be lost here
00804     as some formats do not encode the time. So only
00805     test that the returned stamp is the same. */
00806     check = qof_date_from_qtime (scan);
00807     str2 = qof_date_print (check, df);
00808     qof_date_free (check);
00809     /* 2 digit year errors with format 6  */
00810     do_test ((str2 != NULL), "printed string is null");
00811     do_test ((qof_date_from_qtime (scan) != NULL),
00812         "from_qtime failed");
00813     do_test ((0 == safe_strcasecmp (str1, str2)), 
00814         "stamp different to scan");
00815     if (0 != safe_strcasecmp (str1, str2))
00816         PERR (" df=%d str=%s scan=%s", df, str1, str2);
00817     qof_time_free (scan);
00818     qof_time_free (time);
00819     g_free (str1);
00820     g_free (str2);
00821 }
00822 
00823 static void
00824 run_print_scan_tests (void)
00825 {
00826     gint i;
00827     gint64 secs;
00828     QofDateFormat df;
00829 
00830     /* Set a secs value at the limit of the range of time_t 
00831        on 32bit systems. */
00832     secs = G_MAXINT32;
00833     /* add ten days */
00834     secs += SECS_PER_DAY * 10;
00835     for (i = 1; i <= QOF_DATE_FORMAT_ISO8601; i++)
00836     {
00837         stamp_and_scan (796179600, 0, i);
00838         stamp_and_scan (796179500, 72000, i);
00839         stamp_and_scan (152098136, 0, i);
00840         stamp_and_scan (1964049931, 0, i);
00841         stamp_and_scan (1162088421, 12548000, i);
00842         stamp_and_scan (325659000 - 6500, 0, i);
00843         stamp_and_scan (1143943200, 0, i);
00844         stamp_and_scan (1603591171, 595311000, i);
00845         stamp_and_scan (1738909365, 204102000, i);
00846         stamp_and_scan (1603591171, 595311000, i);
00847         stamp_and_scan (1143943200 - 1, 0, i);
00848         stamp_and_scan (1143943200, 0, i);
00849         stamp_and_scan (1143943200 + (7 * 60 * 60), 0, i);
00850         stamp_and_scan (1143943200 + (8 * 60 * 60), 0, i);
00851         stamp_and_scan (1841443200, 0, i);
00852 
00853         /* work with early dates */
00854         stamp_and_scan (G_GINT64_CONSTANT (-796179600), 253, i);
00855         stamp_and_scan (G_GINT64_CONSTANT (-152098136), 865, i);
00856         stamp_and_scan (G_GINT64_CONSTANT (-1143943200), 67, i);
00857         stamp_and_scan (G_GINT64_CONSTANT (-1964049931), 53, i);
00858         stamp_and_scan (G_GINT64_CONSTANT (-2463880447), 48, i);
00859         stamp_and_scan (G_GINT64_CONSTANT (-22905158401), 9, i);
00860         stamp_and_scan (G_GINT64_CONSTANT (-28502726400), 1, i);
00861         stamp_and_scan (G_GINT64_CONSTANT (-60798211200), 0, i);
00862         stamp_and_scan (G_GINT64_CONSTANT (-32727638740), 0, i);
00863 /*      stamp_and_scan (G_GINT64_CONSTANT (-86956848000), 0, i);*/
00864         stamp_and_scan (secs, 0, i);
00865         /* Wed 29 Jan 2048 03:14:07 UTC */
00866         stamp_and_scan (G_GINT64_CONSTANT (2463880447), 0, i);
00867         /* Sat 29 Jan 2050 03:14:07 UTC */
00868         stamp_and_scan (G_GINT64_CONSTANT (2527038847), 0, i);
00869         /* work with far future dates */
00870         /* 32,727,638,740 Fri Feb  6 02:45:40 UTC 3007 */
00871         stamp_and_scan (G_GINT64_CONSTANT (32727638740), 0, i);
00872         /* 88,313,632,867 Fri Jul 19 12:41:07 UTC 4768 */
00873         stamp_and_scan (G_GINT64_CONSTANT (88313632867), 0, i);
00874         /* 189,216,632,865 Fri Jan 14 07:47:45 UTC 7966 */
00875         stamp_and_scan (G_GINT64_CONSTANT (189216632865), 0, i);
00876         /* 378,432,632,864 Sat Jan 20 07:47:44 UTC 13,962  */
00877         stamp_and_scan (G_GINT64_CONSTANT (378432632864), 0, i);
00878         /* 3165071328567 Wed Feb 13 00:09:27 UTC 102,267 */
00879         stamp_and_scan (G_GINT64_CONSTANT (3165071328567), 0, i);
00880     }
00881     /* far, far future dates delay the test */
00882 #ifdef TEST_DEBUG
00883     /* 43165071328567 Wed Aug 28 23:16:07 UTC 1,369,816 */
00884     stamp_and_scan (G_GINT64_CONSTANT (3165071328567), 
00885         0, QOF_DATE_FORMAT_UTC);
00886     /* 843165071328567 Tue Jun 19 05:29:27 UTC 26,720,807 */
00887     stamp_and_scan (G_GINT64_CONSTANT(843165071328567), 
00888         0, QOF_DATE_FORMAT_UTC);
00890     /* 9843165071328567 Mon Jan  9 21:29:27 UTC 311,919,454 */
00891 /*  stamp_and_scan (G_GINT64_CONSTANT(9843165071328567), 
00892         0, QOF_DATE_FORMAT_UTC);
00893     stamp_and_scan (G_GINT64_CONSTANT(9843165071328567), 
00894         354758450, QOF_DATE_FORMAT_ISO8601);*/
00895 #endif
00896     scan_and_stamp ("05/09/2006", QOF_DATE_FORMAT_US, 
00897         1147132800);
00898     scan_and_stamp ("09/05/2006", QOF_DATE_FORMAT_UK, 
00899         1147132800);
00900     scan_and_stamp ("09.05.2006", QOF_DATE_FORMAT_CE, 
00901         1147132800);
00902     scan_and_stamp ("2006-05-09", QOF_DATE_FORMAT_ISO, 
00903         1147132800);
00904     scan_and_stamp ("2006-05-09T00:00:00Z", QOF_DATE_FORMAT_UTC, 
00905         1147132800);
00906     scan_and_stamp ("2006-05-09T14:49:04Z", QOF_DATE_FORMAT_UTC, 
00907         1147186144);
00908 
00909     /* test a custom format */
00910     df = 0;
00911     do_test ((qof_date_format_add ("%Y-%m-%d %H:%M:%S %z", 
00912         &df) == TRUE), "failed to add scan suitable format");
00913     /* test timezone settings */
00914     /* 1972-01-01T00:00:00Z */
00915     scan_and_stamp ("1971-12-31 15:00:00 -0900", df, 63072000);
00916     /* 1980-01-01T00:00:00Z */
00917     scan_and_stamp ("1979-12-31 15:00:00 -0900", df, 315532800);
00918     scan_and_stamp ("1980-01-01 00:00:00 -0000", df, 315532800);
00919     scan_and_stamp ("1980-01-01 00:00:00 +0000", df, 315532800);
00920     scan_and_stamp ("1980-01-01 09:00:00 +0900", df, 315532800);
00921     scan_and_stamp ("1980-01-01 08:30:00 +0830", df, 315532800);
00922     /* pre-1970 dates */
00923     scan_and_stamp ("1963-11-22 14:00:00 -0500", df, -192776400);
00924     scan_and_stamp ("1945-09-08 11:02:00 +0900", df, -767311080);
00925     scan_and_stamp ("1918-11-11 11:00:00 +0000", df, -1613826000);
00926     /* work with really early dates */
00927     /* 14th October 1066 (time is just a guess) */
00928     scan_and_stamp ("1066-10-14 08:00:00 +0000", df, 
00929         G_GINT64_CONSTANT (-28502726400));
00930     /* May 43AD Roman invasion (day and time guessed) */
00931     scan_and_stamp ("0043-05-20 14:00:00 +0000", df, 
00932         G_GINT64_CONSTANT (-60798160800));
00933     {
00934         QofDate *qd, *qd1, *qd2;
00935         QofTime *qt, *copy;
00936         gint64 secs;
00937         gchar * str1, * str2;
00938 
00939         qt = qof_time_new ();
00940         /* Tue May  9 14:50:10 UTC 2006 */
00941         qof_time_set_secs (qt, 1147186210);
00942         copy = qof_time_copy (qt);
00943         do_test ((copy != NULL), "copy time NULL");
00944         qd1 = qof_date_from_qtime(qt);
00945         qd2 = qof_date_from_qtime(copy);
00946         str1 = g_strdup_printf ("%s\n", qof_date_print(qd1, QOF_DATE_FORMAT_CUSTOM));
00947         str2 = g_strdup_printf ("%s\n", qof_date_print(qd2, QOF_DATE_FORMAT_CUSTOM));
00948         do_test ((safe_strcmp(str1, str2) == 0), "copied time fails to match original");
00949         g_free (str1);
00950         g_free (str2);
00951         do_test ((qof_time_is_valid(qt) == TRUE), "qt time invalid");
00952         do_test ((qof_time_is_valid(copy) == TRUE), "copy time invalid");
00953         do_test ((qof_time_equal(qt, copy) == TRUE), "copy time not equal");
00954 
00955         /* test %s and %N as well as %s.%N */
00956         {
00957             gint id, id1, id2;
00958             gchar * str;
00959             QofDate * qd_s, * qd_a;
00960             QofTime * qt_s;
00961             gint64 secs = qof_time_get_secs (qt);
00962             gint64 nsecs = qof_time_get_nanosecs (qt) + 
00963                 get_random_int_in_range(0, 999999);
00964 
00965             qt_s = qof_time_copy (qt);
00966             qd_s = qof_date_from_qtime (qt_s);
00967             qof_date_format_add ("%s", &id);
00968             id1 = id;
00969             do_test ((id > 0), "add seconds only custom format");
00970             qd_s = qof_date_from_qtime(qt_s);
00971             str = qof_date_print (qd_s, id);
00972             qd_a = qof_date_parse (str, id);
00973             str = qof_date_print (qd_a, QOF_DATE_FORMAT_UTC);
00974             str = qof_date_print (qd_a, id);
00975             qt_s = qof_date_to_qtime (qd_a);
00976             do_test (secs == qof_time_get_secs (qt_s), "second parsing failed");
00977             
00978             qt_s = qof_time_copy (qt);
00979             qof_time_set_nanosecs (qt_s, nsecs);
00980             qd_s = qof_date_from_qtime (qt_s);
00981             qof_date_format_add ("%N", &id);
00982             id2 = id;
00983             do_test ((id > id1), "add nanoseconds only custom format");
00984             qd_s = qof_date_from_qtime(qt_s);
00985             str = qof_date_print (qd_s, id);
00986             qd_s = qof_date_parse (str, id);
00987             qt_s = qof_date_to_qtime (qd_s);
00988             do_test (nsecs == qof_time_get_nanosecs (qt_s), "nanosecond parsing failed");
00989     
00990             qof_date_format_add ("%s.%N", &id);
00991             do_test ((id > id2), "add sec+nanosec custom format");
00992             qof_time_free (qt_s);
00993             qt_s = qof_time_new ();
00994             qof_time_set_secs (qt_s, secs);
00995             qof_time_set_nanosecs (qt_s, nsecs);
00996             qd_s = qof_date_from_qtime(qt_s);
00997             str = qof_date_print (qd_s, id);
00998             qd_s = qof_date_parse (str, id);
00999             qt_s = qof_date_to_qtime (qd_s);
01000             do_test (nsecs == qof_time_get_nanosecs (qt_s), "s.N - nanosecs failed");
01001             do_test (secs == qof_time_get_secs (qt_s), "s.N - seconds failed");
01002         }
01003         qd = qof_date_from_qtime (qt);
01004         do_test ((qof_date_adddays (qd, 45) == TRUE),
01005                  "add_days failed");
01006         secs = 1147186210 + (45 * SECS_PER_DAY);
01007         qof_time_free (qt);
01008         qt = qof_date_to_qtime (qd);
01009         qof_date_free (qd);
01010         do_test ((secs == qof_time_get_secs (qt)),
01011                  "add_days gave incorrect result.");
01012         if (secs != qof_time_get_secs (qt))
01013             PERR (" secs=%" G_GINT64_FORMAT "cmp=%"
01014             G_GINT64_FORMAT, secs, qof_time_get_secs (qt));
01015         qof_time_set_secs (qt, 1147186210);
01016         qd = qof_date_from_qtime (qt);
01017         do_test ((qof_date_addmonths (qd, 50, TRUE) == TRUE),
01018                  "add_months failed");
01019         qof_time_free (qt);
01020         qt = qof_date_to_qtime (qd);
01021         do_test ((1278687010 == qof_time_get_secs (qt)),
01022                  "add_months gave incorrect result.");
01023         qof_time_free (qt);
01024         qof_date_free (qd);
01025     }
01026 }
01027 
01028 static void
01029 run_qofdate_test (void)
01030 {
01031     QofDateFormat df, test;
01032 
01033     df = qof_date_format_get_current ();
01034     /* default date format tests */
01035     {
01036         qof_date_format_set_current (QOF_DATE_FORMAT_UK);
01037         test = qof_date_format_get_current ();
01038         do_test ((test == QOF_DATE_FORMAT_UK), 
01039             "setting current format as UK");
01040         do_test ((safe_strcasecmp (qof_date_format_to_name (test), 
01041             "uk") == 0), "getting the shorthand name");
01042         do_test ((FALSE ==
01043             qof_date_format_set_name ("foo", QOF_DATE_FORMAT_UK)),
01044             "default name should not be overridden");
01045         do_test ((QOF_DATE_FORMAT_UK == 
01046             qof_date_format_from_name ("uk")),
01047             "getting date format from shorthand name");
01048         do_test (('/' == qof_date_format_get_date_separator (test)),
01049             "getting date format separator from date format");
01050         do_test ((FALSE == qof_date_format_set_date_separator (':', 
01051             test)), "default separator should not be overridden");
01052     }
01053     /* custom date format tests */
01054     {
01055         QofDateFormat df, df2;
01056         do_test ((qof_date_format_add ("%T", &df) == TRUE),
01057                  "adding a valid format");
01058         do_test ((qof_date_format_add ("%a%A%b%B%c%C%d%D%e%F%f%r", 
01059                 &df2) == FALSE), "adding an invalid format");
01060         qof_date_format_set_current (df);
01061         test = qof_date_format_get_current ();
01062         do_test ((test == df), "setting current format");
01063         do_test ((safe_strcasecmp (qof_date_format_to_name (test), 
01064             "%T") == 0), "getting the shorthand name");
01065         do_test ((TRUE == qof_date_format_set_name ("foo", test)),
01066                  "custom name should be overridden");
01067         do_test ((test == qof_date_format_from_name ("foo")),
01068                  "getting date format from shorthand name");
01069         do_test (('\0' == qof_date_format_get_date_separator (test)),
01070                  "getting date format separator from date format");
01071         do_test ((TRUE == qof_date_format_set_date_separator (':', test)),
01072                  "custom separator should be overridden");
01073         do_test ((':' == qof_date_format_get_date_separator (test)),
01074                  "getting modified date format separator from date format");
01075     }
01076     qof_date_format_set_current (df);
01077     /* run tests on date_normalise */
01078     {
01079         QofDate *date;
01080 
01081         date = qof_date_new ();
01082         /* Mon Jan  3 00:00:30 UTC 2000 */
01083         date->qd_sec = SECS_PER_DAY * 2 + 30;
01084         date->qd_year = 2000;
01085         do_test ((qof_date_valid (date) == TRUE), "date 1 was invalid");
01086         do_test ((date->qd_sec == 30), "normalised seconds incorrect - 1");
01087         do_test ((date->qd_mday == 3), "normalised day incorrect - 1");
01088         date->qd_mday = 54;
01089         do_test ((qof_date_valid (date) == TRUE), "date 2 was invalid");
01090         do_test ((date->qd_sec == 30), "normalised seconds incorrect - 2");
01091         do_test ((date->qd_mday == 23), "normalised day incorrect - 2");
01092         date->qd_hour = 34;
01093         qof_date_valid (date);
01094         do_test ((date->qd_hour == 10), "normalised hour incorrect");
01095         do_test ((date->qd_mday == 24), "normalised day incorrect - 3");
01096         date->qd_mon = 17;
01097         qof_date_valid (date);
01098         do_test ((date->qd_mon == 5), "normalised month incorrect");
01099         do_test ((date->qd_year == 2001), "normalised year incorrect");
01100         date->qd_hour = 27;
01101         qof_date_valid (date);
01102         do_test ((date->qd_hour == 3), "normalised hour incorrect - 1");
01103         do_test ((date->qd_mday == 25), "normalised day incorrect - 4");
01104         date->qd_hour = -53;
01105         qof_date_valid (date);
01106         do_test ((date->qd_hour == 19), "normalised hour incorrect - 2");
01107         do_test ((date->qd_mday == 22), "normalised day incorrect - 5");
01108         date->qd_min = -225;
01109         qof_date_valid (date);
01110         do_test ((date->qd_min == 15), "normalised min incorrect");
01111         do_test ((date->qd_hour == 15), "normalised hour incorrect - 3");
01112         date->qd_min = 5;
01113         date->qd_sec = 68;
01114         qof_date_valid (date);
01115         do_test ((date->qd_sec == 8), "doxygen sec example incorrect - 1");
01116         do_test ((date->qd_min == 6),  "doxygen min example incorrect - 1");
01117         date->qd_min = 5;
01118         date->qd_sec = -64;
01119         qof_date_valid (date);
01120         do_test ((date->qd_sec == 56), "doxygen sec example incorrect - 2");
01121         do_test ((date->qd_min == 3),  "doxygen min example incorrect - 2");
01122     }
01123     /* run tests against QofDate<->QofTime conversions. */
01124     /* opposite direction compared to the tests above. */
01125     {
01126         QofDate *qd;
01127         QofTime *qt;
01128         gchar *str1;
01129 
01130         qd = qof_date_new ();
01131         qd->qd_year = 2006;
01132         qd->qd_mon = 5;
01133         qd->qd_mday = 30;
01134         qd->qd_hour = 18;
01135         qd->qd_min = 24;
01136         qd->qd_sec = 17;
01137         qd->qd_nanosecs = 123456789;
01138         do_test ((qof_date_valid (qd)), "date not valid");
01139         qt = qof_date_to_qtime (qd);
01140         str1 = qof_date_print (qd, QOF_DATE_FORMAT_UTC);
01141         do_test ((0 == safe_strcasecmp (str1, 
01142             "2006-05-30T18:24:17Z")), "with nanosecs");
01143         do_test ((qof_time_get_nanosecs (qt) ==
01144             123456789L), "nanosecs mismatched.");
01145         do_test ((0 == safe_strcasecmp ("05/30/2006",
01146             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01147             "strftime:US:first");
01148         do_test ((0 == safe_strcasecmp ("30/05/2006",
01149             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01150             "strftime:UK:first");
01151         do_test ((0 == safe_strcasecmp ("30.05.2006",
01152             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01153             "strftime:CE:first");
01154         do_test ((0 == safe_strcasecmp ("2006-05-30",
01155             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01156             "strftime:ISO:first");
01157         do_test ((0 == safe_strcasecmp ("2006-05-30T18:24:17Z",
01158             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01159             "strftime:UTC:first");
01160         do_test ((0 != safe_strcasecmp (NULL,
01161             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01162             "strftime:LOCALE:first:inrange");
01163         do_test ((0 != safe_strcasecmp (NULL,
01164             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01165             "strftime:CUSTOM:first:inrange");
01166         qof_date_free (qd);
01167         qof_time_free (qt);
01168         qd = qof_date_new ();
01169         qd->qd_year = 3005;
01170         qd->qd_mon = 07;
01171         qd->qd_mday = 24;
01172         qd->qd_hour = 06;
01173         qd->qd_min  = 34;
01174         qd->qd_sec  = 26;
01175         do_test ((qof_date_valid (qd)), "date not valid");
01176         qt = qof_date_to_qtime (qd);
01177         do_test ((0 == safe_strcasecmp ("07/24/3005",
01178             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01179             "strftime:US:forward");
01180         do_test ((0 == safe_strcasecmp ("24/07/3005",
01181             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01182             "strftime:UK:forward");
01183         do_test ((0 == safe_strcasecmp ("24.07.3005",
01184             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01185             "strftime:CE:forward");
01186         do_test ((0 == safe_strcasecmp ("3005-07-24",
01187             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01188             "strftime:ISO:forward");
01189         do_test ((0 == safe_strcasecmp ("3005-07-24T06:34:26Z",
01190             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01191             "strftime:UTC:forward");
01192         do_test ((0 != safe_strcasecmp (NULL,
01193             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01194             "strftime:LOCALE:forward:inrange");
01195         do_test ((0 != safe_strcasecmp (NULL,
01196             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01197             "strftime:CUSTOM:forward:inrange");
01198         qof_date_free (qd);
01199         qd = qof_date_new ();
01200         qd->qd_year = 4500;
01201         qd->qd_mon = 07;
01202         qd->qd_mday = 24;
01203         qd->qd_hour = 06;
01204         qd->qd_min  = 34;
01205         qd->qd_sec  = 26;
01206         do_test ((qof_date_valid (qd)), "date not valid");
01207         qt = qof_date_to_qtime (qd);
01208         do_test ((0 == safe_strcasecmp ("07/24/4500",
01209             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01210             "strftime:US:fifth");
01211         do_test ((0 == safe_strcasecmp ("24/07/4500",
01212             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01213             "strftime:UK:fifth");
01214         do_test ((0 == safe_strcasecmp ("24.07.4500",
01215             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01216             "strftime:CE:fifth");
01217         do_test ((0 == safe_strcasecmp ("4500-07-24",
01218             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01219             "strftime:ISO:fifth");
01220         do_test ((0 == safe_strcasecmp ("4500-07-24T06:34:26Z",
01221             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01222             "strftime:UTC:fifth");
01223         do_test ((0 != safe_strcasecmp (NULL,
01224             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01225             "strftime:LOCALE:fifth:inrange");
01226         do_test ((0 != safe_strcasecmp (NULL,
01227             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01228             "strftime:CUSTOM:fifth:inrange");
01229         qof_date_free (qd);
01230         qd = qof_date_new ();
01231         qd->qd_year = 45000;
01232         qd->qd_mon = 07;
01233         qd->qd_mday = 24;
01234         qd->qd_hour = 06;
01235         qd->qd_min  = 34;
01236         qd->qd_sec  = 26;
01237         do_test ((qof_date_valid (qd)), "date not valid");
01238         qt = qof_date_to_qtime (qd);
01239         do_test ((0 == safe_strcasecmp ("07/24/45000",
01240             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01241             "strftime:US:forward2");
01242         do_test ((0 == safe_strcasecmp ("24/07/45000",
01243             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01244             "strftime:UK:forward2");
01245         do_test ((0 == safe_strcasecmp ("24.07.45000",
01246             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01247             "strftime:CE:forward2");
01248         do_test ((0 == safe_strcasecmp ("45000-07-24",
01249             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01250             "strftime:ISO:forward2");
01251         do_test ((0 == safe_strcasecmp ("45000-07-24T06:34:26Z",
01252             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01253             "strftime:UTC:forward2");
01254         do_test ((0 != safe_strcasecmp (NULL,
01255             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01256             "strftime:LOCALE:forward2:outofrange");
01257         do_test ((0 != safe_strcasecmp (NULL,
01258             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01259             "strftime:CUSTOM:forward2:outofrange");
01260         qof_date_free (qd);
01261         g_free (str1);
01262         qd = qof_date_new ();
01263         qd->qd_year = 1914;
01264         qd->qd_mon = 11;
01265         qd->qd_mday = 11;
01266         qd->qd_hour = 11;
01267         do_test ((qof_date_valid (qd)), "date not valid");
01268         qt = qof_date_to_qtime (qd);
01269         str1 = qof_date_print (qd, QOF_DATE_FORMAT_UTC);
01270         do_test ((0 == safe_strcasecmp (str1,
01271             "1914-11-11T11:00:00Z")), "armistice day");
01272         do_test ((0 == safe_strcasecmp ("11/11/1914",
01273             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01274             "strftime:US:second");
01275         do_test ((0 == safe_strcasecmp ("11/11/1914",
01276             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01277             "strftime:UK:second");
01278         do_test ((0 == safe_strcasecmp ("11.11.1914",
01279             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01280             "strftime:CE:second");
01281         do_test ((0 == safe_strcasecmp ("1914-11-11",
01282             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01283             "strftime:ISO:second");
01284         do_test ((0 == safe_strcasecmp ("1914-11-11T11:00:00Z",
01285             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01286             "strftime:UTC:second");
01287         do_test ((0 != safe_strcasecmp (NULL,
01288             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01289             "strftime:LOCALE:second:inrange");
01290         do_test ((0 != safe_strcasecmp (NULL,
01291             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01292             "strftime:CUSTOM:second:inrange");
01293         qof_date_free (qd);
01294         qof_time_free (qt);
01295         qd = qof_date_new ();
01296         qd->qd_year = 1812;
01297         qd->qd_mon = 07;
01298         qd->qd_mday = 24;
01299         qd->qd_hour = 06;
01300         qd->qd_min  = 34;
01301         qd->qd_sec  = 26;
01302         do_test ((qof_date_valid (qd)), "date not valid");
01303         qt = qof_date_to_qtime (qd);
01304         do_test ((0 == safe_strcasecmp ("07/24/1812",
01305             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01306             "strftime:US:third");
01307         do_test ((0 == safe_strcasecmp ("24/07/1812",
01308             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01309             "strftime:UK:third");
01310         do_test ((0 == safe_strcasecmp ("24.07.1812",
01311             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01312             "strftime:CE:third");
01313         do_test ((0 == safe_strcasecmp ("1812-07-24",
01314             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01315             "strftime:ISO:third");
01316         do_test ((0 == safe_strcasecmp ("1812-07-24T06:34:26Z",
01317             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01318             "strftime:UTC:third");
01319         do_test ((0 == safe_strcasecmp (NULL,
01320             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01321             "strftime:LOCALE:third:outofrange");
01322         do_test ((0 == safe_strcasecmp (NULL,
01323             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01324             "strftime:CUSTOM:third:outofrange");
01325         qof_date_free (qd);
01326         qd = qof_date_new ();
01327         qd->qd_year = 1066;
01328         qd->qd_mon = 07;
01329         qd->qd_mday = 24;
01330         qd->qd_hour = 06;
01331         qd->qd_min  = 34;
01332         qd->qd_sec  = 26;
01333         do_test ((qof_date_valid (qd)), "date not valid");
01334         qt = qof_date_to_qtime (qd);
01335         do_test ((0 == safe_strcasecmp ("07/24/1066",
01336             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01337             "strftime:US:fourth");
01338         do_test ((0 == safe_strcasecmp ("24/07/1066",
01339             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01340             "strftime:UK:fourth");
01341         do_test ((0 == safe_strcasecmp ("24.07.1066",
01342             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01343             "strftime:CE:fourth");
01344         do_test ((0 == safe_strcasecmp ("1066-07-24",
01345             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01346             "strftime:ISO:fourth");
01347         do_test ((0 == safe_strcasecmp ("1066-07-24T06:34:26Z",
01348             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01349             "strftime:UTC:fourth");
01350         do_test ((0 == safe_strcasecmp (NULL,
01351             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01352             "strftime:LOCALE:fourth:outofrange");
01353         do_test ((0 == safe_strcasecmp (NULL,
01354             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01355             "strftime:CUSTOM:fourth:outofrange");
01356         qof_date_free (qd);
01357         qd = qof_date_new ();
01358         qd->qd_year = -45;
01359         qd->qd_mon = 07;
01360         qd->qd_mday = 24;
01361         qd->qd_hour = 06;
01362         qd->qd_min  = 34;
01363         qd->qd_sec  = 26;
01364         do_test ((qof_date_valid (qd)), "date not valid");
01365         qt = qof_date_to_qtime (qd);
01366         do_test ((0 == safe_strcasecmp ("07/24/-045",
01367             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01368             "strftime:US:fifth");
01369         do_test ((0 == safe_strcasecmp ("24/07/-045",
01370             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01371             "strftime:UK:fifth");
01372         do_test ((0 == safe_strcasecmp ("24.07.-045",
01373             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01374             "strftime:CE:fifth");
01375         do_test ((0 == safe_strcasecmp ("-045-07-24",
01376             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01377             "strftime:ISO:fifth");
01378         do_test ((0 == safe_strcasecmp ("-045-07-24T06:34:26Z",
01379             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01380             "strftime:UTC:fifth");
01381         do_test ((0 == safe_strcasecmp (NULL,
01382             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01383             "strftime:LOCALE:fifth:outofrange");
01384         do_test ((0 == safe_strcasecmp (NULL,
01385             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01386             "strftime:CUSTOM:fifth:outofrange");
01387         qof_date_free (qd);
01388         qd = qof_date_new ();
01389         qd->qd_year = -4500;
01390         qd->qd_mon = 07;
01391         qd->qd_mday = 24;
01392         qd->qd_hour = 06;
01393         qd->qd_min  = 34;
01394         qd->qd_sec  = 26;
01395         do_test ((qof_date_valid (qd)), "date not valid");
01396         qt = qof_date_to_qtime (qd);
01397         do_test ((0 == safe_strcasecmp ("07/24/-4500",
01398             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01399             "strftime:US:sixth");
01400         do_test ((0 == safe_strcasecmp ("24/07/-4500",
01401             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01402             "strftime:UK:sixth");
01403         do_test ((0 == safe_strcasecmp ("24.07.-4500",
01404             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01405             "strftime:CE:sixth");
01406         do_test ((0 == safe_strcasecmp ("-4500-07-24",
01407             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01408             "strftime:ISO:sixth");
01409         do_test ((0 == safe_strcasecmp ("-4500-07-24T06:34:26Z",
01410             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01411             "strftime:UTC:sixth");
01412         do_test ((0 == safe_strcasecmp (NULL,
01413             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01414             "strftime:LOCALE:sixth:outofrange");
01415         do_test ((0 == safe_strcasecmp (NULL,
01416             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01417             "strftime:CUSTOM:sixth:outofrange");
01418         qof_date_free (qd);
01419         qd = qof_date_new ();
01420         qd->qd_year = -4500000;
01421         qd->qd_mon = 07;
01422         qd->qd_mday = 24;
01423         qd->qd_hour = 06;
01424         qd->qd_min  = 34;
01425         qd->qd_sec  = 26;
01426         do_test ((qof_date_valid (qd)), "date not valid");
01427         qt = qof_date_to_qtime (qd);
01428         do_test ((0 == safe_strcasecmp ("07/24/-4500000",
01429             qof_date_print (qd, QOF_DATE_FORMAT_US))), 
01430             "strftime:US:seventh");
01431         do_test ((0 == safe_strcasecmp ("24/07/-4500000",
01432             qof_date_print (qd, QOF_DATE_FORMAT_UK))), 
01433             "strftime:UK:seventh");
01434         do_test ((0 == safe_strcasecmp ("24.07.-4500000",
01435             qof_date_print (qd, QOF_DATE_FORMAT_CE))), 
01436             "strftime:CE:seventh");
01437         do_test ((0 == safe_strcasecmp ("-4500000-07-24",
01438             qof_date_print (qd, QOF_DATE_FORMAT_ISO))), 
01439             "strftime:ISO:seventh");
01440         do_test ((0 == safe_strcasecmp ("-4500000-07-24T06:34:26Z",
01441             qof_date_print (qd, QOF_DATE_FORMAT_UTC))), 
01442             "strftime:UTC:seventh");
01443         do_test ((0 == safe_strcasecmp (NULL,
01444             qof_date_print (qd, QOF_DATE_FORMAT_LOCALE))), 
01445             "strftime:LOCALE:seventh:outofrange");
01446         do_test ((0 == safe_strcasecmp (NULL,
01447             qof_date_print (qd, QOF_DATE_FORMAT_CUSTOM))), 
01448             "strftime:CUSTOM:seventh:outofrange");
01449         qof_date_free (qd);
01450     }
01451 }
01452 
01453 static void
01454 run_qoftime_test (void)
01455 {
01456     QofTime *time, *cmp, *diff;
01457 
01458     time = qof_time_new ();
01459     do_test ((time != NULL), "failed to initialise QofTime.");
01460     /* basic tests */
01461     {
01462         qof_time_set_secs (time, 796179600);
01463         do_test ((qof_time_get_secs (time) > 0), "failed to set secs");
01464         do_test ((time != NULL), "error found");
01465         qof_time_set_secs (time, 0);
01466         qof_time_set_nanosecs (time, 2041020040);
01467         do_test ((qof_time_get_secs (time) > 0), "failed to normalise.");
01468         do_test ((time != NULL), "error found");
01469         do_test ((qof_time_get_nanosecs (time) > 0),
01470                  "failed to set nanosecs");
01471     }
01472     /* calculation and comparison tests */
01473     {
01474         qof_time_add_secs (time, -1143943200);
01475         do_test ((qof_time_get_secs (time) < 0), "failed to subtract.");
01476         do_test ((time != NULL), "error found");
01477         cmp = qof_time_new ();
01478         qof_time_set_secs (cmp, 0);
01479         do_test ((qof_time_equal (time, cmp) == FALSE), "test equal failed.");
01480         do_test ((qof_time_cmp (time, cmp) == -1), "compare cmp test");
01481         diff = qof_time_new ();
01482         qof_time_set_secs (diff, qof_time_get_secs (cmp));
01483         do_test ((qof_time_cmp (diff, cmp) == 0), "compare diff test");
01484         qof_time_free (diff);
01485         diff = qof_time_diff (time, cmp);
01486         do_test ((qof_time_get_secs (diff) < 0), "diff of negative value");
01487         qof_time_free (diff);
01488         diff = qof_time_diff (cmp, time);
01489         do_test ((qof_time_get_secs (diff) > 0), "diff of negative value");
01490         time = qof_time_abs (time);
01491         do_test ((qof_time_get_nanosecs (time) != 0), "abs failed");
01492         qof_time_set_secs (cmp, qof_time_get_secs (time));
01493         qof_time_set_nanosecs (cmp, qof_time_get_nanosecs (time));
01494         do_test ((qof_time_equal (cmp, time) == TRUE),
01495                  "equality test failed");
01496         qof_time_free (cmp);
01497         qof_time_free (time);
01498     }
01499     /* gdate basic tests */
01500     {
01501         GDate *date, *test;
01502         GTimeVal gtv;
01503 
01504         date = g_date_new_dmy (15, 5, 2006);
01505         time = qof_time_from_gdate (date);
01506         test = qof_time_to_gdate (time);
01507         do_test ((g_date_get_day (test) == 15), "gdate day fail");
01508         do_test ((g_date_get_month (test) == 5), "gdate month fail");
01509         do_test ((g_date_get_year (test) == 2006), "gdate year fail");
01510         do_test ((qof_time_to_gtimeval (time, &gtv)), "gtimeval fail");
01511         {
01512             QofTime *copy, *diff;
01513 
01514             qof_time_add_secs (time, 26451);
01515             copy = qof_time_add_secs_copy (time, -26451);
01516             diff = qof_time_diff (time, copy);
01517             do_test ((qof_time_get_secs (diff) == 26451), 
01518                 "add seconds failed");
01519             qof_time_free (copy);
01520             qof_time_free (diff);
01521         }
01522         g_date_free (date);
01523         g_date_free (test);
01524         qof_time_free (time);
01525     }
01526     /* gdate comparison tests */
01527     {
01528         GDate *date, *cmp;
01529         gint64 time_secs, diff;
01530         //glong time_nano;
01531 
01532         date = g_date_new_dmy (15, 5, 2006);
01533         time = qof_time_from_gdate (date);
01534         cmp = qof_time_to_gdate (time);
01535         do_test ((g_date_compare (date, cmp) == 0),
01536                  "convert to and from gdate failed");
01537         g_date_free (cmp);
01538         time_secs = qof_time_get_secs (time);
01539         //time_nano = qof_time_get_nanosecs (time);
01540         qof_time_add_secs (time, 7252);
01541         qof_time_set_nanosecs (time, 123456);
01542         do_test ((qof_time_set_day_start (time)), "set_day_start failed");
01543         do_test ((qof_time_get_secs (time) == time_secs),
01544                  "start of day incorrect");
01545         do_test ((qof_time_get_nanosecs (time) == 0),
01546                  "set nano at day start incorrect");
01547         do_test ((qof_time_set_day_middle (time) == TRUE),
01548                  "set_day_middle failed");
01549         diff = qof_time_get_secs (time) - time_secs;
01550         do_test (diff == (SECS_PER_DAY / 2), "middle of day incorrect");
01551         /* convert middle of day back to date */
01552         cmp = qof_time_to_gdate (time);
01553         do_test ((g_date_compare (date, cmp) == 0),
01554                  "middle of day not the same as original day");
01555         g_date_free (cmp);
01556 
01557         do_test ((qof_time_set_day_end (time)), "set_day_end failed");
01558         do_test ((qof_time_get_secs (time) - time_secs)
01559                  == (SECS_PER_DAY - 1), "end of day incorrect");
01560 
01561         /* convert end of day back to date */
01562         cmp = qof_time_to_gdate (time);
01563 
01564         do_test ((g_date_compare (date, cmp) == 0),
01565                  "end of day not the same as original day");
01566         qof_time_free (time);
01567         g_date_free (cmp);
01568         g_date_free (date);
01569     }
01570     /* QofTime today tests */
01571     {
01572         GTimeVal *current;
01573         gint64 time_secs;
01574         QofTime *diff;
01575 
01576         current = qof_time_get_current_start ();
01577         diff = qof_time_new ();
01578         qof_time_from_gtimeval (diff, current);
01579         time_secs = qof_time_get_secs (diff);
01580         time = qof_time_get_today_start ();
01581         do_test ((qof_time_get_secs (time) == time_secs),
01582                  "start of day incorrect");
01583         do_test ((qof_time_get_nanosecs (time) == 0),
01584                  "today start nanosecs non zero");
01585         qof_time_free (time);
01586         time = qof_time_get_today_end ();
01587         time_secs += SECS_PER_DAY - 1;
01588         do_test ((qof_time_get_secs (time) == time_secs),
01589                  "start of today incorrect");
01590         do_test ((qof_time_get_nanosecs (time) == 0),
01591                  "today start nanosecs non zero");
01592         qof_time_free (time);
01593     }
01594     /* last mday test */
01595     {
01596         GDate *date;
01597         guint8 mday;
01598 
01599         date = g_date_new_dmy (15, 5, 2006);
01600         time = qof_time_from_gdate (date);
01601         mday = qof_time_last_mday (time);
01602         do_test ((mday == 31), " wrong last day of May");
01603     }
01604     /* qof_date_get_mday and qof_date_get_yday tests */
01605     {
01606         QofDate *d;
01607         /* Wed 3rd Sep 2003 = 246. */
01608         do_test ((246 == qof_date_get_yday (3, 9, 2003)),
01609             "get year day test, September");
01610         d = qof_date_new ();
01611         d->qd_mday = 3;
01612         d->qd_mon  = 9;
01613         d->qd_year = 2003;
01614         do_test ((TRUE == qof_date_valid (d)),
01615             "3/9/2003 not valid");
01616         do_test ((3 == d->qd_wday), "not Wednesday");
01617         qof_date_free (d);
01618         /* Fri 3rd Sep 2004 = 247. */
01619         do_test ((247 == qof_date_get_yday (3, 9, 2004)),
01620             "get year day test, leap year");
01621         d = qof_date_new ();
01622         d->qd_mday = 3;
01623         d->qd_mon  = 9;
01624         d->qd_year = 2004;
01625         do_test ((TRUE == qof_date_valid (d)),
01626             "3/9/2003 not valid");
01627         do_test ((5 == d->qd_wday), "not Friday");
01628         qof_date_free (d);
01629         /* Sun 19th May 2002 = 139. */
01630         do_test ((139 == qof_date_get_yday (19, 5, 2002)),
01631             "get year day test, May");
01632         d = qof_date_new ();
01633         d->qd_mday = 19;
01634         d->qd_mon  = 5;
01635         d->qd_year = 2002;
01636         do_test ((TRUE == qof_date_valid (d)),
01637             "3/9/2003 not valid");
01638         do_test ((0 == d->qd_wday), "not Sunday");
01639         qof_date_free (d);
01640         /* Wed 19th May 2004 = 140. */
01641         do_test ((140 == qof_date_get_yday (19, 5, 2004)),
01642             "get year day test, May");
01643         d = qof_date_new ();
01644         d->qd_mday = 19;
01645         d->qd_mon  = 5;
01646         d->qd_year = 2004;
01647         do_test ((TRUE == qof_date_valid (d)),
01648             "3/9/2003 not valid");
01649         do_test ((3 == d->qd_wday), "not Wednesday, May");
01650         qof_date_free (d);
01651         /* Nov 2003 = 30 */
01652         do_test ((30 == qof_date_get_mday (11, 2003)),
01653             "get days in month, non-leap");
01654         /* Feb 2004 = 29 */
01655         do_test ((29 == qof_date_get_mday (2, 2004)),
01656             "get days in month, leap year");
01657     }
01658     /* time to dmy test */
01659     {
01660         gboolean success;
01661         guint8 day, month;
01662         guint16 year;
01663         GDate *date;
01664         QofTime *reverse;
01665 
01666         date = g_date_new_dmy (15, 5, 2006);
01667         time = qof_time_from_gdate (date);
01668         success = qof_time_to_dmy (time, &day, &month, &year);
01669         do_test ((success == TRUE), "time to dmy failed");
01670         do_test ((day == 15), "wrong day calculated");
01671         do_test ((month == 5), "wrong month calculated");
01672         do_test ((year == 2006), "wrong year calculated");
01673         reverse = qof_time_dmy_to_time (day, month, year);
01674         do_test ((qof_time_cmp (time, reverse) == 0), "dmy to time failed");
01675         g_date_free (date);
01676         qof_time_free (time);
01677         qof_time_free (reverse);
01678     }
01679     {
01680         /* day, month, year wrapping */
01681         QofTime *wrap_t;
01682         QofDate *wrap_d;
01683         glong day, month, year;
01684 
01685         /* Thu Jul 13 18:20:27 UTC 2006 */
01686         wrap_t = qof_time_set (1152814827, 345634);
01687         wrap_d = qof_date_from_qtime (wrap_t);
01688         PINFO (" base date for section =    %s",
01689             qof_date_print (wrap_d, QOF_DATE_FORMAT_ISO8601));
01690         day = wrap_d->qd_mday;
01691         month = wrap_d->qd_mon;
01692         year = wrap_d->qd_year;
01693         qof_date_free (wrap_d);     
01694         /* one day ago */
01695         wrap_d = qof_date_from_qtime (wrap_t);
01696         wrap_d->qd_mday -= 1;
01697         qof_date_valid (wrap_d);
01698         do_test ((wrap_d->qd_mon == month &&
01699             wrap_d->qd_year == year &&
01700             wrap_d->qd_mday == (day - 1)),
01701             " this time on previous day");
01702         PINFO (" same time previous day =   %s",
01703             qof_date_print (wrap_d, QOF_DATE_FORMAT_ISO8601));
01704         qof_date_free (wrap_d);
01705         /* this time last month */
01706         wrap_d = qof_date_from_qtime (wrap_t);
01707         wrap_d->qd_mon -= 1;
01708         qof_date_valid (wrap_d);
01709         do_test ((wrap_d->qd_mon == (month - 1) &&
01710             wrap_d->qd_year == year &&
01711             wrap_d->qd_mday == day),
01712             " this time last month");
01713         PINFO (" same time previous month = %s",
01714             qof_date_print (wrap_d, QOF_DATE_FORMAT_ISO8601));
01715         qof_date_free (wrap_d);
01716         /* this time last year */
01717         wrap_d = qof_date_from_qtime (wrap_t);
01718         wrap_d->qd_year -= 1;
01719         qof_date_valid (wrap_d);
01720         do_test ((wrap_d->qd_mon == month &&
01721             wrap_d->qd_year == (year - 1) &&
01722             wrap_d->qd_mday == day),
01723             " this time last year");
01724         PINFO (" same time previous year =  %s",
01725             qof_date_print (wrap_d, QOF_DATE_FORMAT_ISO8601));
01726         qof_time_free (wrap_t);
01727         qof_date_free (wrap_d);
01728     }
01729 }
01730 
01731 int
01732 main (void)
01733 {
01734     qof_init ();
01735 #ifdef TEST_DEBUG
01736     qof_log_init_filename ("test-date.trace");
01737     qof_log_set_default (QOF_LOG_DETAIL);
01738     ENTER (" ");
01739 #endif
01740     test_date_init ();
01741     run_qoftime_test ();
01742     run_qofdate_test ();
01743     run_print_scan_tests ();
01744     g_list_foreach (test_data, check_date_cycles, NULL);
01745     print_test_results ();
01746     test_date_close ();
01747 #ifdef TEST_DEBUG
01748     LEAVE (" ");
01749     qof_log_shutdown ();
01750 #endif
01751     qof_close ();
01752     exit (get_rv ());
01753 }