QOF  0.8.7
test-date.c
1 /***************************************************************************
2  * test-date.c
3  * Rewritten from scratch for QOF 0.8.0
4  *
5  * Copyright (C) 2002-2008
6  * Free Software Foundation, Inc.
7  *
8  ****************************************************************************/
9 /*
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
23  */
24 
25 #include "config.h"
26 #include <stdio.h>
27 #include <ctype.h>
28 #include <glib.h>
29 #include <time.h>
30 #include "qof.h"
31 #include "test-stuff.h"
32 
33 static gboolean test_data_is_init = FALSE;
34 static GList *test_data = NULL;
35 static QofLogModule log_module = QOF_MOD_DATE;
36 
37 typedef struct
38 {
39  /* time value of the date below */
40  QofTime *time;
41  /* date value of the above time. */
42  QofDate *date;
43  /* GList of the date in each QofDateFormat */
44  GList *string_list;
45  /* unique ID for this date for error reports. */
46  const gchar *id;
47 }QTestDate;
48 
49 static void
50 check_date_cycles (gpointer data,
51  gpointer user_data __attribute__ ((unused)))
52 {
53  QofDateFormat df;
54  gchar *str, *cmp;
55  QTestDate *d;
56  gint i;
57 
58  d = (QTestDate*)data;
60  /* test qof_date_to_qtime and qof_date_from_qtime */
61  {
62  do_test ((0 == qof_time_cmp (qof_date_to_qtime (d->date),
63  d->time)), d->id);
64  do_test ((0 == qof_date_compare (qof_date_from_qtime (d->time),
65  d->date)), d->id);
66  }
67  /* don't test locale-sensitive formats, yet. */
68  for (i = 1; i <= 6; i++)
69  {
70  str = qof_date_print (d->date, i);
71  cmp = (gchar*)g_list_nth_data (d->string_list, (i - 1));
72  if (0 != safe_strcasecmp (str, cmp))
73  DEBUG (" str=%s cmp=%s", str, cmp);
74  do_test ((0 == safe_strcasecmp (str, cmp)), d->id);
75  /* now test qofstrptime */
76  {
77  QofDate *h, *j;
78  const gchar * t;
79  struct tm base;
80 
81  base.tm_year = base.tm_mday = base.tm_mon = 0;
82  base.tm_min = base.tm_hour = base.tm_gmtoff = 0;
83  base.tm_sec = base.tm_isdst = 0;
85  if ((d->date->qd_year > 0) &&
86  (d->date->qd_year < 9999))
87  {
88  h = qof_date_parse (cmp, i);
89  do_test ((h != NULL), "no date could be parsed");
90  if (!h)
91  PERR (" h failed for str=%s, "
92  "cmp=%s, %d\n", str, cmp, i);
94  strptime (cmp, t, &base);
95  j = qof_date_from_struct_tm (&base);
96  do_test ((j != NULL), "no value from struct tm");
97  if (h)
98  {
99  j->qd_nanosecs = h->qd_nanosecs;
100  qof_date_compare (h, j);
101  do_test ((0 == qof_date_compare (h, j)),
102  "compare with strptime");
103  }
104  if (h)
105  qof_date_free (h);
106  }
107  }
108  }
110 }
111 
112 static void
113 test_date_init (void)
114 {
115  test_data_is_init = TRUE;
116  test_data = NULL;
117  /* A selection of current, old and future dates - all in UTC only. */
118  {
119  QTestDate *td = g_new0 (QTestDate, 1);
120  td->time = qof_time_new ();
121  qof_time_set_secs (td->time, 1147621550);
122  qof_time_set_nanosecs (td->time, G_GINT64_CONSTANT(1000));
123  td->date = qof_date_new ();
124  td->date->qd_year = 2006;
125  td->date->qd_mon = 5;
126  td->date->qd_mday = 14;
127  td->date->qd_hour = 15;
128  td->date->qd_min = 45;
129  td->date->qd_sec = G_GINT64_CONSTANT(50);
130  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
131  qof_date_valid (td->date);
132  td->string_list = NULL;
133  td->string_list = g_list_append (td->string_list, "05/14/2006");
134  td->string_list = g_list_append (td->string_list, "14/05/2006");
135  td->string_list = g_list_append (td->string_list, "14.05.2006");
136  td->string_list = g_list_append (td->string_list, "2006-05-14");
137  td->string_list = g_list_append (td->string_list, "2006-05-14T15:45:50Z");
138  td->string_list = g_list_append (td->string_list,
139  "2006-05-14 15:45:50.000001000 +0000");
140  td->id = "a current time";
141  test_data = g_list_prepend (test_data, td);
142  }
143  {
144  QTestDate *td = g_new0 (QTestDate, 1);
145  td->time = qof_time_new ();
146  qof_time_set_secs (td->time, 1147132800);
147  qof_time_set_nanosecs (td->time, 2);
148  td->date = qof_date_new ();
149  td->date->qd_year = 2006;
150  td->date->qd_mon = 5;
151  td->date->qd_mday = 9;
152  td->date->qd_hour = 0;
153  td->date->qd_min = 0;
154  td->date->qd_sec = G_GINT64_CONSTANT(0);
155  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
156  qof_date_valid (td->date);
157  td->string_list = NULL;
158  td->string_list = g_list_prepend (td->string_list, "05/09/2006");
159  td->string_list = g_list_prepend (td->string_list, "09/05/2006");
160  td->string_list = g_list_prepend (td->string_list, "09.05.2006");
161  td->string_list = g_list_prepend (td->string_list, "2006-05-09");
162  td->string_list = g_list_prepend (td->string_list, "2006-05-09T00:00:00Z");
163  td->string_list = g_list_prepend (td->string_list,
164  "2006-05-09 00:00:00.000000002 +0000");
165  td->string_list = g_list_reverse (td->string_list);
166  td->id = "a recent time";
167  test_data = g_list_prepend (test_data, td);
168  }
169  {
170  QTestDate *td = g_new0 (QTestDate, 1);
171  td->time = qof_time_new ();
172  qof_time_set_secs (td->time, 1147186144);
173  qof_time_set_nanosecs (td->time, 100);
174  td->date = qof_date_new ();
175  td->date->qd_year = 2006;
176  td->date->qd_mon = 5;
177  td->date->qd_mday = 9;
178  td->date->qd_hour = 14;
179  td->date->qd_min = 49;
180  td->date->qd_sec = G_GINT64_CONSTANT(4);
181  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
182  qof_date_valid (td->date);
183  td->string_list = NULL;
184  td->string_list = g_list_prepend (td->string_list, "05/09/2006");
185  td->string_list = g_list_prepend (td->string_list, "09/05/2006");
186  td->string_list = g_list_prepend (td->string_list, "09.05.2006");
187  td->string_list = g_list_prepend (td->string_list, "2006-05-09");
188  td->string_list = g_list_prepend (td->string_list, "2006-05-09T14:49:04Z");
189  td->string_list = g_list_prepend (td->string_list,
190  "2006-05-09 14:49:04.000000100 +0000");
191  td->string_list = g_list_reverse (td->string_list);
192  td->id = "second recent time";
193  test_data = g_list_prepend (test_data, td);
194  }
195  {
196  QTestDate *td = g_new0 (QTestDate, 1);
197  td->time = qof_time_new ();
198  qof_time_set_secs (td->time, 63039600);
199  qof_time_set_nanosecs (td->time, 4);
200  td->date = qof_date_new ();
201  td->date->qd_year = 1971;
202  td->date->qd_mon = 12;
203  td->date->qd_mday = 31;
204  td->date->qd_hour = 15;
205  td->date->qd_min = 0;
206  td->date->qd_sec = G_GINT64_CONSTANT(0);
207  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
208  qof_date_valid (td->date);
209  td->string_list = NULL;
210  td->string_list = g_list_prepend (td->string_list, "12/31/1971");
211  td->string_list = g_list_prepend (td->string_list, "31/12/1971");
212  td->string_list = g_list_prepend (td->string_list, "31.12.1971");
213  td->string_list = g_list_prepend (td->string_list, "1971-12-31");
214  td->string_list = g_list_prepend (td->string_list, "1971-12-31T15:00:00Z");
215  td->string_list = g_list_prepend (td->string_list,
216  "1971-12-31 15:00:00.000000004 +0000");
217  td->string_list = g_list_reverse (td->string_list);
218  td->id = "New Year's Eve 1971";
219  test_data = g_list_prepend (test_data, td);
220  }
221  {
222  QTestDate *td = g_new0 (QTestDate, 1);
223  td->time = qof_time_new ();
224  qof_time_set_secs (td->time, 315532800);
225  qof_time_set_nanosecs (td->time, 123456789);
226  td->date = qof_date_new ();
227  td->date->qd_year = 1980;
228  td->date->qd_mon = 1;
229  td->date->qd_mday = 1;
230  td->date->qd_hour = 0;
231  td->date->qd_min = 0;
232  td->date->qd_sec = G_GINT64_CONSTANT(0);
233  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
234  qof_date_valid (td->date);
235  td->string_list = NULL;
236  td->string_list = g_list_prepend (td->string_list, "01/01/1980");
237  td->string_list = g_list_prepend (td->string_list, "01/01/1980");
238  td->string_list = g_list_prepend (td->string_list, "01.01.1980");
239  td->string_list = g_list_prepend (td->string_list, "1980-01-01");
240  td->string_list = g_list_prepend (td->string_list, "1980-01-01T00:00:00Z");
241  td->string_list = g_list_prepend (td->string_list,
242  "1980-01-01 00:00:00.123456789 +0000");
243  td->string_list = g_list_reverse (td->string_list);
244  td->id = "New Year's Day 1980";
245  test_data = g_list_prepend (test_data, td);
246  }
247  {
248  QTestDate *td = g_new0 (QTestDate, 1);
249  td->time = qof_time_new ();
250  qof_time_set_secs (td->time, 946684799);
251  qof_time_set_nanosecs (td->time, 987654321);
252  td->date = qof_date_new ();
253  td->date->qd_year = 1999;
254  td->date->qd_mon = 12;
255  td->date->qd_mday = 31;
256  td->date->qd_hour = 23;
257  td->date->qd_min = 59;
258  td->date->qd_sec = G_GINT64_CONSTANT(59);
259  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
260  qof_date_valid (td->date);
261  td->string_list = NULL;
262  td->string_list = g_list_prepend (td->string_list, "12/31/1999");
263  td->string_list = g_list_prepend (td->string_list, "31/12/1999");
264  td->string_list = g_list_prepend (td->string_list, "31.12.1999");
265  td->string_list = g_list_prepend (td->string_list, "1999-12-31");
266  td->string_list = g_list_prepend (td->string_list, "1999-12-31T23:59:59Z");
267  td->string_list = g_list_prepend (td->string_list,
268  "1999-12-31 23:59:59.987654321 +0000");
269  td->string_list = g_list_reverse (td->string_list);
270  td->id = "Millenium Eve";
271  test_data = g_list_prepend (test_data, td);
272  }
273  {
274  QTestDate *td = g_new0 (QTestDate, 1);
275  td->time = qof_time_new ();
276  qof_time_set_secs (td->time, 699378323);
277  qof_time_set_nanosecs (td->time, 90000);
278  td->date = qof_date_new ();
279  td->date->qd_year = 1992;
280  td->date->qd_mon = 2;
281  td->date->qd_mday = 29;
282  td->date->qd_hour = 15;
283  td->date->qd_min = 45;
284  td->date->qd_sec = G_GINT64_CONSTANT(23);
285  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
286  qof_date_valid (td->date);
287  td->string_list = NULL;
288  td->string_list = g_list_prepend (td->string_list, "02/29/1992");
289  td->string_list = g_list_prepend (td->string_list, "29/02/1992");
290  td->string_list = g_list_prepend (td->string_list, "29.02.1992");
291  td->string_list = g_list_prepend (td->string_list, "1992-02-29");
292  td->string_list = g_list_prepend (td->string_list, "1992-02-29T15:45:23Z");
293  td->string_list = g_list_prepend (td->string_list,
294  "1992-02-29 15:45:23.000090000 +0000");
295  td->string_list = g_list_reverse (td->string_list);
296  td->id = "29th February 1992";
297  test_data = g_list_prepend (test_data, td);
298  }
299  {
300 
301  QTestDate *td = g_new0 (QTestDate, 1);
302  td->time = qof_time_new ();
303  qof_time_set_secs (td->time, -1);
304  qof_time_set_nanosecs (td->time, 9);
305  td->date = qof_date_new ();
306  td->date->qd_year = 1969;
307  td->date->qd_mon = 12;
308  td->date->qd_mday = 31;
309  td->date->qd_hour = 23;
310  td->date->qd_min = 59;
311  td->date->qd_sec = G_GINT64_CONSTANT(59);
312  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
313  qof_date_valid (td->date);
314  td->string_list = NULL;
315  td->string_list = g_list_prepend (td->string_list, "12/31/1969");
316  td->string_list = g_list_prepend (td->string_list, "31/12/1969");
317  td->string_list = g_list_prepend (td->string_list, "31.12.1969");
318  td->string_list = g_list_prepend (td->string_list, "1969-12-31");
319  td->string_list = g_list_prepend (td->string_list, "1969-12-31T23:59:59Z");
320  td->string_list = g_list_prepend (td->string_list,
321  "1969-12-31 23:59:59.000000009 +0000");
322  td->string_list = g_list_reverse (td->string_list);
323  td->id = "epoch eve";
324  test_data = g_list_prepend (test_data, td);
325  }
326  {
327  QTestDate *td = g_new0 (QTestDate, 1);
328  td->time = qof_time_new ();
329  qof_time_set_secs (td->time, -192776400);
330  qof_time_set_nanosecs (td->time, 818818818);
331  td->date = qof_date_new ();
332  td->date->qd_year = 1963;
333  td->date->qd_mon = 11;
334  td->date->qd_mday = 22;
335  td->date->qd_hour = 19;
336  td->date->qd_min = 0;
337  td->date->qd_sec = G_GINT64_CONSTANT(0);
338  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
339  qof_date_valid (td->date);
340  td->string_list = NULL;
341  td->string_list = g_list_prepend (td->string_list, "11/22/1963");
342  td->string_list = g_list_prepend (td->string_list, "22/11/1963");
343  td->string_list = g_list_prepend (td->string_list, "22.11.1963");
344  td->string_list = g_list_prepend (td->string_list, "1963-11-22");
345  td->string_list = g_list_prepend (td->string_list, "1963-11-22T19:00:00Z");
346  td->string_list = g_list_prepend (td->string_list,
347  "1963-11-22 19:00:00.818818818 +0000");
348  td->string_list = g_list_reverse (td->string_list);
349  td->id = "approx JFK, 1963";
350  test_data = g_list_prepend (test_data, td);
351  }
352  {
353  QTestDate *td = g_new0 (QTestDate, 1);
354  td->time = qof_time_new ();
355  qof_time_set_secs (td->time, -767311080);
356  qof_time_set_nanosecs (td->time, 0);
357  td->date = qof_date_new ();
358  td->date->qd_year = 1945;
359  td->date->qd_mon = 9;
360  td->date->qd_mday = 8;
361  td->date->qd_hour = 2;
362  td->date->qd_min = 2;
363  td->date->qd_sec = G_GINT64_CONSTANT(0);
364  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
365  qof_date_valid (td->date);
366  td->string_list = NULL;
367  td->string_list = g_list_prepend (td->string_list, "09/08/1945");
368  td->string_list = g_list_prepend (td->string_list, "08/09/1945");
369  td->string_list = g_list_prepend (td->string_list, "08.09.1945");
370  td->string_list = g_list_prepend (td->string_list, "1945-09-08");
371  td->string_list = g_list_prepend (td->string_list, "1945-09-08T02:02:00Z");
372  td->string_list = g_list_prepend (td->string_list,
373  "1945-09-08 02:02:00.000000000 +0000");
374  td->string_list = g_list_reverse (td->string_list);
375  td->id = "Nagasaki, 1945";
376  test_data = g_list_prepend (test_data, td);
377  }
378  {
379  QTestDate *td = g_new0 (QTestDate, 1);
380  td->time = qof_time_new ();
381  qof_time_set_secs (td->time, -1613826000);
382  qof_time_set_nanosecs (td->time, 0);
383  td->date = qof_date_new ();
384  td->date->qd_year = 1918;
385  td->date->qd_mon = 11;
386  td->date->qd_mday = 11;
387  td->date->qd_hour = 11;
388  td->date->qd_min = 0;
389  td->date->qd_sec = G_GINT64_CONSTANT(0);
390  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
391  qof_date_valid (td->date);
392  td->string_list = NULL;
393  td->string_list = g_list_prepend (td->string_list, "11/11/1918");
394  td->string_list = g_list_prepend (td->string_list, "11/11/1918");
395  td->string_list = g_list_prepend (td->string_list, "11.11.1918");
396  td->string_list = g_list_prepend (td->string_list, "1918-11-11");
397  td->string_list = g_list_prepend (td->string_list, "1918-11-11T11:00:00Z");
398  td->string_list = g_list_prepend (td->string_list,
399  "1918-11-11 11:00:00.000000000 +0000");
400  td->string_list = g_list_reverse (td->string_list);
401  td->id = "Armistice 1918";
402  test_data = g_list_prepend (test_data, td);
403  }
404  {
405  QTestDate *td = g_new0 (QTestDate, 1);
406  td->time = qof_time_new ();
407  qof_time_set_secs (td->time,
408  G_GINT64_CONSTANT(-2208988801));
409  qof_time_set_nanosecs (td->time, 0);
410  td->date = qof_date_new ();
411  td->date->qd_year = 1899;
412  td->date->qd_mon = 12;
413  td->date->qd_mday = 31;
414  td->date->qd_hour = 23;
415  td->date->qd_min = 59;
416  td->date->qd_sec = G_GINT64_CONSTANT(59);
417  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
418  qof_date_valid (td->date);
419  td->string_list = NULL;
420  td->string_list = g_list_prepend (td->string_list, "12/31/1899");
421  td->string_list = g_list_prepend (td->string_list, "31/12/1899");
422  td->string_list = g_list_prepend (td->string_list, "31.12.1899");
423  td->string_list = g_list_prepend (td->string_list, "1899-12-31");
424  td->string_list = g_list_prepend (td->string_list, "1899-12-31T23:59:59Z");
425  td->string_list = g_list_prepend (td->string_list,
426  "1899-12-31 23:59:59.000000000 +0000");
427  td->string_list = g_list_reverse (td->string_list);
428  td->id = "19th century Millenium Eve";
429  test_data = g_list_prepend (test_data, td);
430  }
431  {
432  QTestDate *td = g_new0 (QTestDate, 1);
433  td->time = qof_time_new ();
434  qof_time_set_secs (td->time,
435  G_GINT64_CONSTANT(-13311993599));
436  qof_time_set_nanosecs (td->time, 0);
437  td->date = qof_date_new ();
438  td->date->qd_year = 1548;
439  td->date->qd_mon = 2;
440  td->date->qd_mday = 29;
441  td->date->qd_hour = 0;
442  td->date->qd_min = 0;
443  td->date->qd_sec = G_GINT64_CONSTANT(1);
444  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
445  qof_date_valid (td->date);
446  td->string_list = NULL;
447  td->string_list = g_list_prepend (td->string_list, "02/29/1548");
448  td->string_list = g_list_prepend (td->string_list, "29/02/1548");
449  td->string_list = g_list_prepend (td->string_list, "29.02.1548");
450  td->string_list = g_list_prepend (td->string_list, "1548-02-29");
451  td->string_list = g_list_prepend (td->string_list, "1548-02-29T00:00:01Z");
452  td->string_list = g_list_prepend (td->string_list,
453  "1548-02-29 00:00:01.000000000 +0000");
454  td->string_list = g_list_reverse (td->string_list);
455  td->id = "16th century leap day";
456  test_data = g_list_prepend (test_data, td);
457  }
458  {
459  QTestDate *td = g_new0 (QTestDate, 1);
460  td->time = qof_time_new ();
461  qof_time_set_secs (td->time, G_GINT64_CONSTANT(-28502726400));
462  qof_time_set_nanosecs (td->time, 0);
463  td->date = qof_date_new ();
464  td->date->qd_year = 1066;
465  td->date->qd_mon = 10;
466  td->date->qd_mday = 14;
467  td->date->qd_hour = 8;
468  td->date->qd_min = 0;
469  td->date->qd_sec = G_GINT64_CONSTANT(0);
470  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
471  qof_date_valid (td->date);
472  td->string_list = NULL;
473  td->string_list = g_list_prepend (td->string_list, "10/14/1066");
474  td->string_list = g_list_prepend (td->string_list, "14/10/1066");
475  td->string_list = g_list_prepend (td->string_list, "14.10.1066");
476  td->string_list = g_list_prepend (td->string_list, "1066-10-14");
477  td->string_list = g_list_prepend (td->string_list, "1066-10-14T08:00:00Z");
478  td->string_list = g_list_prepend (td->string_list,
479  "1066-10-14 08:00:00.000000000 +0000");
480  td->string_list = g_list_reverse (td->string_list);
481  td->id = "Battle of Hastings, 1066";
482  test_data = g_list_prepend (test_data, td);
483  }
484  {
485  QTestDate *td = g_new0 (QTestDate, 1);
486  td->time = qof_time_new ();
487  qof_time_set_secs (td->time,
488  G_GINT64_CONSTANT(-36417340799));
489  qof_time_set_nanosecs (td->time, 0);
490  td->date = qof_date_new ();
491  td->date->qd_year = 815;
492  td->date->qd_mon = 12;
493  td->date->qd_mday = 25;
494  td->date->qd_hour = 0;
495  td->date->qd_min = 0;
496  td->date->qd_sec = G_GINT64_CONSTANT(1);
497  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
498  qof_date_valid (td->date);
499  td->string_list = NULL;
500  td->string_list = g_list_prepend (td->string_list, "12/25/0815");
501  td->string_list = g_list_prepend (td->string_list, "25/12/0815");
502  td->string_list = g_list_prepend (td->string_list, "25.12.0815");
503  td->string_list = g_list_prepend (td->string_list, "0815-12-25");
504  td->string_list = g_list_prepend (td->string_list, "0815-12-25T00:00:01Z");
505  td->string_list = g_list_prepend (td->string_list,
506  "0815-12-25 00:00:01.000000000 +0000");
507  td->string_list = g_list_reverse (td->string_list);
508  td->id = "9th century Christmas Day";
509  test_data = g_list_prepend (test_data, td);
510  }
511  {
512  QTestDate *td = g_new0 (QTestDate, 1);
513  td->time = qof_time_new ();
514  qof_time_set_secs (td->time, G_GINT64_CONSTANT(-60798160800));
515  qof_time_set_nanosecs (td->time, 0);
516  td->date = qof_date_new ();
517  td->date->qd_year = 43;
518  td->date->qd_mon = 5;
519  td->date->qd_mday = 20;
520  td->date->qd_hour = 14;
521  td->date->qd_min = 0;
522  td->date->qd_sec = G_GINT64_CONSTANT(0);
523  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
524  qof_date_valid (td->date);
525  td->string_list = NULL;
526  td->string_list = g_list_prepend (td->string_list, "05/20/0043");
527  td->string_list = g_list_prepend (td->string_list, "20/05/0043");
528  td->string_list = g_list_prepend (td->string_list, "20.05.0043");
529  td->string_list = g_list_prepend (td->string_list, "0043-05-20");
530  td->string_list = g_list_prepend (td->string_list, "0043-05-20T14:00:00Z");
531  td->string_list = g_list_prepend (td->string_list,
532  "0043-05-20 14:00:00.000000000 +0000");
533  td->string_list = g_list_reverse (td->string_list);
534  td->id = "approx Roman invasion, 43AD";
535  test_data = g_list_prepend (test_data, td);
536  }
541  {
542  QTestDate *td = g_new0 (QTestDate, 1);
543  td->time = qof_time_new ();
544  qof_time_set_secs (td->time, G_GINT64_CONSTANT(-62167824001));
545  qof_time_set_nanosecs (td->time, 0);
546  td->date = qof_date_new ();
547  td->date->qd_year = -1;
548  td->date->qd_mon = 12;
549  td->date->qd_mday = 24;
550  td->date->qd_hour = 23;
551  td->date->qd_min = 59;
552  td->date->qd_sec = G_GINT64_CONSTANT(59);
553  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
554  qof_date_valid (td->date);
555  td->string_list = NULL;
556  td->string_list = g_list_prepend (td->string_list, "12/24/-001");
557  td->string_list = g_list_prepend (td->string_list, "24/12/-001");
558  td->string_list = g_list_prepend (td->string_list, "24.12.-001");
559  td->string_list = g_list_prepend (td->string_list, "-001-12-24");
560  td->string_list = g_list_prepend (td->string_list, "-001-12-24T23:59:59Z");
561  td->string_list = g_list_prepend (td->string_list,
562  "-001-12-24 23:59:59.000000000 +0000");
563  td->string_list = g_list_reverse (td->string_list);
564  td->id = "Xmas eve, 1BC";
565  test_data = g_list_prepend (test_data, td);
566  }
567  {
568  QTestDate *td = g_new0 (QTestDate, 1);
569  td->time = qof_time_new ();
570  qof_time_set_secs (td->time,
571  G_GINT64_CONSTANT(-204110409601));
572  qof_time_set_nanosecs (td->time, 0);
573  td->date = qof_date_new ();
574  td->date->qd_year = -4499;
575  td->date->qd_mon = 12;
576  td->date->qd_mday = 31;
577  td->date->qd_hour = 23;
578  td->date->qd_min = 59;
579  td->date->qd_sec = G_GINT64_CONSTANT(59);
580  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
581  qof_date_valid (td->date);
582  td->string_list = NULL;
583  td->string_list = g_list_prepend (td->string_list, "12/31/-4499");
584  td->string_list = g_list_prepend (td->string_list, "31/12/-4499");
585  td->string_list = g_list_prepend (td->string_list, "31.12.-4499");
586  td->string_list = g_list_prepend (td->string_list, "-4499-12-31");
587  td->string_list = g_list_prepend (td->string_list, "-4499-12-31T23:59:59Z");
588  td->string_list = g_list_prepend (td->string_list,
589  "-4499-12-31 23:59:59.000000000 +0000");
590  td->string_list = g_list_reverse (td->string_list);
591  td->id = "far past.";
592  test_data = g_list_prepend (test_data, td);
593  }
594  {
595  QTestDate *td = g_new0 (QTestDate, 1);
596  td->time = qof_time_new ();
597  qof_time_set_secs (td->time,
598  G_GINT64_CONSTANT(-2097527529601));
599  qof_time_set_nanosecs (td->time, 0);
600  td->date = qof_date_new ();
601  td->date->qd_year = -64499;
602  td->date->qd_mon = 12;
603  td->date->qd_mday = 31;
604  td->date->qd_hour = 23;
605  td->date->qd_min = 59;
606  td->date->qd_sec = G_GINT64_CONSTANT(59);
607  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
608  qof_date_valid (td->date);
609  td->string_list = NULL;
610  td->string_list = g_list_prepend (td->string_list, "12/31/-64499");
611  td->string_list = g_list_prepend (td->string_list, "31/12/-64499");
612  td->string_list = g_list_prepend (td->string_list, "31.12.-64499");
613  td->string_list = g_list_prepend (td->string_list, "-64499-12-31");
614  td->string_list = g_list_prepend (td->string_list, "-64499-12-31T23:59:59Z");
615  td->string_list = g_list_prepend (td->string_list,
616  "-64499-12-31 23:59:59.000000000 +0000");
617  td->string_list = g_list_reverse (td->string_list);
618  td->id = "far, far past.";
619  test_data = g_list_prepend (test_data, td);
620  }
621  /* now test far future dates */
622  {
623  QTestDate *td = g_new0 (QTestDate, 1);
624  td->time = qof_time_new ();
625  qof_time_set_secs (td->time, G_GINT64_CONSTANT(32679095666));
626  qof_time_set_nanosecs (td->time, 800);
627  td->date = qof_date_new ();
628  td->date->qd_year = 3005;
629  td->date->qd_mon = 7;
630  td->date->qd_mday = 24;
631  td->date->qd_hour = 6;
632  td->date->qd_min = 34;
633  td->date->qd_sec = G_GINT64_CONSTANT(26);
634  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
635  qof_date_valid (td->date);
636  td->string_list = NULL;
637  td->string_list = g_list_prepend (td->string_list, "07/24/3005");
638  td->string_list = g_list_prepend (td->string_list, "24/07/3005");
639  td->string_list = g_list_prepend (td->string_list, "24.07.3005");
640  td->string_list = g_list_prepend (td->string_list, "3005-07-24");
641  td->string_list = g_list_prepend (td->string_list, "3005-07-24T06:34:26Z");
642  td->string_list = g_list_prepend (td->string_list,
643  "3005-07-24 06:34:26.000000800 +0000");
644  td->string_list = g_list_reverse (td->string_list);
645  td->id = "24th July 3005";
646  test_data = g_list_prepend (test_data, td);
647  }
648  {
649  QTestDate *td = g_new0 (QTestDate, 1);
650  td->time = qof_time_new ();
651  qof_time_set_secs (td->time,
652  G_GINT64_CONSTANT(79839129599));
653  qof_time_set_nanosecs (td->time, 50000);
654  td->date = qof_date_new ();
655  td->date->qd_year = 4499;
656  td->date->qd_mon = 12;
657  td->date->qd_mday = 31;
658  td->date->qd_hour = 23;
659  td->date->qd_min = 59;
660  td->date->qd_sec = G_GINT64_CONSTANT(59);
661  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
662  qof_date_valid (td->date);
663  td->string_list = NULL;
664  td->string_list = g_list_prepend (td->string_list, "12/31/4499");
665  td->string_list = g_list_prepend (td->string_list, "31/12/4499");
666  td->string_list = g_list_prepend (td->string_list, "31.12.4499");
667  td->string_list = g_list_prepend (td->string_list, "4499-12-31");
668  td->string_list = g_list_prepend (td->string_list, "4499-12-31T23:59:59Z");
669  td->string_list = g_list_prepend (td->string_list,
670  "4499-12-31 23:59:59.000050000 +0000");
671  td->string_list = g_list_reverse (td->string_list);
672  td->id = "44th century Millenium Eve";
673  test_data = g_list_prepend (test_data, td);
674  }
675  {
676  QTestDate *td = g_new0 (QTestDate, 1);
677  td->time = qof_time_new ();
678  qof_time_set_secs (td->time,
679  G_GINT64_CONSTANT(395408649599));
680  qof_time_set_nanosecs (td->time, 7000000);
681  td->date = qof_date_new ();
682  td->date->qd_year = 14499;
683  td->date->qd_mon = 12;
684  td->date->qd_mday = 31;
685  td->date->qd_hour = 23;
686  td->date->qd_min = 59;
687  td->date->qd_sec = G_GINT64_CONSTANT(59);
688  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
689  qof_date_valid (td->date);
690  td->string_list = NULL;
691  td->string_list = g_list_prepend (td->string_list, "12/31/14499");
692  td->string_list = g_list_prepend (td->string_list, "31/12/14499");
693  td->string_list = g_list_prepend (td->string_list, "31.12.14499");
694  td->string_list = g_list_prepend (td->string_list, "14499-12-31");
695  td->string_list = g_list_prepend (td->string_list, "14499-12-31T23:59:59Z");
696  td->string_list = g_list_prepend (td->string_list,
697  "14499-12-31 23:59:59.007000000 +0000");
698  td->string_list = g_list_reverse (td->string_list);
699  td->id = "144th century Millenium Eve";
700  test_data = g_list_prepend (test_data, td);
701  }
702  {
703  QTestDate *td = g_new0 (QTestDate, 1);
704  td->time = qof_time_new ();
705  qof_time_set_secs (td->time,
706  G_GINT64_CONSTANT(74869815369599));
707  qof_time_set_nanosecs (td->time, 45321545);
708  td->date = qof_date_new ();
709  td->date->qd_year = 2374499;
710  td->date->qd_mon = 12;
711  td->date->qd_mday = 31;
712  td->date->qd_hour = 23;
713  td->date->qd_min = 59;
714  td->date->qd_sec = G_GINT64_CONSTANT(59);
715  td->date->qd_nanosecs = qof_time_get_nanosecs (td->time);
716  qof_date_valid (td->date);
717  td->string_list = NULL;
718  td->string_list = g_list_prepend (td->string_list, "12/31/2374499");
719  td->string_list = g_list_prepend (td->string_list, "31/12/2374499");
720  td->string_list = g_list_prepend (td->string_list, "31.12.2374499");
721  td->string_list = g_list_prepend (td->string_list, "2374499-12-31");
722  td->string_list = g_list_prepend (td->string_list, "2374499-12-31T23:59:59Z");
723  td->string_list = g_list_prepend (td->string_list,
724  "2374499-12-31 23:59:59.045321545 +0000");
725  td->string_list = g_list_reverse (td->string_list);
726  td->id = "far, far future";
727  test_data = g_list_prepend (test_data, td);
728  }
729 }
730 
731 static void
732 free_test_data (gpointer data, gpointer user_data __attribute__ ((unused)))
733 {
734  QTestDate *td;
735 
736  td = (QTestDate*)data;
737  qof_date_free (td->date);
738  qof_time_free (td->time);
739  td->string_list = NULL;
740  g_free (td);
741  td = NULL;
742 }
743 
744 static void
745 test_date_close (void)
746 {
747  g_list_foreach (test_data, free_test_data, NULL);
748 }
749 
750 static void
751 scan_and_stamp (const gchar * str, QofDateFormat df, QofTimeSecs check)
752 {
753  QofTime *scan;
754  QofDate *qd;
755  gchar *stamp;
756 
757  qd = qof_date_parse (str, df);
758  scan = qof_date_to_qtime (qd);
759  do_test ((scan != NULL), "scan failed");
760  if (scan == NULL)
761  return;
762  do_test ((0 == safe_strcasecmp(qd->qd_zone, "GMT")),
763  " timezone reset incorrect");
764  do_test ((qof_time_get_secs (scan) == check),
765  "wrong time value");
766  if (qof_time_get_secs (scan) != check)
767  PERR (" wrong time value %"
768  G_GINT64_FORMAT " %" G_GINT64_FORMAT " diff=%"
769  G_GINT64_FORMAT " df=%d str=%s cmp=%s",
770  qof_time_get_secs (scan), check,
771  qof_time_get_secs (scan) - check, df, str,
773  stamp = qof_date_print (qof_date_from_qtime(scan), df);
774  do_test ((stamp != NULL), "stamp failed");
775  /* timezone tests mean stamp cannot be compared to str */
776  qof_time_free (scan);
777 }
778 
779 static void
780 stamp_and_scan (QofTimeSecs start, glong nanosecs,
781  QofDateFormat df)
782 {
783  gchar *str1, *str2;
784  QofDate *check;
785  QofTime *time, *scan;
786 
787  time = qof_time_new ();
788  qof_time_set_secs (time, start);
789  qof_time_set_nanosecs (time, nanosecs);
790  str1 = qof_date_print (qof_date_from_qtime(time), df);
791  do_test ((str1 != NULL), "stamp failed");
792  if (!str1)
793  return;
794  check = qof_date_parse (str1, df);
795  do_test ((check != NULL), "parse failed");
796  if (!check)
797  PERR (" tried to parse %s\n", str1);
798  scan = qof_date_to_qtime (check);
799  qof_date_free (check);
800  do_test ((scan != NULL), "scan failed");
801  if (!scan)
802  return;
803  /* depending on the format, data may be lost here
804  as some formats do not encode the time. So only
805  test that the returned stamp is the same. */
806  check = qof_date_from_qtime (scan);
807  str2 = qof_date_print (check, df);
808  qof_date_free (check);
809  /* 2 digit year errors with format 6 */
810  do_test ((str2 != NULL), "printed string is null");
811  do_test ((qof_date_from_qtime (scan) != NULL),
812  "from_qtime failed");
813  do_test ((0 == safe_strcasecmp (str1, str2)),
814  "stamp different to scan");
815  if (0 != safe_strcasecmp (str1, str2))
816  PERR (" df=%d str=%s scan=%s", df, str1, str2);
817  qof_time_free (scan);
818  qof_time_free (time);
819  g_free (str1);
820  g_free (str2);
821 }
822 
823 static void
824 run_print_scan_tests (void)
825 {
826  gint i;
827  gint64 secs;
828  QofDateFormat df;
829 
830  /* Set a secs value at the limit of the range of time_t
831  on 32bit systems. */
832  secs = G_MAXINT32;
833  /* add ten days */
834  secs += SECS_PER_DAY * 10;
835  for (i = 1; i <= QOF_DATE_FORMAT_ISO8601; i++)
836  {
837  stamp_and_scan (796179600, 0, i);
838  stamp_and_scan (796179500, 72000, i);
839  stamp_and_scan (152098136, 0, i);
840  stamp_and_scan (1964049931, 0, i);
841  stamp_and_scan (1162088421, 12548000, i);
842  stamp_and_scan (325659000 - 6500, 0, i);
843  stamp_and_scan (1143943200, 0, i);
844  stamp_and_scan (1603591171, 595311000, i);
845  stamp_and_scan (1738909365, 204102000, i);
846  stamp_and_scan (1603591171, 595311000, i);
847  stamp_and_scan (1143943200 - 1, 0, i);
848  stamp_and_scan (1143943200, 0, i);
849  stamp_and_scan (1143943200 + (7 * 60 * 60), 0, i);
850  stamp_and_scan (1143943200 + (8 * 60 * 60), 0, i);
851  stamp_and_scan (1841443200, 0, i);
852 
853  /* work with early dates */
854  stamp_and_scan (G_GINT64_CONSTANT (-796179600), 253, i);
855  stamp_and_scan (G_GINT64_CONSTANT (-152098136), 865, i);
856  stamp_and_scan (G_GINT64_CONSTANT (-1143943200), 67, i);
857  stamp_and_scan (G_GINT64_CONSTANT (-1964049931), 53, i);
858  stamp_and_scan (G_GINT64_CONSTANT (-2463880447), 48, i);
859  stamp_and_scan (G_GINT64_CONSTANT (-22905158401), 9, i);
860  stamp_and_scan (G_GINT64_CONSTANT (-28502726400), 1, i);
861  stamp_and_scan (G_GINT64_CONSTANT (-60798211200), 0, i);
862  stamp_and_scan (G_GINT64_CONSTANT (-32727638740), 0, i);
863 /* stamp_and_scan (G_GINT64_CONSTANT (-86956848000), 0, i);*/
864  stamp_and_scan (secs, 0, i);
865  /* Wed 29 Jan 2048 03:14:07 UTC */
866  stamp_and_scan (G_GINT64_CONSTANT (2463880447), 0, i);
867  /* Sat 29 Jan 2050 03:14:07 UTC */
868  stamp_and_scan (G_GINT64_CONSTANT (2527038847), 0, i);
869  /* work with far future dates */
870  /* 32,727,638,740 Fri Feb 6 02:45:40 UTC 3007 */
871  stamp_and_scan (G_GINT64_CONSTANT (32727638740), 0, i);
872  /* 88,313,632,867 Fri Jul 19 12:41:07 UTC 4768 */
873  stamp_and_scan (G_GINT64_CONSTANT (88313632867), 0, i);
874  /* 189,216,632,865 Fri Jan 14 07:47:45 UTC 7966 */
875  stamp_and_scan (G_GINT64_CONSTANT (189216632865), 0, i);
876  /* 378,432,632,864 Sat Jan 20 07:47:44 UTC 13,962 */
877  stamp_and_scan (G_GINT64_CONSTANT (378432632864), 0, i);
878  /* 3165071328567 Wed Feb 13 00:09:27 UTC 102,267 */
879  stamp_and_scan (G_GINT64_CONSTANT (3165071328567), 0, i);
880  }
881  /* far, far future dates delay the test */
882 #ifdef TEST_DEBUG
883  /* 43165071328567 Wed Aug 28 23:16:07 UTC 1,369,816 */
884  stamp_and_scan (G_GINT64_CONSTANT (3165071328567),
886  /* 843165071328567 Tue Jun 19 05:29:27 UTC 26,720,807 */
887  stamp_and_scan (G_GINT64_CONSTANT(843165071328567),
890  /* 9843165071328567 Mon Jan 9 21:29:27 UTC 311,919,454 */
891 /* stamp_and_scan (G_GINT64_CONSTANT(9843165071328567),
892  0, QOF_DATE_FORMAT_UTC);
893  stamp_and_scan (G_GINT64_CONSTANT(9843165071328567),
894  354758450, QOF_DATE_FORMAT_ISO8601);*/
895 #endif
896  scan_and_stamp ("05/09/2006", QOF_DATE_FORMAT_US,
897  1147132800);
898  scan_and_stamp ("09/05/2006", QOF_DATE_FORMAT_UK,
899  1147132800);
900  scan_and_stamp ("09.05.2006", QOF_DATE_FORMAT_CE,
901  1147132800);
902  scan_and_stamp ("2006-05-09", QOF_DATE_FORMAT_ISO,
903  1147132800);
904  scan_and_stamp ("2006-05-09T00:00:00Z", QOF_DATE_FORMAT_UTC,
905  1147132800);
906  scan_and_stamp ("2006-05-09T14:49:04Z", QOF_DATE_FORMAT_UTC,
907  1147186144);
908 
909  /* test a custom format */
910  df = 0;
911  do_test ((qof_date_format_add ("%Y-%m-%d %H:%M:%S %z",
912  &df) == TRUE), "failed to add scan suitable format");
913  /* test timezone settings */
914  /* 1972-01-01T00:00:00Z */
915  scan_and_stamp ("1971-12-31 15:00:00 -0900", df, 63072000);
916  /* 1980-01-01T00:00:00Z */
917  scan_and_stamp ("1979-12-31 15:00:00 -0900", df, 315532800);
918  scan_and_stamp ("1980-01-01 00:00:00 -0000", df, 315532800);
919  scan_and_stamp ("1980-01-01 00:00:00 +0000", df, 315532800);
920  scan_and_stamp ("1980-01-01 09:00:00 +0900", df, 315532800);
921  scan_and_stamp ("1980-01-01 08:30:00 +0830", df, 315532800);
922  /* pre-1970 dates */
923  scan_and_stamp ("1963-11-22 14:00:00 -0500", df, -192776400);
924  scan_and_stamp ("1945-09-08 11:02:00 +0900", df, -767311080);
925  scan_and_stamp ("1918-11-11 11:00:00 +0000", df, -1613826000);
926  /* work with really early dates */
927  /* 14th October 1066 (time is just a guess) */
928  scan_and_stamp ("1066-10-14 08:00:00 +0000", df,
929  G_GINT64_CONSTANT (-28502726400));
930  /* May 43AD Roman invasion (day and time guessed) */
931  scan_and_stamp ("0043-05-20 14:00:00 +0000", df,
932  G_GINT64_CONSTANT (-60798160800));
933  {
934  QofDate *qd, *qd1, *qd2;
935  QofTime *qt, *copy;
936  gint64 secs;
937  gchar * str1, * str2;
938 
939  qt = qof_time_new ();
940  /* Tue May 9 14:50:10 UTC 2006 */
941  qof_time_set_secs (qt, 1147186210);
942  copy = qof_time_copy (qt);
943  do_test ((copy != NULL), "copy time NULL");
944  qd1 = qof_date_from_qtime(qt);
945  qd2 = qof_date_from_qtime(copy);
946  str1 = g_strdup_printf ("%s\n", qof_date_print(qd1, QOF_DATE_FORMAT_CUSTOM));
947  str2 = g_strdup_printf ("%s\n", qof_date_print(qd2, QOF_DATE_FORMAT_CUSTOM));
948  do_test ((safe_strcmp(str1, str2) == 0), "copied time fails to match original");
949  g_free (str1);
950  g_free (str2);
951  do_test ((qof_time_is_valid(qt) == TRUE), "qt time invalid");
952  do_test ((qof_time_is_valid(copy) == TRUE), "copy time invalid");
953  do_test ((qof_time_equal(qt, copy) == TRUE), "copy time not equal");
954 
955  /* test %s and %N as well as %s.%N */
956  {
957  gint id, id1, id2;
958  gchar * str;
959  QofDate * qd_s, * qd_a;
960  QofTime * qt_s;
961  gint64 secs = qof_time_get_secs (qt);
962  gint64 nsecs = qof_time_get_nanosecs (qt) +
963  get_random_int_in_range(0, 999999);
964 
965  qt_s = qof_time_copy (qt);
966  qd_s = qof_date_from_qtime (qt_s);
967  qof_date_format_add ("%s", &id);
968  id1 = id;
969  do_test ((id > 0), "add seconds only custom format");
970  qd_s = qof_date_from_qtime(qt_s);
971  str = qof_date_print (qd_s, id);
972  qd_a = qof_date_parse (str, id);
973  str = qof_date_print (qd_a, QOF_DATE_FORMAT_UTC);
974  str = qof_date_print (qd_a, id);
975  qt_s = qof_date_to_qtime (qd_a);
976  do_test (secs == qof_time_get_secs (qt_s), "second parsing failed");
977 
978  qt_s = qof_time_copy (qt);
979  qof_time_set_nanosecs (qt_s, nsecs);
980  qd_s = qof_date_from_qtime (qt_s);
981  qof_date_format_add ("%N", &id);
982  id2 = id;
983  do_test ((id > id1), "add nanoseconds only custom format");
984  qd_s = qof_date_from_qtime(qt_s);
985  str = qof_date_print (qd_s, id);
986  qd_s = qof_date_parse (str, id);
987  qt_s = qof_date_to_qtime (qd_s);
988  do_test (nsecs == qof_time_get_nanosecs (qt_s), "nanosecond parsing failed");
989 
990  qof_date_format_add ("%s.%N", &id);
991  do_test ((id > id2), "add sec+nanosec custom format");
992  qof_time_free (qt_s);
993  qt_s = qof_time_new ();
994  qof_time_set_secs (qt_s, secs);
995  qof_time_set_nanosecs (qt_s, nsecs);
996  qd_s = qof_date_from_qtime(qt_s);
997  str = qof_date_print (qd_s, id);
998  qd_s = qof_date_parse (str, id);
999  qt_s = qof_date_to_qtime (qd_s);
1000  do_test (nsecs == qof_time_get_nanosecs (qt_s), "s.N - nanosecs failed");
1001  do_test (secs == qof_time_get_secs (qt_s), "s.N - seconds failed");
1002  }
1003  qd = qof_date_from_qtime (qt);
1004  do_test ((qof_date_adddays (qd, 45) == TRUE),
1005  "add_days failed");
1006  secs = 1147186210 + (45 * SECS_PER_DAY);
1007  qof_time_free (qt);
1008  qt = qof_date_to_qtime (qd);
1009  qof_date_free (qd);
1010  do_test ((secs == qof_time_get_secs (qt)),
1011  "add_days gave incorrect result.");
1012  if (secs != qof_time_get_secs (qt))
1013  PERR (" secs=%" G_GINT64_FORMAT "cmp=%"
1014  G_GINT64_FORMAT, secs, qof_time_get_secs (qt));
1015  qof_time_set_secs (qt, 1147186210);
1016  qd = qof_date_from_qtime (qt);
1017  do_test ((qof_date_addmonths (qd, 50, TRUE) == TRUE),
1018  "add_months failed");
1019  qof_time_free (qt);
1020  qt = qof_date_to_qtime (qd);
1021  do_test ((1278687010 == qof_time_get_secs (qt)),
1022  "add_months gave incorrect result.");
1023  qof_time_free (qt);
1024  qof_date_free (qd);
1025  }
1026 }
1027 
1028 static void
1029 run_qofdate_test (void)
1030 {
1031  QofDateFormat df, test;
1032 
1034  /* default date format tests */
1035  {
1037  test = qof_date_format_get_current ();
1038  do_test ((test == QOF_DATE_FORMAT_UK),
1039  "setting current format as UK");
1040  do_test ((safe_strcasecmp (qof_date_format_to_name (test),
1041  "uk") == 0), "getting the shorthand name");
1042  do_test ((FALSE ==
1044  "default name should not be overridden");
1045  do_test ((QOF_DATE_FORMAT_UK ==
1046  qof_date_format_from_name ("uk")),
1047  "getting date format from shorthand name");
1048  do_test (('/' == qof_date_format_get_date_separator (test)),
1049  "getting date format separator from date format");
1050  do_test ((FALSE == qof_date_format_set_date_separator (':',
1051  test)), "default separator should not be overridden");
1052  }
1053  /* custom date format tests */
1054  {
1055  QofDateFormat df, df2;
1056  do_test ((qof_date_format_add ("%T", &df) == TRUE),
1057  "adding a valid format");
1058  do_test ((qof_date_format_add ("%a%A%b%B%c%C%d%D%e%F%f%r",
1059  &df2) == FALSE), "adding an invalid format");
1061  test = qof_date_format_get_current ();
1062  do_test ((test == df), "setting current format");
1063  do_test ((safe_strcasecmp (qof_date_format_to_name (test),
1064  "%T") == 0), "getting the shorthand name");
1065  do_test ((TRUE == qof_date_format_set_name ("foo", test)),
1066  "custom name should be overridden");
1067  do_test ((test == qof_date_format_from_name ("foo")),
1068  "getting date format from shorthand name");
1069  do_test (('\0' == qof_date_format_get_date_separator (test)),
1070  "getting date format separator from date format");
1071  do_test ((TRUE == qof_date_format_set_date_separator (':', test)),
1072  "custom separator should be overridden");
1073  do_test ((':' == qof_date_format_get_date_separator (test)),
1074  "getting modified date format separator from date format");
1075  }
1077  /* run tests on date_normalise */
1078  {
1079  QofDate *date;
1080 
1081  date = qof_date_new ();
1082  /* Mon Jan 3 00:00:30 UTC 2000 */
1083  date->qd_sec = SECS_PER_DAY * 2 + 30;
1084  date->qd_year = 2000;
1085  do_test ((qof_date_valid (date) == TRUE), "date 1 was invalid");
1086  do_test ((date->qd_sec == 30), "normalised seconds incorrect - 1");
1087  do_test ((date->qd_mday == 3), "normalised day incorrect - 1");
1088  date->qd_mday = 54;
1089  do_test ((qof_date_valid (date) == TRUE), "date 2 was invalid");
1090  do_test ((date->qd_sec == 30), "normalised seconds incorrect - 2");
1091  do_test ((date->qd_mday == 23), "normalised day incorrect - 2");
1092  date->qd_hour = 34;
1093  qof_date_valid (date);
1094  do_test ((date->qd_hour == 10), "normalised hour incorrect");
1095  do_test ((date->qd_mday == 24), "normalised day incorrect - 3");
1096  date->qd_mon = 17;
1097  qof_date_valid (date);
1098  do_test ((date->qd_mon == 5), "normalised month incorrect");
1099  do_test ((date->qd_year == 2001), "normalised year incorrect");
1100  date->qd_hour = 27;
1101  qof_date_valid (date);
1102  do_test ((date->qd_hour == 3), "normalised hour incorrect - 1");
1103  do_test ((date->qd_mday == 25), "normalised day incorrect - 4");
1104  date->qd_hour = -53;
1105  qof_date_valid (date);
1106  do_test ((date->qd_hour == 19), "normalised hour incorrect - 2");
1107  do_test ((date->qd_mday == 22), "normalised day incorrect - 5");
1108  date->qd_min = -225;
1109  qof_date_valid (date);
1110  do_test ((date->qd_min == 15), "normalised min incorrect");
1111  do_test ((date->qd_hour == 15), "normalised hour incorrect - 3");
1112  date->qd_min = 5;
1113  date->qd_sec = 68;
1114  qof_date_valid (date);
1115  do_test ((date->qd_sec == 8), "doxygen sec example incorrect - 1");
1116  do_test ((date->qd_min == 6), "doxygen min example incorrect - 1");
1117  date->qd_min = 5;
1118  date->qd_sec = -64;
1119  qof_date_valid (date);
1120  do_test ((date->qd_sec == 56), "doxygen sec example incorrect - 2");
1121  do_test ((date->qd_min == 3), "doxygen min example incorrect - 2");
1122  }
1123  /* run tests against QofDate<->QofTime conversions. */
1124  /* opposite direction compared to the tests above. */
1125  {
1126  QofDate *qd;
1127  QofTime *qt;
1128  gchar *str1;
1129 
1130  qd = qof_date_new ();
1131  qd->qd_year = 2006;
1132  qd->qd_mon = 5;
1133  qd->qd_mday = 30;
1134  qd->qd_hour = 18;
1135  qd->qd_min = 24;
1136  qd->qd_sec = 17;
1137  qd->qd_nanosecs = 123456789;
1138  do_test ((qof_date_valid (qd)), "date not valid");
1139  qt = qof_date_to_qtime (qd);
1140  str1 = qof_date_print (qd, QOF_DATE_FORMAT_UTC);
1141  do_test ((0 == safe_strcasecmp (str1,
1142  "2006-05-30T18:24:17Z")), "with nanosecs");
1143  do_test ((qof_time_get_nanosecs (qt) ==
1144  123456789L), "nanosecs mismatched.");
1145  do_test ((0 == safe_strcasecmp ("05/30/2006",
1147  "strftime:US:first");
1148  do_test ((0 == safe_strcasecmp ("30/05/2006",
1150  "strftime:UK:first");
1151  do_test ((0 == safe_strcasecmp ("30.05.2006",
1153  "strftime:CE:first");
1154  do_test ((0 == safe_strcasecmp ("2006-05-30",
1156  "strftime:ISO:first");
1157  do_test ((0 == safe_strcasecmp ("2006-05-30T18:24:17Z",
1159  "strftime:UTC:first");
1160  do_test ((0 != safe_strcasecmp (NULL,
1162  "strftime:LOCALE:first:inrange");
1163  do_test ((0 != safe_strcasecmp (NULL,
1165  "strftime:CUSTOM:first:inrange");
1166  qof_date_free (qd);
1167  qof_time_free (qt);
1168  qd = qof_date_new ();
1169  qd->qd_year = 3005;
1170  qd->qd_mon = 07;
1171  qd->qd_mday = 24;
1172  qd->qd_hour = 06;
1173  qd->qd_min = 34;
1174  qd->qd_sec = 26;
1175  do_test ((qof_date_valid (qd)), "date not valid");
1176  qt = qof_date_to_qtime (qd);
1177  do_test ((0 == safe_strcasecmp ("07/24/3005",
1179  "strftime:US:forward");
1180  do_test ((0 == safe_strcasecmp ("24/07/3005",
1182  "strftime:UK:forward");
1183  do_test ((0 == safe_strcasecmp ("24.07.3005",
1185  "strftime:CE:forward");
1186  do_test ((0 == safe_strcasecmp ("3005-07-24",
1188  "strftime:ISO:forward");
1189  do_test ((0 == safe_strcasecmp ("3005-07-24T06:34:26Z",
1191  "strftime:UTC:forward");
1192  do_test ((0 != safe_strcasecmp (NULL,
1194  "strftime:LOCALE:forward:inrange");
1195  do_test ((0 != safe_strcasecmp (NULL,
1197  "strftime:CUSTOM:forward:inrange");
1198  qof_date_free (qd);
1199  qd = qof_date_new ();
1200  qd->qd_year = 4500;
1201  qd->qd_mon = 07;
1202  qd->qd_mday = 24;
1203  qd->qd_hour = 06;
1204  qd->qd_min = 34;
1205  qd->qd_sec = 26;
1206  do_test ((qof_date_valid (qd)), "date not valid");
1207  qt = qof_date_to_qtime (qd);
1208  do_test ((0 == safe_strcasecmp ("07/24/4500",
1210  "strftime:US:fifth");
1211  do_test ((0 == safe_strcasecmp ("24/07/4500",
1213  "strftime:UK:fifth");
1214  do_test ((0 == safe_strcasecmp ("24.07.4500",
1216  "strftime:CE:fifth");
1217  do_test ((0 == safe_strcasecmp ("4500-07-24",
1219  "strftime:ISO:fifth");
1220  do_test ((0 == safe_strcasecmp ("4500-07-24T06:34:26Z",
1222  "strftime:UTC:fifth");
1223  do_test ((0 != safe_strcasecmp (NULL,
1225  "strftime:LOCALE:fifth:inrange");
1226  do_test ((0 != safe_strcasecmp (NULL,
1228  "strftime:CUSTOM:fifth:inrange");
1229  qof_date_free (qd);
1230  qd = qof_date_new ();
1231  qd->qd_year = 45000;
1232  qd->qd_mon = 07;
1233  qd->qd_mday = 24;
1234  qd->qd_hour = 06;
1235  qd->qd_min = 34;
1236  qd->qd_sec = 26;
1237  do_test ((qof_date_valid (qd)), "date not valid");
1238  qt = qof_date_to_qtime (qd);
1239  do_test ((0 == safe_strcasecmp ("07/24/45000",
1241  "strftime:US:forward2");
1242  do_test ((0 == safe_strcasecmp ("24/07/45000",
1244  "strftime:UK:forward2");
1245  do_test ((0 == safe_strcasecmp ("24.07.45000",
1247  "strftime:CE:forward2");
1248  do_test ((0 == safe_strcasecmp ("45000-07-24",
1250  "strftime:ISO:forward2");
1251  do_test ((0 == safe_strcasecmp ("45000-07-24T06:34:26Z",
1253  "strftime:UTC:forward2");
1254  do_test ((0 != safe_strcasecmp (NULL,
1256  "strftime:LOCALE:forward2:outofrange");
1257  do_test ((0 != safe_strcasecmp (NULL,
1259  "strftime:CUSTOM:forward2:outofrange");
1260  qof_date_free (qd);
1261  g_free (str1);
1262  qd = qof_date_new ();
1263  qd->qd_year = 1914;
1264  qd->qd_mon = 11;
1265  qd->qd_mday = 11;
1266  qd->qd_hour = 11;
1267  do_test ((qof_date_valid (qd)), "date not valid");
1268  qt = qof_date_to_qtime (qd);
1269  str1 = qof_date_print (qd, QOF_DATE_FORMAT_UTC);
1270  do_test ((0 == safe_strcasecmp (str1,
1271  "1914-11-11T11:00:00Z")), "armistice day");
1272  do_test ((0 == safe_strcasecmp ("11/11/1914",
1274  "strftime:US:second");
1275  do_test ((0 == safe_strcasecmp ("11/11/1914",
1277  "strftime:UK:second");
1278  do_test ((0 == safe_strcasecmp ("11.11.1914",
1280  "strftime:CE:second");
1281  do_test ((0 == safe_strcasecmp ("1914-11-11",
1283  "strftime:ISO:second");
1284  do_test ((0 == safe_strcasecmp ("1914-11-11T11:00:00Z",
1286  "strftime:UTC:second");
1287  do_test ((0 != safe_strcasecmp (NULL,
1289  "strftime:LOCALE:second:inrange");
1290  do_test ((0 != safe_strcasecmp (NULL,
1292  "strftime:CUSTOM:second:inrange");
1293  qof_date_free (qd);
1294  qof_time_free (qt);
1295  qd = qof_date_new ();
1296  qd->qd_year = 1812;
1297  qd->qd_mon = 07;
1298  qd->qd_mday = 24;
1299  qd->qd_hour = 06;
1300  qd->qd_min = 34;
1301  qd->qd_sec = 26;
1302  do_test ((qof_date_valid (qd)), "date not valid");
1303  qt = qof_date_to_qtime (qd);
1304  do_test ((0 == safe_strcasecmp ("07/24/1812",
1306  "strftime:US:third");
1307  do_test ((0 == safe_strcasecmp ("24/07/1812",
1309  "strftime:UK:third");
1310  do_test ((0 == safe_strcasecmp ("24.07.1812",
1312  "strftime:CE:third");
1313  do_test ((0 == safe_strcasecmp ("1812-07-24",
1315  "strftime:ISO:third");
1316  do_test ((0 == safe_strcasecmp ("1812-07-24T06:34:26Z",
1318  "strftime:UTC:third");
1319  do_test ((0 == safe_strcasecmp (NULL,
1321  "strftime:LOCALE:third:outofrange");
1322  do_test ((0 == safe_strcasecmp (NULL,
1324  "strftime:CUSTOM:third:outofrange");
1325  qof_date_free (qd);
1326  qd = qof_date_new ();
1327  qd->qd_year = 1066;
1328  qd->qd_mon = 07;
1329  qd->qd_mday = 24;
1330  qd->qd_hour = 06;
1331  qd->qd_min = 34;
1332  qd->qd_sec = 26;
1333  do_test ((qof_date_valid (qd)), "date not valid");
1334  qt = qof_date_to_qtime (qd);
1335  do_test ((0 == safe_strcasecmp ("07/24/1066",
1337  "strftime:US:fourth");
1338  do_test ((0 == safe_strcasecmp ("24/07/1066",
1340  "strftime:UK:fourth");
1341  do_test ((0 == safe_strcasecmp ("24.07.1066",
1343  "strftime:CE:fourth");
1344  do_test ((0 == safe_strcasecmp ("1066-07-24",
1346  "strftime:ISO:fourth");
1347  do_test ((0 == safe_strcasecmp ("1066-07-24T06:34:26Z",
1349  "strftime:UTC:fourth");
1350  do_test ((0 == safe_strcasecmp (NULL,
1352  "strftime:LOCALE:fourth:outofrange");
1353  do_test ((0 == safe_strcasecmp (NULL,
1355  "strftime:CUSTOM:fourth:outofrange");
1356  qof_date_free (qd);
1357  qd = qof_date_new ();
1358  qd->qd_year = -45;
1359  qd->qd_mon = 07;
1360  qd->qd_mday = 24;
1361  qd->qd_hour = 06;
1362  qd->qd_min = 34;
1363  qd->qd_sec = 26;
1364  do_test ((qof_date_valid (qd)), "date not valid");
1365  qt = qof_date_to_qtime (qd);
1366  do_test ((0 == safe_strcasecmp ("07/24/-045",
1368  "strftime:US:fifth");
1369  do_test ((0 == safe_strcasecmp ("24/07/-045",
1371  "strftime:UK:fifth");
1372  do_test ((0 == safe_strcasecmp ("24.07.-045",
1374  "strftime:CE:fifth");
1375  do_test ((0 == safe_strcasecmp ("-045-07-24",
1377  "strftime:ISO:fifth");
1378  do_test ((0 == safe_strcasecmp ("-045-07-24T06:34:26Z",
1380  "strftime:UTC:fifth");
1381  do_test ((0 == safe_strcasecmp (NULL,
1383  "strftime:LOCALE:fifth:outofrange");
1384  do_test ((0 == safe_strcasecmp (NULL,
1386  "strftime:CUSTOM:fifth:outofrange");
1387  qof_date_free (qd);
1388  qd = qof_date_new ();
1389  qd->qd_year = -4500;
1390  qd->qd_mon = 07;
1391  qd->qd_mday = 24;
1392  qd->qd_hour = 06;
1393  qd->qd_min = 34;
1394  qd->qd_sec = 26;
1395  do_test ((qof_date_valid (qd)), "date not valid");
1396  qt = qof_date_to_qtime (qd);
1397  do_test ((0 == safe_strcasecmp ("07/24/-4500",
1399  "strftime:US:sixth");
1400  do_test ((0 == safe_strcasecmp ("24/07/-4500",
1402  "strftime:UK:sixth");
1403  do_test ((0 == safe_strcasecmp ("24.07.-4500",
1405  "strftime:CE:sixth");
1406  do_test ((0 == safe_strcasecmp ("-4500-07-24",
1408  "strftime:ISO:sixth");
1409  do_test ((0 == safe_strcasecmp ("-4500-07-24T06:34:26Z",
1411  "strftime:UTC:sixth");
1412  do_test ((0 == safe_strcasecmp (NULL,
1414  "strftime:LOCALE:sixth:outofrange");
1415  do_test ((0 == safe_strcasecmp (NULL,
1417  "strftime:CUSTOM:sixth:outofrange");
1418  qof_date_free (qd);
1419  qd = qof_date_new ();
1420  qd->qd_year = -4500000;
1421  qd->qd_mon = 07;
1422  qd->qd_mday = 24;
1423  qd->qd_hour = 06;
1424  qd->qd_min = 34;
1425  qd->qd_sec = 26;
1426  do_test ((qof_date_valid (qd)), "date not valid");
1427  qt = qof_date_to_qtime (qd);
1428  do_test ((0 == safe_strcasecmp ("07/24/-4500000",
1430  "strftime:US:seventh");
1431  do_test ((0 == safe_strcasecmp ("24/07/-4500000",
1433  "strftime:UK:seventh");
1434  do_test ((0 == safe_strcasecmp ("24.07.-4500000",
1436  "strftime:CE:seventh");
1437  do_test ((0 == safe_strcasecmp ("-4500000-07-24",
1439  "strftime:ISO:seventh");
1440  do_test ((0 == safe_strcasecmp ("-4500000-07-24T06:34:26Z",
1442  "strftime:UTC:seventh");
1443  do_test ((0 == safe_strcasecmp (NULL,
1445  "strftime:LOCALE:seventh:outofrange");
1446  do_test ((0 == safe_strcasecmp (NULL,
1448  "strftime:CUSTOM:seventh:outofrange");
1449  qof_date_free (qd);
1450  }
1451 }
1452 
1453 static void
1454 run_qoftime_test (void)
1455 {
1456  QofTime *time, *cmp, *diff;
1457 
1458  time = qof_time_new ();
1459  do_test ((time != NULL), "failed to initialise QofTime.");
1460  /* basic tests */
1461  {
1462  qof_time_set_secs (time, 796179600);
1463  do_test ((qof_time_get_secs (time) > 0), "failed to set secs");
1464  do_test ((time != NULL), "error found");
1465  qof_time_set_secs (time, 0);
1466  qof_time_set_nanosecs (time, 2041020040);
1467  do_test ((qof_time_get_secs (time) > 0), "failed to normalise.");
1468  do_test ((time != NULL), "error found");
1469  do_test ((qof_time_get_nanosecs (time) > 0),
1470  "failed to set nanosecs");
1471  }
1472  /* calculation and comparison tests */
1473  {
1474  qof_time_add_secs (time, -1143943200);
1475  do_test ((qof_time_get_secs (time) < 0), "failed to subtract.");
1476  do_test ((time != NULL), "error found");
1477  cmp = qof_time_new ();
1478  qof_time_set_secs (cmp, 0);
1479  do_test ((qof_time_equal (time, cmp) == FALSE), "test equal failed.");
1480  do_test ((qof_time_cmp (time, cmp) == -1), "compare cmp test");
1481  diff = qof_time_new ();
1482  qof_time_set_secs (diff, qof_time_get_secs (cmp));
1483  do_test ((qof_time_cmp (diff, cmp) == 0), "compare diff test");
1484  qof_time_free (diff);
1485  diff = qof_time_diff (time, cmp);
1486  do_test ((qof_time_get_secs (diff) < 0), "diff of negative value");
1487  qof_time_free (diff);
1488  diff = qof_time_diff (cmp, time);
1489  do_test ((qof_time_get_secs (diff) > 0), "diff of negative value");
1490  time = qof_time_abs (time);
1491  do_test ((qof_time_get_nanosecs (time) != 0), "abs failed");
1492  qof_time_set_secs (cmp, qof_time_get_secs (time));
1494  do_test ((qof_time_equal (cmp, time) == TRUE),
1495  "equality test failed");
1496  qof_time_free (cmp);
1497  qof_time_free (time);
1498  }
1499  /* gdate basic tests */
1500  {
1501  GDate *date, *test;
1502  GTimeVal gtv;
1503 
1504  date = g_date_new_dmy (15, 5, 2006);
1505  time = qof_time_from_gdate (date);
1506  test = qof_time_to_gdate (time);
1507  do_test ((g_date_get_day (test) == 15), "gdate day fail");
1508  do_test ((g_date_get_month (test) == 5), "gdate month fail");
1509  do_test ((g_date_get_year (test) == 2006), "gdate year fail");
1510  do_test ((qof_time_to_gtimeval (time, &gtv)), "gtimeval fail");
1511  {
1512  QofTime *copy, *diff;
1513 
1514  qof_time_add_secs (time, 26451);
1515  copy = qof_time_add_secs_copy (time, -26451);
1516  diff = qof_time_diff (time, copy);
1517  do_test ((qof_time_get_secs (diff) == 26451),
1518  "add seconds failed");
1519  qof_time_free (copy);
1520  qof_time_free (diff);
1521  }
1522  g_date_free (date);
1523  g_date_free (test);
1524  qof_time_free (time);
1525  }
1526  /* gdate comparison tests */
1527  {
1528  GDate *date, *cmp;
1529  gint64 time_secs, diff;
1530  //glong time_nano;
1531 
1532  date = g_date_new_dmy (15, 5, 2006);
1533  time = qof_time_from_gdate (date);
1534  cmp = qof_time_to_gdate (time);
1535  do_test ((g_date_compare (date, cmp) == 0),
1536  "convert to and from gdate failed");
1537  g_date_free (cmp);
1538  time_secs = qof_time_get_secs (time);
1539  //time_nano = qof_time_get_nanosecs (time);
1540  qof_time_add_secs (time, 7252);
1541  qof_time_set_nanosecs (time, 123456);
1542  do_test ((qof_time_set_day_start (time)), "set_day_start failed");
1543  do_test ((qof_time_get_secs (time) == time_secs),
1544  "start of day incorrect");
1545  do_test ((qof_time_get_nanosecs (time) == 0),
1546  "set nano at day start incorrect");
1547  do_test ((qof_time_set_day_middle (time) == TRUE),
1548  "set_day_middle failed");
1549  diff = qof_time_get_secs (time) - time_secs;
1550  do_test (diff == (SECS_PER_DAY / 2), "middle of day incorrect");
1551  /* convert middle of day back to date */
1552  cmp = qof_time_to_gdate (time);
1553  do_test ((g_date_compare (date, cmp) == 0),
1554  "middle of day not the same as original day");
1555  g_date_free (cmp);
1556 
1557  do_test ((qof_time_set_day_end (time)), "set_day_end failed");
1558  do_test ((qof_time_get_secs (time) - time_secs)
1559  == (SECS_PER_DAY - 1), "end of day incorrect");
1560 
1561  /* convert end of day back to date */
1562  cmp = qof_time_to_gdate (time);
1563 
1564  do_test ((g_date_compare (date, cmp) == 0),
1565  "end of day not the same as original day");
1566  qof_time_free (time);
1567  g_date_free (cmp);
1568  g_date_free (date);
1569  }
1570  /* QofTime today tests */
1571  {
1572  GTimeVal *current;
1573  gint64 time_secs;
1574  QofTime *diff;
1575 
1576  current = qof_time_get_current_start ();
1577  diff = qof_time_new ();
1578  qof_time_from_gtimeval (diff, current);
1579  time_secs = qof_time_get_secs (diff);
1580  time = qof_time_get_today_start ();
1581  do_test ((qof_time_get_secs (time) == time_secs),
1582  "start of day incorrect");
1583  do_test ((qof_time_get_nanosecs (time) == 0),
1584  "today start nanosecs non zero");
1585  qof_time_free (time);
1586  time = qof_time_get_today_end ();
1587  time_secs += SECS_PER_DAY - 1;
1588  do_test ((qof_time_get_secs (time) == time_secs),
1589  "start of today incorrect");
1590  do_test ((qof_time_get_nanosecs (time) == 0),
1591  "today start nanosecs non zero");
1592  qof_time_free (time);
1593  }
1594  /* last mday test */
1595  {
1596  GDate *date;
1597  guint8 mday;
1598 
1599  date = g_date_new_dmy (15, 5, 2006);
1600  time = qof_time_from_gdate (date);
1601  mday = qof_time_last_mday (time);
1602  do_test ((mday == 31), " wrong last day of May");
1603  }
1604  /* qof_date_get_mday and qof_date_get_yday tests */
1605  {
1606  QofDate *d;
1607  /* Wed 3rd Sep 2003 = 246. */
1608  do_test ((246 == qof_date_get_yday (3, 9, 2003)),
1609  "get year day test, September");
1610  d = qof_date_new ();
1611  d->qd_mday = 3;
1612  d->qd_mon = 9;
1613  d->qd_year = 2003;
1614  do_test ((TRUE == qof_date_valid (d)),
1615  "3/9/2003 not valid");
1616  do_test ((3 == d->qd_wday), "not Wednesday");
1617  qof_date_free (d);
1618  /* Fri 3rd Sep 2004 = 247. */
1619  do_test ((247 == qof_date_get_yday (3, 9, 2004)),
1620  "get year day test, leap year");
1621  d = qof_date_new ();
1622  d->qd_mday = 3;
1623  d->qd_mon = 9;
1624  d->qd_year = 2004;
1625  do_test ((TRUE == qof_date_valid (d)),
1626  "3/9/2003 not valid");
1627  do_test ((5 == d->qd_wday), "not Friday");
1628  qof_date_free (d);
1629  /* Sun 19th May 2002 = 139. */
1630  do_test ((139 == qof_date_get_yday (19, 5, 2002)),
1631  "get year day test, May");
1632  d = qof_date_new ();
1633  d->qd_mday = 19;
1634  d->qd_mon = 5;
1635  d->qd_year = 2002;
1636  do_test ((TRUE == qof_date_valid (d)),
1637  "3/9/2003 not valid");
1638  do_test ((0 == d->qd_wday), "not Sunday");
1639  qof_date_free (d);
1640  /* Wed 19th May 2004 = 140. */
1641  do_test ((140 == qof_date_get_yday (19, 5, 2004)),
1642  "get year day test, May");
1643  d = qof_date_new ();
1644  d->qd_mday = 19;
1645  d->qd_mon = 5;
1646  d->qd_year = 2004;
1647  do_test ((TRUE == qof_date_valid (d)),
1648  "3/9/2003 not valid");
1649  do_test ((3 == d->qd_wday), "not Wednesday, May");
1650  qof_date_free (d);
1651  /* Nov 2003 = 30 */
1652  do_test ((30 == qof_date_get_mday (11, 2003)),
1653  "get days in month, non-leap");
1654  /* Feb 2004 = 29 */
1655  do_test ((29 == qof_date_get_mday (2, 2004)),
1656  "get days in month, leap year");
1657  }
1658  /* time to dmy test */
1659  {
1660  gboolean success;
1661  guint8 day, month;
1662  guint16 year;
1663  GDate *date;
1664  QofTime *reverse;
1665 
1666  date = g_date_new_dmy (15, 5, 2006);
1667  time = qof_time_from_gdate (date);
1668  success = qof_time_to_dmy (time, &day, &month, &year);
1669  do_test ((success == TRUE), "time to dmy failed");
1670  do_test ((day == 15), "wrong day calculated");
1671  do_test ((month == 5), "wrong month calculated");
1672  do_test ((year == 2006), "wrong year calculated");
1673  reverse = qof_time_dmy_to_time (day, month, year);
1674  do_test ((qof_time_cmp (time, reverse) == 0), "dmy to time failed");
1675  g_date_free (date);
1676  qof_time_free (time);
1677  qof_time_free (reverse);
1678  }
1679  {
1680  /* day, month, year wrapping */
1681  QofTime *wrap_t;
1682  QofDate *wrap_d;
1683  glong day, month, year;
1684 
1685  /* Thu Jul 13 18:20:27 UTC 2006 */
1686  wrap_t = qof_time_set (1152814827, 345634);
1687  wrap_d = qof_date_from_qtime (wrap_t);
1688  PINFO (" base date for section = %s",
1690  day = wrap_d->qd_mday;
1691  month = wrap_d->qd_mon;
1692  year = wrap_d->qd_year;
1693  qof_date_free (wrap_d);
1694  /* one day ago */
1695  wrap_d = qof_date_from_qtime (wrap_t);
1696  wrap_d->qd_mday -= 1;
1697  qof_date_valid (wrap_d);
1698  do_test ((wrap_d->qd_mon == month &&
1699  wrap_d->qd_year == year &&
1700  wrap_d->qd_mday == (day - 1)),
1701  " this time on previous day");
1702  PINFO (" same time previous day = %s",
1704  qof_date_free (wrap_d);
1705  /* this time last month */
1706  wrap_d = qof_date_from_qtime (wrap_t);
1707  wrap_d->qd_mon -= 1;
1708  qof_date_valid (wrap_d);
1709  do_test ((wrap_d->qd_mon == (month - 1) &&
1710  wrap_d->qd_year == year &&
1711  wrap_d->qd_mday == day),
1712  " this time last month");
1713  PINFO (" same time previous month = %s",
1715  qof_date_free (wrap_d);
1716  /* this time last year */
1717  wrap_d = qof_date_from_qtime (wrap_t);
1718  wrap_d->qd_year -= 1;
1719  qof_date_valid (wrap_d);
1720  do_test ((wrap_d->qd_mon == month &&
1721  wrap_d->qd_year == (year - 1) &&
1722  wrap_d->qd_mday == day),
1723  " this time last year");
1724  PINFO (" same time previous year = %s",
1726  qof_time_free (wrap_t);
1727  qof_date_free (wrap_d);
1728  }
1729 }
1730 
1731 int
1732 main (void)
1733 {
1734  qof_init ();
1735 #ifdef TEST_DEBUG
1736  qof_log_init_filename ("test-date.trace");
1737  qof_log_set_default (QOF_LOG_DETAIL);
1738  ENTER (" ");
1739 #endif
1740  test_date_init ();
1741  run_qoftime_test ();
1742  run_qofdate_test ();
1743  run_print_scan_tests ();
1744  g_list_foreach (test_data, check_date_cycles, NULL);
1745  print_test_results ();
1746  test_date_close ();
1747 #ifdef TEST_DEBUG
1748  LEAVE (" ");
1749  qof_log_shutdown ();
1750 #endif
1751  qof_close ();
1752  exit (get_rv ());
1753 }
gint64 qd_year
Extended version to cope with full range of dates.
Definition: qofdate.h:181
#define QOF_DATE_FORMAT_UTC
QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".
Definition: qofdate.h:277
#define PERR(format, args...)
Definition: qoflog.h:183
gboolean qof_date_format_set_current(QofDateFormat df)
Selects one registered date format as the current default.
Definition: qofdate.c:294
QofTime * qof_time_from_gdate(GDate *date)
Convert a GDate to a QofTime.
Definition: qoftime.c:312
#define QOF_DATE_FORMAT_ISO
Short ISO form. "%F".
Definition: qofdate.h:268
void qof_log_init_filename(const gchar *logfilename)
Definition: qoflog.c:144
#define PINFO(format, args...)
Definition: qoflog.h:199
gboolean qof_date_adddays(QofDate *qd, gint days)
Add a number of days to a QofDate and normalise.
Definition: qofdate.c:1000
void qof_date_free(QofDate *date)
Definition: qofdate.c:642
QofDate * qof_date_from_qtime(const QofTime *qt)
Definition: qofdate.c:884
gboolean qof_time_set_day_end(QofTime *qt)
set the given QofTime to the last second of that day.
Definition: qoftime.c:327
gboolean qof_date_format_set_name(const gchar *name, QofDateFormat format)
Set a shorthand name for a custom date format.
Definition: qofdate.c:269
QofDateFormat qof_date_format_from_name(const gchar *name)
Returns the default date format for a known shorthand name.
Definition: qofdate.c:385
const gchar * qd_zone
Calculated value based on struct tm.tm_zone.
Definition: qofdate.h:208
QofTime * qof_time_add_secs_copy(QofTime *qt, QofTimeSecs secs)
Create a new QofTime, secs different to an original.
Definition: qoftime.c:73
guint8 qof_date_get_mday(gint month, gint64 year)
Definition: qofdate.c:183
QofTime * qof_time_abs(QofTime *qt)
Definition: qoftime.c:196
QofTimeSecs qof_time_get_secs(const QofTime *qt)
Get the number of seconds.
Definition: qoftime.c:133
QofTime * qof_time_get_today_end(void)
Definition: qoftime.c:413
gboolean qof_time_to_dmy(QofTime *qt, guint8 *day, guint8 *month, guint16 *year)
Definition: qoftime.c:439
gint safe_strcasecmp(const gchar *da, const gchar *db)
Definition: qofutil.c:95
gchar * qof_date_print(const QofDate *date, QofDateFormat df)
Convert a QofDate to a timestamp according to the specified date format.
Definition: qofdate.c:581
QofTime * qof_time_copy(const QofTime *qt)
Create a copy of a QofTime.
Definition: qoftime.c:223
gboolean qof_date_format_set_date_separator(const gchar sep, QofDateFormat df)
Set a locale-specific separator.
Definition: qofdate.c:340
#define QOF_MOD_DATE
Definition: qofdate.h:98
void qof_time_set_secs(QofTime *qt, QofTimeSecs secs)
Set the number of seconds.
Definition: qoftime.c:117
QofTime * qof_time_new(void)
create an empty QofTime
Definition: qoftime.c:46
QofDateFormat qof_date_format_get_current(void)
returns the current date format.
Definition: qofdate.c:288
void qof_log_shutdown(void)
Definition: qoflog.c:159
GDate * qof_time_to_gdate(QofTime *qt)
Convert QofTime to GDate.
Definition: qoftime.c:299
gboolean qof_time_set_day_start(QofTime *qt)
set the given QofTime to the first second of that day.
Definition: qoftime.c:374
QofTime * qof_time_dmy_to_time(guint8 day, guint8 month, guint16 year)
Definition: qoftime.c:457
glong qof_time_get_nanosecs(const QofTime *qt)
Get the number of seconds.
Definition: qoftime.c:141
const gchar * qof_date_format_get_format(QofDateFormat df)
Retrieve the strftime format string for a registered date format.
Definition: qofdate.c:310
#define LEAVE(format, args...)
Definition: qoflog.h:227
QofTime * qof_date_to_qtime(const QofDate *qd)
Definition: qofdate.c:926
Full range replacement for struct tm.
Definition: qofdate.h:138
gchar qof_date_format_get_date_separator(QofDateFormat df)
Return the field separator for the current date format.
Definition: qofdate.c:325
gboolean qof_time_set_day_middle(QofTime *qt)
set the given QofTime to midday on the same day.
Definition: qoftime.c:336
QofDate * qof_date_parse(const gchar *str, QofDateFormat df)
Convert a timestamp to a QofTime.
Definition: qofdate.c:557
#define QOF_DATE_FORMAT_CE
Contintental European default. "%d.%m.%Y".
Definition: qofdate.h:263
glong qd_hour
Signed replacement of struct tm.tm_hour.
Definition: qofdate.h:157
void qof_time_free(QofTime *qt)
Free a QofTime when no longer required.
Definition: qoftime.c:56
glong qd_min
Signed replacement of struct tm.tm_min.
Definition: qofdate.h:150
gint qof_time_cmp(const QofTime *ta, const QofTime *tb)
Definition: qoftime.c:165
glong qd_mon
Signed replacement of struct tm.tm_mon.
Definition: qofdate.h:171
guint16 qof_date_get_yday(gint mday, gint month, gint64 year)
Definition: qofdate.c:167
void qof_time_add_secs(QofTime *qt, QofTimeSecs secs)
Add (or subtract) seconds from a QofTime.
Definition: qoftime.c:65
#define DEBUG(format, args...)
Definition: qoflog.h:208
QofTime * qof_time_get_today_start(void)
Definition: qoftime.c:402
GTimeVal * qof_time_get_current_start(void)
Definition: qoftime.c:345
#define QOF_DATE_FORMAT_ISO8601
Definition: qofdate.h:287
#define QOF_DATE_FORMAT_UK
United Kingdom default. "%d/%m/%Y".
Definition: qofdate.h:258
gboolean qof_time_equal(const QofTime *ta, const QofTime *tb)
Definition: qoftime.c:148
#define QOF_DATE_FORMAT_LOCALE
GNU locale default. "%x".
Definition: qofdate.h:303
void qof_time_set_nanosecs(QofTime *qt, glong nano)
Set the number of seconds.
Definition: qoftime.c:125
guint8 qof_time_last_mday(QofTime *qt)
Definition: qoftime.c:423
gint64 qd_sec
Definition: qofdate.h:143
gint QofDateFormat
Definition: qofdate.h:335
QofTime * qof_time_set(QofTimeSecs t, glong nanosecs)
Definition: qoftime.c:210
gboolean qof_date_addmonths(QofDate *qd, gint months, gboolean track_last_day)
Definition: qofdate.c:1009
void qof_log_set_default(QofLogLevel log_level)
Definition: qoflog.c:232
const gchar * qof_date_format_to_name(QofDateFormat format)
Retrieve the shorthand name for the selected date format.
Definition: qofdate.c:254
glong qd_nanosecs
Definition: qofdate.h:141
#define SECS_PER_DAY
Definition: qofdate.h:94
void qof_close(void)
Safely close down the Query Object Framework.
Definition: qofutil.c:840
gint64 QofTimeSecs
Replacement for time_t.
Definition: qoftime.h:121
#define QOF_DATE_FORMAT_CUSTOM
Date and time for the current locale "%c".
Definition: qofdate.h:319
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:112
QofDate * qof_date_new(void)
Definition: qofdate.c:607
gint qof_date_compare(const QofDate *d1, const QofDate *d2)
Definition: qofdate.c:671
gshort qd_wday
Definition: qofdate.h:185
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:75
void qof_time_from_gtimeval(QofTime *qt, GTimeVal *gtv)
Convert a QofTime to a GTimeVal.
Definition: qoftime.c:290
glong qd_mday
Signed replacement of struct tm.tm_mday.
Definition: qofdate.h:164
gboolean qof_time_to_gtimeval(QofTime *qt, GTimeVal *gtv)
Convert a QofTime to a GTimeVal.
Definition: qoftime.c:272
void qof_init(void)
Initialise the Query Object Framework.
Definition: qofutil.c:829
#define ENTER(format, args...)
Definition: qoflog.h:217
gboolean qof_date_format_add(const gchar *str, QofDateFormat *identifier)
Add a specific strftime compatible string as a new QofDateFormat.
Definition: qofdate.c:202
#define QOF_DATE_FORMAT_US
Continental US default. "%m/%d/%Y".
Definition: qofdate.h:253
gboolean qof_date_valid(QofDate *date)
Validate a QofDate.
Definition: qofdate.c:650
QofTime * qof_time_diff(const QofTime *ta, const QofTime *tb)
difference between two QofTimes.
Definition: qoftime.c:182
const gchar * QofLogModule
Definition: qofid.h:85
QofDate * qof_date_from_struct_tm(const struct tm *stm)
Convert a struct tm to a QofDate.
Definition: qofdate.c:713