Merge branch '976-disable-assert-checks' into 'master'
[glib.git] / glib / tests / date.c
blobb1057d9325255a6d1b8d6f8e242cee957f352546
1 #undef G_DISABLE_ASSERT
2 #undef G_LOG_DOMAIN
4 /* We are testing some deprecated APIs here */
5 #define GLIB_DISABLE_DEPRECATION_WARNINGS
7 #include "config.h"
9 #include "glib.h"
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <locale.h>
15 #include <time.h>
17 #ifdef G_OS_WIN32
18 #define WIN32_LEAN_AND_MEAN
19 #include <windows.h>
20 /* mingw defines it while msvc doesn't */
21 #ifndef SUBLANG_LITHUANIAN_LITHUANIA
22 #define SUBLANG_LITHUANIAN_LITHUANIA 0x01
23 #endif
24 #endif
26 static void
27 test_basic (void)
29 g_assert_cmpint (sizeof (GDate), <, 9);
30 g_assert (!g_date_valid_month (G_DATE_BAD_MONTH));
31 g_assert (!g_date_valid_month (13));
32 g_assert (!g_date_valid_day (G_DATE_BAD_DAY));
33 g_assert (!g_date_valid_day (32));
34 g_assert (!g_date_valid_year (G_DATE_BAD_YEAR));
35 g_assert (!g_date_valid_julian (G_DATE_BAD_JULIAN));
36 g_assert (!g_date_valid_weekday (G_DATE_BAD_WEEKDAY));
37 g_assert (g_date_is_leap_year (2000));
38 g_assert (!g_date_is_leap_year (1999));
39 g_assert (g_date_is_leap_year (1996));
40 g_assert (g_date_is_leap_year (1600));
41 g_assert (!g_date_is_leap_year (2100));
42 g_assert (!g_date_is_leap_year (1800));
45 static void
46 test_empty_constructor (void)
48 GDate *d;
50 d = g_date_new ();
51 g_assert (!g_date_valid (d));
52 g_date_free (d);
55 static void
56 test_dmy_constructor (void)
58 GDate *d;
59 guint32 j;
61 d = g_date_new_dmy (1, 1, 1);
62 g_assert (g_date_valid (d));
63 j = g_date_get_julian (d);
64 g_assert_cmpint (j, ==, 1);
65 g_assert_cmpint (g_date_get_month (d), ==, G_DATE_JANUARY);
66 g_assert_cmpint (g_date_get_day (d), ==, 1);
67 g_assert_cmpint (g_date_get_year (d), ==, 1);
68 g_date_free (d);
71 static void
72 test_julian_constructor (void)
74 GDate *d1;
75 GDate *d2;
77 d1 = g_date_new_julian (4000);
78 d2 = g_date_new_julian (5000);
79 g_assert_cmpint (g_date_get_julian (d1), ==, 4000);
80 g_assert_cmpint (g_date_days_between (d1, d2), ==, 1000);
81 g_assert_cmpint (g_date_get_year (d1), ==, 11);
82 g_assert_cmpint (g_date_get_day (d2), ==, 9);
83 g_date_free (d1);
84 g_date_free (d2);
87 static void
88 test_dates (void)
90 GDate *d;
91 GTimeVal tv;
92 time_t now;
94 d = g_date_new ();
96 /* today */
97 now = time (NULL);
98 g_assert_cmpint (now, !=, (time_t) -1);
99 g_date_set_time (d, now);
100 g_assert (g_date_valid (d));
102 /* Unix epoch */
103 g_date_set_time (d, 1);
104 g_assert (g_date_valid (d));
106 tv.tv_sec = 0;
107 tv.tv_usec = 0;
108 g_date_set_time_val (d, &tv);
109 g_assert (g_date_valid (d));
111 /* Julian day 1 */
112 g_date_set_julian (d, 1);
113 g_assert (g_date_valid (d));
115 g_date_set_year (d, 3);
116 g_date_set_day (d, 3);
117 g_date_set_month (d, 3);
118 g_assert (g_date_valid (d));
119 g_assert_cmpint (g_date_get_year (d), ==, 3);
120 g_assert_cmpint (g_date_get_month (d), ==, 3);
121 g_assert_cmpint (g_date_get_day (d), ==, 3);
122 g_assert (!g_date_is_first_of_month (d));
123 g_assert (!g_date_is_last_of_month (d));
124 g_date_set_day (d, 1);
125 g_assert (g_date_is_first_of_month (d));
126 g_date_subtract_days (d, 1);
127 g_assert (g_date_is_last_of_month (d));
129 g_date_free (d);
132 static void
133 test_parse (void)
135 GDate *d;
136 gchar buf[101];
138 d = g_date_new ();
140 g_date_set_dmy (d, 10, 1, 2000);
141 g_date_strftime (buf, 100, "%x", d);
143 g_date_set_parse (d, buf);
144 g_assert (g_date_valid (d));
145 g_assert_cmpint (g_date_get_month (d), ==, 1);
146 g_assert_cmpint (g_date_get_day (d), ==, 10);
147 g_assert_cmpint (g_date_get_year (d), ==, 2000);
149 g_date_set_parse (d, "2001 10 1");
150 g_assert (g_date_valid (d));
151 g_assert_cmpint (g_date_get_month (d), ==, 10);
152 g_assert_cmpint (g_date_get_day (d), ==, 1);
153 g_assert_cmpint (g_date_get_year (d), ==, 2001);
155 g_date_set_parse (d, "2001 10");
156 g_assert (!g_date_valid (d));
158 g_date_set_parse (d, "2001 10 1 1");
159 g_assert (!g_date_valid (d));
161 g_date_set_parse (d, "March 1999");
162 g_assert (g_date_valid (d));
163 g_assert_cmpint (g_date_get_month (d), ==, 3);
164 g_assert_cmpint (g_date_get_day (d), ==, 1);
165 g_assert_cmpint (g_date_get_year (d), ==, 1999);
167 g_date_set_parse (d, "10 Sep 1087");
168 g_assert (g_date_valid (d));
169 g_assert_cmpint (g_date_get_month (d), ==, 9);
170 g_assert_cmpint (g_date_get_day (d), ==, 10);
171 g_assert_cmpint (g_date_get_year (d), ==, 1087);
173 g_date_set_parse (d, "19990301");
174 g_assert (g_date_valid (d));
175 g_assert_cmpint (g_date_get_month (d), ==, 3);
176 g_assert_cmpint (g_date_get_day (d), ==, 1);
177 g_assert_cmpint (g_date_get_year (d), ==, 1999);
179 g_date_set_parse (d, "20011320");
180 g_assert (!g_date_valid (d));
182 g_date_free (d);
185 static void
186 test_month_names (void)
188 #if defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32)
189 GDate *gdate;
190 gchar buf[101];
191 gchar *oldlocale;
192 #ifdef G_OS_WIN32
193 LCID old_lcid;
194 #endif
195 #endif /* defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) */
197 g_test_bug ("749206");
199 /* This test can only work (on non-Windows platforms) if libc supports
200 * the %OB (etc.) format placeholders. If it doesn’t, strftime() (and hence
201 * g_date_strftime()) will return the placeholder unsubstituted.
202 * g_date_strftime() explicitly documents that it doesn’t provide any more
203 * format placeholders than the system strftime(), so we should skip the test
204 * in that case. If people need %OB support, they should depend on a suitable
205 * version of libc, or use g_date_time_format(). Note: a test for a support
206 * of _NL_ABALTMON_* is not strictly the same as checking for %OB support.
207 * Some platforms (BSD, OS X) support %OB while _NL_ABALTMON_* and %Ob
208 * are supported only by glibc 2.27 and newer. But we don’t care about BSD
209 * here, the aim of this test is to make sure that our custom implementation
210 * for Windows works the same as glibc 2.27 native implementation. */
211 #if !defined(HAVE_LANGINFO_ABALTMON) && !defined(G_OS_WIN32)
212 g_test_skip ("libc doesn’t support all alternative month names");
213 #else
215 #define TEST_DATE(d,m,y,f,o) \
216 g_date_set_dmy (gdate, d, m, y); \
217 g_date_strftime (buf, 100, f, gdate); \
218 g_assert_cmpstr (buf, ==, (o)); \
219 g_date_set_parse (gdate, buf); \
220 g_assert (g_date_valid (gdate)); \
221 g_assert_cmpint (g_date_get_day (gdate), ==, d); \
222 g_assert_cmpint (g_date_get_month (gdate), ==, m); \
223 g_assert_cmpint (g_date_get_year (gdate), ==, y);
225 oldlocale = g_strdup (setlocale (LC_ALL, NULL));
226 #ifdef G_OS_WIN32
227 old_lcid = GetThreadLocale ();
228 #endif
230 gdate = g_date_new ();
232 /* Note: Windows implementation of g_date_strftime() does not support
233 * "-" format modifier (e.g., "%-d", "%-e") so we will not use it.
236 /* Make sure that nothing has been changed in western European languages. */
237 setlocale (LC_ALL, "en_GB.utf-8");
238 #ifdef G_OS_WIN32
239 SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_UK), SORT_DEFAULT));
240 #endif
241 if (strstr (setlocale (LC_ALL, NULL), "en_GB") != NULL)
243 TEST_DATE (1, 1, 2018, "%B %d, %Y", "January 01, 2018");
244 TEST_DATE (1, 2, 2018, "%OB %Y", "February 2018");
245 TEST_DATE (1, 3, 2018, "%e %b %Y", " 1 Mar 2018");
246 TEST_DATE (1, 4, 2018, "%Ob %Y", "Apr 2018");
247 TEST_DATE (1, 5, 2018, "%d %h %Y", "01 May 2018");
248 TEST_DATE (1, 6, 2018, "%Oh %Y", "Jun 2018");
250 else
251 g_test_incomplete ("locale en_GB not available, skipping English month names test");
253 setlocale (LC_ALL, "de_DE.utf-8");
254 #ifdef G_OS_WIN32
255 SetThreadLocale (MAKELCID (MAKELANGID (LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT));
256 #endif
257 if (strstr (setlocale (LC_ALL, NULL), "de_DE") != NULL)
259 TEST_DATE (16, 7, 2018, "%d. %B %Y", "16. Juli 2018");
260 TEST_DATE ( 1, 8, 2018, "%OB %Y", "August 2018");
261 TEST_DATE (18, 9, 2018, "%e. %b %Y", "18. Sep 2018");
262 TEST_DATE ( 1, 10, 2018, "%Ob %Y", "Okt 2018");
263 TEST_DATE (20, 11, 2018, "%d. %h %Y", "20. Nov 2018");
264 TEST_DATE ( 1, 12, 2018, "%Oh %Y", "Dez 2018");
266 else
267 g_test_incomplete ("locale de_DE not available, skipping German month names test");
270 setlocale (LC_ALL, "es_ES.utf-8");
271 #ifdef G_OS_WIN32
272 SetThreadLocale (MAKELCID (MAKELANGID (LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT));
273 #endif
274 if (strstr (setlocale (LC_ALL, NULL), "es_ES") != NULL)
276 TEST_DATE ( 9, 1, 2018, "%d de %B de %Y", "09 de enero de 2018");
277 TEST_DATE ( 1, 2, 2018, "%OB de %Y", "febrero de 2018");
278 TEST_DATE (10, 3, 2018, "%e de %b de %Y", "10 de mar de 2018");
279 TEST_DATE ( 1, 4, 2018, "%Ob de %Y", "abr de 2018");
280 TEST_DATE (11, 5, 2018, "%d de %h de %Y", "11 de may de 2018");
281 TEST_DATE ( 1, 6, 2018, "%Oh de %Y", "jun de 2018");
283 else
284 g_test_incomplete ("locale es_ES not available, skipping Spanish month names test");
286 setlocale (LC_ALL, "fr_FR.utf-8");
287 #ifdef G_OS_WIN32
288 SetThreadLocale (MAKELCID (MAKELANGID (LANG_FRENCH, SUBLANG_FRENCH), SORT_DEFAULT));
289 #endif
290 if (strstr (setlocale (LC_ALL, NULL), "fr_FR") != NULL)
292 TEST_DATE (31, 7, 2018, "%d %B %Y", "31 juillet 2018");
293 TEST_DATE ( 1, 8, 2018, "%OB %Y", "août 2018");
294 TEST_DATE (30, 9, 2018, "%e %b %Y", "30 sept. 2018");
295 TEST_DATE ( 1, 10, 2018, "%Ob %Y", "oct. 2018");
296 TEST_DATE (29, 11, 2018, "%d %h %Y", "29 nov. 2018");
297 TEST_DATE ( 1, 12, 2018, "%Oh %Y", "déc. 2018");
299 else
300 g_test_incomplete ("locale fr_FR not available, skipping French month names test");
302 /* Make sure that there are visible changes in some European languages. */
303 setlocale (LC_ALL, "el_GR.utf-8");
304 #ifdef G_OS_WIN32
305 SetThreadLocale (MAKELCID (MAKELANGID (LANG_GREEK, SUBLANG_GREEK_GREECE), SORT_DEFAULT));
306 #endif
307 if (strstr (setlocale (LC_ALL, NULL), "el_GR") != NULL)
309 TEST_DATE ( 2, 1, 2018, "%d %B %Y", "02 Ιανουαρίου 2018");
310 TEST_DATE ( 4, 2, 2018, "%e %B %Y", " 4 Φεβρουαρίου 2018");
311 TEST_DATE (15, 3, 2018, "%d %B %Y", "15 Μαρτίου 2018");
312 TEST_DATE ( 1, 4, 2018, "%OB %Y", "Απρίλιος 2018");
313 TEST_DATE ( 1, 5, 2018, "%OB %Y", "Μάιος 2018");
314 TEST_DATE ( 1, 6, 2018, "%OB %Y", "Ιούνιος 2018");
315 TEST_DATE (16, 7, 2018, "%e %b %Y", "16 Ιούλ 2018");
316 TEST_DATE ( 1, 8, 2018, "%Ob %Y", "Αύγ 2018");
318 else
319 g_test_incomplete ("locale el_GR not available, skipping Greek month names test");
321 setlocale (LC_ALL, "hr_HR.utf-8");
322 #ifdef G_OS_WIN32
323 SetThreadLocale (MAKELCID (MAKELANGID (LANG_CROATIAN, SUBLANG_CROATIAN_CROATIA), SORT_DEFAULT));
324 #endif
325 if (strstr (setlocale (LC_ALL, NULL), "hr_HR") != NULL)
327 TEST_DATE ( 8, 5, 2018, "%d. %B %Y", "08. svibnja 2018");
328 TEST_DATE ( 9, 6, 2018, "%e. %B %Y", " 9. lipnja 2018");
329 TEST_DATE (10, 7, 2018, "%d. %B %Y", "10. srpnja 2018");
330 TEST_DATE ( 1, 8, 2018, "%OB %Y", "Kolovoz 2018");
331 TEST_DATE ( 1, 9, 2018, "%OB %Y", "Rujan 2018");
332 TEST_DATE ( 1, 10, 2018, "%OB %Y", "Listopad 2018");
333 TEST_DATE (11, 11, 2018, "%e. %b %Y", "11. Stu 2018");
334 TEST_DATE ( 1, 12, 2018, "%Ob %Y", "Pro 2018");
336 else
337 g_test_incomplete ("locale hr_HR not available, skipping Croatian month names test");
339 setlocale (LC_ALL, "lt_LT.utf-8");
340 #ifdef G_OS_WIN32
341 SetThreadLocale (MAKELCID (MAKELANGID (LANG_LITHUANIAN, SUBLANG_LITHUANIAN_LITHUANIA), SORT_DEFAULT));
342 #endif
343 if (strstr (setlocale (LC_ALL, NULL), "lt_LT") != NULL)
345 TEST_DATE ( 1, 1, 2018, "%Y m. %B %d d.", "2018 m. sausio 01 d.");
346 TEST_DATE ( 2, 2, 2018, "%Y m. %B %e d.", "2018 m. vasario 2 d.");
347 TEST_DATE ( 3, 3, 2018, "%Y m. %B %d d.", "2018 m. kovo 03 d.");
348 TEST_DATE ( 1, 4, 2018, "%Y m. %OB", "2018 m. balandis");
349 TEST_DATE ( 1, 5, 2018, "%Y m. %OB", "2018 m. gegužė");
350 TEST_DATE ( 1, 6, 2018, "%Y m. %OB", "2018 m. birželis");
351 TEST_DATE (17, 7, 2018, "%Y m. %b %e d.", "2018 m. Lie 17 d.");
352 TEST_DATE ( 1, 8, 2018, "%Y m. %Ob", "2018 m. Rgp");
354 else
355 g_test_incomplete ("locale lt_LT not available, skipping Lithuanian month names test");
357 setlocale (LC_ALL, "pl_PL.utf-8");
358 #ifdef G_OS_WIN32
359 SetThreadLocale (MAKELCID (MAKELANGID (LANG_POLISH, SUBLANG_POLISH_POLAND), SORT_DEFAULT));
360 #endif
361 if (strstr (setlocale (LC_ALL, NULL), "pl_PL") != NULL)
363 TEST_DATE ( 3, 5, 2018, "%d %B %Y", "03 maja 2018");
364 TEST_DATE ( 4, 6, 2018, "%e %B %Y", " 4 czerwca 2018");
365 TEST_DATE (20, 7, 2018, "%d %B %Y", "20 lipca 2018");
366 TEST_DATE ( 1, 8, 2018, "%OB %Y", "sierpień 2018");
367 TEST_DATE ( 1, 9, 2018, "%OB %Y", "wrzesień 2018");
368 TEST_DATE ( 1, 10, 2018, "%OB %Y", "październik 2018");
369 TEST_DATE (25, 11, 2018, "%e %b %Y", "25 lis 2018");
370 TEST_DATE ( 1, 12, 2018, "%Ob %Y", "gru 2018");
372 else
373 g_test_incomplete ("locale pl_PL not available, skipping Polish month names test");
375 setlocale (LC_ALL, "ru_RU.utf-8");
376 #ifdef G_OS_WIN32
377 SetThreadLocale (MAKELCID (MAKELANGID (LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA), SORT_DEFAULT));
378 #endif
379 if (strstr (setlocale (LC_ALL, NULL), "ru_RU") != NULL)
381 TEST_DATE ( 3, 1, 2018, "%d %B %Y", "03 января 2018");
382 TEST_DATE ( 4, 2, 2018, "%e %B %Y", " 4 февраля 2018");
383 TEST_DATE (23, 3, 2018, "%d %B %Y", "23 марта 2018");
384 TEST_DATE ( 1, 4, 2018, "%OB %Y", "Апрель 2018");
385 TEST_DATE ( 1, 5, 2018, "%OB %Y", "Май 2018");
386 TEST_DATE ( 1, 6, 2018, "%OB %Y", "Июнь 2018");
387 TEST_DATE (24, 7, 2018, "%e %b %Y", "24 июл 2018");
388 TEST_DATE ( 1, 8, 2018, "%Ob %Y", "авг 2018");
389 /* This difference is very important in Russian: */
390 TEST_DATE (19, 5, 2018, "%e %b %Y", "19 мая 2018");
391 TEST_DATE (20, 5, 2018, "%Ob, %d-е, %Y", "май, 20-е, 2018");
393 else
394 g_test_incomplete ("locale ru_RU not available, skipping Russian month names test");
396 g_date_free (gdate);
398 setlocale (LC_ALL, oldlocale);
399 #ifdef G_OS_WIN32
400 SetThreadLocale (old_lcid);
401 #endif
402 g_free (oldlocale);
403 #endif /* defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) */
406 static void
407 test_year (gconstpointer t)
409 GDateYear y = GPOINTER_TO_INT (t);
410 GDateMonth m;
411 GDateDay day;
412 guint32 j;
413 GDate *d;
414 gint i;
415 GDate tmp;
417 guint32 first_day_of_year = G_DATE_BAD_JULIAN;
418 guint16 days_in_year = g_date_is_leap_year (y) ? 366 : 365;
419 guint sunday_week_of_year = 0;
420 guint sunday_weeks_in_year = g_date_get_sunday_weeks_in_year (y);
421 guint monday_week_of_year = 0;
422 guint monday_weeks_in_year = g_date_get_monday_weeks_in_year (y);
423 guint iso8601_week_of_year = 0;
425 g_assert (g_date_valid_year (y));
426 /* Years ought to have roundabout 52 weeks */
427 g_assert (sunday_weeks_in_year == 52 || sunday_weeks_in_year == 53);
428 g_assert (monday_weeks_in_year == 52 || monday_weeks_in_year == 53);
430 m = 1;
431 while (m < 13)
433 guint8 dim = g_date_get_days_in_month (m, y);
434 GDate days[31];
436 g_date_clear (days, 31);
438 g_assert (dim > 0 && dim < 32);
439 g_assert (g_date_valid_month (m));
441 day = 1;
442 while (day <= dim)
444 g_assert (g_date_valid_dmy (day, m, y));
446 d = &days[day - 1];
447 //g_assert (!g_date_valid (d));
449 g_date_set_dmy (d, day, m, y);
451 g_assert (g_date_valid (d));
453 if (m == G_DATE_JANUARY && day == 1)
454 first_day_of_year = g_date_get_julian (d);
456 g_assert (first_day_of_year != G_DATE_BAD_JULIAN);
458 g_assert_cmpint (g_date_get_month (d), ==, m);
459 g_assert_cmpint (g_date_get_year (d), ==, y);
460 g_assert_cmpint (g_date_get_day (d), ==, day);
462 g_assert (g_date_get_julian (d) + 1 - first_day_of_year ==
463 g_date_get_day_of_year (d));
465 if (m == G_DATE_DECEMBER && day == 31)
466 g_assert_cmpint (g_date_get_day_of_year (d), ==, days_in_year);
468 g_assert_cmpint (g_date_get_day_of_year (d), <=, days_in_year);
469 g_assert_cmpint (g_date_get_monday_week_of_year (d), <=, monday_weeks_in_year);
470 g_assert_cmpint (g_date_get_monday_week_of_year (d), >=, monday_week_of_year);
472 if (g_date_get_weekday(d) == G_DATE_MONDAY)
474 g_assert_cmpint (g_date_get_monday_week_of_year (d) - monday_week_of_year, ==, 1);
475 if ((m == G_DATE_JANUARY && day <= 4) ||
476 (m == G_DATE_DECEMBER && day >= 29))
477 g_assert_cmpint (g_date_get_iso8601_week_of_year (d), ==, 1);
478 else
479 g_assert_cmpint (g_date_get_iso8601_week_of_year (d) - iso8601_week_of_year, ==, 1);
481 else
483 g_assert_cmpint (g_date_get_monday_week_of_year(d) - monday_week_of_year, ==, 0);
484 if (!(day == 1 && m == G_DATE_JANUARY))
485 g_assert_cmpint (g_date_get_iso8601_week_of_year(d) - iso8601_week_of_year, ==, 0);
488 monday_week_of_year = g_date_get_monday_week_of_year (d);
489 iso8601_week_of_year = g_date_get_iso8601_week_of_year (d);
491 g_assert_cmpint (g_date_get_sunday_week_of_year (d), <=, sunday_weeks_in_year);
492 g_assert_cmpint (g_date_get_sunday_week_of_year (d), >=, sunday_week_of_year);
493 if (g_date_get_weekday(d) == G_DATE_SUNDAY)
494 g_assert_cmpint (g_date_get_sunday_week_of_year (d) - sunday_week_of_year, ==, 1);
495 else
496 g_assert_cmpint (g_date_get_sunday_week_of_year (d) - sunday_week_of_year, ==, 0);
498 sunday_week_of_year = g_date_get_sunday_week_of_year (d);
500 g_assert_cmpint (g_date_compare (d, d), ==, 0);
502 i = 1;
503 while (i < 402) /* Need to get 400 year increments in */
505 tmp = *d;
506 g_date_add_days (d, i);
507 g_assert_cmpint (g_date_compare (d, &tmp), >, 0);
508 g_date_subtract_days (d, i);
509 g_assert_cmpint (g_date_get_day (d), ==, day);
510 g_assert_cmpint (g_date_get_month (d), ==, m);
511 g_assert_cmpint (g_date_get_year (d), ==, y);
513 tmp = *d;
514 g_date_add_months (d, i);
515 g_assert_cmpint (g_date_compare (d, &tmp), >, 0);
516 g_date_subtract_months (d, i);
517 g_assert_cmpint (g_date_get_month (d), ==, m);
518 g_assert_cmpint (g_date_get_year (d), ==, y);
520 if (day < 29)
521 g_assert_cmpint (g_date_get_day (d), ==, day);
522 else
523 g_date_set_day (d, day);
525 tmp = *d;
526 g_date_add_years (d, i);
527 g_assert_cmpint (g_date_compare (d, &tmp), >, 0);
528 g_date_subtract_years (d, i);
529 g_assert_cmpint (g_date_get_month (d), ==, m);
530 g_assert_cmpint (g_date_get_year (d), ==, y);
532 if (m != 2 && day != 29)
533 g_assert_cmpint (g_date_get_day (d), ==, day);
534 else
535 g_date_set_day (d, day); /* reset */
537 i += 10;
540 j = g_date_get_julian (d);
542 ++day;
544 ++m;
547 /* at this point, d is the last day of year y */
548 g_date_set_dmy (&tmp, 1, 1, y + 1);
549 g_assert_cmpint (j + 1, ==, g_date_get_julian (&tmp));
551 g_date_add_days (&tmp, 1);
552 g_assert_cmpint (j + 2, ==, g_date_get_julian (&tmp));
555 static void
556 test_clamp (void)
558 GDate d1, d2, d, o;
560 g_date_set_dmy (&d1, 1, 1, 1970);
561 g_date_set_dmy (&d2, 1, 1, 1980);
562 g_date_set_dmy (&d, 1, 1, 1);
564 o = d;
565 g_date_clamp (&o, NULL, NULL);
566 g_assert (g_date_compare (&o, &d) == 0);
568 g_date_clamp (&o, &d1, &d2);
569 g_assert (g_date_compare (&o, &d1) == 0);
571 g_date_set_dmy (&o, 1, 1, 2000);
573 g_date_clamp (&o, &d1, &d2);
574 g_assert (g_date_compare (&o, &d2) == 0);
577 static void
578 test_order (void)
580 GDate d1, d2;
582 g_date_set_dmy (&d1, 1, 1, 1970);
583 g_date_set_dmy (&d2, 1, 1, 1980);
585 g_assert (g_date_compare (&d1, &d2) == -1);
586 g_date_order (&d2, &d1);
587 g_assert (g_date_compare (&d1, &d2) == 1);
590 static void
591 test_copy (void)
593 GDate *d;
594 GDate *c;
596 d = g_date_new ();
597 g_assert_false (g_date_valid (d));
599 c = g_date_copy (d);
600 g_assert_nonnull (c);
601 g_assert_false (g_date_valid (c));
602 g_date_free (c);
604 g_date_set_day (d, 10);
606 c = g_date_copy (d);
607 g_date_set_month (c, 1);
608 g_date_set_year (c, 2015);
609 g_assert_true (g_date_valid (c));
610 g_assert_cmpuint (g_date_get_day (c), ==, 10);
611 g_date_free (c);
613 g_date_free (d);
616 /* Check the results of g_date_valid_dmy() for various inputs. */
617 static void
618 test_valid_dmy (void)
620 const struct
622 GDateDay day;
623 GDateMonth month;
624 GDateYear year;
625 gboolean expected_valid;
627 vectors[] =
629 /* Lower bounds */
630 { 0, 0, 0, FALSE },
631 { 1, 1, 1, TRUE },
632 { 1, 1, 0, FALSE },
633 /* Leap year month lengths */
634 { 30, 2, 2000, FALSE },
635 { 29, 2, 2000, TRUE },
636 { 29, 2, 2001, FALSE },
637 /* Maximum year */
638 { 1, 1, G_MAXUINT16, TRUE },
640 gsize i;
642 for (i = 0; i < G_N_ELEMENTS (vectors); i++)
644 gboolean valid;
645 g_test_message ("Vector %" G_GSIZE_FORMAT ": %04u-%02u-%02u, %s",
646 i, vectors[i].year, vectors[i].month, vectors[i].day,
647 vectors[i].expected_valid ? "valid" : "invalid");
649 valid = g_date_valid_dmy (vectors[i].day, vectors[i].month, vectors[i].year);
651 if (vectors[i].expected_valid)
652 g_assert_true (valid);
653 else
654 g_assert_false (valid);
659 main (int argc, char** argv)
661 gchar *path;
662 gint i;
664 /* Try to get all the leap year cases. */
665 int check_years[] = {
666 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
667 11, 12, 13, 14, 98, 99, 100, 101, 102, 103, 397,
668 398, 399, 400, 401, 402, 403, 404, 405, 406,
669 1598, 1599, 1600, 1601, 1602, 1650, 1651,
670 1897, 1898, 1899, 1900, 1901, 1902, 1903,
671 1961, 1962, 1963, 1964, 1965, 1967,
672 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976,
673 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
674 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
675 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
676 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
677 3000, 3001, 3002, 3998, 3999, 4000, 4001, 4002, 4003
680 g_setenv ("LC_ALL", "en_US.utf-8", TRUE);
681 setlocale (LC_ALL, "");
682 #ifdef G_OS_WIN32
683 SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
684 #endif
686 g_test_init (&argc, &argv, NULL);
687 g_test_bug_base ("http://bugzilla.gnome.org/");
689 g_test_add_func ("/date/basic", test_basic);
690 g_test_add_func ("/date/empty", test_empty_constructor);
691 g_test_add_func ("/date/dmy", test_dmy_constructor);
692 g_test_add_func ("/date/julian", test_julian_constructor);
693 g_test_add_func ("/date/dates", test_dates);
694 g_test_add_func ("/date/parse", test_parse);
695 g_test_add_func ("/date/month_names", test_month_names);
696 g_test_add_func ("/date/clamp", test_clamp);
697 g_test_add_func ("/date/order", test_order);
698 for (i = 0; i < G_N_ELEMENTS (check_years); i++)
700 path = g_strdup_printf ("/date/year/%d", check_years[i]);
701 g_test_add_data_func (path, GINT_TO_POINTER(check_years[i]), test_year);
702 g_free (path);
704 g_test_add_func ("/date/copy", test_copy);
705 g_test_add_func ("/date/valid-dmy", test_valid_dmy);
707 return g_test_run ();