Merge branch 'g-clear-pointer-no-side-effects' into 'master'
[glib.git] / glib / tests / date.c
blobb801ca704c7828a6686f3f61cfec864103ee8ec8
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 /* If running uninstalled (G_TEST_BUILDDIR is set), skip this test, since we
200 * need the translations to be installed. We can’t mess around with
201 * bindtextdomain() here, as the compiled .gmo files in po/ are not in the
202 * right installed directory hierarchy to be successfully loaded by gettext. */
203 if (g_getenv ("G_TEST_BUILDDIR") != NULL)
205 g_test_skip ("Skipping due to running uninstalled. "
206 "This test can only be run when the translations are installed.");
207 return;
210 /* This test can only work (on non-Windows platforms) if libc supports
211 * the %OB (etc.) format placeholders. If it doesn’t, strftime() (and hence
212 * g_date_strftime()) will return the placeholder unsubstituted.
213 * g_date_strftime() explicitly documents that it doesn’t provide any more
214 * format placeholders than the system strftime(), so we should skip the test
215 * in that case. If people need %OB support, they should depend on a suitable
216 * version of libc, or use g_date_time_format(). Note: a test for a support
217 * of _NL_ABALTMON_* is not strictly the same as checking for %OB support.
218 * Some platforms (BSD, OS X) support %OB while _NL_ABALTMON_* and %Ob
219 * are supported only by glibc 2.27 and newer. But we don’t care about BSD
220 * here, the aim of this test is to make sure that our custom implementation
221 * for Windows works the same as glibc 2.27 native implementation. */
222 #if !defined(HAVE_LANGINFO_ABALTMON) && !defined(G_OS_WIN32)
223 g_test_skip ("libc doesn’t support all alternative month names");
224 #else
226 #define TEST_DATE(d,m,y,f,o) G_STMT_START { \
227 gchar *o_casefold, *buf_casefold; \
228 g_date_set_dmy (gdate, d, m, y); \
229 g_date_strftime (buf, 100, f, gdate); \
230 buf_casefold = g_utf8_casefold (buf, -1); \
231 o_casefold = g_utf8_casefold ((o), -1); \
232 g_assert_cmpstr (buf_casefold, ==, o_casefold); \
233 g_free (buf_casefold); \
234 g_free (o_casefold); \
235 g_date_set_parse (gdate, buf); \
236 g_assert (g_date_valid (gdate)); \
237 g_assert_cmpint (g_date_get_day (gdate), ==, d); \
238 g_assert_cmpint (g_date_get_month (gdate), ==, m); \
239 g_assert_cmpint (g_date_get_year (gdate), ==, y); \
240 } G_STMT_END
242 oldlocale = g_strdup (setlocale (LC_ALL, NULL));
243 #ifdef G_OS_WIN32
244 old_lcid = GetThreadLocale ();
245 #endif
247 gdate = g_date_new ();
249 /* Note: Windows implementation of g_date_strftime() does not support
250 * "-" format modifier (e.g., "%-d", "%-e") so we will not use it.
253 /* Make sure that nothing has been changed in western European languages. */
254 setlocale (LC_ALL, "en_GB.utf-8");
255 #ifdef G_OS_WIN32
256 SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_UK), SORT_DEFAULT));
257 #endif
258 if (strstr (setlocale (LC_ALL, NULL), "en_GB") != NULL)
260 TEST_DATE (1, 1, 2018, "%B %d, %Y", "January 01, 2018");
261 TEST_DATE (1, 2, 2018, "%OB %Y", "February 2018");
262 TEST_DATE (1, 3, 2018, "%e %b %Y", " 1 Mar 2018");
263 TEST_DATE (1, 4, 2018, "%Ob %Y", "Apr 2018");
264 TEST_DATE (1, 5, 2018, "%d %h %Y", "01 May 2018");
265 TEST_DATE (1, 6, 2018, "%Oh %Y", "Jun 2018");
267 else
268 g_test_skip ("locale en_GB not available, skipping English month names test");
270 setlocale (LC_ALL, "de_DE.utf-8");
271 #ifdef G_OS_WIN32
272 SetThreadLocale (MAKELCID (MAKELANGID (LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT));
273 #endif
274 if (strstr (setlocale (LC_ALL, NULL), "de_DE") != NULL)
276 TEST_DATE (16, 7, 2018, "%d. %B %Y", "16. Juli 2018");
277 TEST_DATE ( 1, 8, 2018, "%OB %Y", "August 2018");
278 TEST_DATE (18, 9, 2018, "%e. %b %Y", "18. Sep 2018");
279 TEST_DATE ( 1, 10, 2018, "%Ob %Y", "Okt 2018");
280 TEST_DATE (20, 11, 2018, "%d. %h %Y", "20. Nov 2018");
281 TEST_DATE ( 1, 12, 2018, "%Oh %Y", "Dez 2018");
283 else
284 g_test_skip ("locale de_DE not available, skipping German month names test");
287 setlocale (LC_ALL, "es_ES.utf-8");
288 #ifdef G_OS_WIN32
289 SetThreadLocale (MAKELCID (MAKELANGID (LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT));
290 #endif
291 if (strstr (setlocale (LC_ALL, NULL), "es_ES") != NULL)
293 TEST_DATE ( 9, 1, 2018, "%d de %B de %Y", "09 de enero de 2018");
294 TEST_DATE ( 1, 2, 2018, "%OB de %Y", "febrero de 2018");
295 TEST_DATE (10, 3, 2018, "%e de %b de %Y", "10 de mar de 2018");
296 TEST_DATE ( 1, 4, 2018, "%Ob de %Y", "abr de 2018");
297 TEST_DATE (11, 5, 2018, "%d de %h de %Y", "11 de may de 2018");
298 TEST_DATE ( 1, 6, 2018, "%Oh de %Y", "jun de 2018");
300 else
301 g_test_skip ("locale es_ES not available, skipping Spanish month names test");
303 setlocale (LC_ALL, "fr_FR.utf-8");
304 #ifdef G_OS_WIN32
305 SetThreadLocale (MAKELCID (MAKELANGID (LANG_FRENCH, SUBLANG_FRENCH), SORT_DEFAULT));
306 #endif
307 if (strstr (setlocale (LC_ALL, NULL), "fr_FR") != NULL)
309 TEST_DATE (31, 7, 2018, "%d %B %Y", "31 juillet 2018");
310 TEST_DATE ( 1, 8, 2018, "%OB %Y", "août 2018");
311 TEST_DATE (30, 9, 2018, "%e %b %Y", "30 sept. 2018");
312 TEST_DATE ( 1, 10, 2018, "%Ob %Y", "oct. 2018");
313 TEST_DATE (29, 11, 2018, "%d %h %Y", "29 nov. 2018");
314 TEST_DATE ( 1, 12, 2018, "%Oh %Y", "déc. 2018");
316 else
317 g_test_skip ("locale fr_FR not available, skipping French month names test");
319 /* Make sure that there are visible changes in some European languages. */
320 setlocale (LC_ALL, "el_GR.utf-8");
321 #ifdef G_OS_WIN32
322 SetThreadLocale (MAKELCID (MAKELANGID (LANG_GREEK, SUBLANG_GREEK_GREECE), SORT_DEFAULT));
323 #endif
324 if (strstr (setlocale (LC_ALL, NULL), "el_GR") != NULL)
326 TEST_DATE ( 2, 1, 2018, "%d %B %Y", "02 Ιανουαρίου 2018");
327 TEST_DATE ( 4, 2, 2018, "%e %B %Y", " 4 Φεβρουαρίου 2018");
328 TEST_DATE (15, 3, 2018, "%d %B %Y", "15 Μαρτίου 2018");
329 TEST_DATE ( 1, 4, 2018, "%OB %Y", "Απρίλιος 2018");
330 TEST_DATE ( 1, 5, 2018, "%OB %Y", "Μάιος 2018");
331 TEST_DATE ( 1, 6, 2018, "%OB %Y", "Ιούνιος 2018");
332 TEST_DATE (16, 7, 2018, "%e %b %Y", "16 Ιούλ 2018");
333 TEST_DATE ( 1, 8, 2018, "%Ob %Y", "Αύγ 2018");
335 else
336 g_test_skip ("locale el_GR not available, skipping Greek month names test");
338 setlocale (LC_ALL, "hr_HR.utf-8");
339 #ifdef G_OS_WIN32
340 SetThreadLocale (MAKELCID (MAKELANGID (LANG_CROATIAN, SUBLANG_CROATIAN_CROATIA), SORT_DEFAULT));
341 #endif
342 if (strstr (setlocale (LC_ALL, NULL), "hr_HR") != NULL)
344 TEST_DATE ( 8, 5, 2018, "%d. %B %Y", "08. svibnja 2018");
345 TEST_DATE ( 9, 6, 2018, "%e. %B %Y", " 9. lipnja 2018");
346 TEST_DATE (10, 7, 2018, "%d. %B %Y", "10. srpnja 2018");
347 TEST_DATE ( 1, 8, 2018, "%OB %Y", "Kolovoz 2018");
348 TEST_DATE ( 1, 9, 2018, "%OB %Y", "Rujan 2018");
349 TEST_DATE ( 1, 10, 2018, "%OB %Y", "Listopad 2018");
350 TEST_DATE (11, 11, 2018, "%e. %b %Y", "11. Stu 2018");
351 TEST_DATE ( 1, 12, 2018, "%Ob %Y", "Pro 2018");
353 else
354 g_test_skip ("locale hr_HR not available, skipping Croatian month names test");
356 setlocale (LC_ALL, "lt_LT.utf-8");
357 #ifdef G_OS_WIN32
358 SetThreadLocale (MAKELCID (MAKELANGID (LANG_LITHUANIAN, SUBLANG_LITHUANIAN_LITHUANIA), SORT_DEFAULT));
359 #endif
360 if (strstr (setlocale (LC_ALL, NULL), "lt_LT") != NULL)
362 TEST_DATE ( 1, 1, 2018, "%Y m. %B %d d.", "2018 m. sausio 01 d.");
363 TEST_DATE ( 2, 2, 2018, "%Y m. %B %e d.", "2018 m. vasario 2 d.");
364 TEST_DATE ( 3, 3, 2018, "%Y m. %B %d d.", "2018 m. kovo 03 d.");
365 TEST_DATE ( 1, 4, 2018, "%Y m. %OB", "2018 m. balandis");
366 TEST_DATE ( 1, 5, 2018, "%Y m. %OB", "2018 m. gegužė");
367 TEST_DATE ( 1, 6, 2018, "%Y m. %OB", "2018 m. birželis");
368 TEST_DATE (17, 7, 2018, "%Y m. %b %e d.", "2018 m. Lie 17 d.");
369 TEST_DATE ( 1, 8, 2018, "%Y m. %Ob", "2018 m. Rgp");
371 else
372 g_test_skip ("locale lt_LT not available, skipping Lithuanian month names test");
374 setlocale (LC_ALL, "pl_PL.utf-8");
375 #ifdef G_OS_WIN32
376 SetThreadLocale (MAKELCID (MAKELANGID (LANG_POLISH, SUBLANG_POLISH_POLAND), SORT_DEFAULT));
377 #endif
378 if (strstr (setlocale (LC_ALL, NULL), "pl_PL") != NULL)
380 TEST_DATE ( 3, 5, 2018, "%d %B %Y", "03 maja 2018");
381 TEST_DATE ( 4, 6, 2018, "%e %B %Y", " 4 czerwca 2018");
382 TEST_DATE (20, 7, 2018, "%d %B %Y", "20 lipca 2018");
383 TEST_DATE ( 1, 8, 2018, "%OB %Y", "sierpień 2018");
384 TEST_DATE ( 1, 9, 2018, "%OB %Y", "wrzesień 2018");
385 TEST_DATE ( 1, 10, 2018, "%OB %Y", "październik 2018");
386 TEST_DATE (25, 11, 2018, "%e %b %Y", "25 lis 2018");
387 TEST_DATE ( 1, 12, 2018, "%Ob %Y", "gru 2018");
389 else
390 g_test_skip ("locale pl_PL not available, skipping Polish month names test");
392 setlocale (LC_ALL, "ru_RU.utf-8");
393 #ifdef G_OS_WIN32
394 SetThreadLocale (MAKELCID (MAKELANGID (LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA), SORT_DEFAULT));
395 #endif
396 if (strstr (setlocale (LC_ALL, NULL), "ru_RU") != NULL)
398 TEST_DATE ( 3, 1, 2018, "%d %B %Y", "03 января 2018");
399 TEST_DATE ( 4, 2, 2018, "%e %B %Y", " 4 февраля 2018");
400 TEST_DATE (23, 3, 2018, "%d %B %Y", "23 марта 2018");
401 TEST_DATE ( 1, 4, 2018, "%OB %Y", "Апрель 2018");
402 TEST_DATE ( 1, 5, 2018, "%OB %Y", "Май 2018");
403 TEST_DATE ( 1, 6, 2018, "%OB %Y", "Июнь 2018");
404 TEST_DATE (24, 7, 2018, "%e %b %Y", "24 июл 2018");
405 TEST_DATE ( 1, 8, 2018, "%Ob %Y", "авг 2018");
406 /* This difference is very important in Russian: */
407 TEST_DATE (19, 5, 2018, "%e %b %Y", "19 мая 2018");
408 TEST_DATE (20, 5, 2018, "%Ob, %d-е, %Y", "май, 20-е, 2018");
410 else
411 g_test_skip ("locale ru_RU not available, skipping Russian month names test");
413 g_date_free (gdate);
415 setlocale (LC_ALL, oldlocale);
416 #ifdef G_OS_WIN32
417 SetThreadLocale (old_lcid);
418 #endif
419 g_free (oldlocale);
420 #endif /* defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) */
423 static void
424 test_year (gconstpointer t)
426 GDateYear y = GPOINTER_TO_INT (t);
427 GDateMonth m;
428 GDateDay day;
429 guint32 j;
430 GDate *d;
431 gint i;
432 GDate tmp;
434 guint32 first_day_of_year = G_DATE_BAD_JULIAN;
435 guint16 days_in_year = g_date_is_leap_year (y) ? 366 : 365;
436 guint sunday_week_of_year = 0;
437 guint sunday_weeks_in_year = g_date_get_sunday_weeks_in_year (y);
438 guint monday_week_of_year = 0;
439 guint monday_weeks_in_year = g_date_get_monday_weeks_in_year (y);
440 guint iso8601_week_of_year = 0;
442 g_assert (g_date_valid_year (y));
443 /* Years ought to have roundabout 52 weeks */
444 g_assert (sunday_weeks_in_year == 52 || sunday_weeks_in_year == 53);
445 g_assert (monday_weeks_in_year == 52 || monday_weeks_in_year == 53);
447 m = 1;
448 while (m < 13)
450 guint8 dim = g_date_get_days_in_month (m, y);
451 GDate days[31];
453 g_date_clear (days, 31);
455 g_assert (dim > 0 && dim < 32);
456 g_assert (g_date_valid_month (m));
458 day = 1;
459 while (day <= dim)
461 g_assert (g_date_valid_dmy (day, m, y));
463 d = &days[day - 1];
464 //g_assert (!g_date_valid (d));
466 g_date_set_dmy (d, day, m, y);
468 g_assert (g_date_valid (d));
470 if (m == G_DATE_JANUARY && day == 1)
471 first_day_of_year = g_date_get_julian (d);
473 g_assert (first_day_of_year != G_DATE_BAD_JULIAN);
475 g_assert_cmpint (g_date_get_month (d), ==, m);
476 g_assert_cmpint (g_date_get_year (d), ==, y);
477 g_assert_cmpint (g_date_get_day (d), ==, day);
479 g_assert (g_date_get_julian (d) + 1 - first_day_of_year ==
480 g_date_get_day_of_year (d));
482 if (m == G_DATE_DECEMBER && day == 31)
483 g_assert_cmpint (g_date_get_day_of_year (d), ==, days_in_year);
485 g_assert_cmpint (g_date_get_day_of_year (d), <=, days_in_year);
486 g_assert_cmpint (g_date_get_monday_week_of_year (d), <=, monday_weeks_in_year);
487 g_assert_cmpint (g_date_get_monday_week_of_year (d), >=, monday_week_of_year);
489 if (g_date_get_weekday(d) == G_DATE_MONDAY)
491 g_assert_cmpint (g_date_get_monday_week_of_year (d) - monday_week_of_year, ==, 1);
492 if ((m == G_DATE_JANUARY && day <= 4) ||
493 (m == G_DATE_DECEMBER && day >= 29))
494 g_assert_cmpint (g_date_get_iso8601_week_of_year (d), ==, 1);
495 else
496 g_assert_cmpint (g_date_get_iso8601_week_of_year (d) - iso8601_week_of_year, ==, 1);
498 else
500 g_assert_cmpint (g_date_get_monday_week_of_year(d) - monday_week_of_year, ==, 0);
501 if (!(day == 1 && m == G_DATE_JANUARY))
502 g_assert_cmpint (g_date_get_iso8601_week_of_year(d) - iso8601_week_of_year, ==, 0);
505 monday_week_of_year = g_date_get_monday_week_of_year (d);
506 iso8601_week_of_year = g_date_get_iso8601_week_of_year (d);
508 g_assert_cmpint (g_date_get_sunday_week_of_year (d), <=, sunday_weeks_in_year);
509 g_assert_cmpint (g_date_get_sunday_week_of_year (d), >=, sunday_week_of_year);
510 if (g_date_get_weekday(d) == G_DATE_SUNDAY)
511 g_assert_cmpint (g_date_get_sunday_week_of_year (d) - sunday_week_of_year, ==, 1);
512 else
513 g_assert_cmpint (g_date_get_sunday_week_of_year (d) - sunday_week_of_year, ==, 0);
515 sunday_week_of_year = g_date_get_sunday_week_of_year (d);
517 g_assert_cmpint (g_date_compare (d, d), ==, 0);
519 i = 1;
520 while (i < 402) /* Need to get 400 year increments in */
522 tmp = *d;
523 g_date_add_days (d, i);
524 g_assert_cmpint (g_date_compare (d, &tmp), >, 0);
525 g_date_subtract_days (d, i);
526 g_assert_cmpint (g_date_get_day (d), ==, day);
527 g_assert_cmpint (g_date_get_month (d), ==, m);
528 g_assert_cmpint (g_date_get_year (d), ==, y);
530 tmp = *d;
531 g_date_add_months (d, i);
532 g_assert_cmpint (g_date_compare (d, &tmp), >, 0);
533 g_date_subtract_months (d, i);
534 g_assert_cmpint (g_date_get_month (d), ==, m);
535 g_assert_cmpint (g_date_get_year (d), ==, y);
537 if (day < 29)
538 g_assert_cmpint (g_date_get_day (d), ==, day);
539 else
540 g_date_set_day (d, day);
542 tmp = *d;
543 g_date_add_years (d, i);
544 g_assert_cmpint (g_date_compare (d, &tmp), >, 0);
545 g_date_subtract_years (d, i);
546 g_assert_cmpint (g_date_get_month (d), ==, m);
547 g_assert_cmpint (g_date_get_year (d), ==, y);
549 if (m != 2 && day != 29)
550 g_assert_cmpint (g_date_get_day (d), ==, day);
551 else
552 g_date_set_day (d, day); /* reset */
554 i += 10;
557 j = g_date_get_julian (d);
559 ++day;
561 ++m;
564 /* at this point, d is the last day of year y */
565 g_date_set_dmy (&tmp, 1, 1, y + 1);
566 g_assert_cmpint (j + 1, ==, g_date_get_julian (&tmp));
568 g_date_add_days (&tmp, 1);
569 g_assert_cmpint (j + 2, ==, g_date_get_julian (&tmp));
572 static void
573 test_clamp (void)
575 GDate d1, d2, d, o;
577 g_date_set_dmy (&d1, 1, 1, 1970);
578 g_date_set_dmy (&d2, 1, 1, 1980);
579 g_date_set_dmy (&d, 1, 1, 1);
581 o = d;
582 g_date_clamp (&o, NULL, NULL);
583 g_assert (g_date_compare (&o, &d) == 0);
585 g_date_clamp (&o, &d1, &d2);
586 g_assert (g_date_compare (&o, &d1) == 0);
588 g_date_set_dmy (&o, 1, 1, 2000);
590 g_date_clamp (&o, &d1, &d2);
591 g_assert (g_date_compare (&o, &d2) == 0);
594 static void
595 test_order (void)
597 GDate d1, d2;
599 g_date_set_dmy (&d1, 1, 1, 1970);
600 g_date_set_dmy (&d2, 1, 1, 1980);
602 g_assert (g_date_compare (&d1, &d2) == -1);
603 g_date_order (&d2, &d1);
604 g_assert (g_date_compare (&d1, &d2) == 1);
607 static void
608 test_copy (void)
610 GDate *d;
611 GDate *c;
613 d = g_date_new ();
614 g_assert_false (g_date_valid (d));
616 c = g_date_copy (d);
617 g_assert_nonnull (c);
618 g_assert_false (g_date_valid (c));
619 g_date_free (c);
621 g_date_set_day (d, 10);
623 c = g_date_copy (d);
624 g_date_set_month (c, 1);
625 g_date_set_year (c, 2015);
626 g_assert_true (g_date_valid (c));
627 g_assert_cmpuint (g_date_get_day (c), ==, 10);
628 g_date_free (c);
630 g_date_free (d);
633 /* Check the results of g_date_valid_dmy() for various inputs. */
634 static void
635 test_valid_dmy (void)
637 const struct
639 GDateDay day;
640 GDateMonth month;
641 GDateYear year;
642 gboolean expected_valid;
644 vectors[] =
646 /* Lower bounds */
647 { 0, 0, 0, FALSE },
648 { 1, 1, 1, TRUE },
649 { 1, 1, 0, FALSE },
650 /* Leap year month lengths */
651 { 30, 2, 2000, FALSE },
652 { 29, 2, 2000, TRUE },
653 { 29, 2, 2001, FALSE },
654 /* Maximum year */
655 { 1, 1, G_MAXUINT16, TRUE },
657 gsize i;
659 for (i = 0; i < G_N_ELEMENTS (vectors); i++)
661 gboolean valid;
662 g_test_message ("Vector %" G_GSIZE_FORMAT ": %04u-%02u-%02u, %s",
663 i, vectors[i].year, vectors[i].month, vectors[i].day,
664 vectors[i].expected_valid ? "valid" : "invalid");
666 valid = g_date_valid_dmy (vectors[i].day, vectors[i].month, vectors[i].year);
668 if (vectors[i].expected_valid)
669 g_assert_true (valid);
670 else
671 g_assert_false (valid);
676 main (int argc, char** argv)
678 gchar *path;
679 gint i;
681 /* Try to get all the leap year cases. */
682 int check_years[] = {
683 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
684 11, 12, 13, 14, 98, 99, 100, 101, 102, 103, 397,
685 398, 399, 400, 401, 402, 403, 404, 405, 406,
686 1598, 1599, 1600, 1601, 1602, 1650, 1651,
687 1897, 1898, 1899, 1900, 1901, 1902, 1903,
688 1961, 1962, 1963, 1964, 1965, 1967,
689 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976,
690 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
691 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
692 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
693 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
694 3000, 3001, 3002, 3998, 3999, 4000, 4001, 4002, 4003
697 g_setenv ("LC_ALL", "en_US.utf-8", TRUE);
698 setlocale (LC_ALL, "");
699 #ifdef G_OS_WIN32
700 SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
701 #endif
703 g_test_init (&argc, &argv, NULL);
704 g_test_bug_base ("http://bugzilla.gnome.org/");
706 g_test_add_func ("/date/basic", test_basic);
707 g_test_add_func ("/date/empty", test_empty_constructor);
708 g_test_add_func ("/date/dmy", test_dmy_constructor);
709 g_test_add_func ("/date/julian", test_julian_constructor);
710 g_test_add_func ("/date/dates", test_dates);
711 g_test_add_func ("/date/parse", test_parse);
712 g_test_add_func ("/date/month_names", test_month_names);
713 g_test_add_func ("/date/clamp", test_clamp);
714 g_test_add_func ("/date/order", test_order);
715 for (i = 0; i < G_N_ELEMENTS (check_years); i++)
717 path = g_strdup_printf ("/date/year/%d", check_years[i]);
718 g_test_add_data_func (path, GINT_TO_POINTER(check_years[i]), test_year);
719 g_free (path);
721 g_test_add_func ("/date/copy", test_copy);
722 g_test_add_func ("/date/valid-dmy", test_valid_dmy);
724 return g_test_run ();