1 | #undef G_DISABLE_ASSERT |
2 | #undef G_LOG_DOMAIN |
3 | |
4 | /* We are testing some deprecated APIs here */ |
5 | #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS |
6 | #define GLIB_DISABLE_DEPRECATION_WARNINGS |
7 | #endif |
8 | |
9 | #include "config.h" |
10 | |
11 | #include "glib.h" |
12 | |
13 | #include <stdio.h> |
14 | #include <string.h> |
15 | #include <stdlib.h> |
16 | #include <locale.h> |
17 | #include <time.h> |
18 | |
19 | #ifdef G_OS_WIN32 |
20 | #define WIN32_LEAN_AND_MEAN |
21 | #include <windows.h> |
22 | /* mingw defines it while msvc doesn't */ |
23 | #ifndef SUBLANG_LITHUANIAN_LITHUANIA |
24 | #define SUBLANG_LITHUANIAN_LITHUANIA 0x01 |
25 | #endif |
26 | #endif |
27 | |
28 | static void |
29 | test_basic (void) |
30 | { |
31 | g_assert_cmpint (sizeof (GDate), <, 9); |
32 | g_assert (!g_date_valid_month (G_DATE_BAD_MONTH)); |
33 | g_assert (!g_date_valid_month (13)); |
34 | g_assert (!g_date_valid_day (G_DATE_BAD_DAY)); |
35 | g_assert (!g_date_valid_day (32)); |
36 | g_assert (!g_date_valid_year (G_DATE_BAD_YEAR)); |
37 | g_assert (!g_date_valid_julian (G_DATE_BAD_JULIAN)); |
38 | g_assert (!g_date_valid_weekday (G_DATE_BAD_WEEKDAY)); |
39 | g_assert (g_date_is_leap_year (2000)); |
40 | g_assert (!g_date_is_leap_year (1999)); |
41 | g_assert (g_date_is_leap_year (1996)); |
42 | g_assert (g_date_is_leap_year (1600)); |
43 | g_assert (!g_date_is_leap_year (2100)); |
44 | g_assert (!g_date_is_leap_year (1800)); |
45 | } |
46 | |
47 | static void |
48 | test_empty_constructor (void) |
49 | { |
50 | GDate *d; |
51 | |
52 | d = g_date_new (); |
53 | g_assert (!g_date_valid (d)); |
54 | g_date_free (date: d); |
55 | } |
56 | |
57 | static void |
58 | test_dmy_constructor (void) |
59 | { |
60 | GDate *d; |
61 | guint32 j; |
62 | |
63 | d = g_date_new_dmy (day: 1, month: 1, year: 1); |
64 | g_assert (g_date_valid (d)); |
65 | j = g_date_get_julian (date: d); |
66 | g_assert_cmpint (j, ==, 1); |
67 | g_assert_cmpint (g_date_get_month (d), ==, G_DATE_JANUARY); |
68 | g_assert_cmpint (g_date_get_day (d), ==, 1); |
69 | g_assert_cmpint (g_date_get_year (d), ==, 1); |
70 | g_date_free (date: d); |
71 | } |
72 | |
73 | static void |
74 | test_julian_constructor (void) |
75 | { |
76 | GDate *d1; |
77 | GDate *d2; |
78 | |
79 | d1 = g_date_new_julian (julian_day: 4000); |
80 | d2 = g_date_new_julian (julian_day: 5000); |
81 | g_assert_cmpint (g_date_get_julian (d1), ==, 4000); |
82 | g_assert_cmpint (g_date_days_between (d1, d2), ==, 1000); |
83 | g_assert_cmpint (g_date_get_year (d1), ==, 11); |
84 | g_assert_cmpint (g_date_get_day (d2), ==, 9); |
85 | g_date_free (date: d1); |
86 | g_date_free (date: d2); |
87 | } |
88 | |
89 | static void |
90 | test_dates (void) |
91 | { |
92 | GDate *d; |
93 | GTimeVal tv; |
94 | time_t now; |
95 | |
96 | d = g_date_new (); |
97 | |
98 | /* today */ |
99 | now = time (NULL); |
100 | g_assert_cmpint (now, !=, (time_t) -1); |
101 | g_date_set_time (date: d, time_: now); |
102 | g_assert (g_date_valid (d)); |
103 | |
104 | /* Unix epoch */ |
105 | g_date_set_time (date: d, time_: 1); |
106 | g_assert (g_date_valid (d)); |
107 | |
108 | tv.tv_sec = 0; |
109 | tv.tv_usec = 0; |
110 | g_date_set_time_val (date: d, timeval: &tv); |
111 | g_assert (g_date_valid (d)); |
112 | |
113 | /* Julian day 1 */ |
114 | g_date_set_julian (date: d, julian_date: 1); |
115 | g_assert (g_date_valid (d)); |
116 | |
117 | g_date_set_year (date: d, year: 3); |
118 | g_date_set_day (date: d, day: 3); |
119 | g_date_set_month (date: d, month: 3); |
120 | g_assert (g_date_valid (d)); |
121 | g_assert_cmpint (g_date_get_year (d), ==, 3); |
122 | g_assert_cmpint (g_date_get_month (d), ==, 3); |
123 | g_assert_cmpint (g_date_get_day (d), ==, 3); |
124 | g_assert (!g_date_is_first_of_month (d)); |
125 | g_assert (!g_date_is_last_of_month (d)); |
126 | g_date_set_day (date: d, day: 1); |
127 | g_assert (g_date_is_first_of_month (d)); |
128 | g_date_subtract_days (date: d, n_days: 1); |
129 | g_assert (g_date_is_last_of_month (d)); |
130 | |
131 | g_date_free (date: d); |
132 | } |
133 | |
134 | static void |
135 | test_parse (void) |
136 | { |
137 | GDate *d; |
138 | gchar buf[101]; |
139 | |
140 | d = g_date_new (); |
141 | |
142 | g_date_set_dmy (date: d, day: 10, month: 1, y: 2000); |
143 | g_date_strftime (s: buf, slen: 100, format: "%x" , date: d); |
144 | |
145 | g_date_set_parse (date: d, str: buf); |
146 | g_assert (g_date_valid (d)); |
147 | g_assert_cmpint (g_date_get_month (d), ==, 1); |
148 | g_assert_cmpint (g_date_get_day (d), ==, 10); |
149 | g_assert_cmpint (g_date_get_year (d), ==, 2000); |
150 | |
151 | g_date_set_parse (date: d, str: "2001 10 1" ); |
152 | g_assert (g_date_valid (d)); |
153 | g_assert_cmpint (g_date_get_month (d), ==, 10); |
154 | g_assert_cmpint (g_date_get_day (d), ==, 1); |
155 | g_assert_cmpint (g_date_get_year (d), ==, 2001); |
156 | |
157 | g_date_set_parse (date: d, str: "2001 10" ); |
158 | g_assert (!g_date_valid (d)); |
159 | |
160 | g_date_set_parse (date: d, str: "2001 10 1 1" ); |
161 | g_assert (!g_date_valid (d)); |
162 | |
163 | g_date_set_parse (date: d, str: "March 1999" ); |
164 | g_assert (g_date_valid (d)); |
165 | g_assert_cmpint (g_date_get_month (d), ==, 3); |
166 | g_assert_cmpint (g_date_get_day (d), ==, 1); |
167 | g_assert_cmpint (g_date_get_year (d), ==, 1999); |
168 | |
169 | g_date_set_parse (date: d, str: "10 Sep 1087" ); |
170 | g_assert (g_date_valid (d)); |
171 | g_assert_cmpint (g_date_get_month (d), ==, 9); |
172 | g_assert_cmpint (g_date_get_day (d), ==, 10); |
173 | g_assert_cmpint (g_date_get_year (d), ==, 1087); |
174 | |
175 | g_date_set_parse (date: d, str: "19990301" ); |
176 | g_assert (g_date_valid (d)); |
177 | g_assert_cmpint (g_date_get_month (d), ==, 3); |
178 | g_assert_cmpint (g_date_get_day (d), ==, 1); |
179 | g_assert_cmpint (g_date_get_year (d), ==, 1999); |
180 | |
181 | g_date_set_parse (date: d, str: "20011320" ); |
182 | g_assert (!g_date_valid (d)); |
183 | |
184 | g_date_free (date: d); |
185 | } |
186 | |
187 | static void |
188 | test_parse_invalid (void) |
189 | { |
190 | const gchar * const strs[] = |
191 | { |
192 | /* Incomplete UTF-8 sequence */ |
193 | "\xfd" , |
194 | /* Ridiculously long input */ |
195 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890" |
196 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890" |
197 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890" , |
198 | }; |
199 | gsize i; |
200 | |
201 | for (i = 0; i < G_N_ELEMENTS (strs); i++) |
202 | { |
203 | GDate *d = g_date_new (); |
204 | |
205 | g_test_message (format: "Test %" G_GSIZE_FORMAT, i); |
206 | g_date_set_parse (date: d, str: strs[i]); |
207 | |
208 | g_assert_false (g_date_valid (d)); |
209 | |
210 | g_date_free (date: d); |
211 | } |
212 | } |
213 | |
214 | static void |
215 | test_parse_locale_change (void) |
216 | { |
217 | /* Checks that g_date_set_parse correctly changes locale specific data as |
218 | * necessary. In this particular case year adjustment, as Thai calendar is |
219 | * 543 years ahead of the Gregorian calendar. */ |
220 | |
221 | GDate date; |
222 | |
223 | if (setlocale (LC_ALL, locale: "th_TH" ) == NULL) |
224 | { |
225 | g_test_skip (msg: "locale th_TH not available" ); |
226 | return; |
227 | } |
228 | |
229 | g_date_set_parse (date: &date, str: "04/07/2519" ); |
230 | |
231 | setlocale (LC_ALL, locale: "C" ); |
232 | g_date_set_parse (date: &date, str: "07/04/76" ); |
233 | g_assert_cmpint (g_date_get_day (&date), ==, 4); |
234 | g_assert_cmpint (g_date_get_month (&date), ==, 7); |
235 | g_assert_cmpint (g_date_get_year (&date), ==, 1976); |
236 | |
237 | setlocale (LC_ALL, locale: "" ); |
238 | } |
239 | |
240 | static void |
241 | test_month_substring (void) |
242 | { |
243 | GDate date; |
244 | |
245 | g_test_bug (bug_uri_snippet: "793550" ); |
246 | |
247 | if (setlocale (LC_ALL, locale: "pl_PL" ) == NULL) |
248 | { |
249 | g_test_skip (msg: "pl_PL locale not available" ); |
250 | return; |
251 | } |
252 | |
253 | /* In Polish language September is "wrzesień" and August is "sierpień" |
254 | * abbreviated as "sie". The former used to be confused with the latter |
255 | * because "sie" is a substring of "wrzesień" and was matched first. */ |
256 | |
257 | g_date_set_parse (date: &date, str: "wrzesień 2018" ); |
258 | g_assert_true (g_date_valid (&date)); |
259 | g_assert_cmpint (g_date_get_month (&date), ==, G_DATE_SEPTEMBER); |
260 | |
261 | g_date_set_parse (date: &date, str: "sie 2018" ); |
262 | g_assert_true (g_date_valid (&date)); |
263 | g_assert_cmpint (g_date_get_month (&date), ==, G_DATE_AUGUST); |
264 | |
265 | g_date_set_parse (date: &date, str: "sierpień 2018" ); |
266 | g_assert_true (g_date_valid (&date)); |
267 | g_assert_cmpint (g_date_get_month (&date), ==, G_DATE_AUGUST); |
268 | |
269 | setlocale (LC_ALL, locale: "" ); |
270 | } |
271 | |
272 | |
273 | static void |
274 | test_month_names (void) |
275 | { |
276 | #if defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) |
277 | GDate *gdate; |
278 | gchar buf[101]; |
279 | gchar *oldlocale; |
280 | #ifdef G_OS_WIN32 |
281 | LCID old_lcid; |
282 | #endif |
283 | #endif /* defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) */ |
284 | |
285 | g_test_bug (bug_uri_snippet: "749206" ); |
286 | |
287 | /* If running uninstalled (G_TEST_BUILDDIR is set), skip this test, since we |
288 | * need the translations to be installed. We can’t mess around with |
289 | * bindtextdomain() here, as the compiled .gmo files in po/ are not in the |
290 | * right installed directory hierarchy to be successfully loaded by gettext. */ |
291 | if (g_getenv (variable: "G_TEST_BUILDDIR" ) != NULL) |
292 | { |
293 | g_test_skip (msg: "Skipping due to running uninstalled. " |
294 | "This test can only be run when the translations are installed." ); |
295 | return; |
296 | } |
297 | |
298 | /* This test can only work (on non-Windows platforms) if libc supports |
299 | * the %OB (etc.) format placeholders. If it doesn’t, strftime() (and hence |
300 | * g_date_strftime()) will return the placeholder unsubstituted. |
301 | * g_date_strftime() explicitly documents that it doesn’t provide any more |
302 | * format placeholders than the system strftime(), so we should skip the test |
303 | * in that case. If people need %OB support, they should depend on a suitable |
304 | * version of libc, or use g_date_time_format(). Note: a test for a support |
305 | * of _NL_ABALTMON_* is not strictly the same as checking for %OB support. |
306 | * Some platforms (BSD, OS X) support %OB while _NL_ABALTMON_* and %Ob |
307 | * are supported only by glibc 2.27 and newer. But we don’t care about BSD |
308 | * here, the aim of this test is to make sure that our custom implementation |
309 | * for Windows works the same as glibc 2.27 native implementation. */ |
310 | #if !defined(HAVE_LANGINFO_ABALTMON) && !defined(G_OS_WIN32) |
311 | g_test_skip ("libc doesn’t support all alternative month names" ); |
312 | #else |
313 | |
314 | #define TEST_DATE(d,m,y,f,o) G_STMT_START { \ |
315 | gchar *o_casefold, *buf_casefold; \ |
316 | g_date_set_dmy (gdate, d, m, y); \ |
317 | g_date_strftime (buf, 100, f, gdate); \ |
318 | buf_casefold = g_utf8_casefold (buf, -1); \ |
319 | o_casefold = g_utf8_casefold ((o), -1); \ |
320 | g_assert_cmpstr (buf_casefold, ==, o_casefold); \ |
321 | g_free (buf_casefold); \ |
322 | g_free (o_casefold); \ |
323 | g_date_set_parse (gdate, buf); \ |
324 | g_assert (g_date_valid (gdate)); \ |
325 | g_assert_cmpint (g_date_get_day (gdate), ==, d); \ |
326 | g_assert_cmpint (g_date_get_month (gdate), ==, m); \ |
327 | g_assert_cmpint (g_date_get_year (gdate), ==, y); \ |
328 | } G_STMT_END |
329 | |
330 | oldlocale = g_strdup (str: setlocale (LC_ALL, NULL)); |
331 | #ifdef G_OS_WIN32 |
332 | old_lcid = GetThreadLocale (); |
333 | #endif |
334 | |
335 | gdate = g_date_new (); |
336 | |
337 | /* Note: Windows implementation of g_date_strftime() does not support |
338 | * "-" format modifier (e.g., "%-d", "%-e") so we will not use it. |
339 | */ |
340 | |
341 | /* Make sure that nothing has been changed in western European languages. */ |
342 | setlocale (LC_ALL, locale: "en_GB.utf-8" ); |
343 | #ifdef G_OS_WIN32 |
344 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_UK), SORT_DEFAULT)); |
345 | #endif |
346 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "en_GB" ) != NULL) |
347 | { |
348 | TEST_DATE (1, 1, 2018, "%B %d, %Y" , "January 01, 2018" ); |
349 | TEST_DATE (1, 2, 2018, "%OB %Y" , "February 2018" ); |
350 | TEST_DATE (1, 3, 2018, "%e %b %Y" , " 1 Mar 2018" ); |
351 | TEST_DATE (1, 4, 2018, "%Ob %Y" , "Apr 2018" ); |
352 | TEST_DATE (1, 5, 2018, "%d %h %Y" , "01 May 2018" ); |
353 | TEST_DATE (1, 6, 2018, "%Oh %Y" , "Jun 2018" ); |
354 | } |
355 | else |
356 | g_test_skip (msg: "locale en_GB not available, skipping English month names test" ); |
357 | |
358 | setlocale (LC_ALL, locale: "de_DE.utf-8" ); |
359 | #ifdef G_OS_WIN32 |
360 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT)); |
361 | #endif |
362 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "de_DE" ) != NULL) |
363 | { |
364 | TEST_DATE (16, 7, 2018, "%d. %B %Y" , "16. Juli 2018" ); |
365 | TEST_DATE ( 1, 8, 2018, "%OB %Y" , "August 2018" ); |
366 | TEST_DATE (18, 9, 2018, "%e. %b %Y" , "18. Sep 2018" ); |
367 | TEST_DATE ( 1, 10, 2018, "%Ob %Y" , "Okt 2018" ); |
368 | TEST_DATE (20, 11, 2018, "%d. %h %Y" , "20. Nov 2018" ); |
369 | TEST_DATE ( 1, 12, 2018, "%Oh %Y" , "Dez 2018" ); |
370 | } |
371 | else |
372 | g_test_skip (msg: "locale de_DE not available, skipping German month names test" ); |
373 | |
374 | |
375 | setlocale (LC_ALL, locale: "es_ES.utf-8" ); |
376 | #ifdef G_OS_WIN32 |
377 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT)); |
378 | #endif |
379 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "es_ES" ) != NULL) |
380 | { |
381 | TEST_DATE ( 9, 1, 2018, "%d de %B de %Y" , "09 de enero de 2018" ); |
382 | TEST_DATE ( 1, 2, 2018, "%OB de %Y" , "febrero de 2018" ); |
383 | TEST_DATE (10, 3, 2018, "%e de %b de %Y" , "10 de mar de 2018" ); |
384 | TEST_DATE ( 1, 4, 2018, "%Ob de %Y" , "abr de 2018" ); |
385 | TEST_DATE (11, 5, 2018, "%d de %h de %Y" , "11 de may de 2018" ); |
386 | TEST_DATE ( 1, 6, 2018, "%Oh de %Y" , "jun de 2018" ); |
387 | } |
388 | else |
389 | g_test_skip (msg: "locale es_ES not available, skipping Spanish month names test" ); |
390 | |
391 | setlocale (LC_ALL, locale: "fr_FR.utf-8" ); |
392 | #ifdef G_OS_WIN32 |
393 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_FRENCH, SUBLANG_FRENCH), SORT_DEFAULT)); |
394 | #endif |
395 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "fr_FR" ) != NULL) |
396 | { |
397 | TEST_DATE (31, 7, 2018, "%d %B %Y" , "31 juillet 2018" ); |
398 | TEST_DATE ( 1, 8, 2018, "%OB %Y" , "août 2018" ); |
399 | TEST_DATE (30, 9, 2018, "%e %b %Y" , "30 sept. 2018" ); |
400 | TEST_DATE ( 1, 10, 2018, "%Ob %Y" , "oct. 2018" ); |
401 | TEST_DATE (29, 11, 2018, "%d %h %Y" , "29 nov. 2018" ); |
402 | TEST_DATE ( 1, 12, 2018, "%Oh %Y" , "déc. 2018" ); |
403 | } |
404 | else |
405 | g_test_skip (msg: "locale fr_FR not available, skipping French month names test" ); |
406 | |
407 | /* Make sure that there are visible changes in some European languages. */ |
408 | setlocale (LC_ALL, locale: "el_GR.utf-8" ); |
409 | #ifdef G_OS_WIN32 |
410 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_GREEK, SUBLANG_GREEK_GREECE), SORT_DEFAULT)); |
411 | #endif |
412 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "el_GR" ) != NULL) |
413 | { |
414 | TEST_DATE ( 2, 1, 2018, "%d %B %Y" , "02 Ιανουαρίου 2018" ); |
415 | TEST_DATE ( 4, 2, 2018, "%e %B %Y" , " 4 Φεβρουαρίου 2018" ); |
416 | TEST_DATE (15, 3, 2018, "%d %B %Y" , "15 Μαρτίου 2018" ); |
417 | TEST_DATE ( 1, 4, 2018, "%OB %Y" , "Απρίλιος 2018" ); |
418 | TEST_DATE ( 1, 5, 2018, "%OB %Y" , "Μάιος 2018" ); |
419 | TEST_DATE ( 1, 6, 2018, "%OB %Y" , "Ιούνιος 2018" ); |
420 | TEST_DATE (16, 7, 2018, "%e %b %Y" , "16 Ιουλ 2018" ); |
421 | TEST_DATE ( 1, 8, 2018, "%Ob %Y" , "Αύγ 2018" ); |
422 | } |
423 | else |
424 | g_test_skip (msg: "locale el_GR not available, skipping Greek month names test" ); |
425 | |
426 | setlocale (LC_ALL, locale: "hr_HR.utf-8" ); |
427 | #ifdef G_OS_WIN32 |
428 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_CROATIAN, SUBLANG_CROATIAN_CROATIA), SORT_DEFAULT)); |
429 | #endif |
430 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "hr_HR" ) != NULL) |
431 | { |
432 | TEST_DATE ( 8, 5, 2018, "%d. %B %Y" , "08. svibnja 2018" ); |
433 | TEST_DATE ( 9, 6, 2018, "%e. %B %Y" , " 9. lipnja 2018" ); |
434 | TEST_DATE (10, 7, 2018, "%d. %B %Y" , "10. srpnja 2018" ); |
435 | TEST_DATE ( 1, 8, 2018, "%OB %Y" , "Kolovoz 2018" ); |
436 | TEST_DATE ( 1, 9, 2018, "%OB %Y" , "Rujan 2018" ); |
437 | TEST_DATE ( 1, 10, 2018, "%OB %Y" , "Listopad 2018" ); |
438 | TEST_DATE (11, 11, 2018, "%e. %b %Y" , "11. Stu 2018" ); |
439 | TEST_DATE ( 1, 12, 2018, "%Ob %Y" , "Pro 2018" ); |
440 | } |
441 | else |
442 | g_test_skip (msg: "locale hr_HR not available, skipping Croatian month names test" ); |
443 | |
444 | setlocale (LC_ALL, locale: "lt_LT.utf-8" ); |
445 | #ifdef G_OS_WIN32 |
446 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_LITHUANIAN, SUBLANG_LITHUANIAN_LITHUANIA), SORT_DEFAULT)); |
447 | #endif |
448 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "lt_LT" ) != NULL) |
449 | { |
450 | TEST_DATE ( 1, 1, 2018, "%Y m. %B %d d." , "2018 m. sausio 01 d." ); |
451 | TEST_DATE ( 2, 2, 2018, "%Y m. %B %e d." , "2018 m. vasario 2 d." ); |
452 | TEST_DATE ( 3, 3, 2018, "%Y m. %B %d d." , "2018 m. kovo 03 d." ); |
453 | TEST_DATE ( 1, 4, 2018, "%Y m. %OB" , "2018 m. balandis" ); |
454 | TEST_DATE ( 1, 5, 2018, "%Y m. %OB" , "2018 m. gegužė" ); |
455 | TEST_DATE ( 1, 6, 2018, "%Y m. %OB" , "2018 m. birželis" ); |
456 | TEST_DATE (17, 7, 2018, "%Y m. %b %e d." , "2018 m. liep. 17 d." ); |
457 | TEST_DATE ( 1, 8, 2018, "%Y m. %Ob" , "2018 m. rugp." ); |
458 | } |
459 | else |
460 | g_test_skip (msg: "locale lt_LT not available, skipping Lithuanian month names test" ); |
461 | |
462 | setlocale (LC_ALL, locale: "pl_PL.utf-8" ); |
463 | #ifdef G_OS_WIN32 |
464 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_POLISH, SUBLANG_POLISH_POLAND), SORT_DEFAULT)); |
465 | #endif |
466 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "pl_PL" ) != NULL) |
467 | { |
468 | TEST_DATE ( 3, 5, 2018, "%d %B %Y" , "03 maja 2018" ); |
469 | TEST_DATE ( 4, 6, 2018, "%e %B %Y" , " 4 czerwca 2018" ); |
470 | TEST_DATE (20, 7, 2018, "%d %B %Y" , "20 lipca 2018" ); |
471 | TEST_DATE ( 1, 8, 2018, "%OB %Y" , "sierpień 2018" ); |
472 | TEST_DATE ( 1, 9, 2018, "%OB %Y" , "wrzesień 2018" ); |
473 | TEST_DATE ( 1, 10, 2018, "%OB %Y" , "październik 2018" ); |
474 | TEST_DATE (25, 11, 2018, "%e %b %Y" , "25 lis 2018" ); |
475 | TEST_DATE ( 1, 12, 2018, "%Ob %Y" , "gru 2018" ); |
476 | } |
477 | else |
478 | g_test_skip (msg: "locale pl_PL not available, skipping Polish month names test" ); |
479 | |
480 | setlocale (LC_ALL, locale: "ru_RU.utf-8" ); |
481 | #ifdef G_OS_WIN32 |
482 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA), SORT_DEFAULT)); |
483 | #endif |
484 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "ru_RU" ) != NULL) |
485 | { |
486 | TEST_DATE ( 3, 1, 2018, "%d %B %Y" , "03 января 2018" ); |
487 | TEST_DATE ( 4, 2, 2018, "%e %B %Y" , " 4 февраля 2018" ); |
488 | TEST_DATE (23, 3, 2018, "%d %B %Y" , "23 марта 2018" ); |
489 | TEST_DATE ( 1, 4, 2018, "%OB %Y" , "Апрель 2018" ); |
490 | TEST_DATE ( 1, 5, 2018, "%OB %Y" , "Май 2018" ); |
491 | TEST_DATE ( 1, 6, 2018, "%OB %Y" , "Июнь 2018" ); |
492 | TEST_DATE (24, 7, 2018, "%e %b %Y" , "24 июл 2018" ); |
493 | TEST_DATE ( 1, 8, 2018, "%Ob %Y" , "авг 2018" ); |
494 | /* This difference is very important in Russian: */ |
495 | TEST_DATE (19, 5, 2018, "%e %b %Y" , "19 мая 2018" ); |
496 | TEST_DATE (20, 5, 2018, "%Ob, %d-е, %Y" , "май, 20-е, 2018" ); |
497 | } |
498 | else |
499 | g_test_skip (msg: "locale ru_RU not available, skipping Russian month names test" ); |
500 | |
501 | g_date_free (date: gdate); |
502 | |
503 | setlocale (LC_ALL, locale: oldlocale); |
504 | #ifdef G_OS_WIN32 |
505 | SetThreadLocale (old_lcid); |
506 | #endif |
507 | g_free (mem: oldlocale); |
508 | #endif /* defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) */ |
509 | } |
510 | |
511 | static void |
512 | test_year (gconstpointer t) |
513 | { |
514 | GDateYear y = GPOINTER_TO_INT (t); |
515 | GDateMonth m; |
516 | GDateDay day; |
517 | guint32 j; |
518 | GDate *d; |
519 | gint i; |
520 | GDate tmp; |
521 | |
522 | guint32 first_day_of_year = G_DATE_BAD_JULIAN; |
523 | guint16 days_in_year = g_date_is_leap_year (year: y) ? 366 : 365; |
524 | guint sunday_week_of_year = 0; |
525 | guint sunday_weeks_in_year = g_date_get_sunday_weeks_in_year (year: y); |
526 | guint monday_week_of_year = 0; |
527 | guint monday_weeks_in_year = g_date_get_monday_weeks_in_year (year: y); |
528 | guint iso8601_week_of_year = 0; |
529 | |
530 | g_assert (g_date_valid_year (y)); |
531 | /* Years ought to have roundabout 52 weeks */ |
532 | g_assert (sunday_weeks_in_year == 52 || sunday_weeks_in_year == 53); |
533 | g_assert (monday_weeks_in_year == 52 || monday_weeks_in_year == 53); |
534 | |
535 | m = 1; |
536 | while (m < 13) |
537 | { |
538 | guint8 dim = g_date_get_days_in_month (month: m, year: y); |
539 | GDate days[31]; |
540 | |
541 | g_date_clear (date: days, n_dates: 31); |
542 | |
543 | g_assert (dim > 0 && dim < 32); |
544 | g_assert (g_date_valid_month (m)); |
545 | |
546 | day = 1; |
547 | while (day <= dim) |
548 | { |
549 | g_assert (g_date_valid_dmy (day, m, y)); |
550 | |
551 | d = &days[day - 1]; |
552 | //g_assert (!g_date_valid (d)); |
553 | |
554 | g_date_set_dmy (date: d, day, month: m, y); |
555 | |
556 | g_assert (g_date_valid (d)); |
557 | |
558 | if (m == G_DATE_JANUARY && day == 1) |
559 | first_day_of_year = g_date_get_julian (date: d); |
560 | |
561 | g_assert (first_day_of_year != G_DATE_BAD_JULIAN); |
562 | |
563 | g_assert_cmpint (g_date_get_month (d), ==, m); |
564 | g_assert_cmpint (g_date_get_year (d), ==, y); |
565 | g_assert_cmpint (g_date_get_day (d), ==, day); |
566 | |
567 | g_assert (g_date_get_julian (d) + 1 - first_day_of_year == |
568 | g_date_get_day_of_year (d)); |
569 | |
570 | if (m == G_DATE_DECEMBER && day == 31) |
571 | g_assert_cmpint (g_date_get_day_of_year (d), ==, days_in_year); |
572 | |
573 | g_assert_cmpint (g_date_get_day_of_year (d), <=, days_in_year); |
574 | g_assert_cmpint (g_date_get_monday_week_of_year (d), <=, monday_weeks_in_year); |
575 | g_assert_cmpint (g_date_get_monday_week_of_year (d), >=, monday_week_of_year); |
576 | |
577 | if (g_date_get_weekday(date: d) == G_DATE_MONDAY) |
578 | { |
579 | g_assert_cmpint (g_date_get_monday_week_of_year (d) - monday_week_of_year, ==, 1); |
580 | if ((m == G_DATE_JANUARY && day <= 4) || |
581 | (m == G_DATE_DECEMBER && day >= 29)) |
582 | g_assert_cmpint (g_date_get_iso8601_week_of_year (d), ==, 1); |
583 | else |
584 | g_assert_cmpint (g_date_get_iso8601_week_of_year (d) - iso8601_week_of_year, ==, 1); |
585 | } |
586 | else |
587 | { |
588 | g_assert_cmpint (g_date_get_monday_week_of_year(d) - monday_week_of_year, ==, 0); |
589 | if (!(day == 1 && m == G_DATE_JANUARY)) |
590 | g_assert_cmpint (g_date_get_iso8601_week_of_year(d) - iso8601_week_of_year, ==, 0); |
591 | } |
592 | |
593 | monday_week_of_year = g_date_get_monday_week_of_year (date: d); |
594 | iso8601_week_of_year = g_date_get_iso8601_week_of_year (date: d); |
595 | |
596 | g_assert_cmpint (g_date_get_sunday_week_of_year (d), <=, sunday_weeks_in_year); |
597 | g_assert_cmpint (g_date_get_sunday_week_of_year (d), >=, sunday_week_of_year); |
598 | if (g_date_get_weekday(date: d) == G_DATE_SUNDAY) |
599 | g_assert_cmpint (g_date_get_sunday_week_of_year (d) - sunday_week_of_year, ==, 1); |
600 | else |
601 | g_assert_cmpint (g_date_get_sunday_week_of_year (d) - sunday_week_of_year, ==, 0); |
602 | |
603 | sunday_week_of_year = g_date_get_sunday_week_of_year (date: d); |
604 | |
605 | g_assert_cmpint (g_date_compare (d, d), ==, 0); |
606 | |
607 | i = 1; |
608 | while (i < 402) /* Need to get 400 year increments in */ |
609 | { |
610 | tmp = *d; |
611 | g_date_add_days (date: d, n_days: i); |
612 | g_assert_cmpint (g_date_compare (d, &tmp), >, 0); |
613 | g_date_subtract_days (date: d, n_days: i); |
614 | g_assert_cmpint (g_date_get_day (d), ==, day); |
615 | g_assert_cmpint (g_date_get_month (d), ==, m); |
616 | g_assert_cmpint (g_date_get_year (d), ==, y); |
617 | |
618 | tmp = *d; |
619 | g_date_add_months (date: d, n_months: i); |
620 | g_assert_cmpint (g_date_compare (d, &tmp), >, 0); |
621 | g_date_subtract_months (date: d, n_months: i); |
622 | g_assert_cmpint (g_date_get_month (d), ==, m); |
623 | g_assert_cmpint (g_date_get_year (d), ==, y); |
624 | |
625 | if (day < 29) |
626 | g_assert_cmpint (g_date_get_day (d), ==, day); |
627 | else |
628 | g_date_set_day (date: d, day); |
629 | |
630 | tmp = *d; |
631 | g_date_add_years (date: d, n_years: i); |
632 | g_assert_cmpint (g_date_compare (d, &tmp), >, 0); |
633 | g_date_subtract_years (date: d, n_years: i); |
634 | g_assert_cmpint (g_date_get_month (d), ==, m); |
635 | g_assert_cmpint (g_date_get_year (d), ==, y); |
636 | |
637 | if (m != 2 && day != 29) |
638 | g_assert_cmpint (g_date_get_day (d), ==, day); |
639 | else |
640 | g_date_set_day (date: d, day); /* reset */ |
641 | |
642 | i += 10; |
643 | } |
644 | |
645 | j = g_date_get_julian (date: d); |
646 | |
647 | ++day; |
648 | } |
649 | ++m; |
650 | } |
651 | |
652 | /* at this point, d is the last day of year y */ |
653 | g_date_set_dmy (date: &tmp, day: 1, month: 1, y: y + 1); |
654 | g_assert_cmpint (j + 1, ==, g_date_get_julian (&tmp)); |
655 | |
656 | g_date_add_days (date: &tmp, n_days: 1); |
657 | g_assert_cmpint (j + 2, ==, g_date_get_julian (&tmp)); |
658 | } |
659 | |
660 | static void |
661 | test_clamp (void) |
662 | { |
663 | GDate d1, d2, d, o; |
664 | |
665 | g_date_set_dmy (date: &d1, day: 1, month: 1, y: 1970); |
666 | g_date_set_dmy (date: &d2, day: 1, month: 1, y: 1980); |
667 | g_date_set_dmy (date: &d, day: 1, month: 1, y: 1); |
668 | |
669 | o = d; |
670 | g_date_clamp (date: &o, NULL, NULL); |
671 | g_assert (g_date_compare (&o, &d) == 0); |
672 | |
673 | g_date_clamp (date: &o, min_date: &d1, max_date: &d2); |
674 | g_assert (g_date_compare (&o, &d1) == 0); |
675 | |
676 | g_date_set_dmy (date: &o, day: 1, month: 1, y: 2000); |
677 | |
678 | g_date_clamp (date: &o, min_date: &d1, max_date: &d2); |
679 | g_assert (g_date_compare (&o, &d2) == 0); |
680 | } |
681 | |
682 | static void |
683 | test_order (void) |
684 | { |
685 | GDate d1, d2; |
686 | |
687 | g_date_set_dmy (date: &d1, day: 1, month: 1, y: 1970); |
688 | g_date_set_dmy (date: &d2, day: 1, month: 1, y: 1980); |
689 | |
690 | g_assert (g_date_compare (&d1, &d2) == -1); |
691 | g_date_order (date1: &d2, date2: &d1); |
692 | g_assert (g_date_compare (&d1, &d2) == 1); |
693 | } |
694 | |
695 | static void |
696 | test_copy (void) |
697 | { |
698 | GDate *d; |
699 | GDate *c; |
700 | |
701 | d = g_date_new (); |
702 | g_assert_false (g_date_valid (d)); |
703 | |
704 | c = g_date_copy (date: d); |
705 | g_assert_nonnull (c); |
706 | g_assert_false (g_date_valid (c)); |
707 | g_date_free (date: c); |
708 | |
709 | g_date_set_day (date: d, day: 10); |
710 | |
711 | c = g_date_copy (date: d); |
712 | g_date_set_month (date: c, month: 1); |
713 | g_date_set_year (date: c, year: 2015); |
714 | g_assert_true (g_date_valid (c)); |
715 | g_assert_cmpuint (g_date_get_day (c), ==, 10); |
716 | g_date_free (date: c); |
717 | |
718 | g_date_free (date: d); |
719 | } |
720 | |
721 | /* Check the results of g_date_valid_dmy() for various inputs. */ |
722 | static void |
723 | test_valid_dmy (void) |
724 | { |
725 | const struct |
726 | { |
727 | GDateDay day; |
728 | GDateMonth month; |
729 | GDateYear year; |
730 | gboolean expected_valid; |
731 | } |
732 | vectors[] = |
733 | { |
734 | /* Lower bounds */ |
735 | { 0, 0, 0, FALSE }, |
736 | { 1, 1, 1, TRUE }, |
737 | { 1, 1, 0, FALSE }, |
738 | /* Leap year month lengths */ |
739 | { 30, 2, 2000, FALSE }, |
740 | { 29, 2, 2000, TRUE }, |
741 | { 29, 2, 2001, FALSE }, |
742 | /* Maximum year */ |
743 | { 1, 1, G_MAXUINT16, TRUE }, |
744 | }; |
745 | gsize i; |
746 | |
747 | for (i = 0; i < G_N_ELEMENTS (vectors); i++) |
748 | { |
749 | gboolean valid; |
750 | g_test_message (format: "Vector %" G_GSIZE_FORMAT ": %04u-%02u-%02u, %s" , |
751 | i, vectors[i].year, vectors[i].month, vectors[i].day, |
752 | vectors[i].expected_valid ? "valid" : "invalid" ); |
753 | |
754 | valid = g_date_valid_dmy (day: vectors[i].day, month: vectors[i].month, year: vectors[i].year); |
755 | |
756 | if (vectors[i].expected_valid) |
757 | g_assert_true (valid); |
758 | else |
759 | g_assert_false (valid); |
760 | } |
761 | } |
762 | |
763 | int |
764 | main (int argc, char** argv) |
765 | { |
766 | gchar *path; |
767 | gsize i; |
768 | |
769 | /* Try to get all the leap year cases. */ |
770 | int check_years[] = { |
771 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, |
772 | 11, 12, 13, 14, 98, 99, 100, 101, 102, 103, 397, |
773 | 398, 399, 400, 401, 402, 403, 404, 405, 406, |
774 | 1598, 1599, 1600, 1601, 1602, 1650, 1651, |
775 | 1897, 1898, 1899, 1900, 1901, 1902, 1903, |
776 | 1961, 1962, 1963, 1964, 1965, 1967, |
777 | 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, |
778 | 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, |
779 | 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, |
780 | 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, |
781 | 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, |
782 | 3000, 3001, 3002, 3998, 3999, 4000, 4001, 4002, 4003 |
783 | }; |
784 | |
785 | g_setenv (variable: "LC_ALL" , value: "en_US.utf-8" , TRUE); |
786 | setlocale (LC_ALL, locale: "" ); |
787 | #ifdef G_OS_WIN32 |
788 | SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); |
789 | #endif |
790 | |
791 | g_test_init (argc: &argc, argv: &argv, NULL); |
792 | g_test_bug_base (uri_pattern: "http://bugzilla.gnome.org/" ); |
793 | |
794 | g_test_add_func (testpath: "/date/basic" , test_func: test_basic); |
795 | g_test_add_func (testpath: "/date/empty" , test_func: test_empty_constructor); |
796 | g_test_add_func (testpath: "/date/dmy" , test_func: test_dmy_constructor); |
797 | g_test_add_func (testpath: "/date/julian" , test_func: test_julian_constructor); |
798 | g_test_add_func (testpath: "/date/dates" , test_func: test_dates); |
799 | g_test_add_func (testpath: "/date/parse" , test_func: test_parse); |
800 | g_test_add_func (testpath: "/date/parse/invalid" , test_func: test_parse_invalid); |
801 | g_test_add_func (testpath: "/date/parse_locale_change" , test_func: test_parse_locale_change); |
802 | g_test_add_func (testpath: "/date/month_substring" , test_func: test_month_substring); |
803 | g_test_add_func (testpath: "/date/month_names" , test_func: test_month_names); |
804 | g_test_add_func (testpath: "/date/clamp" , test_func: test_clamp); |
805 | g_test_add_func (testpath: "/date/order" , test_func: test_order); |
806 | for (i = 0; i < G_N_ELEMENTS (check_years); i++) |
807 | { |
808 | path = g_strdup_printf (format: "/date/year/%d" , check_years[i]); |
809 | g_test_add_data_func (testpath: path, GINT_TO_POINTER(check_years[i]), test_func: test_year); |
810 | g_free (mem: path); |
811 | } |
812 | g_test_add_func (testpath: "/date/copy" , test_func: test_copy); |
813 | g_test_add_func (testpath: "/date/valid-dmy" , test_func: test_valid_dmy); |
814 | |
815 | return g_test_run (); |
816 | } |
817 | |