GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
test-date.c
1 /*
2  * -- fix borken timezone test -- linas May 2004
3  */
4 
5 #include "config.h"
6 #include <ctype.h>
7 #include <glib.h>
8 #include <time.h>
9 
10 #include "gnc-date.h"
11 #include "gnc-module.h"
12 #include "test-stuff.h"
13 #include "test-engine-stuff.h"
14 
15 
16 static gboolean
17 check_time (Timespec ts, gboolean always_print)
18 {
19  Timespec ts_2;
20  char str[128];
21  gboolean ok;
22 
23  ts.tv_nsec = MIN (ts.tv_nsec, 999999999);
24  ts.tv_nsec /= 1000;
25  ts.tv_nsec *= 1000;
26 
28 
29  /* The time, in seconds, everywhere on the planet, is always
30  * the same, and is independent of location. In particular,
31  * the time, in seconds, is identical to the local time in
32  * Greenwich (GMT).
33  */
34  ts_2 = gnc_iso8601_to_timespec_gmt (str);
35 
36  ok = timespec_equal (&ts, &ts_2);
37 
38  if (!ok || always_print)
39  {
40  fprintf (stderr,
41  "\n%" G_GINT64_FORMAT ":%ld -> %s ->\n"
42  "\t%" G_GINT64_FORMAT ":%ld"
43  " (diff of %" G_GINT64_FORMAT " secs %ld nsecs)\n",
44  ts.tv_sec, ts.tv_nsec, str,
45  ts_2.tv_sec, ts_2.tv_nsec,
46  ts.tv_sec - ts_2.tv_sec, ts.tv_nsec - ts_2.tv_nsec);
47 
48  if (!ok)
49  {
50  failure ("timespec to iso8601 string conversion failed");
51  return FALSE;
52  }
53  }
54 
55  success ("timespec to iso8601 string conversion passes");
56 
57  return TRUE;
58 }
59 
60 static gboolean
61 check_conversion (const char * str, Timespec expected_ts)
62 {
63  Timespec ts;
64  int day, month, year;
65  GDate d1, d2;
66 
67  ts = gnc_iso8601_to_timespec_gmt (str);
68 
69  // We test the conversion to GDate against the timespec2dmy
70  // conversion, and also the conversion back to timespec and again
71  // to GDate so that it is still the original GDate
72  gnc_timespec2dmy(ts, &day, &month, &year);
73  d1 = timespec_to_gdate(ts);
75  if ((g_date_compare(&d1, &d2) != 0)
76  || (g_date_get_day(&d1) != day)
77  || (g_date_get_month(&d1) != month)
78  || (g_date_get_year(&d1) != year))
79  {
80  fprintf (stderr,
81  "\nmis-converted \"%s\" to GDate\n",
82  str);
83  failure ("misconverted timespec");
84  return FALSE;
85  }
86 
87  if ((expected_ts.tv_sec != ts.tv_sec) || (expected_ts.tv_nsec != ts.tv_nsec))
88  {
89  fprintf (stderr,
90  "\nmis-converted \"%s\" to %" G_GUINT64_FORMAT ".%09ld seconds\n"
91  "\twas expecting %" G_GUINT64_FORMAT ".%09ld seconds\n",
92  str, ts.tv_sec, ts.tv_nsec,
93  expected_ts.tv_sec, expected_ts.tv_nsec);
94  failure ("misconverted timespec");
95  return FALSE;
96  }
97  success ("good conversion");
98  return TRUE;
99 }
100 
101 static void
102 run_test (void)
103 {
104  Timespec ts;
105  int i;
106  gboolean do_print = FALSE;
107 
108  /* Now leaving the 60's:
109  *
110  * Black Panthers
111  * Weather Underground
112  * Kent State
113  * Evacuation of Vietnam
114  * Impeachment
115  * Gas Crisis
116  * New York Garbage Crisis
117  * Stagflation
118  * Delapidated Bicentennial
119  * Sex Pistols
120  * Punk Rock
121  *
122  * Of course, anything had to be better than the miserable 70's,
123  * which explains why Reagan was elected. Food for thought.
124  */
125  ts.tv_sec = 10 * 365 * 24 * 3600 + 2 * 24 * 3600;
126  ts.tv_nsec = 0;
127  check_conversion ("1979-12-31 15:00:00.000000 -0900", ts);
128  check_conversion ("1979-12-31 16:00:00.000000 -0800", ts);
129  check_conversion ("1979-12-31 17:00:00.000000 -0700", ts);
130  check_conversion ("1979-12-31 18:00:00.000000 -0600", ts);
131  check_conversion ("1979-12-31 19:00:00.000000 -0500", ts);
132  check_conversion ("1979-12-31 20:00:00.000000 -0400", ts);
133  check_conversion ("1979-12-31 21:00:00.000000 -0300", ts);
134  check_conversion ("1979-12-31 22:00:00.000000 -0200", ts);
135  check_conversion ("1979-12-31 23:00:00.000000 -0100", ts);
136 
137  check_conversion ("1980-01-01 00:00:00.000000 -0000", ts);
138  check_conversion ("1980-01-01 00:00:00.000000 +0000", ts);
139 
140  check_conversion ("1980-01-01 01:00:00.000000 +0100", ts);
141  check_conversion ("1980-01-01 02:00:00.000000 +0200", ts);
142  check_conversion ("1980-01-01 03:00:00.000000 +0300", ts);
143  check_conversion ("1980-01-01 04:00:00.000000 +0400", ts);
144  check_conversion ("1980-01-01 05:00:00.000000 +0500", ts);
145  check_conversion ("1980-01-01 06:00:00.000000 +0600", ts);
146  check_conversion ("1980-01-01 07:00:00.000000 +0700", ts);
147  check_conversion ("1980-01-01 08:00:00.000000 +0800", ts);
148 
149  /* check minute-offsets as well */
150  check_conversion ("1980-01-01 08:01:00.000000 +0801", ts);
151  check_conversion ("1980-01-01 08:02:00.000000 +0802", ts);
152  check_conversion ("1980-01-01 08:03:00.000000 +0803", ts);
153  check_conversion ("1980-01-01 08:23:00.000000 +0823", ts);
154  check_conversion ("1980-01-01 08:35:00.000000 +0835", ts);
155  check_conversion ("1980-01-01 08:47:00.000000 +0847", ts);
156  check_conversion ("1980-01-01 08:59:00.000000 +0859", ts);
157 
158  check_conversion ("1979-12-31 15:01:00.000000 -0859", ts);
159  check_conversion ("1979-12-31 15:02:00.000000 -0858", ts);
160  check_conversion ("1979-12-31 15:03:00.000000 -0857", ts);
161  check_conversion ("1979-12-31 15:23:00.000000 -0837", ts);
162  check_conversion ("1979-12-31 15:45:00.000000 -0815", ts);
163 
164 
165  /* The 90's */
166  ts.tv_sec = 20 * 365 * 24 * 3600 + 5 * 24 * 3600;
167  ts.tv_nsec = 0;
168  check_conversion ("1989-12-31 15:00:00.000000 -0900", ts);
169  check_conversion ("1989-12-31 16:00:00.000000 -0800", ts);
170  check_conversion ("1989-12-31 17:00:00.000000 -0700", ts);
171  check_conversion ("1989-12-31 18:00:00.000000 -0600", ts);
172  check_conversion ("1989-12-31 19:00:00.000000 -0500", ts);
173  check_conversion ("1989-12-31 20:00:00.000000 -0400", ts);
174  check_conversion ("1989-12-31 21:00:00.000000 -0300", ts);
175  check_conversion ("1989-12-31 22:00:00.000000 -0200", ts);
176  check_conversion ("1989-12-31 23:00:00.000000 -0100", ts);
177 
178  check_conversion ("1990-01-01 00:00:00.000000 -0000", ts);
179  check_conversion ("1990-01-01 00:00:00.000000 +0000", ts);
180 
181  check_conversion ("1990-01-01 01:00:00.000000 +0100", ts);
182  check_conversion ("1990-01-01 02:00:00.000000 +0200", ts);
183  check_conversion ("1990-01-01 03:00:00.000000 +0300", ts);
184  check_conversion ("1990-01-01 04:00:00.000000 +0400", ts);
185  check_conversion ("1990-01-01 05:00:00.000000 +0500", ts);
186  check_conversion ("1990-01-01 06:00:00.000000 +0600", ts);
187  check_conversion ("1990-01-01 07:00:00.000000 +0700", ts);
188  check_conversion ("1990-01-01 08:00:00.000000 +0800", ts);
189 
190  /* check minute-offsets as well */
191  check_conversion ("1990-01-01 08:01:00.000000 +0801", ts);
192  check_conversion ("1990-01-01 08:02:00.000000 +0802", ts);
193  check_conversion ("1990-01-01 08:03:00.000000 +0803", ts);
194  check_conversion ("1990-01-01 08:23:00.000000 +0823", ts);
195  check_conversion ("1990-01-01 08:35:00.000000 +0835", ts);
196  check_conversion ("1990-01-01 08:47:00.000000 +0847", ts);
197  check_conversion ("1990-01-01 08:59:00.000000 +0859", ts);
198 
199  check_conversion ("1989-12-31 15:01:00.000000 -0859", ts);
200  check_conversion ("1989-12-31 15:02:00.000000 -0858", ts);
201  check_conversion ("1989-12-31 15:03:00.000000 -0857", ts);
202  check_conversion ("1989-12-31 15:23:00.000000 -0837", ts);
203  check_conversion ("1989-12-31 15:45:00.000000 -0815", ts);
204 
205 
206  /* The naughties */
207  ts.tv_sec = 30 * 365 * 24 * 3600 + 7 * 24 * 3600;
208  ts.tv_nsec = 0;
209  check_conversion ("1999-12-31 15:00:00.000000 -0900", ts);
210  check_conversion ("1999-12-31 16:00:00.000000 -0800", ts);
211  check_conversion ("1999-12-31 17:00:00.000000 -0700", ts);
212  check_conversion ("1999-12-31 18:00:00.000000 -0600", ts);
213  check_conversion ("1999-12-31 19:00:00.000000 -0500", ts);
214  check_conversion ("1999-12-31 20:00:00.000000 -0400", ts);
215  check_conversion ("1999-12-31 21:00:00.000000 -0300", ts);
216  check_conversion ("1999-12-31 22:00:00.000000 -0200", ts);
217  check_conversion ("1999-12-31 23:00:00.000000 -0100", ts);
218 
219  check_conversion ("2000-01-01 00:00:00.000000 -0000", ts);
220  check_conversion ("2000-01-01 00:00:00.000000 +0000", ts);
221 
222  check_conversion ("2000-01-01 01:00:00.000000 +0100", ts);
223  check_conversion ("2000-01-01 02:00:00.000000 +0200", ts);
224  check_conversion ("2000-01-01 03:00:00.000000 +0300", ts);
225  check_conversion ("2000-01-01 04:00:00.000000 +0400", ts);
226  check_conversion ("2000-01-01 05:00:00.000000 +0500", ts);
227  check_conversion ("2000-01-01 06:00:00.000000 +0600", ts);
228  check_conversion ("2000-01-01 07:00:00.000000 +0700", ts);
229  check_conversion ("2000-01-01 08:00:00.000000 +0800", ts);
230 
231  /* check minute-offsets as well */
232  check_conversion ("2000-01-01 08:01:00.000000 +0801", ts);
233  check_conversion ("2000-01-01 08:02:00.000000 +0802", ts);
234  check_conversion ("2000-01-01 08:03:00.000000 +0803", ts);
235  check_conversion ("2000-01-01 08:23:00.000000 +0823", ts);
236  check_conversion ("2000-01-01 08:35:00.000000 +0835", ts);
237  check_conversion ("2000-01-01 08:47:00.000000 +0847", ts);
238  check_conversion ("2000-01-01 08:59:00.000000 +0859", ts);
239 
240  check_conversion ("1999-12-31 15:01:00.000000 -0859", ts);
241  check_conversion ("1999-12-31 15:02:00.000000 -0858", ts);
242  check_conversion ("1999-12-31 15:03:00.000000 -0857", ts);
243  check_conversion ("1999-12-31 15:23:00.000000 -0837", ts);
244  check_conversion ("1999-12-31 15:45:00.000000 -0815", ts);
245 
246 
247  /* The nows */
248  ts.tv_sec = 35 * 365 * 24 * 3600 + 9 * 24 * 3600;
249  ts.tv_nsec = 0;
250  check_conversion ("2004-12-31 15:00:00.000000 -0900", ts);
251  check_conversion ("2004-12-31 16:00:00.000000 -0800", ts);
252  check_conversion ("2004-12-31 17:00:00.000000 -0700", ts);
253  check_conversion ("2004-12-31 18:00:00.000000 -0600", ts);
254  check_conversion ("2004-12-31 19:00:00.000000 -0500", ts);
255  check_conversion ("2004-12-31 20:00:00.000000 -0400", ts);
256  check_conversion ("2004-12-31 21:00:00.000000 -0300", ts);
257  check_conversion ("2004-12-31 22:00:00.000000 -0200", ts);
258  check_conversion ("2004-12-31 23:00:00.000000 -0100", ts);
259 
260  check_conversion ("2005-01-01 00:00:00.000000 -0000", ts);
261  check_conversion ("2005-01-01 00:00:00.000000 +0000", ts);
262 
263  check_conversion ("2005-01-01 01:00:00.000000 +0100", ts);
264  check_conversion ("2005-01-01 02:00:00.000000 +0200", ts);
265  check_conversion ("2005-01-01 03:00:00.000000 +0300", ts);
266  check_conversion ("2005-01-01 04:00:00.000000 +0400", ts);
267  check_conversion ("2005-01-01 05:00:00.000000 +0500", ts);
268  check_conversion ("2005-01-01 06:00:00.000000 +0600", ts);
269  check_conversion ("2005-01-01 07:00:00.000000 +0700", ts);
270  check_conversion ("2005-01-01 08:00:00.000000 +0800", ts);
271 
272  /* check minute-offsets as well */
273  check_conversion ("2005-01-01 08:01:00.000000 +0801", ts);
274  check_conversion ("2005-01-01 08:02:00.000000 +0802", ts);
275  check_conversion ("2005-01-01 08:03:00.000000 +0803", ts);
276  check_conversion ("2005-01-01 08:23:00.000000 +0823", ts);
277  check_conversion ("2005-01-01 08:35:00.000000 +0835", ts);
278  check_conversion ("2005-01-01 08:47:00.000000 +0847", ts);
279  check_conversion ("2005-01-01 08:59:00.000000 +0859", ts);
280 
281  check_conversion ("2004-12-31 15:01:00.000000 -0859", ts);
282  check_conversion ("2004-12-31 15:02:00.000000 -0858", ts);
283  check_conversion ("2004-12-31 15:03:00.000000 -0857", ts);
284  check_conversion ("2004-12-31 15:23:00.000000 -0837", ts);
285  check_conversion ("2004-12-31 15:45:00.000000 -0815", ts);
286 
287 
288  /* Various leap-year days and near-leap times. */
289  ts = gnc_iso8601_to_timespec_gmt ("1980-02-29 00:00:00.000000 -0000");
290  check_time (ts, do_print);
291 
292  ts = gnc_iso8601_to_timespec_gmt ("1979-02-28 00:00:00.000000 -0000");
293  check_time (ts, do_print);
294 
295  ts = gnc_iso8601_to_timespec_gmt ("1990-02-28 00:00:00.000000 -0000");
296  check_time (ts, do_print);
297 
298  ts = gnc_iso8601_to_timespec_gmt ("2000-02-29 00:00:00.000000 -0000");
299  check_time (ts, do_print);
300 
301  ts = gnc_iso8601_to_timespec_gmt ("2004-02-29 00:00:00.000000 -0000");
302  check_time (ts, do_print);
303 
304  ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:00:00.000000 -0000");
305  check_time (ts, do_print);
306 
307  ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:01:00.000000 -0000");
308  check_time (ts, do_print);
309 
310  ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 02:02:00.000000 -0000");
311  check_time (ts, do_print);
312 
313  ts = gnc_iso8601_to_timespec_gmt ("2008-02-28 23:23:23.000000 -0000");
314  check_time (ts, do_print);
315 
316  /* Here's a date ten days after the 2038 rollover that should work
317  if/when we support it. */
318  ts.tv_nsec = 0;
319  ts.tv_sec = (long long int) 0x7fffffff + 3600 * 24 * 10;
320  check_time(ts, do_print);
321 
322  /* Various 'special' times. What makes these so special? */
323  ts.tv_sec = 152098136;
324  ts.tv_nsec = 0;
325  check_time (ts, do_print);
326 
327  ts.tv_sec = 1162088421;
328  ts.tv_nsec = 12548000;
329  check_time (ts, do_print);
330 
331  ts.tv_sec = 325659000 - 6500;
332  ts.tv_nsec = 0;
333  check_time (ts, do_print);
334 
335  ts.tv_sec = 1143943200;
336  ts.tv_nsec = 0;
337  check_time (ts, do_print);
338 
339  ts.tv_sec = 1603591171;
340  ts.tv_nsec = 595311000;
341  check_time (ts, do_print);
342 
343  ts.tv_sec = 1738909365;
344  ts.tv_nsec = 204102000;
345  check_time (ts, do_print);
346 
347  ts.tv_sec = 1603591171;
348  ts.tv_nsec = 595311000;
349  check_time (ts, do_print);
350 
351  ts.tv_sec = 1143943200 - 1;
352  ts.tv_nsec = 0;
353  check_time (ts, do_print);
354 
355  ts.tv_sec = 1143943200;
356  ts.tv_nsec = 0;
357  check_time (ts, do_print);
358 
359  ts.tv_sec = 1143943200 + (7 * 60 * 60);
360  ts.tv_nsec = 0;
361  check_time (ts, do_print);
362 
363  ts.tv_sec = 1143943200 + (8 * 60 * 60);
364  ts.tv_nsec = 0;
365  check_time (ts, do_print);
366 
367  ts = *get_random_timespec ();
368 
369  for (i = 0; i < 10000; i++)
370  {
371  ts.tv_sec += 10800;
372  if (!check_time (ts, FALSE))
373  return;
374  }
375 
376  for (i = 0; i < 5000; i++)
377  {
378  ts = *get_random_timespec ();
379 
380  if (!check_time (ts, FALSE))
381  return;
382  }
383 }
384 
385 int
386 main (int argc, char **argv)
387 {
388  run_test ();
389 
390  success ("dates seem to work");
391 
392  print_test_results();
393  exit(get_rv());
394 }
gchar * gnc_timespec_to_iso8601_buff(Timespec ts, gchar *buff)
Date and Time handling routines.
gboolean timespec_equal(const Timespec *ta, const Timespec *tb)
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
GDate timespec_to_gdate(Timespec ts)
Timespec gnc_iso8601_to_timespec_gmt(const gchar *)
Timespec gdate_to_timespec(GDate d)
void gnc_timespec2dmy(Timespec ts, gint *day, gint *month, gint *year)