1 | /* gdatetime-tests.c |
2 | * |
3 | * Copyright (C) 2009-2010 Christian Hergert <chris@dronelabs.com> |
4 | * |
5 | * This is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Lesser General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2.1 of the License, or (at your option) any later version. |
9 | * |
10 | * This is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Lesser General Public License |
16 | * along with this library; if not, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | #include "config.h" |
20 | |
21 | #include <math.h> |
22 | #include <string.h> |
23 | #include <time.h> |
24 | #include <gi18n.h> |
25 | #include <glib.h> |
26 | #include <glib/gstdio.h> |
27 | #include <locale.h> |
28 | |
29 | #ifdef G_OS_WIN32 |
30 | #define WIN32_LEAN_AND_MEAN |
31 | #include <windows.h> |
32 | |
33 | #ifndef NAN |
34 | #define NAN HUGE_VAL * 0.0f |
35 | #endif |
36 | #endif |
37 | |
38 | #define ASSERT_DATE(dt,y,m,d) G_STMT_START { \ |
39 | g_assert_nonnull ((dt)); \ |
40 | g_assert_cmpint ((y), ==, g_date_time_get_year ((dt))); \ |
41 | g_assert_cmpint ((m), ==, g_date_time_get_month ((dt))); \ |
42 | g_assert_cmpint ((d), ==, g_date_time_get_day_of_month ((dt))); \ |
43 | } G_STMT_END |
44 | #define ASSERT_TIME(dt,H,M,S,U) G_STMT_START { \ |
45 | g_assert_nonnull ((dt)); \ |
46 | g_assert_cmpint ((H), ==, g_date_time_get_hour ((dt))); \ |
47 | g_assert_cmpint ((M), ==, g_date_time_get_minute ((dt))); \ |
48 | g_assert_cmpint ((S), ==, g_date_time_get_second ((dt))); \ |
49 | g_assert_cmpint ((U), ==, g_date_time_get_microsecond ((dt))); \ |
50 | } G_STMT_END |
51 | |
52 | static void |
53 | get_localtime_tm (time_t time_, |
54 | struct tm *retval) |
55 | { |
56 | #ifdef HAVE_LOCALTIME_R |
57 | localtime_r (timer: &time_, tp: retval); |
58 | #else |
59 | { |
60 | struct tm *ptm = localtime (&time_); |
61 | |
62 | if (ptm == NULL) |
63 | { |
64 | /* Happens at least in Microsoft's C library if you pass a |
65 | * negative time_t. Use 2000-01-01 as default date. |
66 | */ |
67 | #ifndef G_DISABLE_CHECKS |
68 | g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, "ptm != NULL" ); |
69 | #endif |
70 | |
71 | retval->tm_mon = 0; |
72 | retval->tm_mday = 1; |
73 | retval->tm_year = 100; |
74 | } |
75 | else |
76 | memcpy ((void *) retval, (void *) ptm, sizeof (struct tm)); |
77 | } |
78 | #endif /* HAVE_LOCALTIME_R */ |
79 | } |
80 | |
81 | static void |
82 | test_GDateTime_now (void) |
83 | { |
84 | GDateTime *dt; |
85 | struct tm tm; |
86 | time_t before; |
87 | time_t after; |
88 | |
89 | /* before <= dt.to_unix() <= after, but the inequalities might not be |
90 | * equality if we're close to the boundary between seconds. |
91 | * We loop until before == after (and hence dt.to_unix() should equal both) |
92 | * to guard against that. */ |
93 | do |
94 | { |
95 | before = g_get_real_time () / G_TIME_SPAN_SECOND; |
96 | |
97 | memset (s: &tm, c: 0, n: sizeof (tm)); |
98 | get_localtime_tm (time_: before, retval: &tm); |
99 | |
100 | dt = g_date_time_new_now_local (); |
101 | |
102 | after = g_get_real_time () / G_TIME_SPAN_SECOND; |
103 | } |
104 | while (before != after); |
105 | |
106 | g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year); |
107 | g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon); |
108 | g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, tm.tm_mday); |
109 | g_assert_cmpint (g_date_time_get_hour (dt), ==, tm.tm_hour); |
110 | g_assert_cmpint (g_date_time_get_minute (dt), ==, tm.tm_min); |
111 | g_assert_cmpint (g_date_time_get_second (dt), ==, tm.tm_sec); |
112 | |
113 | g_date_time_unref (datetime: dt); |
114 | } |
115 | |
116 | static void |
117 | test_GDateTime_new_from_unix (void) |
118 | { |
119 | GDateTime *dt; |
120 | struct tm tm; |
121 | time_t t; |
122 | |
123 | memset (s: &tm, c: 0, n: sizeof (tm)); |
124 | t = time (NULL); |
125 | g_assert_cmpint (t, !=, (time_t) -1); |
126 | get_localtime_tm (time_: t, retval: &tm); |
127 | |
128 | dt = g_date_time_new_from_unix_local (t); |
129 | g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year); |
130 | g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon); |
131 | g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, tm.tm_mday); |
132 | g_assert_cmpint (g_date_time_get_hour (dt), ==, tm.tm_hour); |
133 | g_assert_cmpint (g_date_time_get_minute (dt), ==, tm.tm_min); |
134 | g_assert_cmpint (g_date_time_get_second (dt), ==, tm.tm_sec); |
135 | g_date_time_unref (datetime: dt); |
136 | |
137 | /* Choose 1990-01-01 04:00:00 because no DST leaps happened then. The more |
138 | * obvious 1990-01-01 00:00:00 was a DST leap in America/Lima (which has, |
139 | * confusingly, since stopped using DST). */ |
140 | memset (s: &tm, c: 0, n: sizeof (tm)); |
141 | tm.tm_year = 90; |
142 | tm.tm_mday = 1; |
143 | tm.tm_mon = 0; |
144 | tm.tm_hour = 4; |
145 | tm.tm_min = 0; |
146 | tm.tm_sec = 0; |
147 | tm.tm_isdst = -1; |
148 | t = mktime (tp: &tm); |
149 | |
150 | dt = g_date_time_new_from_unix_local (t); |
151 | g_assert_cmpint (g_date_time_get_year (dt), ==, 1990); |
152 | g_assert_cmpint (g_date_time_get_month (dt), ==, 1); |
153 | g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 1); |
154 | g_assert_cmpint (g_date_time_get_hour (dt), ==, 4); |
155 | g_assert_cmpint (g_date_time_get_minute (dt), ==, 0); |
156 | g_assert_cmpint (g_date_time_get_second (dt), ==, 0); |
157 | g_date_time_unref (datetime: dt); |
158 | } |
159 | |
160 | /* Check that trying to create a #GDateTime too far in the future (or past) reliably |
161 | * fails. Previously, the checks for this overflowed and it silently returned |
162 | * an incorrect #GDateTime. */ |
163 | static void |
164 | test_GDateTime_new_from_unix_overflow (void) |
165 | { |
166 | GDateTime *dt; |
167 | |
168 | g_test_bug (bug_uri_snippet: "http://bugzilla.gnome.org/782089" ); |
169 | |
170 | dt = g_date_time_new_from_unix_utc (G_MAXINT64); |
171 | g_assert_null (dt); |
172 | |
173 | dt = g_date_time_new_from_unix_local (G_MAXINT64); |
174 | g_assert_null (dt); |
175 | |
176 | dt = g_date_time_new_from_unix_utc (G_MININT64); |
177 | g_assert_null (dt); |
178 | |
179 | dt = g_date_time_new_from_unix_local (G_MININT64); |
180 | g_assert_null (dt); |
181 | } |
182 | |
183 | static void |
184 | test_GDateTime_invalid (void) |
185 | { |
186 | GDateTime *dt; |
187 | |
188 | g_test_bug (bug_uri_snippet: "http://bugzilla.gnome.org/702674" ); |
189 | |
190 | dt = g_date_time_new_utc (year: 2013, month: -2147483647, day: 31, hour: 17, minute: 15, seconds: 48); |
191 | g_assert (dt == NULL); |
192 | } |
193 | |
194 | static void |
195 | test_GDateTime_compare (void) |
196 | { |
197 | GDateTime *dt1, *dt2; |
198 | gint i; |
199 | |
200 | dt1 = g_date_time_new_utc (year: 2000, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
201 | |
202 | for (i = 1; i < 2000; i++) |
203 | { |
204 | dt2 = g_date_time_new_utc (year: i, month: 12, day: 31, hour: 0, minute: 0, seconds: 0); |
205 | g_assert_cmpint (1, ==, g_date_time_compare (dt1, dt2)); |
206 | g_date_time_unref (datetime: dt2); |
207 | } |
208 | |
209 | dt2 = g_date_time_new_utc (year: 1999, month: 12, day: 31, hour: 23, minute: 59, seconds: 59); |
210 | g_assert_cmpint (1, ==, g_date_time_compare (dt1, dt2)); |
211 | g_date_time_unref (datetime: dt2); |
212 | |
213 | dt2 = g_date_time_new_utc (year: 2000, month: 1, day: 1, hour: 0, minute: 0, seconds: 1); |
214 | g_assert_cmpint (-1, ==, g_date_time_compare (dt1, dt2)); |
215 | g_date_time_unref (datetime: dt2); |
216 | |
217 | dt2 = g_date_time_new_utc (year: 2000, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
218 | g_assert_cmpint (0, ==, g_date_time_compare (dt1, dt2)); |
219 | g_date_time_unref (datetime: dt2); |
220 | g_date_time_unref (datetime: dt1); |
221 | } |
222 | |
223 | static void |
224 | test_GDateTime_equal (void) |
225 | { |
226 | GDateTime *dt1, *dt2; |
227 | GTimeZone *tz; |
228 | |
229 | dt1 = g_date_time_new_local (year: 2009, month: 10, day: 19, hour: 0, minute: 0, seconds: 0); |
230 | dt2 = g_date_time_new_local (year: 2009, month: 10, day: 19, hour: 0, minute: 0, seconds: 0); |
231 | g_assert (g_date_time_equal (dt1, dt2)); |
232 | g_date_time_unref (datetime: dt1); |
233 | g_date_time_unref (datetime: dt2); |
234 | |
235 | dt1 = g_date_time_new_local (year: 2009, month: 10, day: 18, hour: 0, minute: 0, seconds: 0); |
236 | dt2 = g_date_time_new_local (year: 2009, month: 10, day: 19, hour: 0, minute: 0, seconds: 0); |
237 | g_assert (!g_date_time_equal (dt1, dt2)); |
238 | g_date_time_unref (datetime: dt1); |
239 | g_date_time_unref (datetime: dt2); |
240 | |
241 | /* UTC-0300 and not in DST */ |
242 | tz = g_time_zone_new_identifier (identifier: "-03:00" ); |
243 | g_assert_nonnull (tz); |
244 | dt1 = g_date_time_new (tz, year: 2010, month: 5, day: 24, hour: 8, minute: 0, seconds: 0); |
245 | g_time_zone_unref (tz); |
246 | g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600)); |
247 | /* UTC */ |
248 | dt2 = g_date_time_new_utc (year: 2010, month: 5, day: 24, hour: 11, minute: 0, seconds: 0); |
249 | g_assert_cmpint (g_date_time_get_utc_offset (dt2), ==, 0); |
250 | |
251 | g_assert (g_date_time_equal (dt1, dt2)); |
252 | g_date_time_unref (datetime: dt1); |
253 | |
254 | /* America/Recife is in UTC-0300 */ |
255 | #ifdef G_OS_UNIX |
256 | tz = g_time_zone_new_identifier (identifier: "America/Recife" ); |
257 | #elif defined G_OS_WIN32 |
258 | tz = g_time_zone_new_identifier ("E. South America Standard Time" ); |
259 | #endif |
260 | g_assert_nonnull (tz); |
261 | dt1 = g_date_time_new (tz, year: 2010, month: 5, day: 24, hour: 8, minute: 0, seconds: 0); |
262 | g_time_zone_unref (tz); |
263 | g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600)); |
264 | g_assert (g_date_time_equal (dt1, dt2)); |
265 | g_date_time_unref (datetime: dt1); |
266 | g_date_time_unref (datetime: dt2); |
267 | } |
268 | |
269 | static void |
270 | test_GDateTime_get_day_of_week (void) |
271 | { |
272 | GDateTime *dt; |
273 | |
274 | dt = g_date_time_new_local (year: 2009, month: 10, day: 19, hour: 0, minute: 0, seconds: 0); |
275 | g_assert_cmpint (1, ==, g_date_time_get_day_of_week (dt)); |
276 | g_date_time_unref (datetime: dt); |
277 | |
278 | dt = g_date_time_new_local (year: 2000, month: 10, day: 1, hour: 0, minute: 0, seconds: 0); |
279 | g_assert_cmpint (7, ==, g_date_time_get_day_of_week (dt)); |
280 | g_date_time_unref (datetime: dt); |
281 | } |
282 | |
283 | static void |
284 | test_GDateTime_get_day_of_month (void) |
285 | { |
286 | GDateTime *dt; |
287 | |
288 | dt = g_date_time_new_local (year: 2009, month: 10, day: 19, hour: 0, minute: 0, seconds: 0); |
289 | g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 19); |
290 | g_date_time_unref (datetime: dt); |
291 | |
292 | dt = g_date_time_new_local (year: 1400, month: 3, day: 12, hour: 0, minute: 0, seconds: 0); |
293 | g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 12); |
294 | g_date_time_unref (datetime: dt); |
295 | |
296 | dt = g_date_time_new_local (year: 1800, month: 12, day: 31, hour: 0, minute: 0, seconds: 0); |
297 | g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 31); |
298 | g_date_time_unref (datetime: dt); |
299 | |
300 | dt = g_date_time_new_local (year: 1000, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
301 | g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 1); |
302 | g_date_time_unref (datetime: dt); |
303 | } |
304 | |
305 | static void |
306 | test_GDateTime_get_hour (void) |
307 | { |
308 | GDateTime *dt; |
309 | |
310 | dt = g_date_time_new_utc (year: 2009, month: 10, day: 19, hour: 15, minute: 13, seconds: 11); |
311 | g_assert_cmpint (15, ==, g_date_time_get_hour (dt)); |
312 | g_date_time_unref (datetime: dt); |
313 | |
314 | dt = g_date_time_new_utc (year: 100, month: 10, day: 19, hour: 1, minute: 0, seconds: 0); |
315 | g_assert_cmpint (1, ==, g_date_time_get_hour (dt)); |
316 | g_date_time_unref (datetime: dt); |
317 | |
318 | dt = g_date_time_new_utc (year: 100, month: 10, day: 19, hour: 0, minute: 0, seconds: 0); |
319 | g_assert_cmpint (0, ==, g_date_time_get_hour (dt)); |
320 | g_date_time_unref (datetime: dt); |
321 | |
322 | dt = g_date_time_new_utc (year: 100, month: 10, day: 1, hour: 23, minute: 59, seconds: 59); |
323 | g_assert_cmpint (23, ==, g_date_time_get_hour (dt)); |
324 | g_date_time_unref (datetime: dt); |
325 | } |
326 | |
327 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
328 | static void |
329 | test_GDateTime_get_microsecond (void) |
330 | { |
331 | GTimeVal tv; |
332 | GDateTime *dt; |
333 | |
334 | g_get_current_time (result: &tv); |
335 | dt = g_date_time_new_from_timeval_local (tv: &tv); |
336 | g_assert_cmpint (tv.tv_usec, ==, g_date_time_get_microsecond (dt)); |
337 | g_date_time_unref (datetime: dt); |
338 | } |
339 | G_GNUC_END_IGNORE_DEPRECATIONS |
340 | |
341 | static void |
342 | test_GDateTime_get_year (void) |
343 | { |
344 | GDateTime *dt; |
345 | |
346 | dt = g_date_time_new_local (year: 2009, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
347 | g_assert_cmpint (2009, ==, g_date_time_get_year (dt)); |
348 | g_date_time_unref (datetime: dt); |
349 | |
350 | dt = g_date_time_new_local (year: 1, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
351 | g_assert_cmpint (1, ==, g_date_time_get_year (dt)); |
352 | g_date_time_unref (datetime: dt); |
353 | |
354 | dt = g_date_time_new_local (year: 13, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
355 | g_assert_cmpint (13, ==, g_date_time_get_year (dt)); |
356 | g_date_time_unref (datetime: dt); |
357 | |
358 | dt = g_date_time_new_local (year: 3000, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
359 | g_assert_cmpint (3000, ==, g_date_time_get_year (dt)); |
360 | g_date_time_unref (datetime: dt); |
361 | } |
362 | |
363 | static void |
364 | test_GDateTime_hash (void) |
365 | { |
366 | GHashTable *h; |
367 | |
368 | h = g_hash_table_new_full (hash_func: g_date_time_hash, key_equal_func: g_date_time_equal, |
369 | key_destroy_func: (GDestroyNotify)g_date_time_unref, |
370 | NULL); |
371 | g_hash_table_add (hash_table: h, key: g_date_time_new_now_local ()); |
372 | g_hash_table_remove_all (hash_table: h); |
373 | g_hash_table_destroy (hash_table: h); |
374 | } |
375 | |
376 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
377 | static void |
378 | test_GDateTime_new_from_timeval (void) |
379 | { |
380 | GDateTime *dt; |
381 | GTimeVal tv, tv2; |
382 | |
383 | g_get_current_time (result: &tv); |
384 | dt = g_date_time_new_from_timeval_local (tv: &tv); |
385 | |
386 | if (g_test_verbose ()) |
387 | g_printerr (format: "\nDT%04d-%02d-%02dT%02d:%02d:%02d%s\n" , |
388 | g_date_time_get_year (datetime: dt), |
389 | g_date_time_get_month (datetime: dt), |
390 | g_date_time_get_day_of_month (datetime: dt), |
391 | g_date_time_get_hour (datetime: dt), |
392 | g_date_time_get_minute (datetime: dt), |
393 | g_date_time_get_second (datetime: dt), |
394 | g_date_time_get_timezone_abbreviation (datetime: dt)); |
395 | |
396 | g_date_time_to_timeval (datetime: dt, tv: &tv2); |
397 | g_assert_cmpint (tv.tv_sec, ==, tv2.tv_sec); |
398 | g_assert_cmpint (tv.tv_usec, ==, tv2.tv_usec); |
399 | g_date_time_unref (datetime: dt); |
400 | } |
401 | |
402 | static glong |
403 | find_maximum_supported_tv_sec (void) |
404 | { |
405 | glong highest_success = 0, lowest_failure = G_MAXLONG; |
406 | GTimeVal tv; |
407 | GDateTime *dt = NULL; |
408 | |
409 | tv.tv_usec = 0; |
410 | |
411 | /* Corner case of all glong values being valid. */ |
412 | tv.tv_sec = G_MAXLONG; |
413 | dt = g_date_time_new_from_timeval_utc (tv: &tv); |
414 | if (dt != NULL) |
415 | { |
416 | highest_success = tv.tv_sec; |
417 | g_date_time_unref (datetime: dt); |
418 | } |
419 | |
420 | while (highest_success < lowest_failure - 1) |
421 | { |
422 | tv.tv_sec = highest_success + (lowest_failure - highest_success) / 2; |
423 | dt = g_date_time_new_from_timeval_utc (tv: &tv); |
424 | |
425 | if (dt != NULL) |
426 | { |
427 | highest_success = tv.tv_sec; |
428 | g_date_time_unref (datetime: dt); |
429 | } |
430 | else |
431 | { |
432 | lowest_failure = tv.tv_sec; |
433 | } |
434 | } |
435 | |
436 | return highest_success; |
437 | } |
438 | |
439 | /* Check that trying to create a #GDateTime too far in the future reliably |
440 | * fails. With a #GTimeVal, this is subtle, as the tv_usec are added into the |
441 | * calculation part-way through. |
442 | * |
443 | * This varies a bit between 32- and 64-bit architectures, due to the |
444 | * differences in the size of glong (tv.tv_sec). */ |
445 | static void |
446 | test_GDateTime_new_from_timeval_overflow (void) |
447 | { |
448 | GDateTime *dt; |
449 | GTimeVal tv; |
450 | |
451 | g_test_bug (bug_uri_snippet: "http://bugzilla.gnome.org/782089" ); |
452 | |
453 | tv.tv_sec = find_maximum_supported_tv_sec (); |
454 | tv.tv_usec = G_USEC_PER_SEC - 1; |
455 | |
456 | g_test_message (format: "Maximum supported GTimeVal.tv_sec = %lu" , tv.tv_sec); |
457 | |
458 | /* Sanity check: do we support the year 2000? */ |
459 | g_assert_cmpint (tv.tv_sec, >=, 946684800); |
460 | |
461 | dt = g_date_time_new_from_timeval_utc (tv: &tv); |
462 | g_assert_nonnull (dt); |
463 | g_date_time_unref (datetime: dt); |
464 | |
465 | if (tv.tv_sec < G_MAXLONG) |
466 | { |
467 | tv.tv_sec++; |
468 | tv.tv_usec = 0; |
469 | |
470 | dt = g_date_time_new_from_timeval_utc (tv: &tv); |
471 | g_assert_null (dt); |
472 | } |
473 | } |
474 | |
475 | static void |
476 | test_GDateTime_new_from_timeval_utc (void) |
477 | { |
478 | GDateTime *dt; |
479 | GTimeVal tv, tv2; |
480 | |
481 | g_get_current_time (result: &tv); |
482 | dt = g_date_time_new_from_timeval_utc (tv: &tv); |
483 | |
484 | if (g_test_verbose ()) |
485 | g_printerr (format: "\nDT%04d-%02d-%02dT%02d:%02d:%02d%s\n" , |
486 | g_date_time_get_year (datetime: dt), |
487 | g_date_time_get_month (datetime: dt), |
488 | g_date_time_get_day_of_month (datetime: dt), |
489 | g_date_time_get_hour (datetime: dt), |
490 | g_date_time_get_minute (datetime: dt), |
491 | g_date_time_get_second (datetime: dt), |
492 | g_date_time_get_timezone_abbreviation (datetime: dt)); |
493 | |
494 | g_date_time_to_timeval (datetime: dt, tv: &tv2); |
495 | g_assert_cmpint (tv.tv_sec, ==, tv2.tv_sec); |
496 | g_assert_cmpint (tv.tv_usec, ==, tv2.tv_usec); |
497 | g_date_time_unref (datetime: dt); |
498 | } |
499 | G_GNUC_END_IGNORE_DEPRECATIONS |
500 | |
501 | static void |
502 | test_GDateTime_new_from_iso8601 (void) |
503 | { |
504 | GDateTime *dt; |
505 | GTimeZone *tz; |
506 | |
507 | /* Need non-empty string */ |
508 | dt = g_date_time_new_from_iso8601 (text: "" , NULL); |
509 | g_assert_null (dt); |
510 | |
511 | /* Needs to be correctly formatted */ |
512 | dt = g_date_time_new_from_iso8601 (text: "not a date" , NULL); |
513 | g_assert_null (dt); |
514 | |
515 | dt = g_date_time_new_from_iso8601 (text: " +55" , NULL); |
516 | g_assert_null (dt); |
517 | |
518 | /* Check common case */ |
519 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42Z" , NULL); |
520 | ASSERT_DATE (dt, 2016, 8, 24); |
521 | ASSERT_TIME (dt, 22, 10, 42, 0); |
522 | g_date_time_unref (datetime: dt); |
523 | |
524 | /* Timezone is required in text or passed as arg */ |
525 | tz = g_time_zone_new_utc (); |
526 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42" , default_tz: tz); |
527 | ASSERT_DATE (dt, 2016, 8, 24); |
528 | g_date_time_unref (datetime: dt); |
529 | g_time_zone_unref (tz); |
530 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42" , NULL); |
531 | g_assert_null (dt); |
532 | |
533 | /* Can't have whitespace */ |
534 | dt = g_date_time_new_from_iso8601 (text: "2016 08 24T22:10:42Z" , NULL); |
535 | g_assert_null (dt); |
536 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42Z " , NULL); |
537 | g_assert_null (dt); |
538 | dt = g_date_time_new_from_iso8601 (text: " 2016-08-24T22:10:42Z" , NULL); |
539 | g_assert_null (dt); |
540 | |
541 | /* Check lowercase time separator or space allowed */ |
542 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24t22:10:42Z" , NULL); |
543 | ASSERT_DATE (dt, 2016, 8, 24); |
544 | ASSERT_TIME (dt, 22, 10, 42, 0); |
545 | g_date_time_unref (datetime: dt); |
546 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24 22:10:42Z" , NULL); |
547 | ASSERT_DATE (dt, 2016, 8, 24); |
548 | ASSERT_TIME (dt, 22, 10, 42, 0); |
549 | g_date_time_unref (datetime: dt); |
550 | |
551 | /* Check dates without separators allowed */ |
552 | dt = g_date_time_new_from_iso8601 (text: "20160824T22:10:42Z" , NULL); |
553 | ASSERT_DATE (dt, 2016, 8, 24); |
554 | ASSERT_TIME (dt, 22, 10, 42, 0); |
555 | g_date_time_unref (datetime: dt); |
556 | |
557 | /* Months are two digits */ |
558 | dt = g_date_time_new_from_iso8601 (text: "2016-1-01T22:10:42Z" , NULL); |
559 | g_assert_null (dt); |
560 | |
561 | /* Days are two digits */ |
562 | dt = g_date_time_new_from_iso8601 (text: "2016-01-1T22:10:42Z" , NULL); |
563 | g_assert_null (dt); |
564 | |
565 | /* Need consistent usage of separators */ |
566 | dt = g_date_time_new_from_iso8601 (text: "2016-0824T22:10:42Z" , NULL); |
567 | g_assert_null (dt); |
568 | dt = g_date_time_new_from_iso8601 (text: "201608-24T22:10:42Z" , NULL); |
569 | g_assert_null (dt); |
570 | |
571 | /* Check month within valid range */ |
572 | dt = g_date_time_new_from_iso8601 (text: "2016-00-13T22:10:42Z" , NULL); |
573 | g_assert_null (dt); |
574 | dt = g_date_time_new_from_iso8601 (text: "2016-13-13T22:10:42Z" , NULL); |
575 | g_assert_null (dt); |
576 | |
577 | /* Check day within valid range */ |
578 | dt = g_date_time_new_from_iso8601 (text: "2016-01-00T22:10:42Z" , NULL); |
579 | g_assert_null (dt); |
580 | dt = g_date_time_new_from_iso8601 (text: "2016-01-31T22:10:42Z" , NULL); |
581 | ASSERT_DATE (dt, 2016, 1, 31); |
582 | g_date_time_unref (datetime: dt); |
583 | dt = g_date_time_new_from_iso8601 (text: "2016-01-32T22:10:42Z" , NULL); |
584 | g_assert_null (dt); |
585 | dt = g_date_time_new_from_iso8601 (text: "2016-02-29T22:10:42Z" , NULL); |
586 | ASSERT_DATE (dt, 2016, 2, 29); |
587 | g_date_time_unref (datetime: dt); |
588 | dt = g_date_time_new_from_iso8601 (text: "2016-02-30T22:10:42Z" , NULL); |
589 | g_assert_null (dt); |
590 | dt = g_date_time_new_from_iso8601 (text: "2017-02-28T22:10:42Z" , NULL); |
591 | ASSERT_DATE (dt, 2017, 2, 28); |
592 | g_date_time_unref (datetime: dt); |
593 | dt = g_date_time_new_from_iso8601 (text: "2017-02-29T22:10:42Z" , NULL); |
594 | g_assert_null (dt); |
595 | dt = g_date_time_new_from_iso8601 (text: "2016-03-31T22:10:42Z" , NULL); |
596 | ASSERT_DATE (dt, 2016, 3, 31); |
597 | g_date_time_unref (datetime: dt); |
598 | dt = g_date_time_new_from_iso8601 (text: "2016-03-32T22:10:42Z" , NULL); |
599 | g_assert_null (dt); |
600 | dt = g_date_time_new_from_iso8601 (text: "2016-04-30T22:10:42Z" , NULL); |
601 | ASSERT_DATE (dt, 2016, 4, 30); |
602 | g_date_time_unref (datetime: dt); |
603 | dt = g_date_time_new_from_iso8601 (text: "2016-04-31T22:10:42Z" , NULL); |
604 | g_assert_null (dt); |
605 | dt = g_date_time_new_from_iso8601 (text: "2016-05-31T22:10:42Z" , NULL); |
606 | ASSERT_DATE (dt, 2016, 5, 31); |
607 | g_date_time_unref (datetime: dt); |
608 | dt = g_date_time_new_from_iso8601 (text: "2016-05-32T22:10:42Z" , NULL); |
609 | g_assert_null (dt); |
610 | dt = g_date_time_new_from_iso8601 (text: "2016-06-30T22:10:42Z" , NULL); |
611 | ASSERT_DATE (dt, 2016, 6, 30); |
612 | g_date_time_unref (datetime: dt); |
613 | dt = g_date_time_new_from_iso8601 (text: "2016-06-31T22:10:42Z" , NULL); |
614 | g_assert_null (dt); |
615 | dt = g_date_time_new_from_iso8601 (text: "2016-07-31T22:10:42Z" , NULL); |
616 | ASSERT_DATE (dt, 2016, 7, 31); |
617 | g_date_time_unref (datetime: dt); |
618 | dt = g_date_time_new_from_iso8601 (text: "2016-07-32T22:10:42Z" , NULL); |
619 | g_assert_null (dt); |
620 | dt = g_date_time_new_from_iso8601 (text: "2016-08-31T22:10:42Z" , NULL); |
621 | ASSERT_DATE (dt, 2016, 8, 31); |
622 | g_date_time_unref (datetime: dt); |
623 | dt = g_date_time_new_from_iso8601 (text: "2016-08-32T22:10:42Z" , NULL); |
624 | g_assert_null (dt); |
625 | dt = g_date_time_new_from_iso8601 (text: "2016-09-30T22:10:42Z" , NULL); |
626 | ASSERT_DATE (dt, 2016, 9, 30); |
627 | g_date_time_unref (datetime: dt); |
628 | dt = g_date_time_new_from_iso8601 (text: "2016-09-31T22:10:42Z" , NULL); |
629 | g_assert_null (dt); |
630 | dt = g_date_time_new_from_iso8601 (text: "2016-10-31T22:10:42Z" , NULL); |
631 | ASSERT_DATE (dt, 2016, 10, 31); |
632 | g_date_time_unref (datetime: dt); |
633 | dt = g_date_time_new_from_iso8601 (text: "2016-10-32T22:10:42Z" , NULL); |
634 | g_assert_null (dt); |
635 | dt = g_date_time_new_from_iso8601 (text: "2016-11-30T22:10:42Z" , NULL); |
636 | ASSERT_DATE (dt, 2016, 11, 30); |
637 | g_date_time_unref (datetime: dt); |
638 | dt = g_date_time_new_from_iso8601 (text: "2016-11-31T22:10:42Z" , NULL); |
639 | g_assert_null (dt); |
640 | dt = g_date_time_new_from_iso8601 (text: "2016-12-31T22:10:42Z" , NULL); |
641 | ASSERT_DATE (dt, 2016, 12, 31); |
642 | g_date_time_unref (datetime: dt); |
643 | dt = g_date_time_new_from_iso8601 (text: "2016-12-32T22:10:42Z" , NULL); |
644 | g_assert_null (dt); |
645 | |
646 | /* Check ordinal days work */ |
647 | dt = g_date_time_new_from_iso8601 (text: "2016-237T22:10:42Z" , NULL); |
648 | ASSERT_DATE (dt, 2016, 8, 24); |
649 | ASSERT_TIME (dt, 22, 10, 42, 0); |
650 | g_date_time_unref (datetime: dt); |
651 | dt = g_date_time_new_from_iso8601 (text: "2016237T22:10:42Z" , NULL); |
652 | ASSERT_DATE (dt, 2016, 8, 24); |
653 | ASSERT_TIME (dt, 22, 10, 42, 0); |
654 | g_date_time_unref (datetime: dt); |
655 | |
656 | /* Check ordinal leap days */ |
657 | dt = g_date_time_new_from_iso8601 (text: "2016-366T22:10:42Z" , NULL); |
658 | ASSERT_DATE (dt, 2016, 12, 31); |
659 | ASSERT_TIME (dt, 22, 10, 42, 0); |
660 | g_date_time_unref (datetime: dt); |
661 | dt = g_date_time_new_from_iso8601 (text: "2017-365T22:10:42Z" , NULL); |
662 | ASSERT_DATE (dt, 2017, 12, 31); |
663 | ASSERT_TIME (dt, 22, 10, 42, 0); |
664 | g_date_time_unref (datetime: dt); |
665 | dt = g_date_time_new_from_iso8601 (text: "2017-366T22:10:42Z" , NULL); |
666 | g_assert_null (dt); |
667 | |
668 | /* Days start at 1 */ |
669 | dt = g_date_time_new_from_iso8601 (text: "2016-000T22:10:42Z" , NULL); |
670 | g_assert_null (dt); |
671 | |
672 | /* Limited to number of days in the year (2016 is a leap year) */ |
673 | dt = g_date_time_new_from_iso8601 (text: "2016-367T22:10:42Z" , NULL); |
674 | g_assert_null (dt); |
675 | |
676 | /* Days are two digits */ |
677 | dt = g_date_time_new_from_iso8601 (text: "2016-1T22:10:42Z" , NULL); |
678 | g_assert_null (dt); |
679 | dt = g_date_time_new_from_iso8601 (text: "2016-12T22:10:42Z" , NULL); |
680 | g_assert_null (dt); |
681 | |
682 | /* Check week days work */ |
683 | dt = g_date_time_new_from_iso8601 (text: "2016-W34-3T22:10:42Z" , NULL); |
684 | ASSERT_DATE (dt, 2016, 8, 24); |
685 | ASSERT_TIME (dt, 22, 10, 42, 0); |
686 | g_date_time_unref (datetime: dt); |
687 | dt = g_date_time_new_from_iso8601 (text: "2016W343T22:10:42Z" , NULL); |
688 | ASSERT_DATE (dt, 2016, 8, 24); |
689 | ASSERT_TIME (dt, 22, 10, 42, 0); |
690 | g_date_time_unref (datetime: dt); |
691 | |
692 | /* We don't support weeks without weekdays (valid ISO 8601) */ |
693 | dt = g_date_time_new_from_iso8601 (text: "2016-W34T22:10:42Z" , NULL); |
694 | g_assert_null (dt); |
695 | dt = g_date_time_new_from_iso8601 (text: "2016W34T22:10:42Z" , NULL); |
696 | g_assert_null (dt); |
697 | |
698 | /* Weeks are two digits */ |
699 | dt = g_date_time_new_from_iso8601 (text: "2016-W3-1T22:10:42Z" , NULL); |
700 | g_assert_null (dt); |
701 | |
702 | /* Weeks start at 1 */ |
703 | dt = g_date_time_new_from_iso8601 (text: "2016-W00-1T22:10:42Z" , NULL); |
704 | g_assert_null (dt); |
705 | |
706 | /* Week one might be in the previous year */ |
707 | dt = g_date_time_new_from_iso8601 (text: "2015-W01-1T22:10:42Z" , NULL); |
708 | ASSERT_DATE (dt, 2014, 12, 29); |
709 | g_date_time_unref (datetime: dt); |
710 | |
711 | /* Last week might be in next year */ |
712 | dt = g_date_time_new_from_iso8601 (text: "2015-W53-7T22:10:42Z" , NULL); |
713 | ASSERT_DATE (dt, 2016, 1, 3); |
714 | g_date_time_unref (datetime: dt); |
715 | |
716 | /* Week 53 doesn't always exist */ |
717 | dt = g_date_time_new_from_iso8601 (text: "2016-W53-1T22:10:42Z" , NULL); |
718 | g_assert_null (dt); |
719 | |
720 | /* Limited to number of days in the week */ |
721 | dt = g_date_time_new_from_iso8601 (text: "2016-W34-0T22:10:42Z" , NULL); |
722 | g_assert_null (dt); |
723 | dt = g_date_time_new_from_iso8601 (text: "2016-W34-8T22:10:42Z" , NULL); |
724 | g_assert_null (dt); |
725 | |
726 | /* Days are one digit */ |
727 | dt = g_date_time_new_from_iso8601 (text: "2016-W34-99T22:10:42Z" , NULL); |
728 | g_assert_null (dt); |
729 | |
730 | /* Check week day changes depending on year */ |
731 | dt = g_date_time_new_from_iso8601 (text: "2017-W34-1T22:10:42Z" , NULL); |
732 | ASSERT_DATE (dt, 2017, 8, 21); |
733 | g_date_time_unref (datetime: dt); |
734 | |
735 | /* Check week day changes depending on leap years */ |
736 | dt = g_date_time_new_from_iso8601 (text: "1900-W01-1T22:10:42Z" , NULL); |
737 | ASSERT_DATE (dt, 1900, 1, 1); |
738 | g_date_time_unref (datetime: dt); |
739 | |
740 | /* YYYY-MM not allowed (NOT valid ISO 8601) */ |
741 | dt = g_date_time_new_from_iso8601 (text: "2016-08T22:10:42Z" , NULL); |
742 | g_assert_null (dt); |
743 | |
744 | /* We don't support omitted year (valid ISO 8601) */ |
745 | dt = g_date_time_new_from_iso8601 (text: "--08-24T22:10:42Z" , NULL); |
746 | g_assert_null (dt); |
747 | dt = g_date_time_new_from_iso8601 (text: "--0824T22:10:42Z" , NULL); |
748 | g_assert_null (dt); |
749 | |
750 | /* Seconds must be two digits. */ |
751 | dt = g_date_time_new_from_iso8601 (text: "2016-08-10T22:10:4Z" , NULL); |
752 | g_assert_null (dt); |
753 | |
754 | /* Seconds must all be digits. */ |
755 | dt = g_date_time_new_from_iso8601 (text: "2016-08-10T22:10:4aZ" , NULL); |
756 | g_assert_null (dt); |
757 | |
758 | /* Check subseconds work */ |
759 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42.123456Z" , NULL); |
760 | ASSERT_DATE (dt, 2016, 8, 24); |
761 | ASSERT_TIME (dt, 22, 10, 42, 123456); |
762 | g_date_time_unref (datetime: dt); |
763 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42,123456Z" , NULL); |
764 | ASSERT_DATE (dt, 2016, 8, 24); |
765 | ASSERT_TIME (dt, 22, 10, 42, 123456); |
766 | g_date_time_unref (datetime: dt); |
767 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42.Z" , NULL); |
768 | g_assert_null (dt); |
769 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T221042.123456Z" , NULL); |
770 | ASSERT_DATE (dt, 2016, 8, 24); |
771 | ASSERT_TIME (dt, 22, 10, 42, 123456); |
772 | g_date_time_unref (datetime: dt); |
773 | |
774 | /* Subseconds must all be digits. */ |
775 | dt = g_date_time_new_from_iso8601 (text: "2016-08-10T22:10:42.5aZ" , NULL); |
776 | g_assert_null (dt); |
777 | |
778 | /* Subseconds can be an arbitrary length, but must not overflow. |
779 | * The ASSERT_TIME() comparisons are constrained by only comparing up to |
780 | * microsecond granularity. */ |
781 | dt = g_date_time_new_from_iso8601 (text: "2016-08-10T22:10:09.222222222222222222Z" , NULL); |
782 | ASSERT_DATE (dt, 2016, 8, 10); |
783 | ASSERT_TIME (dt, 22, 10, 9, 222222); |
784 | g_date_time_unref (datetime: dt); |
785 | dt = g_date_time_new_from_iso8601 (text: "2016-08-10T22:10:09.2222222222222222222Z" , NULL); |
786 | g_assert_null (dt); |
787 | |
788 | /* Small numerator, large divisor when parsing the subseconds. */ |
789 | dt = g_date_time_new_from_iso8601 (text: "2016-08-10T22:10:00.0000000000000000001Z" , NULL); |
790 | ASSERT_DATE (dt, 2016, 8, 10); |
791 | ASSERT_TIME (dt, 22, 10, 0, 0); |
792 | g_date_time_unref (datetime: dt); |
793 | dt = g_date_time_new_from_iso8601 (text: "2016-08-10T22:10:00.00000000000000000001Z" , NULL); |
794 | g_assert_null (dt); |
795 | |
796 | /* We don't support times without minutes / seconds (valid ISO 8601) */ |
797 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22Z" , NULL); |
798 | g_assert_null (dt); |
799 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10Z" , NULL); |
800 | g_assert_null (dt); |
801 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T2210Z" , NULL); |
802 | g_assert_null (dt); |
803 | |
804 | /* UTC time uses 'Z' */ |
805 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42Z" , NULL); |
806 | ASSERT_DATE (dt, 2016, 8, 24); |
807 | ASSERT_TIME (dt, 22, 10, 42, 0); |
808 | g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, 0); |
809 | g_date_time_unref (datetime: dt); |
810 | |
811 | /* Check timezone works */ |
812 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42+12:00" , NULL); |
813 | ASSERT_DATE (dt, 2016, 8, 24); |
814 | ASSERT_TIME (dt, 22, 10, 42, 0); |
815 | g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, 12 * G_TIME_SPAN_HOUR); |
816 | g_date_time_unref (datetime: dt); |
817 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42+12" , NULL); |
818 | ASSERT_DATE (dt, 2016, 8, 24); |
819 | ASSERT_TIME (dt, 22, 10, 42, 0); |
820 | g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, 12 * G_TIME_SPAN_HOUR); |
821 | g_date_time_unref (datetime: dt); |
822 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22:10:42-02" , NULL); |
823 | ASSERT_DATE (dt, 2016, 8, 24); |
824 | ASSERT_TIME (dt, 22, 10, 42, 0); |
825 | g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, -2 * G_TIME_SPAN_HOUR); |
826 | g_date_time_unref (datetime: dt); |
827 | |
828 | /* Timezone seconds not allowed */ |
829 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22-12:00:00" , NULL); |
830 | g_assert_null (dt); |
831 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22-12:00:00.000" , NULL); |
832 | g_assert_null (dt); |
833 | |
834 | /* Timezone hours two digits */ |
835 | dt = g_date_time_new_from_iso8601 (text: "2016-08-24T22-2Z" , NULL); |
836 | g_assert_null (dt); |
837 | |
838 | /* Ordinal date (YYYYDDD), space separator, and then time as HHMMSS,SSS |
839 | * The interesting bit is that the seconds field is so long as to parse as |
840 | * NaN */ |
841 | dt = g_date_time_new_from_iso8601 (text: "0005306 000001,666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666600080000-00" , NULL); |
842 | g_assert_null (dt); |
843 | } |
844 | |
845 | typedef struct { |
846 | gboolean success; |
847 | const gchar *in; |
848 | |
849 | /* Expected result: */ |
850 | guint year; |
851 | guint month; |
852 | guint day; |
853 | guint hour; |
854 | guint minute; |
855 | guint second; |
856 | guint microsecond; |
857 | GTimeSpan utc_offset; |
858 | } Iso8601ParseTest; |
859 | |
860 | static void |
861 | test_GDateTime_new_from_iso8601_2 (void) |
862 | { |
863 | const Iso8601ParseTest tests[] = { |
864 | { TRUE, "1990-11-01T10:21:17Z" , 1990, 11, 1, 10, 21, 17, 0, 0 }, |
865 | { TRUE, "19901101T102117Z" , 1990, 11, 1, 10, 21, 17, 0, 0 }, |
866 | { TRUE, "1970-01-01T00:00:17.12Z" , 1970, 1, 1, 0, 0, 17, 120000, 0 }, |
867 | { TRUE, "1970-01-01T00:00:17.1234Z" , 1970, 1, 1, 0, 0, 17, 123400, 0 }, |
868 | { TRUE, "1970-01-01T00:00:17.123456Z" , 1970, 1, 1, 0, 0, 17, 123456, 0 }, |
869 | { TRUE, "1980-02-22T12:36:00+02:00" , 1980, 2, 22, 12, 36, 0, 0, 2 * G_TIME_SPAN_HOUR }, |
870 | { TRUE, "1990-12-31T15:59:60-08:00" , 1990, 12, 31, 15, 59, 59, 0, -8 * G_TIME_SPAN_HOUR }, |
871 | { FALSE, " " , 0, 0, 0, 0, 0, 0, 0, 0 }, |
872 | { FALSE, "x" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
873 | { FALSE, "123x" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
874 | { FALSE, "2001-10+x" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
875 | { FALSE, "1980-02-22T" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
876 | { FALSE, "2001-10-08Tx" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
877 | { FALSE, "2001-10-08T10:11x" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
878 | { FALSE, "Wed Dec 19 17:20:20 GMT 2007" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
879 | { FALSE, "1980-02-22T10:36:00Zulu" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
880 | { FALSE, "2T0+819855292164632335" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
881 | { TRUE, "2018-08-03T14:08:05.446178377+01:00" , 2018, 8, 3, 14, 8, 5, 446178, 1 * G_TIME_SPAN_HOUR }, |
882 | { FALSE, "2147483648-08-03T14:08:05.446178377+01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
883 | { FALSE, "2018-13-03T14:08:05.446178377+01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
884 | { FALSE, "2018-00-03T14:08:05.446178377+01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
885 | { FALSE, "2018-08-00T14:08:05.446178377+01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
886 | { FALSE, "2018-08-32T14:08:05.446178377+01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
887 | { FALSE, "2018-08-03T24:08:05.446178377+01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
888 | { FALSE, "2018-08-03T14:60:05.446178377+01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
889 | { FALSE, "2018-08-03T14:08:63.446178377+01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
890 | { FALSE, "2018-08-03T14:08:05.446178377+100:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
891 | { TRUE, "20180803T140805.446178377+0100" , 2018, 8, 3, 14, 8, 5, 446178, 1 * G_TIME_SPAN_HOUR }, |
892 | { FALSE, "21474836480803T140805.446178377+0100" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
893 | { FALSE, "20181303T140805.446178377+0100" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
894 | { FALSE, "20180003T140805.446178377+0100" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
895 | { FALSE, "20180800T140805.446178377+0100" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
896 | { FALSE, "20180832T140805.446178377+0100" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
897 | { FALSE, "20180803T240805.446178377+0100" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
898 | { FALSE, "20180803T146005.446178377+0100" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
899 | { FALSE, "20180803T140863.446178377+0100" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
900 | { FALSE, "20180803T140805.446178377+10000" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
901 | { FALSE, "-0005-01-01T00:00:00Z" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
902 | { FALSE, "2018-08-06" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
903 | /* This is not accepted by g_time_val_from_iso8601(), but is accepted by g_date_time_new_from_iso8601(): |
904 | { FALSE, "2018-08-06 13:51:00Z", 0, 0, 0, 0, 0, 0, 0, 0 }, |
905 | * */ |
906 | { TRUE, "20180803T140805,446178377+0100" , 2018, 8, 3, 14, 8, 5, 446178, 1 * G_TIME_SPAN_HOUR }, |
907 | { TRUE, "2018-08-03T14:08:05.446178377-01:00" , 2018, 8, 3, 14, 8, 5, 446178, -1 * G_TIME_SPAN_HOUR }, |
908 | { FALSE, "2018-08-03T14:08:05.446178377 01:00" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
909 | { TRUE, "1990-11-01T10:21:17" , 1990, 11, 1, 10, 21, 17, 0, 0 }, |
910 | /* These are accepted by g_time_val_from_iso8601(), but not by g_date_time_new_from_iso8601(): |
911 | { TRUE, "19901101T102117+5", 1990, 11, 1, 10, 21, 17, 0, 5 * G_TIME_SPAN_HOUR }, |
912 | { TRUE, "19901101T102117+3:15", 1990, 11, 1, 10, 21, 17, 0, 3 * G_TIME_SPAN_HOUR + 15 * G_TIME_SPAN_MINUTE }, |
913 | { TRUE, " 1990-11-01T10:21:17Z ", 1990, 11, 1, 10, 21, 17, 0, 0 }, |
914 | { FALSE, "2018-08-03T14:08:05.446178377+01:60", 0, 0, 0, 0, 0, 0, 0, 0 }, |
915 | { FALSE, "20180803T140805.446178377+0160", 0, 0, 0, 0, 0, 0, 0, 0 }, |
916 | { TRUE, "+1980-02-22T12:36:00+02:00", 1980, 2, 22, 12, 36, 0, 0, 2 * G_TIME_SPAN_HOUR }, |
917 | { TRUE, "1990-11-01T10:21:17 ", 1990, 11, 1, 10, 21, 17, 0, 0 }, |
918 | */ |
919 | { FALSE, "1719W462 407777-07" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
920 | { FALSE, "4011090 260528Z" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
921 | { FALSE, "0000W011 228214-22" , 0, 0, 0, 0, 0, 0, 0, 0 }, |
922 | }; |
923 | GTimeZone *tz = NULL; |
924 | GDateTime *dt = NULL; |
925 | gsize i; |
926 | |
927 | g_test_summary (summary: "Further parser tests for g_date_time_new_from_iso8601(), " |
928 | "checking success and failure using test vectors." ); |
929 | |
930 | tz = g_time_zone_new_utc (); |
931 | |
932 | for (i = 0; i < G_N_ELEMENTS (tests); i++) |
933 | { |
934 | g_test_message (format: "Vector %" G_GSIZE_FORMAT ": %s" , i, tests[i].in); |
935 | |
936 | dt = g_date_time_new_from_iso8601 (text: tests[i].in, default_tz: tz); |
937 | if (tests[i].success) |
938 | { |
939 | g_assert_nonnull (dt); |
940 | ASSERT_DATE (dt, tests[i].year, tests[i].month, tests[i].day); |
941 | ASSERT_TIME (dt, tests[i].hour, tests[i].minute, tests[i].second, tests[i].microsecond); |
942 | g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, tests[i].utc_offset); |
943 | } |
944 | else |
945 | { |
946 | g_assert_null (dt); |
947 | } |
948 | |
949 | g_clear_pointer (&dt, g_date_time_unref); |
950 | } |
951 | |
952 | g_time_zone_unref (tz); |
953 | } |
954 | |
955 | static void |
956 | test_GDateTime_to_unix (void) |
957 | { |
958 | GDateTime *dt; |
959 | time_t t; |
960 | |
961 | t = time (NULL); |
962 | g_assert_cmpint (t, !=, (time_t) -1); |
963 | dt = g_date_time_new_from_unix_local (t); |
964 | g_assert_cmpint (g_date_time_to_unix (dt), ==, t); |
965 | g_date_time_unref (datetime: dt); |
966 | } |
967 | |
968 | static void |
969 | test_GDateTime_add_years (void) |
970 | { |
971 | GDateTime *dt, *dt2; |
972 | |
973 | dt = g_date_time_new_local (year: 2009, month: 10, day: 19, hour: 0, minute: 0, seconds: 0); |
974 | dt2 = g_date_time_add_years (datetime: dt, years: 1); |
975 | g_assert_cmpint (2010, ==, g_date_time_get_year (dt2)); |
976 | g_date_time_unref (datetime: dt); |
977 | g_date_time_unref (datetime: dt2); |
978 | } |
979 | |
980 | static void |
981 | test_GDateTime_add_months (void) |
982 | { |
983 | #define TEST_ADD_MONTHS(y,m,d,a,ny,nm,nd) G_STMT_START { \ |
984 | GDateTime *dt, *dt2; \ |
985 | dt = g_date_time_new_utc (y, m, d, 0, 0, 0); \ |
986 | dt2 = g_date_time_add_months (dt, a); \ |
987 | ASSERT_DATE (dt2, ny, nm, nd); \ |
988 | g_date_time_unref (dt); \ |
989 | g_date_time_unref (dt2); \ |
990 | } G_STMT_END |
991 | |
992 | TEST_ADD_MONTHS (2009, 12, 31, 1, 2010, 1, 31); |
993 | TEST_ADD_MONTHS (2009, 12, 31, 1, 2010, 1, 31); |
994 | TEST_ADD_MONTHS (2009, 6, 15, 1, 2009, 7, 15); |
995 | TEST_ADD_MONTHS (1400, 3, 1, 1, 1400, 4, 1); |
996 | TEST_ADD_MONTHS (1400, 1, 31, 1, 1400, 2, 28); |
997 | TEST_ADD_MONTHS (1400, 1, 31, 7200, 2000, 1, 31); |
998 | TEST_ADD_MONTHS (2008, 2, 29, 12, 2009, 2, 28); |
999 | TEST_ADD_MONTHS (2000, 8, 16, -5, 2000, 3, 16); |
1000 | TEST_ADD_MONTHS (2000, 8, 16, -12, 1999, 8, 16); |
1001 | TEST_ADD_MONTHS (2011, 2, 1, -13, 2010, 1, 1); |
1002 | TEST_ADD_MONTHS (1776, 7, 4, 1200, 1876, 7, 4); |
1003 | } |
1004 | |
1005 | static void |
1006 | test_GDateTime_add_days (void) |
1007 | { |
1008 | #define TEST_ADD_DAYS(y,m,d,a,ny,nm,nd) G_STMT_START { \ |
1009 | GDateTime *dt, *dt2; \ |
1010 | dt = g_date_time_new_local (y, m, d, 0, 0, 0); \ |
1011 | dt2 = g_date_time_add_days (dt, a); \ |
1012 | g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ |
1013 | g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ |
1014 | g_assert_cmpint (nd, ==, g_date_time_get_day_of_month (dt2)); \ |
1015 | g_date_time_unref (dt); \ |
1016 | g_date_time_unref (dt2); \ |
1017 | } G_STMT_END |
1018 | |
1019 | TEST_ADD_DAYS (2009, 1, 31, 1, 2009, 2, 1); |
1020 | TEST_ADD_DAYS (2009, 2, 1, -1, 2009, 1, 31); |
1021 | TEST_ADD_DAYS (2008, 2, 28, 1, 2008, 2, 29); |
1022 | TEST_ADD_DAYS (2008, 12, 31, 1, 2009, 1, 1); |
1023 | TEST_ADD_DAYS (1, 1, 1, 1, 1, 1, 2); |
1024 | TEST_ADD_DAYS (1955, 5, 24, 10, 1955, 6, 3); |
1025 | TEST_ADD_DAYS (1955, 5, 24, -10, 1955, 5, 14); |
1026 | } |
1027 | |
1028 | static void |
1029 | test_GDateTime_add_weeks (void) |
1030 | { |
1031 | #define TEST_ADD_WEEKS(y,m,d,a,ny,nm,nd) G_STMT_START { \ |
1032 | GDateTime *dt, *dt2; \ |
1033 | dt = g_date_time_new_local (y, m, d, 0, 0, 0); \ |
1034 | dt2 = g_date_time_add_weeks (dt, a); \ |
1035 | g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ |
1036 | g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ |
1037 | g_assert_cmpint (nd, ==, g_date_time_get_day_of_month (dt2)); \ |
1038 | g_date_time_unref (dt); \ |
1039 | g_date_time_unref (dt2); \ |
1040 | } G_STMT_END |
1041 | |
1042 | TEST_ADD_WEEKS (2009, 1, 1, 1, 2009, 1, 8); |
1043 | TEST_ADD_WEEKS (2009, 8, 30, 1, 2009, 9, 6); |
1044 | TEST_ADD_WEEKS (2009, 12, 31, 1, 2010, 1, 7); |
1045 | TEST_ADD_WEEKS (2009, 1, 1, -1, 2008, 12, 25); |
1046 | } |
1047 | |
1048 | static void |
1049 | test_GDateTime_add_hours (void) |
1050 | { |
1051 | #define TEST_ADD_HOURS(y,m,d,h,mi,s,a,ny,nm,nd,nh,nmi,ns) G_STMT_START { \ |
1052 | GDateTime *dt, *dt2; \ |
1053 | dt = g_date_time_new_utc (y, m, d, h, mi, s); \ |
1054 | dt2 = g_date_time_add_hours (dt, a); \ |
1055 | g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ |
1056 | g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ |
1057 | g_assert_cmpint (nd, ==, g_date_time_get_day_of_month (dt2)); \ |
1058 | g_assert_cmpint (nh, ==, g_date_time_get_hour (dt2)); \ |
1059 | g_assert_cmpint (nmi, ==, g_date_time_get_minute (dt2)); \ |
1060 | g_assert_cmpint (ns, ==, g_date_time_get_second (dt2)); \ |
1061 | g_date_time_unref (dt); \ |
1062 | g_date_time_unref (dt2); \ |
1063 | } G_STMT_END |
1064 | |
1065 | TEST_ADD_HOURS (2009, 1, 1, 0, 0, 0, 1, 2009, 1, 1, 1, 0, 0); |
1066 | TEST_ADD_HOURS (2008, 12, 31, 23, 0, 0, 1, 2009, 1, 1, 0, 0, 0); |
1067 | } |
1068 | |
1069 | static void |
1070 | test_GDateTime_add_full (void) |
1071 | { |
1072 | #define TEST_ADD_FULL(y,m,d,h,mi,s,ay,am,ad,ah,ami,as,ny,nm,nd,nh,nmi,ns) G_STMT_START { \ |
1073 | GDateTime *dt, *dt2; \ |
1074 | dt = g_date_time_new_utc (y, m, d, h, mi, s); \ |
1075 | dt2 = g_date_time_add_full (dt, ay, am, ad, ah, ami, as); \ |
1076 | g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ |
1077 | g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ |
1078 | g_assert_cmpint (nd, ==, g_date_time_get_day_of_month (dt2)); \ |
1079 | g_assert_cmpint (nh, ==, g_date_time_get_hour (dt2)); \ |
1080 | g_assert_cmpint (nmi, ==, g_date_time_get_minute (dt2)); \ |
1081 | g_assert_cmpint (ns, ==, g_date_time_get_second (dt2)); \ |
1082 | g_date_time_unref (dt); \ |
1083 | g_date_time_unref (dt2); \ |
1084 | } G_STMT_END |
1085 | |
1086 | TEST_ADD_FULL (2009, 10, 21, 0, 0, 0, |
1087 | 1, 1, 1, 1, 1, 1, |
1088 | 2010, 11, 22, 1, 1, 1); |
1089 | TEST_ADD_FULL (2000, 1, 1, 1, 1, 1, |
1090 | 0, 1, 0, 0, 0, 0, |
1091 | 2000, 2, 1, 1, 1, 1); |
1092 | TEST_ADD_FULL (2000, 1, 1, 0, 0, 0, |
1093 | -1, 1, 0, 0, 0, 0, |
1094 | 1999, 2, 1, 0, 0, 0); |
1095 | TEST_ADD_FULL (2010, 10, 31, 0, 0, 0, |
1096 | 0, 4, 0, 0, 0, 0, |
1097 | 2011, 2, 28, 0, 0, 0); |
1098 | TEST_ADD_FULL (2010, 8, 25, 22, 45, 0, |
1099 | 0, 1, 6, 1, 25, 0, |
1100 | 2010, 10, 2, 0, 10, 0); |
1101 | } |
1102 | |
1103 | static void |
1104 | test_GDateTime_add_minutes (void) |
1105 | { |
1106 | #define TEST_ADD_MINUTES(i,o) G_STMT_START { \ |
1107 | GDateTime *dt, *dt2; \ |
1108 | dt = g_date_time_new_local (2000, 1, 1, 0, 0, 0); \ |
1109 | dt2 = g_date_time_add_minutes (dt, i); \ |
1110 | g_assert_cmpint (o, ==, g_date_time_get_minute (dt2)); \ |
1111 | g_date_time_unref (dt); \ |
1112 | g_date_time_unref (dt2); \ |
1113 | } G_STMT_END |
1114 | |
1115 | TEST_ADD_MINUTES (60, 0); |
1116 | TEST_ADD_MINUTES (100, 40); |
1117 | TEST_ADD_MINUTES (5, 5); |
1118 | TEST_ADD_MINUTES (1441, 1); |
1119 | TEST_ADD_MINUTES (-1441, 59); |
1120 | } |
1121 | |
1122 | static void |
1123 | test_GDateTime_add_seconds (void) |
1124 | { |
1125 | #define TEST_ADD_SECONDS(i,o) G_STMT_START { \ |
1126 | GDateTime *dt, *dt2; \ |
1127 | dt = g_date_time_new_local (2000, 1, 1, 0, 0, 0); \ |
1128 | dt2 = g_date_time_add_seconds (dt, i); \ |
1129 | g_assert_cmpint (o, ==, g_date_time_get_second (dt2)); \ |
1130 | g_date_time_unref (dt); \ |
1131 | g_date_time_unref (dt2); \ |
1132 | } G_STMT_END |
1133 | |
1134 | TEST_ADD_SECONDS (1, 1); |
1135 | TEST_ADD_SECONDS (60, 0); |
1136 | TEST_ADD_SECONDS (61, 1); |
1137 | TEST_ADD_SECONDS (120, 0); |
1138 | TEST_ADD_SECONDS (-61, 59); |
1139 | TEST_ADD_SECONDS (86401, 1); |
1140 | TEST_ADD_SECONDS (-86401, 59); |
1141 | TEST_ADD_SECONDS (-31, 29); |
1142 | TEST_ADD_SECONDS (13, 13); |
1143 | } |
1144 | |
1145 | static void |
1146 | test_GDateTime_diff (void) |
1147 | { |
1148 | #define TEST_DIFF(y,m,d,y2,m2,d2,u) G_STMT_START { \ |
1149 | GDateTime *dt1, *dt2; \ |
1150 | GTimeSpan ts = 0; \ |
1151 | dt1 = g_date_time_new_utc (y, m, d, 0, 0, 0); \ |
1152 | dt2 = g_date_time_new_utc (y2, m2, d2, 0, 0, 0); \ |
1153 | ts = g_date_time_difference (dt2, dt1); \ |
1154 | g_assert_cmpint (ts, ==, u); \ |
1155 | g_date_time_unref (dt1); \ |
1156 | g_date_time_unref (dt2); \ |
1157 | } G_STMT_END |
1158 | |
1159 | TEST_DIFF (2009, 1, 1, 2009, 2, 1, G_TIME_SPAN_DAY * 31); |
1160 | TEST_DIFF (2009, 1, 1, 2010, 1, 1, G_TIME_SPAN_DAY * 365); |
1161 | TEST_DIFF (2008, 2, 28, 2008, 2, 29, G_TIME_SPAN_DAY); |
1162 | TEST_DIFF (2008, 2, 29, 2008, 2, 28, -G_TIME_SPAN_DAY); |
1163 | |
1164 | /* TODO: Add usec tests */ |
1165 | } |
1166 | |
1167 | static void |
1168 | test_GDateTime_get_minute (void) |
1169 | { |
1170 | GDateTime *dt; |
1171 | |
1172 | dt = g_date_time_new_utc (year: 2009, month: 12, day: 1, hour: 1, minute: 31, seconds: 0); |
1173 | g_assert_cmpint (31, ==, g_date_time_get_minute (dt)); |
1174 | g_date_time_unref (datetime: dt); |
1175 | } |
1176 | |
1177 | static void |
1178 | test_GDateTime_get_month (void) |
1179 | { |
1180 | GDateTime *dt; |
1181 | |
1182 | dt = g_date_time_new_utc (year: 2009, month: 12, day: 1, hour: 1, minute: 31, seconds: 0); |
1183 | g_assert_cmpint (12, ==, g_date_time_get_month (dt)); |
1184 | g_date_time_unref (datetime: dt); |
1185 | } |
1186 | |
1187 | static void |
1188 | test_GDateTime_get_second (void) |
1189 | { |
1190 | GDateTime *dt; |
1191 | |
1192 | dt = g_date_time_new_utc (year: 2009, month: 12, day: 1, hour: 1, minute: 31, seconds: 44); |
1193 | g_assert_cmpint (44, ==, g_date_time_get_second (dt)); |
1194 | g_date_time_unref (datetime: dt); |
1195 | } |
1196 | |
1197 | static void |
1198 | test_GDateTime_new_full (void) |
1199 | { |
1200 | GTimeZone *tz, *dt_tz; |
1201 | GDateTime *dt; |
1202 | |
1203 | #ifdef G_OS_WIN32 |
1204 | LCID currLcid = GetThreadLocale (); |
1205 | LANGID currLangId = LANGIDFROMLCID (currLcid); |
1206 | LANGID en = MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US); |
1207 | SetThreadUILanguage (en); |
1208 | #endif |
1209 | |
1210 | dt = g_date_time_new_utc (year: 2009, month: 12, day: 11, hour: 12, minute: 11, seconds: 10); |
1211 | g_assert_cmpint (2009, ==, g_date_time_get_year (dt)); |
1212 | g_assert_cmpint (12, ==, g_date_time_get_month (dt)); |
1213 | g_assert_cmpint (11, ==, g_date_time_get_day_of_month (dt)); |
1214 | g_assert_cmpint (12, ==, g_date_time_get_hour (dt)); |
1215 | g_assert_cmpint (11, ==, g_date_time_get_minute (dt)); |
1216 | g_assert_cmpint (10, ==, g_date_time_get_second (dt)); |
1217 | g_date_time_unref (datetime: dt); |
1218 | |
1219 | #ifdef G_OS_UNIX |
1220 | tz = g_time_zone_new_identifier (identifier: "America/Tijuana" ); |
1221 | #elif defined G_OS_WIN32 |
1222 | tz = g_time_zone_new_identifier ("Pacific Standard Time" ); |
1223 | #endif |
1224 | g_assert_nonnull (tz); |
1225 | dt = g_date_time_new (tz, year: 2010, month: 11, day: 24, hour: 8, minute: 4, seconds: 0); |
1226 | |
1227 | dt_tz = g_date_time_get_timezone (datetime: dt); |
1228 | g_assert_cmpstr (g_time_zone_get_identifier (dt_tz), ==, |
1229 | g_time_zone_get_identifier (tz)); |
1230 | |
1231 | g_assert_cmpint (2010, ==, g_date_time_get_year (dt)); |
1232 | g_assert_cmpint (11, ==, g_date_time_get_month (dt)); |
1233 | g_assert_cmpint (24, ==, g_date_time_get_day_of_month (dt)); |
1234 | g_assert_cmpint (8, ==, g_date_time_get_hour (dt)); |
1235 | g_assert_cmpint (4, ==, g_date_time_get_minute (dt)); |
1236 | g_assert_cmpint (0, ==, g_date_time_get_second (dt)); |
1237 | #ifdef G_OS_UNIX |
1238 | g_assert_cmpstr ("PST" , ==, g_date_time_get_timezone_abbreviation (dt)); |
1239 | g_assert_cmpstr ("America/Tijuana" , ==, g_time_zone_get_identifier (dt_tz)); |
1240 | #elif defined G_OS_WIN32 |
1241 | g_assert_cmpstr ("Pacific Standard Time" , ==, |
1242 | g_date_time_get_timezone_abbreviation (dt)); |
1243 | g_assert_cmpstr ("Pacific Standard Time" , ==, |
1244 | g_time_zone_get_identifier (dt_tz)); |
1245 | SetThreadUILanguage (currLangId); |
1246 | #endif |
1247 | g_assert (!g_date_time_is_daylight_savings (dt)); |
1248 | g_date_time_unref (datetime: dt); |
1249 | g_time_zone_unref (tz); |
1250 | |
1251 | /* Check month limits */ |
1252 | dt = g_date_time_new_utc (year: 2016, month: 1, day: 31, hour: 22, minute: 10, seconds: 42); |
1253 | ASSERT_DATE (dt, 2016, 1, 31); |
1254 | g_date_time_unref (datetime: dt); |
1255 | dt = g_date_time_new_utc (year: 2016, month: 1, day: 32, hour: 22, minute: 10, seconds: 42); |
1256 | g_assert_null (dt); |
1257 | dt = g_date_time_new_utc (year: 2016, month: 2, day: 29, hour: 22, minute: 10, seconds: 42); |
1258 | ASSERT_DATE (dt, 2016, 2, 29); |
1259 | g_date_time_unref (datetime: dt); |
1260 | dt = g_date_time_new_utc (year: 2016, month: 2, day: 30, hour: 22, minute: 10, seconds: 42); |
1261 | g_assert_null (dt); |
1262 | dt = g_date_time_new_utc (year: 2017, month: 2, day: 28, hour: 22, minute: 10, seconds: 42); |
1263 | ASSERT_DATE (dt, 2017, 2, 28); |
1264 | g_date_time_unref (datetime: dt); |
1265 | dt = g_date_time_new_utc (year: 2017, month: 2, day: 29, hour: 22, minute: 10, seconds: 42); |
1266 | g_assert_null (dt); |
1267 | dt = g_date_time_new_utc (year: 2016, month: 3, day: 31, hour: 22, minute: 10, seconds: 42); |
1268 | ASSERT_DATE (dt, 2016, 3, 31); |
1269 | g_date_time_unref (datetime: dt); |
1270 | dt = g_date_time_new_utc (year: 2016, month: 3, day: 32, hour: 22, minute: 10, seconds: 42); |
1271 | g_assert_null (dt); |
1272 | dt = g_date_time_new_utc (year: 2016, month: 4, day: 30, hour: 22, minute: 10, seconds: 42); |
1273 | ASSERT_DATE (dt, 2016, 4, 30); |
1274 | g_date_time_unref (datetime: dt); |
1275 | dt = g_date_time_new_utc (year: 2016, month: 4, day: 31, hour: 22, minute: 10, seconds: 42); |
1276 | g_assert_null (dt); |
1277 | dt = g_date_time_new_utc (year: 2016, month: 5, day: 31, hour: 22, minute: 10, seconds: 42); |
1278 | ASSERT_DATE (dt, 2016, 5, 31); |
1279 | g_date_time_unref (datetime: dt); |
1280 | dt = g_date_time_new_utc (year: 2016, month: 5, day: 32, hour: 22, minute: 10, seconds: 42); |
1281 | g_assert_null (dt); |
1282 | dt = g_date_time_new_utc (year: 2016, month: 6, day: 30, hour: 22, minute: 10, seconds: 42); |
1283 | ASSERT_DATE (dt, 2016, 6, 30); |
1284 | g_date_time_unref (datetime: dt); |
1285 | dt = g_date_time_new_utc (year: 2016, month: 6, day: 31, hour: 22, minute: 10, seconds: 42); |
1286 | g_assert_null (dt); |
1287 | dt = g_date_time_new_utc (year: 2016, month: 7, day: 31, hour: 22, minute: 10, seconds: 42); |
1288 | ASSERT_DATE (dt, 2016, 7, 31); |
1289 | g_date_time_unref (datetime: dt); |
1290 | dt = g_date_time_new_utc (year: 2016, month: 7, day: 32, hour: 22, minute: 10, seconds: 42); |
1291 | g_assert_null (dt); |
1292 | dt = g_date_time_new_utc (year: 2016, month: 8, day: 31, hour: 22, minute: 10, seconds: 42); |
1293 | ASSERT_DATE (dt, 2016, 8, 31); |
1294 | g_date_time_unref (datetime: dt); |
1295 | dt = g_date_time_new_utc (year: 2016, month: 8, day: 32, hour: 22, minute: 10, seconds: 42); |
1296 | g_assert_null (dt); |
1297 | dt = g_date_time_new_utc (year: 2016, month: 9, day: 30, hour: 22, minute: 10, seconds: 42); |
1298 | ASSERT_DATE (dt, 2016, 9, 30); |
1299 | g_date_time_unref (datetime: dt); |
1300 | dt = g_date_time_new_utc (year: 2016, month: 9, day: 31, hour: 22, minute: 10, seconds: 42); |
1301 | g_assert_null (dt); |
1302 | dt = g_date_time_new_utc (year: 2016, month: 10, day: 31, hour: 22, minute: 10, seconds: 42); |
1303 | ASSERT_DATE (dt, 2016, 10, 31); |
1304 | g_date_time_unref (datetime: dt); |
1305 | dt = g_date_time_new_utc (year: 2016, month: 10, day: 32, hour: 22, minute: 10, seconds: 42); |
1306 | g_assert_null (dt); |
1307 | dt = g_date_time_new_utc (year: 2016, month: 11, day: 30, hour: 22, minute: 10, seconds: 42); |
1308 | ASSERT_DATE (dt, 2016, 11, 30); |
1309 | g_date_time_unref (datetime: dt); |
1310 | dt = g_date_time_new_utc (year: 2016, month: 11, day: 31, hour: 22, minute: 10, seconds: 42); |
1311 | g_assert_null (dt); |
1312 | dt = g_date_time_new_utc (year: 2016, month: 12, day: 31, hour: 22, minute: 10, seconds: 42); |
1313 | ASSERT_DATE (dt, 2016, 12, 31); |
1314 | g_date_time_unref (datetime: dt); |
1315 | dt = g_date_time_new_utc (year: 2016, month: 12, day: 32, hour: 22, minute: 10, seconds: 42); |
1316 | g_assert_null (dt); |
1317 | |
1318 | /* Seconds limits. */ |
1319 | dt = g_date_time_new_utc (year: 2020, month: 12, day: 9, hour: 14, minute: 49, NAN); |
1320 | g_assert_null (dt); |
1321 | dt = g_date_time_new_utc (year: 2020, month: 12, day: 9, hour: 14, minute: 49, seconds: -0.1); |
1322 | g_assert_null (dt); |
1323 | dt = g_date_time_new_utc (year: 2020, month: 12, day: 9, hour: 14, minute: 49, seconds: 60.0); |
1324 | g_assert_null (dt); |
1325 | |
1326 | /* Year limits */ |
1327 | dt = g_date_time_new_utc (year: 10000, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
1328 | dt = g_date_time_new_utc (year: 0, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
1329 | } |
1330 | |
1331 | static void |
1332 | test_GDateTime_now_utc (void) |
1333 | { |
1334 | GDateTime *dt; |
1335 | struct tm tm; |
1336 | time_t t; |
1337 | time_t after; |
1338 | |
1339 | /* t <= dt.to_unix() <= after, but the inequalities might not be |
1340 | * equality if we're close to the boundary between seconds. |
1341 | * We loop until t == after (and hence dt.to_unix() should equal both) |
1342 | * to guard against that. */ |
1343 | do |
1344 | { |
1345 | t = g_get_real_time () / G_TIME_SPAN_SECOND; |
1346 | #ifdef HAVE_GMTIME_R |
1347 | gmtime_r (timer: &t, tp: &tm); |
1348 | #else |
1349 | { |
1350 | struct tm *tmp = gmtime (&t); |
1351 | /* Assume gmtime() can't fail as we got t from time(NULL). (Note |
1352 | * that on Windows, gmtime() *is* MT-safe, it uses a thread-local |
1353 | * buffer.) |
1354 | */ |
1355 | memcpy (&tm, tmp, sizeof (struct tm)); |
1356 | } |
1357 | #endif |
1358 | dt = g_date_time_new_now_utc (); |
1359 | |
1360 | after = g_get_real_time () / G_TIME_SPAN_SECOND; |
1361 | } |
1362 | while (t != after); |
1363 | |
1364 | g_assert_cmpint (tm.tm_year + 1900, ==, g_date_time_get_year (dt)); |
1365 | g_assert_cmpint (tm.tm_mon + 1, ==, g_date_time_get_month (dt)); |
1366 | g_assert_cmpint (tm.tm_mday, ==, g_date_time_get_day_of_month (dt)); |
1367 | g_assert_cmpint (tm.tm_hour, ==, g_date_time_get_hour (dt)); |
1368 | g_assert_cmpint (tm.tm_min, ==, g_date_time_get_minute (dt)); |
1369 | g_assert_cmpint (tm.tm_sec, ==, g_date_time_get_second (dt)); |
1370 | g_date_time_unref (datetime: dt); |
1371 | } |
1372 | |
1373 | static void |
1374 | test_GDateTime_new_from_unix_utc (void) |
1375 | { |
1376 | GDateTime *dt; |
1377 | gint64 t; |
1378 | |
1379 | t = g_get_real_time (); |
1380 | |
1381 | #if 0 |
1382 | dt = g_date_time_new_from_unix_utc (t); |
1383 | g_assert (dt == NULL); |
1384 | #endif |
1385 | |
1386 | t = t / 1e6; /* oops, this was microseconds */ |
1387 | |
1388 | dt = g_date_time_new_from_unix_utc (t); |
1389 | g_assert (dt != NULL); |
1390 | |
1391 | g_assert (dt == g_date_time_ref (dt)); |
1392 | g_date_time_unref (datetime: dt); |
1393 | g_assert_cmpint (g_date_time_to_unix (dt), ==, t); |
1394 | g_date_time_unref (datetime: dt); |
1395 | } |
1396 | |
1397 | static void |
1398 | test_GDateTime_get_utc_offset (void) |
1399 | { |
1400 | #if defined (HAVE_STRUCT_TM_TM_GMTOFF) || defined (HAVE_STRUCT_TM___TM_GMTOFF) |
1401 | GDateTime *dt; |
1402 | GTimeSpan ts; |
1403 | struct tm tm; |
1404 | |
1405 | memset (s: &tm, c: 0, n: sizeof (tm)); |
1406 | get_localtime_tm (time_: g_get_real_time () / G_TIME_SPAN_SECOND, retval: &tm); |
1407 | |
1408 | dt = g_date_time_new_now_local (); |
1409 | ts = g_date_time_get_utc_offset (datetime: dt); |
1410 | #ifdef HAVE_STRUCT_TM_TM_GMTOFF |
1411 | g_assert_cmpint (ts, ==, (tm.tm_gmtoff * G_TIME_SPAN_SECOND)); |
1412 | #endif |
1413 | #ifdef HAVE_STRUCT_TM___TM_GMTOFF |
1414 | g_assert_cmpint (ts, ==, (tm.__tm_gmtoff * G_TIME_SPAN_SECOND)); |
1415 | #endif |
1416 | g_date_time_unref (datetime: dt); |
1417 | #endif |
1418 | } |
1419 | |
1420 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
1421 | static void |
1422 | test_GDateTime_to_timeval (void) |
1423 | { |
1424 | GTimeVal tv1, tv2; |
1425 | GDateTime *dt; |
1426 | |
1427 | memset (s: &tv1, c: 0, n: sizeof (tv1)); |
1428 | memset (s: &tv2, c: 0, n: sizeof (tv2)); |
1429 | |
1430 | g_get_current_time (result: &tv1); |
1431 | dt = g_date_time_new_from_timeval_local (tv: &tv1); |
1432 | g_date_time_to_timeval (datetime: dt, tv: &tv2); |
1433 | g_assert_cmpint (tv1.tv_sec, ==, tv2.tv_sec); |
1434 | g_assert_cmpint (tv1.tv_usec, ==, tv2.tv_usec); |
1435 | g_date_time_unref (datetime: dt); |
1436 | } |
1437 | G_GNUC_END_IGNORE_DEPRECATIONS |
1438 | |
1439 | static void |
1440 | test_GDateTime_to_local (void) |
1441 | { |
1442 | GDateTime *utc = NULL, *now = NULL, *dt; |
1443 | time_t before, after; |
1444 | |
1445 | /* before <= utc.to_unix() <= now.to_unix() <= after, but the inequalities |
1446 | * might not be equality if we're close to the boundary between seconds. |
1447 | * We loop until before == after (and hence the GDateTimes should match) |
1448 | * to guard against that. */ |
1449 | do |
1450 | { |
1451 | before = g_get_real_time () / G_TIME_SPAN_SECOND; |
1452 | g_clear_pointer (&utc, g_date_time_unref); |
1453 | g_clear_pointer (&now, g_date_time_unref); |
1454 | utc = g_date_time_new_now_utc (); |
1455 | now = g_date_time_new_now_local (); |
1456 | after = g_get_real_time () / G_TIME_SPAN_SECOND; |
1457 | } |
1458 | while (before != after); |
1459 | |
1460 | dt = g_date_time_to_local (datetime: utc); |
1461 | |
1462 | g_assert_cmpint (g_date_time_get_year (now), ==, g_date_time_get_year (dt)); |
1463 | g_assert_cmpint (g_date_time_get_month (now), ==, g_date_time_get_month (dt)); |
1464 | g_assert_cmpint (g_date_time_get_day_of_month (now), ==, g_date_time_get_day_of_month (dt)); |
1465 | g_assert_cmpint (g_date_time_get_hour (now), ==, g_date_time_get_hour (dt)); |
1466 | g_assert_cmpint (g_date_time_get_minute (now), ==, g_date_time_get_minute (dt)); |
1467 | g_assert_cmpint (g_date_time_get_second (now), ==, g_date_time_get_second (dt)); |
1468 | |
1469 | g_date_time_unref (datetime: now); |
1470 | g_date_time_unref (datetime: utc); |
1471 | g_date_time_unref (datetime: dt); |
1472 | } |
1473 | |
1474 | static void |
1475 | test_GDateTime_to_utc (void) |
1476 | { |
1477 | GDateTime *dt, *dt2; |
1478 | time_t t; |
1479 | struct tm tm; |
1480 | |
1481 | t = time (NULL); |
1482 | g_assert_cmpint (t, !=, (time_t) -1); |
1483 | #ifdef HAVE_GMTIME_R |
1484 | gmtime_r (timer: &t, tp: &tm); |
1485 | #else |
1486 | { |
1487 | struct tm *tmp = gmtime (&t); |
1488 | memcpy (&tm, tmp, sizeof (struct tm)); |
1489 | } |
1490 | #endif |
1491 | dt2 = g_date_time_new_from_unix_local (t); |
1492 | dt = g_date_time_to_utc (datetime: dt2); |
1493 | g_assert_cmpint (tm.tm_year + 1900, ==, g_date_time_get_year (dt)); |
1494 | g_assert_cmpint (tm.tm_mon + 1, ==, g_date_time_get_month (dt)); |
1495 | g_assert_cmpint (tm.tm_mday, ==, g_date_time_get_day_of_month (dt)); |
1496 | g_assert_cmpint (tm.tm_hour, ==, g_date_time_get_hour (dt)); |
1497 | g_assert_cmpint (tm.tm_min, ==, g_date_time_get_minute (dt)); |
1498 | g_assert_cmpint (tm.tm_sec, ==, g_date_time_get_second (dt)); |
1499 | g_date_time_unref (datetime: dt); |
1500 | g_date_time_unref (datetime: dt2); |
1501 | } |
1502 | |
1503 | static void |
1504 | test_GDateTime_get_day_of_year (void) |
1505 | { |
1506 | #define TEST_DAY_OF_YEAR(y,m,d,o) G_STMT_START { \ |
1507 | GDateTime *__dt = g_date_time_new_local ((y), (m), (d), 0, 0, 0); \ |
1508 | g_assert_cmpint ((o), ==, g_date_time_get_day_of_year (__dt)); \ |
1509 | g_date_time_unref (__dt); } G_STMT_END |
1510 | |
1511 | TEST_DAY_OF_YEAR (2009, 1, 1, 1); |
1512 | TEST_DAY_OF_YEAR (2009, 2, 1, 32); |
1513 | TEST_DAY_OF_YEAR (2009, 8, 16, 228); |
1514 | TEST_DAY_OF_YEAR (2008, 8, 16, 229); |
1515 | } |
1516 | |
1517 | static void |
1518 | test_GDateTime_printf (void) |
1519 | { |
1520 | /* 64 seems big, but one zoneinfo file, Factory, has an abbreviation |
1521 | * that long, and it will cause the test to fail if dst isn't big |
1522 | * enough. |
1523 | */ |
1524 | gchar *old_lc_all; |
1525 | gchar *old_lc_messages; |
1526 | gchar dst[64]; |
1527 | struct tm tt; |
1528 | time_t t; |
1529 | |
1530 | #ifdef G_OS_WIN32 |
1531 | gchar *current_tz = NULL; |
1532 | DYNAMIC_TIME_ZONE_INFORMATION dtz_info; |
1533 | #endif |
1534 | |
1535 | #define TEST_PRINTF(f,o) G_STMT_START { \ |
1536 | GDateTime *__dt = g_date_time_new_local (2009, 10, 24, 0, 0, 0);\ |
1537 | gchar *__p = g_date_time_format (__dt, (f)); \ |
1538 | g_assert_cmpstr (__p, ==, (o)); \ |
1539 | g_date_time_unref (__dt); \ |
1540 | g_free (__p); } G_STMT_END |
1541 | |
1542 | #define TEST_PRINTF_DATE(y,m,d,f,o) G_STMT_START { \ |
1543 | GDateTime *dt = g_date_time_new_local (y, m, d, 0, 0, 0); \ |
1544 | gchar *p = g_date_time_format (dt, (f)); \ |
1545 | gchar *o_casefold = g_utf8_casefold (o, -1); \ |
1546 | gchar *p_casefold = g_utf8_casefold (p, -1); \ |
1547 | g_assert_cmpstr (p_casefold, ==, (o_casefold)); \ |
1548 | g_date_time_unref (dt); \ |
1549 | g_free (p_casefold); \ |
1550 | g_free (o_casefold); \ |
1551 | g_free (p); } G_STMT_END |
1552 | |
1553 | #define TEST_PRINTF_TIME(h,m,s,f,o) G_STMT_START { \ |
1554 | GDateTime *dt = g_date_time_new_local (2009, 10, 24, (h), (m), (s)); \ |
1555 | gchar *p = g_date_time_format (dt, (f)); \ |
1556 | g_assert_cmpstr (p, ==, (o)); \ |
1557 | g_date_time_unref (dt); \ |
1558 | g_free (p); } G_STMT_END |
1559 | |
1560 | old_lc_all = g_strdup (str: g_getenv (variable: "LC_ALL" )); |
1561 | g_unsetenv (variable: "LC_ALL" ); |
1562 | |
1563 | old_lc_messages = g_strdup (str: g_getenv (variable: "LC_MESSAGES" )); |
1564 | g_setenv (variable: "LC_MESSAGES" , value: "C" , TRUE); |
1565 | |
1566 | /* |
1567 | * This is a little helper to make sure we can compare timezones to |
1568 | * that of the generated timezone. |
1569 | */ |
1570 | t = time (NULL); |
1571 | g_assert_cmpint (t, !=, (time_t) -1); |
1572 | memset (s: &tt, c: 0, n: sizeof(tt)); |
1573 | get_localtime_tm (time_: t, retval: &tt); |
1574 | tt.tm_year = 2009 - 1900; |
1575 | tt.tm_mon = 9; /* 0 indexed */ |
1576 | tt.tm_mday = 24; |
1577 | t = mktime (tp: &tt); |
1578 | memset (s: &tt, c: 0, n: sizeof(tt)); |
1579 | get_localtime_tm (time_: t, retval: &tt); |
1580 | strftime (s: dst, maxsize: sizeof(dst), format: "%Z" , tp: &tt); |
1581 | |
1582 | TEST_PRINTF ("%a" , "Sat" ); |
1583 | TEST_PRINTF ("%A" , "Saturday" ); |
1584 | TEST_PRINTF ("%b" , "Oct" ); |
1585 | TEST_PRINTF ("%B" , "October" ); |
1586 | TEST_PRINTF ("%d" , "24" ); |
1587 | TEST_PRINTF_DATE (2009, 1, 1, "%d" , "01" ); |
1588 | TEST_PRINTF ("%e" , "24" ); // fixme |
1589 | TEST_PRINTF_TIME (10, 10, 1.001, "%f" , "001000" ); |
1590 | TEST_PRINTF ("%h" , "Oct" ); |
1591 | TEST_PRINTF ("%H" , "00" ); |
1592 | TEST_PRINTF_TIME (15, 0, 0, "%H" , "15" ); |
1593 | TEST_PRINTF ("%I" , "12" ); |
1594 | TEST_PRINTF_TIME (12, 0, 0, "%I" , "12" ); |
1595 | TEST_PRINTF_TIME (15, 0, 0, "%I" , "03" ); |
1596 | TEST_PRINTF ("%j" , "297" ); |
1597 | TEST_PRINTF ("%k" , " 0" ); |
1598 | TEST_PRINTF_TIME (13, 13, 13, "%k" , "13" ); |
1599 | TEST_PRINTF ("%l" , "12" ); |
1600 | TEST_PRINTF_TIME (12, 0, 0, "%I" , "12" ); |
1601 | TEST_PRINTF_TIME (13, 13, 13, "%l" , " 1" ); |
1602 | TEST_PRINTF_TIME (10, 13, 13, "%l" , "10" ); |
1603 | TEST_PRINTF ("%m" , "10" ); |
1604 | TEST_PRINTF ("%M" , "00" ); |
1605 | TEST_PRINTF ("%p" , "AM" ); |
1606 | TEST_PRINTF_TIME (13, 13, 13, "%p" , "PM" ); |
1607 | TEST_PRINTF ("%P" , "am" ); |
1608 | TEST_PRINTF_TIME (13, 13, 13, "%P" , "pm" ); |
1609 | TEST_PRINTF ("%r" , "12:00:00 AM" ); |
1610 | TEST_PRINTF_TIME (13, 13, 13, "%r" , "01:13:13 PM" ); |
1611 | TEST_PRINTF ("%R" , "00:00" ); |
1612 | TEST_PRINTF_TIME (13, 13, 31, "%R" , "13:13" ); |
1613 | TEST_PRINTF ("%S" , "00" ); |
1614 | TEST_PRINTF ("%t" , " " ); |
1615 | TEST_PRINTF ("%u" , "6" ); |
1616 | TEST_PRINTF ("%x" , "10/24/09" ); |
1617 | TEST_PRINTF ("%X" , "00:00:00" ); |
1618 | TEST_PRINTF_TIME (13, 14, 15, "%X" , "13:14:15" ); |
1619 | TEST_PRINTF ("%y" , "09" ); |
1620 | TEST_PRINTF ("%Y" , "2009" ); |
1621 | TEST_PRINTF ("%%" , "%" ); |
1622 | TEST_PRINTF ("%" , "" ); |
1623 | TEST_PRINTF ("%9" , NULL); |
1624 | #ifdef G_OS_UNIX |
1625 | TEST_PRINTF ("%Z" , dst); |
1626 | #elif defined G_OS_WIN32 |
1627 | g_assert (GetDynamicTimeZoneInformation (&dtz_info) != TIME_ZONE_ID_INVALID); |
1628 | if (wcscmp (dtz_info.StandardName, L"" ) != 0) |
1629 | current_tz = g_utf16_to_utf8 (dtz_info.StandardName, -1, NULL, NULL, NULL); |
1630 | else |
1631 | current_tz = g_utf16_to_utf8 (dtz_info.DaylightName, -1, NULL, NULL, NULL); |
1632 | |
1633 | TEST_PRINTF ("%Z" , current_tz); |
1634 | g_free (current_tz); |
1635 | #endif |
1636 | |
1637 | if (old_lc_messages != NULL) |
1638 | g_setenv (variable: "LC_MESSAGES" , value: old_lc_messages, TRUE); |
1639 | else |
1640 | g_unsetenv (variable: "LC_MESSAGES" ); |
1641 | g_free (mem: old_lc_messages); |
1642 | |
1643 | if (old_lc_all != NULL) |
1644 | g_setenv (variable: "LC_ALL" , value: old_lc_all, TRUE); |
1645 | g_free (mem: old_lc_all); |
1646 | } |
1647 | |
1648 | static void |
1649 | test_non_utf8_printf (void) |
1650 | { |
1651 | gchar *oldlocale; |
1652 | |
1653 | /* If running uninstalled (G_TEST_BUILDDIR is set), skip this test, since we |
1654 | * need the translations to be installed. We can’t mess around with |
1655 | * bindtextdomain() here, as the compiled .gmo files in po/ are not in the |
1656 | * right installed directory hierarchy to be successfully loaded by gettext. */ |
1657 | if (g_getenv (variable: "G_TEST_BUILDDIR" ) != NULL) |
1658 | { |
1659 | g_test_skip (msg: "Skipping due to running uninstalled. " |
1660 | "This test can only be run when the translations are installed." ); |
1661 | return; |
1662 | } |
1663 | |
1664 | oldlocale = g_strdup (str: setlocale (LC_ALL, NULL)); |
1665 | setlocale (LC_ALL, locale: "ja_JP.eucjp" ); |
1666 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "ja_JP" ) == NULL) |
1667 | { |
1668 | g_test_skip (msg: "locale ja_JP.eucjp not available, skipping non-UTF8 tests" ); |
1669 | g_free (mem: oldlocale); |
1670 | return; |
1671 | } |
1672 | if (g_get_charset (NULL)) |
1673 | { |
1674 | g_test_skip (msg: "locale ja_JP.eucjp may be available, but glib seems to think that it's equivalent to UTF-8, skipping non-UTF-8 tests. This is a known issue on Darwin" ); |
1675 | setlocale (LC_ALL, locale: oldlocale); |
1676 | g_free (mem: oldlocale); |
1677 | return; |
1678 | } |
1679 | |
1680 | /* These are the outputs that ja_JP.UTF-8 generates; if everything |
1681 | * is working then ja_JP.eucjp should generate the same. |
1682 | */ |
1683 | TEST_PRINTF ("%a" , "\345\234\237" ); |
1684 | TEST_PRINTF ("%A" , "\345\234\237\346\233\234\346\227\245" ); |
1685 | #ifndef __APPLE__ /* OSX just returns the number */ |
1686 | TEST_PRINTF ("%b" , "10\346\234\210" ); |
1687 | #endif |
1688 | TEST_PRINTF ("%B" , "10\346\234\210" ); |
1689 | TEST_PRINTF ("%d" , "24" ); |
1690 | TEST_PRINTF_DATE (2009, 1, 1, "%d" , "01" ); |
1691 | TEST_PRINTF ("%e" , "24" ); // fixme |
1692 | #ifndef __APPLE__ /* OSX just returns the number */ |
1693 | TEST_PRINTF ("%h" , "10\346\234\210" ); |
1694 | #endif |
1695 | TEST_PRINTF ("%H" , "00" ); |
1696 | TEST_PRINTF_TIME (15, 0, 0, "%H" , "15" ); |
1697 | TEST_PRINTF ("%I" , "12" ); |
1698 | TEST_PRINTF_TIME (12, 0, 0, "%I" , "12" ); |
1699 | TEST_PRINTF_TIME (15, 0, 0, "%I" , "03" ); |
1700 | TEST_PRINTF ("%j" , "297" ); |
1701 | TEST_PRINTF ("%k" , " 0" ); |
1702 | TEST_PRINTF_TIME (13, 13, 13, "%k" , "13" ); |
1703 | TEST_PRINTF ("%l" , "12" ); |
1704 | TEST_PRINTF_TIME (12, 0, 0, "%I" , "12" ); |
1705 | TEST_PRINTF_TIME (13, 13, 13, "%l" , " 1" ); |
1706 | TEST_PRINTF_TIME (10, 13, 13, "%l" , "10" ); |
1707 | TEST_PRINTF ("%m" , "10" ); |
1708 | TEST_PRINTF ("%M" , "00" ); |
1709 | #ifndef __APPLE__ /* OSX returns latin "AM", not japanese */ |
1710 | TEST_PRINTF ("%p" , "\345\215\210\345\211\215" ); |
1711 | TEST_PRINTF_TIME (13, 13, 13, "%p" , "\345\215\210\345\276\214" ); |
1712 | TEST_PRINTF ("%P" , "\345\215\210\345\211\215" ); |
1713 | TEST_PRINTF_TIME (13, 13, 13, "%P" , "\345\215\210\345\276\214" ); |
1714 | TEST_PRINTF ("%r" , "\345\215\210\345\211\21512\346\231\20200\345\210\20600\347\247\222" ); |
1715 | TEST_PRINTF_TIME (13, 13, 13, "%r" , "\345\215\210\345\276\21401\346\231\20213\345\210\20613\347\247\222" ); |
1716 | #endif |
1717 | TEST_PRINTF ("%R" , "00:00" ); |
1718 | TEST_PRINTF_TIME (13, 13, 31, "%R" , "13:13" ); |
1719 | TEST_PRINTF ("%S" , "00" ); |
1720 | TEST_PRINTF ("%t" , " " ); |
1721 | TEST_PRINTF ("%u" , "6" ); |
1722 | #ifndef __APPLE__ /* OSX returns YYYY/MM/DD in ASCII */ |
1723 | TEST_PRINTF ("%x" , "2009\345\271\26410\346\234\21024\346\227\245" ); |
1724 | #endif |
1725 | TEST_PRINTF ("%X" , "00\346\231\20200\345\210\20600\347\247\222" ); |
1726 | TEST_PRINTF_TIME (13, 14, 15, "%X" , "13\346\231\20214\345\210\20615\347\247\222" ); |
1727 | TEST_PRINTF ("%y" , "09" ); |
1728 | TEST_PRINTF ("%Y" , "2009" ); |
1729 | TEST_PRINTF ("%%" , "%" ); |
1730 | TEST_PRINTF ("%" , "" ); |
1731 | TEST_PRINTF ("%9" , NULL); |
1732 | |
1733 | setlocale (LC_ALL, locale: oldlocale); |
1734 | g_free (mem: oldlocale); |
1735 | } |
1736 | |
1737 | /* Checks that it is possible to use format string that |
1738 | * is unrepresentable in current locale charset. */ |
1739 | static void |
1740 | test_format_unrepresentable (void) |
1741 | { |
1742 | gchar *oldlocale = g_strdup (str: setlocale (LC_ALL, NULL)); |
1743 | setlocale (LC_ALL, locale: "POSIX" ); |
1744 | |
1745 | TEST_PRINTF ("ąśćł" , "ąśćł" ); |
1746 | |
1747 | /* We are using Unicode ratio symbol here, which is outside ASCII. */ |
1748 | TEST_PRINTF_TIME (23, 15, 0, "%H∶%M" , "23∶15" ); |
1749 | |
1750 | /* Test again, this time in locale with non ASCII charset. */ |
1751 | if (setlocale (LC_ALL, locale: "pl_PL.ISO-8859-2" ) != NULL) |
1752 | TEST_PRINTF_TIME (23, 15, 0, "%H∶%M" , "23∶15" ); |
1753 | else |
1754 | g_test_skip (msg: "locale pl_PL.ISO-8859-2 not available, skipping test" ); |
1755 | |
1756 | setlocale (LC_ALL, locale: oldlocale); |
1757 | g_free (mem: oldlocale); |
1758 | } |
1759 | |
1760 | static void |
1761 | test_modifiers (void) |
1762 | { |
1763 | gchar *oldlocale; |
1764 | |
1765 | TEST_PRINTF_DATE (2009, 1, 1, "%d" , "01" ); |
1766 | TEST_PRINTF_DATE (2009, 1, 1, "%_d" , " 1" ); |
1767 | TEST_PRINTF_DATE (2009, 1, 1, "%-d" , "1" ); |
1768 | TEST_PRINTF_DATE (2009, 1, 1, "%0d" , "01" ); |
1769 | TEST_PRINTF_DATE (2009, 1, 21, "%d" , "21" ); |
1770 | TEST_PRINTF_DATE (2009, 1, 21, "%_d" , "21" ); |
1771 | TEST_PRINTF_DATE (2009, 1, 21, "%-d" , "21" ); |
1772 | TEST_PRINTF_DATE (2009, 1, 21, "%0d" , "21" ); |
1773 | |
1774 | TEST_PRINTF_DATE (2009, 1, 1, "%e" , " 1" ); |
1775 | TEST_PRINTF_DATE (2009, 1, 1, "%_e" , " 1" ); |
1776 | TEST_PRINTF_DATE (2009, 1, 1, "%-e" , "1" ); |
1777 | TEST_PRINTF_DATE (2009, 1, 1, "%0e" , "01" ); |
1778 | TEST_PRINTF_DATE (2009, 1, 21, "%e" , "21" ); |
1779 | TEST_PRINTF_DATE (2009, 1, 21, "%_e" , "21" ); |
1780 | TEST_PRINTF_DATE (2009, 1, 21, "%-e" , "21" ); |
1781 | TEST_PRINTF_DATE (2009, 1, 21, "%0e" , "21" ); |
1782 | |
1783 | TEST_PRINTF_TIME ( 1, 0, 0, "%H" , "01" ); |
1784 | TEST_PRINTF_TIME ( 1, 0, 0, "%_H" , " 1" ); |
1785 | TEST_PRINTF_TIME ( 1, 0, 0, "%-H" , "1" ); |
1786 | TEST_PRINTF_TIME ( 1, 0, 0, "%0H" , "01" ); |
1787 | TEST_PRINTF_TIME (21, 0, 0, "%H" , "21" ); |
1788 | TEST_PRINTF_TIME (21, 0, 0, "%_H" , "21" ); |
1789 | TEST_PRINTF_TIME (21, 0, 0, "%-H" , "21" ); |
1790 | TEST_PRINTF_TIME (21, 0, 0, "%0H" , "21" ); |
1791 | |
1792 | TEST_PRINTF_TIME ( 1, 0, 0, "%I" , "01" ); |
1793 | TEST_PRINTF_TIME ( 1, 0, 0, "%_I" , " 1" ); |
1794 | TEST_PRINTF_TIME ( 1, 0, 0, "%-I" , "1" ); |
1795 | TEST_PRINTF_TIME ( 1, 0, 0, "%0I" , "01" ); |
1796 | TEST_PRINTF_TIME (23, 0, 0, "%I" , "11" ); |
1797 | TEST_PRINTF_TIME (23, 0, 0, "%_I" , "11" ); |
1798 | TEST_PRINTF_TIME (23, 0, 0, "%-I" , "11" ); |
1799 | TEST_PRINTF_TIME (23, 0, 0, "%0I" , "11" ); |
1800 | |
1801 | TEST_PRINTF_TIME ( 1, 0, 0, "%k" , " 1" ); |
1802 | TEST_PRINTF_TIME ( 1, 0, 0, "%_k" , " 1" ); |
1803 | TEST_PRINTF_TIME ( 1, 0, 0, "%-k" , "1" ); |
1804 | TEST_PRINTF_TIME ( 1, 0, 0, "%0k" , "01" ); |
1805 | |
1806 | oldlocale = g_strdup (str: setlocale (LC_ALL, NULL)); |
1807 | setlocale (LC_ALL, locale: "fa_IR.utf-8" ); |
1808 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "fa_IR" ) != NULL) |
1809 | { |
1810 | TEST_PRINTF_TIME (23, 0, 0, "%OH" , "\333\262\333\263" ); /* '23' */ |
1811 | TEST_PRINTF_TIME (23, 0, 0, "%OI" , "\333\261\333\261" ); /* '11' */ |
1812 | TEST_PRINTF_TIME (23, 0, 0, "%OM" , "\333\260\333\260" ); /* '00' */ |
1813 | |
1814 | TEST_PRINTF_DATE (2011, 7, 1, "%Om" , "\333\260\333\267" ); /* '07' */ |
1815 | TEST_PRINTF_DATE (2011, 7, 1, "%0Om" , "\333\260\333\267" ); /* '07' */ |
1816 | TEST_PRINTF_DATE (2011, 7, 1, "%-Om" , "\333\267" ); /* '7' */ |
1817 | TEST_PRINTF_DATE (2011, 7, 1, "%_Om" , " \333\267" ); /* ' 7' */ |
1818 | } |
1819 | else |
1820 | g_test_skip (msg: "locale fa_IR not available, skipping O modifier tests" ); |
1821 | setlocale (LC_ALL, locale: oldlocale); |
1822 | g_free (mem: oldlocale); |
1823 | } |
1824 | |
1825 | /* Test that the `O` modifier for g_date_time_format() works with %B, %b and %h; |
1826 | * i.e. whether genitive month names are supported. */ |
1827 | static void |
1828 | test_month_names (void) |
1829 | { |
1830 | gchar *oldlocale; |
1831 | |
1832 | g_test_bug (bug_uri_snippet: "http://bugzilla.gnome.org/749206" ); |
1833 | |
1834 | /* If running uninstalled (G_TEST_BUILDDIR is set), skip this test, since we |
1835 | * need the translations to be installed. We can’t mess around with |
1836 | * bindtextdomain() here, as the compiled .gmo files in po/ are not in the |
1837 | * right installed directory hierarchy to be successfully loaded by gettext. */ |
1838 | if (g_getenv (variable: "G_TEST_BUILDDIR" ) != NULL) |
1839 | { |
1840 | g_test_skip (msg: "Skipping due to running uninstalled. " |
1841 | "This test can only be run when the translations are installed." ); |
1842 | return; |
1843 | } |
1844 | |
1845 | oldlocale = g_strdup (str: setlocale (LC_ALL, NULL)); |
1846 | |
1847 | /* Make sure that nothing has been changed in western European languages. */ |
1848 | setlocale (LC_ALL, locale: "en_GB.utf-8" ); |
1849 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "en_GB" ) != NULL) |
1850 | { |
1851 | TEST_PRINTF_DATE (2018, 1, 1, "%B" , "January" ); |
1852 | TEST_PRINTF_DATE (2018, 2, 1, "%OB" , "February" ); |
1853 | TEST_PRINTF_DATE (2018, 3, 1, "%b" , "Mar" ); |
1854 | TEST_PRINTF_DATE (2018, 4, 1, "%Ob" , "Apr" ); |
1855 | TEST_PRINTF_DATE (2018, 5, 1, "%h" , "May" ); |
1856 | TEST_PRINTF_DATE (2018, 6, 1, "%Oh" , "Jun" ); |
1857 | } |
1858 | else |
1859 | g_test_skip (msg: "locale en_GB not available, skipping English month names test" ); |
1860 | |
1861 | setlocale (LC_ALL, locale: "de_DE.utf-8" ); |
1862 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "de_DE" ) != NULL) |
1863 | { |
1864 | TEST_PRINTF_DATE (2018, 7, 1, "%B" , "Juli" ); |
1865 | TEST_PRINTF_DATE (2018, 8, 1, "%OB" , "August" ); |
1866 | TEST_PRINTF_DATE (2018, 9, 1, "%b" , "Sep" ); |
1867 | TEST_PRINTF_DATE (2018, 10, 1, "%Ob" , "Okt" ); |
1868 | TEST_PRINTF_DATE (2018, 11, 1, "%h" , "Nov" ); |
1869 | TEST_PRINTF_DATE (2018, 12, 1, "%Oh" , "Dez" ); |
1870 | } |
1871 | else |
1872 | g_test_skip (msg: "locale de_DE not available, skipping German month names test" ); |
1873 | |
1874 | setlocale (LC_ALL, locale: "es_ES.utf-8" ); |
1875 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "es_ES" ) != NULL) |
1876 | { |
1877 | TEST_PRINTF_DATE (2018, 1, 1, "%B" , "enero" ); |
1878 | TEST_PRINTF_DATE (2018, 2, 1, "%OB" , "febrero" ); |
1879 | TEST_PRINTF_DATE (2018, 3, 1, "%b" , "mar" ); |
1880 | TEST_PRINTF_DATE (2018, 4, 1, "%Ob" , "abr" ); |
1881 | TEST_PRINTF_DATE (2018, 5, 1, "%h" , "may" ); |
1882 | TEST_PRINTF_DATE (2018, 6, 1, "%Oh" , "jun" ); |
1883 | } |
1884 | else |
1885 | g_test_skip (msg: "locale es_ES not available, skipping Spanish month names test" ); |
1886 | |
1887 | setlocale (LC_ALL, locale: "fr_FR.utf-8" ); |
1888 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "fr_FR" ) != NULL) |
1889 | { |
1890 | TEST_PRINTF_DATE (2018, 7, 1, "%B" , "juillet" ); |
1891 | TEST_PRINTF_DATE (2018, 8, 1, "%OB" , "août" ); |
1892 | TEST_PRINTF_DATE (2018, 9, 1, "%b" , "sept." ); |
1893 | TEST_PRINTF_DATE (2018, 10, 1, "%Ob" , "oct." ); |
1894 | TEST_PRINTF_DATE (2018, 11, 1, "%h" , "nov." ); |
1895 | TEST_PRINTF_DATE (2018, 12, 1, "%Oh" , "déc." ); |
1896 | } |
1897 | else |
1898 | g_test_skip (msg: "locale fr_FR not available, skipping French month names test" ); |
1899 | |
1900 | /* Make sure that there are visible changes in some European languages. */ |
1901 | setlocale (LC_ALL, locale: "el_GR.utf-8" ); |
1902 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "el_GR" ) != NULL) |
1903 | { |
1904 | TEST_PRINTF_DATE (2018, 1, 1, "%B" , "Ιανουαρίου" ); |
1905 | TEST_PRINTF_DATE (2018, 2, 1, "%B" , "Φεβρουαρίου" ); |
1906 | TEST_PRINTF_DATE (2018, 3, 1, "%B" , "Μαρτίου" ); |
1907 | TEST_PRINTF_DATE (2018, 4, 1, "%OB" , "Απρίλιος" ); |
1908 | TEST_PRINTF_DATE (2018, 5, 1, "%OB" , "Μάιος" ); |
1909 | TEST_PRINTF_DATE (2018, 6, 1, "%OB" , "Ιούνιος" ); |
1910 | TEST_PRINTF_DATE (2018, 7, 1, "%b" , "Ιουλ" ); |
1911 | TEST_PRINTF_DATE (2018, 8, 1, "%Ob" , "Αύγ" ); |
1912 | } |
1913 | else |
1914 | g_test_skip (msg: "locale el_GR not available, skipping Greek month names test" ); |
1915 | |
1916 | setlocale (LC_ALL, locale: "hr_HR.utf-8" ); |
1917 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "hr_HR" ) != NULL) |
1918 | { |
1919 | TEST_PRINTF_DATE (2018, 5, 1, "%B" , "svibnja" ); |
1920 | TEST_PRINTF_DATE (2018, 6, 1, "%B" , "lipnja" ); |
1921 | TEST_PRINTF_DATE (2018, 7, 1, "%B" , "srpnja" ); |
1922 | TEST_PRINTF_DATE (2018, 8, 1, "%OB" , "Kolovoz" ); |
1923 | TEST_PRINTF_DATE (2018, 9, 1, "%OB" , "Rujan" ); |
1924 | TEST_PRINTF_DATE (2018, 10, 1, "%OB" , "Listopad" ); |
1925 | TEST_PRINTF_DATE (2018, 11, 1, "%b" , "Stu" ); |
1926 | TEST_PRINTF_DATE (2018, 12, 1, "%Ob" , "Pro" ); |
1927 | } |
1928 | else |
1929 | g_test_skip (msg: "locale hr_HR not available, skipping Croatian month names test" ); |
1930 | |
1931 | setlocale (LC_ALL, locale: "lt_LT.utf-8" ); |
1932 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "lt_LT" ) != NULL) |
1933 | { |
1934 | TEST_PRINTF_DATE (2018, 1, 1, "%B" , "sausio" ); |
1935 | TEST_PRINTF_DATE (2018, 2, 1, "%B" , "vasario" ); |
1936 | TEST_PRINTF_DATE (2018, 3, 1, "%B" , "kovo" ); |
1937 | TEST_PRINTF_DATE (2018, 4, 1, "%OB" , "balandis" ); |
1938 | TEST_PRINTF_DATE (2018, 5, 1, "%OB" , "gegužė" ); |
1939 | TEST_PRINTF_DATE (2018, 6, 1, "%OB" , "birželis" ); |
1940 | TEST_PRINTF_DATE (2018, 7, 1, "%b" , "liep." ); |
1941 | TEST_PRINTF_DATE (2018, 8, 1, "%Ob" , "rugp." ); |
1942 | } |
1943 | else |
1944 | g_test_skip (msg: "locale lt_LT not available, skipping Lithuanian month names test" ); |
1945 | |
1946 | setlocale (LC_ALL, locale: "pl_PL.utf-8" ); |
1947 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "pl_PL" ) != NULL) |
1948 | { |
1949 | TEST_PRINTF_DATE (2018, 5, 1, "%B" , "maja" ); |
1950 | TEST_PRINTF_DATE (2018, 6, 1, "%B" , "czerwca" ); |
1951 | TEST_PRINTF_DATE (2018, 7, 1, "%B" , "lipca" ); |
1952 | TEST_PRINTF_DATE (2018, 8, 1, "%OB" , "sierpień" ); |
1953 | TEST_PRINTF_DATE (2018, 9, 1, "%OB" , "wrzesień" ); |
1954 | TEST_PRINTF_DATE (2018, 10, 1, "%OB" , "październik" ); |
1955 | TEST_PRINTF_DATE (2018, 11, 1, "%b" , "lis" ); |
1956 | TEST_PRINTF_DATE (2018, 12, 1, "%Ob" , "gru" ); |
1957 | } |
1958 | else |
1959 | g_test_skip (msg: "locale pl_PL not available, skipping Polish month names test" ); |
1960 | |
1961 | setlocale (LC_ALL, locale: "ru_RU.utf-8" ); |
1962 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "ru_RU" ) != NULL) |
1963 | { |
1964 | TEST_PRINTF_DATE (2018, 1, 1, "%B" , "января" ); |
1965 | TEST_PRINTF_DATE (2018, 2, 1, "%B" , "февраля" ); |
1966 | TEST_PRINTF_DATE (2018, 3, 1, "%B" , "марта" ); |
1967 | TEST_PRINTF_DATE (2018, 4, 1, "%OB" , "Апрель" ); |
1968 | TEST_PRINTF_DATE (2018, 5, 1, "%OB" , "Май" ); |
1969 | TEST_PRINTF_DATE (2018, 6, 1, "%OB" , "Июнь" ); |
1970 | TEST_PRINTF_DATE (2018, 7, 1, "%b" , "июл" ); |
1971 | TEST_PRINTF_DATE (2018, 8, 1, "%Ob" , "авг" ); |
1972 | /* This difference is very important in Russian: */ |
1973 | TEST_PRINTF_DATE (2018, 5, 1, "%b" , "мая" ); |
1974 | TEST_PRINTF_DATE (2018, 5, 1, "%Ob" , "май" ); |
1975 | } |
1976 | else |
1977 | g_test_skip (msg: "locale ru_RU not available, skipping Russian month names test" ); |
1978 | |
1979 | setlocale (LC_ALL, locale: oldlocale); |
1980 | g_free (mem: oldlocale); |
1981 | } |
1982 | |
1983 | static void |
1984 | test_GDateTime_dst (void) |
1985 | { |
1986 | GDateTime *dt1, *dt2; |
1987 | GTimeZone *tz; |
1988 | |
1989 | /* this date has the DST state set for Europe/London */ |
1990 | #ifdef G_OS_UNIX |
1991 | tz = g_time_zone_new_identifier (identifier: "Europe/London" ); |
1992 | #elif defined G_OS_WIN32 |
1993 | tz = g_time_zone_new_identifier ("GMT Standard Time" ); |
1994 | #endif |
1995 | g_assert_nonnull (tz); |
1996 | dt1 = g_date_time_new (tz, year: 2009, month: 8, day: 15, hour: 3, minute: 0, seconds: 1); |
1997 | g_assert (g_date_time_is_daylight_savings (dt1)); |
1998 | g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, 3600); |
1999 | g_assert_cmpint (g_date_time_get_hour (dt1), ==, 3); |
2000 | |
2001 | /* add 6 months to clear the DST flag but keep the same time */ |
2002 | dt2 = g_date_time_add_months (datetime: dt1, months: 6); |
2003 | g_assert (!g_date_time_is_daylight_savings (dt2)); |
2004 | g_assert_cmpint (g_date_time_get_utc_offset (dt2) / G_USEC_PER_SEC, ==, 0); |
2005 | g_assert_cmpint (g_date_time_get_hour (dt2), ==, 3); |
2006 | |
2007 | g_date_time_unref (datetime: dt2); |
2008 | g_date_time_unref (datetime: dt1); |
2009 | |
2010 | /* now do the reverse: start with a non-DST state and move to DST */ |
2011 | dt1 = g_date_time_new (tz, year: 2009, month: 2, day: 15, hour: 2, minute: 0, seconds: 1); |
2012 | g_assert (!g_date_time_is_daylight_savings (dt1)); |
2013 | g_assert_cmpint (g_date_time_get_hour (dt1), ==, 2); |
2014 | |
2015 | dt2 = g_date_time_add_months (datetime: dt1, months: 6); |
2016 | g_assert (g_date_time_is_daylight_savings (dt2)); |
2017 | g_assert_cmpint (g_date_time_get_hour (dt2), ==, 2); |
2018 | |
2019 | g_date_time_unref (datetime: dt2); |
2020 | g_date_time_unref (datetime: dt1); |
2021 | g_time_zone_unref (tz); |
2022 | } |
2023 | |
2024 | static inline gboolean |
2025 | is_leap_year (gint year) |
2026 | { |
2027 | g_assert (1 <= year && year <= 9999); |
2028 | |
2029 | return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); |
2030 | } |
2031 | |
2032 | static inline gint |
2033 | days_in_month (gint year, gint month) |
2034 | { |
2035 | const gint table[2][13] = { |
2036 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, |
2037 | {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} |
2038 | }; |
2039 | |
2040 | g_assert (1 <= month && month <= 12); |
2041 | |
2042 | return table[is_leap_year (year)][month]; |
2043 | } |
2044 | |
2045 | static void |
2046 | test_all_dates (void) |
2047 | { |
2048 | gint year, month, day; |
2049 | GTimeZone *timezone; |
2050 | gint64 unix_time; |
2051 | gint day_of_year; |
2052 | gint week_year; |
2053 | gint week_num; |
2054 | gint weekday; |
2055 | |
2056 | /* save some time by hanging on to this. */ |
2057 | timezone = g_time_zone_new_utc (); |
2058 | |
2059 | unix_time = G_GINT64_CONSTANT(-62135596800); |
2060 | |
2061 | /* 0001-01-01 is 0001-W01-1 */ |
2062 | week_year = 1; |
2063 | week_num = 1; |
2064 | weekday = 1; |
2065 | |
2066 | |
2067 | /* The calendar makes a full cycle every 400 years, so we could |
2068 | * theoretically just test years 1 through 400. That assumes that our |
2069 | * software has no bugs, so probably we should just test them all. :) |
2070 | */ |
2071 | for (year = 1; year <= 9999; year++) |
2072 | { |
2073 | day_of_year = 1; |
2074 | |
2075 | for (month = 1; month <= 12; month++) |
2076 | for (day = 1; day <= days_in_month (year, month); day++) |
2077 | { |
2078 | GDateTime *dt; |
2079 | |
2080 | dt = g_date_time_new (tz: timezone, year, month, day, hour: 0, minute: 0, seconds: 0); |
2081 | |
2082 | #if 0 |
2083 | g_printerr ("%04d-%02d-%02d = %04d-W%02d-%d = %04d-%03d\n" , |
2084 | year, month, day, |
2085 | week_year, week_num, weekday, |
2086 | year, day_of_year); |
2087 | #endif |
2088 | |
2089 | /* sanity check */ |
2090 | if G_UNLIKELY (g_date_time_get_year (dt) != year || |
2091 | g_date_time_get_month (dt) != month || |
2092 | g_date_time_get_day_of_month (dt) != day) |
2093 | g_error ("%04d-%02d-%02d comes out as %04d-%02d-%02d" , |
2094 | year, month, day, |
2095 | g_date_time_get_year (dt), |
2096 | g_date_time_get_month (dt), |
2097 | g_date_time_get_day_of_month (dt)); |
2098 | |
2099 | if G_UNLIKELY (g_date_time_get_week_numbering_year (dt) != week_year || |
2100 | g_date_time_get_week_of_year (dt) != week_num || |
2101 | g_date_time_get_day_of_week (dt) != weekday) |
2102 | g_error ("%04d-%02d-%02d should be %04d-W%02d-%d but " |
2103 | "comes out as %04d-W%02d-%d" , year, month, day, |
2104 | week_year, week_num, weekday, |
2105 | g_date_time_get_week_numbering_year (dt), |
2106 | g_date_time_get_week_of_year (dt), |
2107 | g_date_time_get_day_of_week (dt)); |
2108 | |
2109 | if G_UNLIKELY (g_date_time_to_unix (dt) != unix_time) |
2110 | g_error ("%04d-%02d-%02d 00:00:00 UTC should have unix time %" |
2111 | G_GINT64_FORMAT " but comes out as %" G_GINT64_FORMAT, |
2112 | year, month, day, unix_time, g_date_time_to_unix (dt)); |
2113 | |
2114 | if G_UNLIKELY (g_date_time_get_day_of_year (dt) != day_of_year) |
2115 | g_error ("%04d-%02d-%02d should be day of year %d" |
2116 | " but comes out as %d" , year, month, day, |
2117 | day_of_year, g_date_time_get_day_of_year (dt)); |
2118 | |
2119 | if G_UNLIKELY (g_date_time_get_hour (dt) != 0 || |
2120 | g_date_time_get_minute (dt) != 0 || |
2121 | g_date_time_get_seconds (dt) != 0) |
2122 | g_error ("%04d-%02d-%02d 00:00:00 UTC comes out " |
2123 | "as %02d:%02d:%02.6f" , year, month, day, |
2124 | g_date_time_get_hour (dt), |
2125 | g_date_time_get_minute (dt), |
2126 | g_date_time_get_seconds (dt)); |
2127 | /* done */ |
2128 | |
2129 | /* add 24 hours to unix time */ |
2130 | unix_time += 24 * 60 * 60; |
2131 | |
2132 | /* move day of year forward */ |
2133 | day_of_year++; |
2134 | |
2135 | /* move the week date forward */ |
2136 | if (++weekday == 8) |
2137 | { |
2138 | weekday = 1; /* Sunday -> Monday */ |
2139 | |
2140 | /* NOTE: year/month/day is the final day of the week we |
2141 | * just finished. |
2142 | * |
2143 | * If we just finished the last week of last year then |
2144 | * we are definitely starting the first week of this |
2145 | * year. |
2146 | * |
2147 | * Otherwise, if we're still in this year, but Sunday |
2148 | * fell on or after December 28 then December 29, 30, 31 |
2149 | * could be days within the next year's first year. |
2150 | */ |
2151 | if (year != week_year || (month == 12 && day >= 28)) |
2152 | { |
2153 | /* first week of the new year */ |
2154 | week_num = 1; |
2155 | week_year++; |
2156 | } |
2157 | else |
2158 | week_num++; |
2159 | } |
2160 | |
2161 | g_date_time_unref (datetime: dt); |
2162 | } |
2163 | } |
2164 | |
2165 | g_time_zone_unref (tz: timezone); |
2166 | } |
2167 | |
2168 | static void |
2169 | test_z (void) |
2170 | { |
2171 | GTimeZone *tz; |
2172 | GDateTime *dt; |
2173 | gchar *p; |
2174 | |
2175 | g_test_bug (bug_uri_snippet: "http://bugzilla.gnome.org/642935" ); |
2176 | |
2177 | tz = g_time_zone_new_identifier (identifier: "-08:00" ); |
2178 | g_assert_nonnull (tz); |
2179 | dt = g_date_time_new (tz, year: 1, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
2180 | |
2181 | p = g_date_time_format (datetime: dt, format: "%z" ); |
2182 | g_assert_cmpstr (p, ==, "-0800" ); |
2183 | g_free (mem: p); |
2184 | |
2185 | p = g_date_time_format (datetime: dt, format: "%:z" ); |
2186 | g_assert_cmpstr (p, ==, "-08:00" ); |
2187 | g_free (mem: p); |
2188 | |
2189 | p = g_date_time_format (datetime: dt, format: "%::z" ); |
2190 | g_assert_cmpstr (p, ==, "-08:00:00" ); |
2191 | g_free (mem: p); |
2192 | |
2193 | p = g_date_time_format (datetime: dt, format: "%:::z" ); |
2194 | g_assert_cmpstr (p, ==, "-08" ); |
2195 | g_free (mem: p); |
2196 | |
2197 | g_date_time_unref (datetime: dt); |
2198 | g_time_zone_unref (tz); |
2199 | |
2200 | tz = g_time_zone_new_identifier (identifier: "+00:00" ); |
2201 | g_assert_nonnull (tz); |
2202 | dt = g_date_time_new (tz, year: 1, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
2203 | p = g_date_time_format (datetime: dt, format: "%:::z" ); |
2204 | g_assert_cmpstr (p, ==, "+00" ); |
2205 | g_free (mem: p); |
2206 | g_date_time_unref (datetime: dt); |
2207 | g_time_zone_unref (tz); |
2208 | |
2209 | tz = g_time_zone_new_identifier (identifier: "+08:23" ); |
2210 | g_assert_nonnull (tz); |
2211 | dt = g_date_time_new (tz, year: 1, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
2212 | p = g_date_time_format (datetime: dt, format: "%:::z" ); |
2213 | g_assert_cmpstr (p, ==, "+08:23" ); |
2214 | g_free (mem: p); |
2215 | g_date_time_unref (datetime: dt); |
2216 | g_time_zone_unref (tz); |
2217 | |
2218 | tz = g_time_zone_new_identifier (identifier: "+08:23:45" ); |
2219 | g_assert_nonnull (tz); |
2220 | dt = g_date_time_new (tz, year: 1, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
2221 | p = g_date_time_format (datetime: dt, format: "%:::z" ); |
2222 | g_assert_cmpstr (p, ==, "+08:23:45" ); |
2223 | g_free (mem: p); |
2224 | g_date_time_unref (datetime: dt); |
2225 | g_time_zone_unref (tz); |
2226 | |
2227 | tz = g_time_zone_new_identifier (identifier: "-00:15" ); |
2228 | g_assert_nonnull (tz); |
2229 | dt = g_date_time_new (tz, year: 1, month: 1, day: 1, hour: 0, minute: 0, seconds: 0); |
2230 | |
2231 | p = g_date_time_format (datetime: dt, format: "%z" ); |
2232 | g_assert_cmpstr (p, ==, "-0015" ); |
2233 | g_free (mem: p); |
2234 | |
2235 | p = g_date_time_format (datetime: dt, format: "%:z" ); |
2236 | g_assert_cmpstr (p, ==, "-00:15" ); |
2237 | g_free (mem: p); |
2238 | |
2239 | p = g_date_time_format (datetime: dt, format: "%::z" ); |
2240 | g_assert_cmpstr (p, ==, "-00:15:00" ); |
2241 | g_free (mem: p); |
2242 | |
2243 | p = g_date_time_format (datetime: dt, format: "%:::z" ); |
2244 | g_assert_cmpstr (p, ==, "-00:15" ); |
2245 | g_free (mem: p); |
2246 | |
2247 | g_date_time_unref (datetime: dt); |
2248 | g_time_zone_unref (tz); |
2249 | } |
2250 | |
2251 | static void |
2252 | test_6_days_until_end_of_the_month (void) |
2253 | { |
2254 | GTimeZone *tz; |
2255 | GDateTime *dt; |
2256 | gchar *p; |
2257 | |
2258 | g_test_bug (bug_uri_snippet: "https://gitlab.gnome.org/GNOME/glib/-/issues/2215" ); |
2259 | |
2260 | #ifdef G_OS_UNIX |
2261 | /* This is the footertz string from `Europe/Paris` from tzdata 2020b. It’s |
2262 | * used by GLib when the tzdata file was compiled with `zic -b slim`, which is |
2263 | * the default in tzcode ≥2020b. |
2264 | * |
2265 | * The `M10.5.0` part indicates that the summer time end transition happens on |
2266 | * the Sunday (`0`) in the last week (`5`) of October (`10`). That’s 6 days |
2267 | * before the end of the month, and hence was triggering issue #2215. |
2268 | * |
2269 | * References: |
2270 | * - https://tools.ietf.org/id/draft-murchison-tzdist-tzif-15.html#rfc.section.3.3 |
2271 | * - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 |
2272 | */ |
2273 | tz = g_time_zone_new_identifier (identifier: "CET-1CEST,M3.5.0,M10.5.0/3" ); |
2274 | #elif defined (G_OS_WIN32) |
2275 | tz = g_time_zone_new_identifier ("Romance Standard Time" ); |
2276 | #endif |
2277 | g_assert_nonnull (tz); |
2278 | dt = g_date_time_new (tz, year: 2020, month: 10, day: 5, hour: 1, minute: 1, seconds: 1); |
2279 | |
2280 | p = g_date_time_format (datetime: dt, format: "%Y-%m-%d %H:%M:%S%z" ); |
2281 | /* Incorrect output is "2020-10-05 01:01:01+0100" */ |
2282 | g_assert_cmpstr (p, ==, "2020-10-05 01:01:01+0200" ); |
2283 | g_free (mem: p); |
2284 | |
2285 | g_date_time_unref (datetime: dt); |
2286 | g_time_zone_unref (tz); |
2287 | } |
2288 | |
2289 | static void |
2290 | test_format_iso8601 (void) |
2291 | { |
2292 | GTimeZone *tz = NULL; |
2293 | GDateTime *dt = NULL; |
2294 | gchar *p = NULL; |
2295 | |
2296 | tz = g_time_zone_new_utc (); |
2297 | dt = g_date_time_new (tz, year: 2019, month: 6, day: 26, hour: 15, minute: 1, seconds: 5); |
2298 | p = g_date_time_format_iso8601 (datetime: dt); |
2299 | g_assert_cmpstr (p, ==, "2019-06-26T15:01:05Z" ); |
2300 | g_free (mem: p); |
2301 | g_date_time_unref (datetime: dt); |
2302 | g_time_zone_unref (tz); |
2303 | |
2304 | tz = g_time_zone_new_offset (seconds: -60 * 60); |
2305 | dt = g_date_time_new (tz, year: 2019, month: 6, day: 26, hour: 15, minute: 1, seconds: 5); |
2306 | p = g_date_time_format_iso8601 (datetime: dt); |
2307 | g_assert_cmpstr (p, ==, "2019-06-26T15:01:05-01" ); |
2308 | g_free (mem: p); |
2309 | g_date_time_unref (datetime: dt); |
2310 | g_time_zone_unref (tz); |
2311 | |
2312 | tz = g_time_zone_new_utc (); |
2313 | dt = g_date_time_new (tz, year: 2020, month: 8, day: 5, hour: 12, minute: 30, seconds: 55.000001); |
2314 | p = g_date_time_format_iso8601 (datetime: dt); |
2315 | g_assert_cmpstr (p, ==, "2020-08-05T12:30:55.000001Z" ); |
2316 | g_free (mem: p); |
2317 | g_date_time_unref (datetime: dt); |
2318 | g_time_zone_unref (tz); |
2319 | } |
2320 | |
2321 | #pragma GCC diagnostic push |
2322 | #pragma GCC diagnostic ignored "-Wformat-y2k" |
2323 | static void |
2324 | test_strftime (void) |
2325 | { |
2326 | #ifdef __linux__ |
2327 | #define TEST_FORMAT \ |
2328 | "a%a A%A b%b B%B c%c C%C d%d e%e F%F g%g G%G h%h H%H I%I j%j m%m M%M " \ |
2329 | "n%n p%p r%r R%R S%S t%t T%T u%u V%V w%w x%x X%X y%y Y%Y z%z Z%Z %%" |
2330 | time_t t; |
2331 | |
2332 | /* 127997 is prime, 1315005118 is now */ |
2333 | for (t = 0; t < 1315005118; t += 127997) |
2334 | { |
2335 | GDateTime *date_time; |
2336 | gchar c_str[1000]; |
2337 | gchar *dt_str; |
2338 | |
2339 | date_time = g_date_time_new_from_unix_local (t); |
2340 | dt_str = g_date_time_format (datetime: date_time, TEST_FORMAT); |
2341 | strftime (s: c_str, maxsize: sizeof c_str, TEST_FORMAT, tp: localtime (timer: &t)); |
2342 | g_assert_cmpstr (c_str, ==, dt_str); |
2343 | g_date_time_unref (datetime: date_time); |
2344 | g_free (mem: dt_str); |
2345 | } |
2346 | #endif |
2347 | } |
2348 | #pragma GCC diagnostic pop |
2349 | |
2350 | /* Check that g_date_time_format() correctly returns %NULL for format |
2351 | * placeholders which are not supported in the current locale. */ |
2352 | static void |
2353 | test_GDateTime_strftime_error_handling (void) |
2354 | { |
2355 | gchar *oldlocale; |
2356 | |
2357 | oldlocale = g_strdup (str: setlocale (LC_ALL, NULL)); |
2358 | setlocale (LC_ALL, locale: "de_DE.utf-8" ); |
2359 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "de_DE" ) != NULL) |
2360 | { |
2361 | /* de_DE doesn’t ever write time in 12-hour notation, so %r is |
2362 | * unsupported for it. */ |
2363 | TEST_PRINTF_TIME (23, 0, 0, "%r" , NULL); |
2364 | } |
2365 | else |
2366 | g_test_skip (msg: "locale de_DE not available, skipping error handling tests" ); |
2367 | setlocale (LC_ALL, locale: oldlocale); |
2368 | g_free (mem: oldlocale); |
2369 | } |
2370 | |
2371 | static void |
2372 | test_find_interval (void) |
2373 | { |
2374 | GTimeZone *tz; |
2375 | GDateTime *dt; |
2376 | gint64 u; |
2377 | gint i1, i2; |
2378 | |
2379 | #ifdef G_OS_UNIX |
2380 | tz = g_time_zone_new_identifier (identifier: "America/Toronto" ); |
2381 | #elif defined G_OS_WIN32 |
2382 | tz = g_time_zone_new_identifier ("Eastern Standard Time" ); |
2383 | #endif |
2384 | g_assert_nonnull (tz); |
2385 | dt = g_date_time_new_utc (year: 2010, month: 11, day: 7, hour: 1, minute: 30, seconds: 0); |
2386 | u = g_date_time_to_unix (datetime: dt); |
2387 | |
2388 | i1 = g_time_zone_find_interval (tz, type: G_TIME_TYPE_STANDARD, time_: u); |
2389 | i2 = g_time_zone_find_interval (tz, type: G_TIME_TYPE_DAYLIGHT, time_: u); |
2390 | |
2391 | g_assert_cmpint (i1, !=, i2); |
2392 | |
2393 | g_date_time_unref (datetime: dt); |
2394 | |
2395 | dt = g_date_time_new_utc (year: 2010, month: 3, day: 14, hour: 2, minute: 0, seconds: 0); |
2396 | u = g_date_time_to_unix (datetime: dt); |
2397 | |
2398 | i1 = g_time_zone_find_interval (tz, type: G_TIME_TYPE_STANDARD, time_: u); |
2399 | g_assert_cmpint (i1, ==, -1); |
2400 | |
2401 | g_date_time_unref (datetime: dt); |
2402 | g_time_zone_unref (tz); |
2403 | } |
2404 | |
2405 | static void |
2406 | test_adjust_time (void) |
2407 | { |
2408 | GTimeZone *tz; |
2409 | GDateTime *dt; |
2410 | gint64 u, u2; |
2411 | gint i1, i2; |
2412 | |
2413 | #ifdef G_OS_UNIX |
2414 | tz = g_time_zone_new_identifier (identifier: "America/Toronto" ); |
2415 | #elif defined G_OS_WIN32 |
2416 | tz = g_time_zone_new_identifier ("Eastern Standard Time" ); |
2417 | #endif |
2418 | g_assert_nonnull (tz); |
2419 | dt = g_date_time_new_utc (year: 2010, month: 11, day: 7, hour: 1, minute: 30, seconds: 0); |
2420 | u = g_date_time_to_unix (datetime: dt); |
2421 | u2 = u; |
2422 | |
2423 | i1 = g_time_zone_find_interval (tz, type: G_TIME_TYPE_DAYLIGHT, time_: u); |
2424 | i2 = g_time_zone_adjust_time (tz, type: G_TIME_TYPE_DAYLIGHT, time_: &u2); |
2425 | |
2426 | g_assert_cmpint (i1, ==, i2); |
2427 | g_assert (u == u2); |
2428 | |
2429 | g_date_time_unref (datetime: dt); |
2430 | |
2431 | dt = g_date_time_new_utc (year: 2010, month: 3, day: 14, hour: 2, minute: 30, seconds: 0); |
2432 | u2 = g_date_time_to_unix (datetime: dt); |
2433 | g_date_time_unref (datetime: dt); |
2434 | |
2435 | dt = g_date_time_new_utc (year: 2010, month: 3, day: 14, hour: 3, minute: 0, seconds: 0); |
2436 | u = g_date_time_to_unix (datetime: dt); |
2437 | g_date_time_unref (datetime: dt); |
2438 | |
2439 | i1 = g_time_zone_adjust_time (tz, type: G_TIME_TYPE_DAYLIGHT, time_: &u2); |
2440 | g_assert_cmpint (i1, >=, 0); |
2441 | g_assert (u == u2); |
2442 | |
2443 | g_time_zone_unref (tz); |
2444 | } |
2445 | |
2446 | static void |
2447 | (void) |
2448 | { |
2449 | GTimeZone *tz; |
2450 | |
2451 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
2452 | tz = g_time_zone_new (identifier: "blabla" ); |
2453 | G_GNUC_END_IGNORE_DEPRECATIONS |
2454 | |
2455 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC" ); |
2456 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "UTC" ); |
2457 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 0); |
2458 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2459 | |
2460 | g_time_zone_unref (tz); |
2461 | } |
2462 | |
2463 | static void |
2464 | (void) |
2465 | { |
2466 | GTimeZone *tz; |
2467 | |
2468 | tz = g_time_zone_new_identifier (identifier: "blabla" ); |
2469 | |
2470 | g_assert_null (tz); |
2471 | } |
2472 | |
2473 | static void |
2474 | test_posix_parse (void) |
2475 | { |
2476 | GTimeZone *tz; |
2477 | GDateTime *gdt1, *gdt2; |
2478 | |
2479 | /* Check that an unknown zone name falls back to UTC. */ |
2480 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
2481 | tz = g_time_zone_new (identifier: "nonexistent" ); |
2482 | G_GNUC_END_IGNORE_DEPRECATIONS |
2483 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC" ); |
2484 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "UTC" ); |
2485 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 0); |
2486 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2487 | g_time_zone_unref (tz); |
2488 | |
2489 | /* An existent zone name should not fall back to UTC. */ |
2490 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
2491 | tz = g_time_zone_new (identifier: "PST8" ); |
2492 | G_GNUC_END_IGNORE_DEPRECATIONS |
2493 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8" ); |
2494 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST" ); |
2495 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600); |
2496 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2497 | g_time_zone_unref (tz); |
2498 | |
2499 | /* This fails rules_from_identifier on Unix (though not on Windows) |
2500 | * but passes anyway because PST8PDT is a zone name. |
2501 | */ |
2502 | tz = g_time_zone_new_identifier (identifier: "PST8PDT" ); |
2503 | g_assert_nonnull (tz); |
2504 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8PDT" ); |
2505 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST" ); |
2506 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600); |
2507 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2508 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "PDT" ); |
2509 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==,- 7 * 3600); |
2510 | g_assert (g_time_zone_is_dst (tz, 1)); |
2511 | g_time_zone_unref (tz); |
2512 | |
2513 | tz = g_time_zone_new_identifier (identifier: "PST8PDT6:32:15" ); |
2514 | #ifdef G_OS_WIN32 |
2515 | g_assert_nonnull (tz); |
2516 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8PDT6:32:15" ); |
2517 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST" ); |
2518 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600); |
2519 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2520 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "PDT" ); |
2521 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, - 6 * 3600 - 32 *60 - 15); |
2522 | g_assert (g_time_zone_is_dst (tz, 1)); |
2523 | gdt1 = g_date_time_new (tz, 2012, 12, 6, 11, 15, 23.0); |
2524 | gdt2 = g_date_time_new (tz, 2012, 6, 6, 11, 15, 23.0); |
2525 | g_assert (!g_date_time_is_daylight_savings (gdt1)); |
2526 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, -28800); |
2527 | g_assert (g_date_time_is_daylight_savings (gdt2)); |
2528 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, -23535); |
2529 | g_date_time_unref (gdt1); |
2530 | g_date_time_unref (gdt2); |
2531 | #else |
2532 | g_assert_null (tz); |
2533 | #endif |
2534 | g_clear_pointer (&tz, g_time_zone_unref); |
2535 | |
2536 | tz = g_time_zone_new_identifier (identifier: "NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0" ); |
2537 | g_assert_nonnull (tz); |
2538 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0" ); |
2539 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST" ); |
2540 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); |
2541 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2542 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "NZDT" ); |
2543 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, 13 * 3600); |
2544 | g_assert (g_time_zone_is_dst (tz, 1)); |
2545 | gdt1 = g_date_time_new (tz, year: 2012, month: 3, day: 18, hour: 0, minute: 15, seconds: 23.0); |
2546 | gdt2 = g_date_time_new (tz, year: 2012, month: 3, day: 18, hour: 3, minute: 15, seconds: 23.0); |
2547 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2548 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2549 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2550 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2551 | g_date_time_unref (datetime: gdt1); |
2552 | g_date_time_unref (datetime: gdt2); |
2553 | gdt1 = g_date_time_new (tz, year: 2012, month: 10, day: 7, hour: 3, minute: 15, seconds: 23.0); |
2554 | gdt2 = g_date_time_new (tz, year: 2012, month: 10, day: 7, hour: 1, minute: 15, seconds: 23.0); |
2555 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2556 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2557 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2558 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2559 | g_date_time_unref (datetime: gdt1); |
2560 | g_date_time_unref (datetime: gdt2); |
2561 | g_time_zone_unref (tz); |
2562 | |
2563 | tz = g_time_zone_new_identifier (identifier: "NZST-12:00:00NZDT-13:00:00,279,76" ); |
2564 | g_assert_nonnull (tz); |
2565 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,279,76" ); |
2566 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST" ); |
2567 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); |
2568 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2569 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "NZDT" ); |
2570 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, 13 * 3600); |
2571 | g_assert (g_time_zone_is_dst (tz, 1)); |
2572 | gdt1 = g_date_time_new (tz, year: 2012, month: 3, day: 18, hour: 0, minute: 15, seconds: 23.0); |
2573 | gdt2 = g_date_time_new (tz, year: 2012, month: 3, day: 18, hour: 3, minute: 15, seconds: 23.0); |
2574 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2575 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2576 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2577 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2578 | g_date_time_unref (datetime: gdt1); |
2579 | g_date_time_unref (datetime: gdt2); |
2580 | gdt1 = g_date_time_new (tz, year: 2012, month: 10, day: 7, hour: 3, minute: 15, seconds: 23.0); |
2581 | gdt2 = g_date_time_new (tz, year: 2012, month: 10, day: 7, hour: 1, minute: 15, seconds: 23.0); |
2582 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2583 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2584 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2585 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2586 | g_date_time_unref (datetime: gdt1); |
2587 | g_date_time_unref (datetime: gdt2); |
2588 | g_time_zone_unref (tz); |
2589 | |
2590 | tz = g_time_zone_new_identifier (identifier: "NZST-12:00:00NZDT-13:00:00,J279,J76" ); |
2591 | g_assert_nonnull (tz); |
2592 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,J279,J76" ); |
2593 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST" ); |
2594 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); |
2595 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2596 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "NZDT" ); |
2597 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, 13 * 3600); |
2598 | g_assert (g_time_zone_is_dst (tz, 1)); |
2599 | gdt1 = g_date_time_new (tz, year: 2012, month: 3, day: 18, hour: 0, minute: 15, seconds: 23.0); |
2600 | gdt2 = g_date_time_new (tz, year: 2012, month: 3, day: 18, hour: 3, minute: 15, seconds: 23.0); |
2601 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2602 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2603 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2604 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2605 | g_date_time_unref (datetime: gdt1); |
2606 | g_date_time_unref (datetime: gdt2); |
2607 | gdt1 = g_date_time_new (tz, year: 2012, month: 10, day: 7, hour: 3, minute: 15, seconds: 23.0); |
2608 | gdt2 = g_date_time_new (tz, year: 2012, month: 10, day: 7, hour: 1, minute: 15, seconds: 23.0); |
2609 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2610 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2611 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2612 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2613 | g_date_time_unref (datetime: gdt1); |
2614 | g_date_time_unref (datetime: gdt2); |
2615 | g_time_zone_unref (tz); |
2616 | |
2617 | tz = g_time_zone_new_identifier (identifier: "NZST-12:00:00NZDT-13:00:00,M10.1.0/07:00,M3.3.0/07:00" ); |
2618 | g_assert_nonnull (tz); |
2619 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,M10.1.0/07:00,M3.3.0/07:00" ); |
2620 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST" ); |
2621 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); |
2622 | g_assert (!g_time_zone_is_dst (tz, 0)); |
2623 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "NZDT" ); |
2624 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, 13 * 3600); |
2625 | g_assert (g_time_zone_is_dst (tz, 1)); |
2626 | gdt1 = g_date_time_new (tz, year: 2012, month: 3, day: 18, hour: 5, minute: 15, seconds: 23.0); |
2627 | gdt2 = g_date_time_new (tz, year: 2012, month: 3, day: 18, hour: 8, minute: 15, seconds: 23.0); |
2628 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2629 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2630 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2631 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2632 | g_date_time_unref (datetime: gdt1); |
2633 | g_date_time_unref (datetime: gdt2); |
2634 | gdt1 = g_date_time_new (tz, year: 2012, month: 10, day: 7, hour: 8, minute: 15, seconds: 23.0); |
2635 | gdt2 = g_date_time_new (tz, year: 2012, month: 10, day: 7, hour: 6, minute: 15, seconds: 23.0); |
2636 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2637 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2638 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2639 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2640 | g_date_time_unref (datetime: gdt1); |
2641 | g_date_time_unref (datetime: gdt2); |
2642 | gdt1 = g_date_time_new (tz, year: 1902, month: 10, day: 7, hour: 8, minute: 15, seconds: 23.0); |
2643 | gdt2 = g_date_time_new (tz, year: 1902, month: 10, day: 7, hour: 6, minute: 15, seconds: 23.0); |
2644 | g_assert (!g_date_time_is_daylight_savings (gdt1)); |
2645 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 43200); |
2646 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2647 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2648 | g_date_time_unref (datetime: gdt1); |
2649 | g_date_time_unref (datetime: gdt2); |
2650 | gdt1 = g_date_time_new (tz, year: 2142, month: 10, day: 7, hour: 8, minute: 15, seconds: 23.0); |
2651 | gdt2 = g_date_time_new (tz, year: 2142, month: 10, day: 7, hour: 6, minute: 15, seconds: 23.0); |
2652 | g_assert (g_date_time_is_daylight_savings (gdt1)); |
2653 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); |
2654 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2655 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2656 | g_date_time_unref (datetime: gdt1); |
2657 | g_date_time_unref (datetime: gdt2); |
2658 | gdt1 = g_date_time_new (tz, year: 3212, month: 10, day: 7, hour: 8, minute: 15, seconds: 23.0); |
2659 | gdt2 = g_date_time_new (tz, year: 3212, month: 10, day: 7, hour: 6, minute: 15, seconds: 23.0); |
2660 | g_assert (!g_date_time_is_daylight_savings (gdt1)); |
2661 | g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 43200); |
2662 | g_assert (!g_date_time_is_daylight_savings (gdt2)); |
2663 | g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); |
2664 | g_date_time_unref (datetime: gdt1); |
2665 | g_date_time_unref (datetime: gdt2); |
2666 | g_time_zone_unref (tz); |
2667 | |
2668 | tz = g_time_zone_new_identifier (identifier: "VIR-00:30" ); |
2669 | g_assert_nonnull (tz); |
2670 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-00:30" ); |
2671 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR" ); |
2672 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (30 * 60)); |
2673 | g_assert_false (g_time_zone_is_dst (tz, 0)); |
2674 | |
2675 | tz = g_time_zone_new_identifier (identifier: "VIR-00:30VID,0/00:00:00,365/23:59:59" ); |
2676 | g_assert_nonnull (tz); |
2677 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-00:30VID,0/00:00:00,365/23:59:59" ); |
2678 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR" ); |
2679 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (30 * 60)); |
2680 | g_assert_false (g_time_zone_is_dst (tz, 0)); |
2681 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID" ); |
2682 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (90 * 60)); |
2683 | g_assert_true (g_time_zone_is_dst (tz, 1)); |
2684 | |
2685 | tz = g_time_zone_new_identifier (identifier: "VIR-02:30VID,0/00:00:00,365/23:59:59" ); |
2686 | g_assert_nonnull (tz); |
2687 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-02:30VID,0/00:00:00,365/23:59:59" ); |
2688 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR" ); |
2689 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (150 * 60)); |
2690 | g_assert_false (g_time_zone_is_dst (tz, 0)); |
2691 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID" ); |
2692 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (210 * 60)); |
2693 | g_assert_true (g_time_zone_is_dst (tz, 1)); |
2694 | |
2695 | tz = g_time_zone_new_identifier (identifier: "VIR-02:30VID-04:30,0/00:00:00,365/23:59:59" ); |
2696 | g_assert_nonnull (tz); |
2697 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-02:30VID-04:30,0/00:00:00,365/23:59:59" ); |
2698 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR" ); |
2699 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (150 * 60)); |
2700 | g_assert_false (g_time_zone_is_dst (tz, 0)); |
2701 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID" ); |
2702 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (270 * 60)); |
2703 | g_assert_true (g_time_zone_is_dst (tz, 1)); |
2704 | |
2705 | tz = g_time_zone_new_identifier (identifier: "VIR-12:00VID-13:00,0/00:00:00,365/23:59:59" ); |
2706 | g_assert_nonnull (tz); |
2707 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-12:00VID-13:00,0/00:00:00,365/23:59:59" ); |
2708 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR" ); |
2709 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (720 * 60)); |
2710 | g_assert_false (g_time_zone_is_dst (tz, 0)); |
2711 | g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID" ); |
2712 | g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (780 * 60)); |
2713 | g_assert_true (g_time_zone_is_dst (tz, 1)); |
2714 | } |
2715 | |
2716 | static void |
2717 | test_GDateTime_floating_point (void) |
2718 | { |
2719 | GDateTime *dt; |
2720 | GTimeZone *tz; |
2721 | |
2722 | g_test_bug (bug_uri_snippet: "http://bugzilla.gnome.org/697715" ); |
2723 | |
2724 | tz = g_time_zone_new_identifier (identifier: "-03:00" ); |
2725 | g_assert_nonnull (tz); |
2726 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "-03:00" ); |
2727 | dt = g_date_time_new (tz, year: 2010, month: 5, day: 24, hour: 8, minute: 0, seconds: 1.000001); |
2728 | g_time_zone_unref (tz); |
2729 | g_assert_cmpint (g_date_time_get_microsecond (dt), ==, 1); |
2730 | g_date_time_unref (datetime: dt); |
2731 | } |
2732 | |
2733 | /* Check that g_time_zone_get_identifier() returns the identifier given to |
2734 | * g_time_zone_new(), or "UTC" if loading the timezone failed. */ |
2735 | static void |
2736 | test_identifier (void) |
2737 | { |
2738 | GTimeZone *tz; |
2739 | gchar *old_tz = g_strdup (str: g_getenv (variable: "TZ" )); |
2740 | |
2741 | #ifdef G_OS_WIN32 |
2742 | const char *recife_tz = "SA Eastern Standard Time" ; |
2743 | #else |
2744 | const char *recife_tz = "America/Recife" ; |
2745 | #endif |
2746 | |
2747 | tz = g_time_zone_new_identifier (identifier: "UTC" ); |
2748 | g_assert_nonnull (tz); |
2749 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC" ); |
2750 | g_time_zone_unref (tz); |
2751 | |
2752 | tz = g_time_zone_new_utc (); |
2753 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC" ); |
2754 | g_time_zone_unref (tz); |
2755 | |
2756 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
2757 | tz = g_time_zone_new (identifier: "some rubbish" ); |
2758 | G_GNUC_END_IGNORE_DEPRECATIONS |
2759 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC" ); |
2760 | g_time_zone_unref (tz); |
2761 | |
2762 | tz = g_time_zone_new_identifier (identifier: "Z" ); |
2763 | g_assert_nonnull (tz); |
2764 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "Z" ); |
2765 | g_time_zone_unref (tz); |
2766 | |
2767 | tz = g_time_zone_new_identifier (identifier: "+03:15" ); |
2768 | g_assert_nonnull (tz); |
2769 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "+03:15" ); |
2770 | g_time_zone_unref (tz); |
2771 | |
2772 | /* System timezone. We can’t change this, but we can at least assert that |
2773 | * the identifier is non-NULL and non-empty. */ |
2774 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
2775 | tz = g_time_zone_new (NULL); |
2776 | G_GNUC_END_IGNORE_DEPRECATIONS |
2777 | g_test_message (format: "System time zone identifier: %s" , g_time_zone_get_identifier (tz)); |
2778 | g_assert_nonnull (g_time_zone_get_identifier (tz)); |
2779 | g_assert_cmpstr (g_time_zone_get_identifier (tz), !=, "" ); |
2780 | g_time_zone_unref (tz); |
2781 | |
2782 | /* Local timezone tests. */ |
2783 | if (g_setenv (variable: "TZ" , value: recife_tz, TRUE)) |
2784 | { |
2785 | tz = g_time_zone_new_local (); |
2786 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, recife_tz); |
2787 | g_time_zone_unref (tz); |
2788 | } |
2789 | |
2790 | if (g_setenv (variable: "TZ" , value: "some rubbish" , TRUE)) |
2791 | { |
2792 | tz = g_time_zone_new_local (); |
2793 | g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC" ); |
2794 | g_time_zone_unref (tz); |
2795 | } |
2796 | |
2797 | if (old_tz != NULL) |
2798 | g_assert_true (g_setenv ("TZ" , old_tz, TRUE)); |
2799 | else |
2800 | g_unsetenv (variable: "TZ" ); |
2801 | |
2802 | g_free (mem: old_tz); |
2803 | } |
2804 | |
2805 | /* Test various calls to g_time_zone_new_offset(). */ |
2806 | static void |
2807 | test_new_offset (void) |
2808 | { |
2809 | const gint32 vectors[] = |
2810 | { |
2811 | -10000, |
2812 | -3600, |
2813 | -61, |
2814 | -60, |
2815 | -59, |
2816 | 0, |
2817 | 59, |
2818 | 60, |
2819 | 61, |
2820 | 3600, |
2821 | 10000, |
2822 | }; |
2823 | gsize i; |
2824 | |
2825 | for (i = 0; i < G_N_ELEMENTS (vectors); i++) |
2826 | { |
2827 | GTimeZone *tz = NULL; |
2828 | |
2829 | g_test_message (format: "Vector %" G_GSIZE_FORMAT ": %d" , i, vectors[i]); |
2830 | |
2831 | tz = g_time_zone_new_offset (seconds: vectors[i]); |
2832 | g_assert_nonnull (tz); |
2833 | g_assert_cmpstr (g_time_zone_get_identifier (tz), !=, "UTC" ); |
2834 | g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, vectors[i]); |
2835 | g_time_zone_unref (tz); |
2836 | } |
2837 | } |
2838 | |
2839 | static void |
2840 | test_time_zone_parse_rfc8536 (void) |
2841 | { |
2842 | const gchar *test_files[] = |
2843 | { |
2844 | /* Generated with `zic -b slim`; see |
2845 | * https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1533#note_842235 */ |
2846 | "Amsterdam-slim" , |
2847 | /* Generated with `zic -b fat` */ |
2848 | "Amsterdam-fat" , |
2849 | }; |
2850 | gsize i; |
2851 | |
2852 | g_test_summary (summary: "Test parsing time zone files in RFC 8536 version 3 format" ); |
2853 | g_test_bug (bug_uri_snippet: "https://gitlab.gnome.org/GNOME/glib/-/issues/2129" ); |
2854 | |
2855 | for (i = 0; i < G_N_ELEMENTS (test_files); i++) |
2856 | { |
2857 | gchar *path = NULL; |
2858 | GTimeZone *tz = NULL; |
2859 | |
2860 | path = g_test_build_filename (file_type: G_TEST_DIST, first_path: "time-zones" , test_files[i], NULL); |
2861 | g_assert_true (g_path_is_absolute (path)); |
2862 | tz = g_time_zone_new_identifier (identifier: path); |
2863 | g_assert_nonnull (tz); |
2864 | g_time_zone_unref (tz); |
2865 | g_free (mem: path); |
2866 | } |
2867 | } |
2868 | |
2869 | /* Check GTimeZone instances are cached. */ |
2870 | static void |
2871 | test_time_zone_caching (void) |
2872 | { |
2873 | GTimeZone *tz1 = NULL, *tz2 = NULL; |
2874 | |
2875 | g_test_summary (summary: "GTimeZone instances are cached" ); |
2876 | |
2877 | /* Check a specific (arbitrary) timezone. These are only cached while third |
2878 | * party code holds a ref to at least one instance. */ |
2879 | #ifdef G_OS_UNIX |
2880 | tz1 = g_time_zone_new_identifier (identifier: "Europe/London" ); |
2881 | g_assert_nonnull (tz1); |
2882 | tz2 = g_time_zone_new_identifier (identifier: "Europe/London" ); |
2883 | g_assert_nonnull (tz2); |
2884 | g_time_zone_unref (tz: tz1); |
2885 | g_time_zone_unref (tz: tz2); |
2886 | #elif defined G_OS_WIN32 |
2887 | tz1 = g_time_zone_new_identifier ("GMT Standard Time" ); |
2888 | g_assert_nonnull (tz1); |
2889 | tz2 = g_time_zone_new_identifier ("GMT Standard Time" ); |
2890 | g_assert_nonnull (tz2); |
2891 | g_time_zone_unref (tz1); |
2892 | g_time_zone_unref (tz2); |
2893 | #endif |
2894 | |
2895 | /* Only compare pointers */ |
2896 | g_assert_true (tz1 == tz2); |
2897 | |
2898 | /* Check the default timezone, local and UTC. These are cached internally in |
2899 | * GLib, so should persist even after the last third party reference is |
2900 | * dropped. |
2901 | * |
2902 | * The default timezone could be NULL on some platforms (FreeBSD) if |
2903 | * `/etc/localtime` is not set correctly. */ |
2904 | tz1 = g_time_zone_new_identifier (NULL); |
2905 | if (tz1 != NULL) |
2906 | { |
2907 | g_assert_nonnull (tz1); |
2908 | g_time_zone_unref (tz: tz1); |
2909 | tz2 = g_time_zone_new_identifier (NULL); |
2910 | g_assert_nonnull (tz2); |
2911 | g_time_zone_unref (tz: tz2); |
2912 | |
2913 | g_assert_true (tz1 == tz2); |
2914 | } |
2915 | |
2916 | tz1 = g_time_zone_new_utc (); |
2917 | g_time_zone_unref (tz: tz1); |
2918 | tz2 = g_time_zone_new_utc (); |
2919 | g_time_zone_unref (tz: tz2); |
2920 | |
2921 | g_assert_true (tz1 == tz2); |
2922 | |
2923 | tz1 = g_time_zone_new_local (); |
2924 | g_time_zone_unref (tz: tz1); |
2925 | tz2 = g_time_zone_new_local (); |
2926 | g_time_zone_unref (tz: tz2); |
2927 | |
2928 | g_assert_true (tz1 == tz2); |
2929 | } |
2930 | |
2931 | |
2932 | gint |
2933 | main (gint argc, |
2934 | gchar *argv[]) |
2935 | { |
2936 | /* In glibc, LANGUAGE is used as highest priority guess for category value. |
2937 | * Unset it to avoid interference with tests using setlocale and translation. */ |
2938 | g_unsetenv (variable: "LANGUAGE" ); |
2939 | |
2940 | g_test_init (argc: &argc, argv: &argv, NULL); |
2941 | |
2942 | /* GDateTime Tests */ |
2943 | bind_textdomain_codeset (domainname: "glib20" , codeset: "UTF-8" ); |
2944 | |
2945 | g_test_add_func (testpath: "/GDateTime/invalid" , test_func: test_GDateTime_invalid); |
2946 | g_test_add_func (testpath: "/GDateTime/add_days" , test_func: test_GDateTime_add_days); |
2947 | g_test_add_func (testpath: "/GDateTime/add_full" , test_func: test_GDateTime_add_full); |
2948 | g_test_add_func (testpath: "/GDateTime/add_hours" , test_func: test_GDateTime_add_hours); |
2949 | g_test_add_func (testpath: "/GDateTime/add_minutes" , test_func: test_GDateTime_add_minutes); |
2950 | g_test_add_func (testpath: "/GDateTime/add_months" , test_func: test_GDateTime_add_months); |
2951 | g_test_add_func (testpath: "/GDateTime/add_seconds" , test_func: test_GDateTime_add_seconds); |
2952 | g_test_add_func (testpath: "/GDateTime/add_weeks" , test_func: test_GDateTime_add_weeks); |
2953 | g_test_add_func (testpath: "/GDateTime/add_years" , test_func: test_GDateTime_add_years); |
2954 | g_test_add_func (testpath: "/GDateTime/compare" , test_func: test_GDateTime_compare); |
2955 | g_test_add_func (testpath: "/GDateTime/diff" , test_func: test_GDateTime_diff); |
2956 | g_test_add_func (testpath: "/GDateTime/equal" , test_func: test_GDateTime_equal); |
2957 | g_test_add_func (testpath: "/GDateTime/get_day_of_week" , test_func: test_GDateTime_get_day_of_week); |
2958 | g_test_add_func (testpath: "/GDateTime/get_day_of_month" , test_func: test_GDateTime_get_day_of_month); |
2959 | g_test_add_func (testpath: "/GDateTime/get_day_of_year" , test_func: test_GDateTime_get_day_of_year); |
2960 | g_test_add_func (testpath: "/GDateTime/get_hour" , test_func: test_GDateTime_get_hour); |
2961 | g_test_add_func (testpath: "/GDateTime/get_microsecond" , test_func: test_GDateTime_get_microsecond); |
2962 | g_test_add_func (testpath: "/GDateTime/get_minute" , test_func: test_GDateTime_get_minute); |
2963 | g_test_add_func (testpath: "/GDateTime/get_month" , test_func: test_GDateTime_get_month); |
2964 | g_test_add_func (testpath: "/GDateTime/get_second" , test_func: test_GDateTime_get_second); |
2965 | g_test_add_func (testpath: "/GDateTime/get_utc_offset" , test_func: test_GDateTime_get_utc_offset); |
2966 | g_test_add_func (testpath: "/GDateTime/get_year" , test_func: test_GDateTime_get_year); |
2967 | g_test_add_func (testpath: "/GDateTime/hash" , test_func: test_GDateTime_hash); |
2968 | g_test_add_func (testpath: "/GDateTime/new_from_unix" , test_func: test_GDateTime_new_from_unix); |
2969 | g_test_add_func (testpath: "/GDateTime/new_from_unix_utc" , test_func: test_GDateTime_new_from_unix_utc); |
2970 | g_test_add_func (testpath: "/GDateTime/new_from_unix/overflow" , test_func: test_GDateTime_new_from_unix_overflow); |
2971 | g_test_add_func (testpath: "/GDateTime/new_from_timeval" , test_func: test_GDateTime_new_from_timeval); |
2972 | g_test_add_func (testpath: "/GDateTime/new_from_timeval_utc" , test_func: test_GDateTime_new_from_timeval_utc); |
2973 | g_test_add_func (testpath: "/GDateTime/new_from_timeval/overflow" , test_func: test_GDateTime_new_from_timeval_overflow); |
2974 | g_test_add_func (testpath: "/GDateTime/new_from_iso8601" , test_func: test_GDateTime_new_from_iso8601); |
2975 | g_test_add_func (testpath: "/GDateTime/new_from_iso8601/2" , test_func: test_GDateTime_new_from_iso8601_2); |
2976 | g_test_add_func (testpath: "/GDateTime/new_full" , test_func: test_GDateTime_new_full); |
2977 | g_test_add_func (testpath: "/GDateTime/now" , test_func: test_GDateTime_now); |
2978 | g_test_add_func (testpath: "/GDateTime/test-6-days-until-end-of-the-month" , test_func: test_6_days_until_end_of_the_month); |
2979 | g_test_add_func (testpath: "/GDateTime/printf" , test_func: test_GDateTime_printf); |
2980 | g_test_add_func (testpath: "/GDateTime/non_utf8_printf" , test_func: test_non_utf8_printf); |
2981 | g_test_add_func (testpath: "/GDateTime/format_unrepresentable" , test_func: test_format_unrepresentable); |
2982 | g_test_add_func (testpath: "/GDateTime/format_iso8601" , test_func: test_format_iso8601); |
2983 | g_test_add_func (testpath: "/GDateTime/strftime" , test_func: test_strftime); |
2984 | g_test_add_func (testpath: "/GDateTime/strftime/error_handling" , test_func: test_GDateTime_strftime_error_handling); |
2985 | g_test_add_func (testpath: "/GDateTime/modifiers" , test_func: test_modifiers); |
2986 | g_test_add_func (testpath: "/GDateTime/month_names" , test_func: test_month_names); |
2987 | g_test_add_func (testpath: "/GDateTime/to_local" , test_func: test_GDateTime_to_local); |
2988 | g_test_add_func (testpath: "/GDateTime/to_unix" , test_func: test_GDateTime_to_unix); |
2989 | g_test_add_func (testpath: "/GDateTime/to_timeval" , test_func: test_GDateTime_to_timeval); |
2990 | g_test_add_func (testpath: "/GDateTime/to_utc" , test_func: test_GDateTime_to_utc); |
2991 | g_test_add_func (testpath: "/GDateTime/now_utc" , test_func: test_GDateTime_now_utc); |
2992 | g_test_add_func (testpath: "/GDateTime/dst" , test_func: test_GDateTime_dst); |
2993 | g_test_add_func (testpath: "/GDateTime/test_z" , test_func: test_z); |
2994 | g_test_add_func (testpath: "/GDateTime/test-all-dates" , test_func: test_all_dates); |
2995 | g_test_add_func (testpath: "/GTimeZone/find-interval" , test_func: test_find_interval); |
2996 | g_test_add_func (testpath: "/GTimeZone/adjust-time" , test_func: test_adjust_time); |
2997 | g_test_add_func (testpath: "/GTimeZone/no-header" , test_func: test_no_header); |
2998 | g_test_add_func (testpath: "/GTimeZone/no-header-identifier" , test_func: test_no_header_identifier); |
2999 | g_test_add_func (testpath: "/GTimeZone/posix-parse" , test_func: test_posix_parse); |
3000 | g_test_add_func (testpath: "/GTimeZone/floating-point" , test_func: test_GDateTime_floating_point); |
3001 | g_test_add_func (testpath: "/GTimeZone/identifier" , test_func: test_identifier); |
3002 | g_test_add_func (testpath: "/GTimeZone/new-offset" , test_func: test_new_offset); |
3003 | g_test_add_func (testpath: "/GTimeZone/parse-rfc8536" , test_func: test_time_zone_parse_rfc8536); |
3004 | g_test_add_func (testpath: "/GTimeZone/caching" , test_func: test_time_zone_caching); |
3005 | |
3006 | return g_test_run (); |
3007 | } |
3008 | |