3 * Copyright (C) 2009-2010 Christian Hergert <chris@dronelabs.com>
4 * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
5 * Copyright (C) 2010 Emmanuele Bassi <ebassi@linux.intel.com>
7 * This is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 /* Algorithms within this file are based on the Calendar FAQ by
23 * Claus Tondering. It can be found at
24 * http://www.tondering.dk/claus/cal/calendar29.txt
26 * Copyright and disclaimer
27 * ------------------------
28 * This document is Copyright (C) 2008 by Claus Tondering.
29 * E-mail: claus@tondering.dk. (Please include the word
30 * "calendar" in the subject line.)
31 * The document may be freely distributed, provided this
32 * copyright notice is included and no money is charged for
35 * This document is provided "as is". No warranties are made as
51 #endif /* !G_OS_WIN32 */
53 #include "gdatetime.h"
56 #include "gfileutils.h"
58 #include "gstrfuncs.h"
59 #include "gtestutils.h"
65 * @short_description: A structure representing Date and Time
67 * #GDateTime is a structure that combines a date and time into a single
68 * structure. It provides many conversion and methods to manipulate dates
69 * and times. Time precision is provided down to microseconds.
71 * #GDateTime is an immutable object: once it has been created it cannot be
72 * modified further. All modifiers will create a new #GDateTime.
74 * #GDateTime is reference counted: the reference count is increased by calling
75 * g_date_time_ref() and decreased by calling g_date_time_unref(). When the
76 * reference count drops to 0, the resources allocated by the #GDateTime
77 * structure are released.
79 * Internally, #GDateTime uses the Proleptic Gregorian Calendar, the first
80 * representable date is 0001-01-01. However, the public API uses the
81 * internationally accepted Gregorian Calendar.
83 * #GDateTime is available since GLib 2.26.
86 #define UNIX_EPOCH_START 719163
88 #define DAYS_IN_4YEARS 1461 /* days in 4 years */
89 #define DAYS_IN_100YEARS 36524 /* days in 100 years */
90 #define DAYS_IN_400YEARS 146097 /* days in 400 years */
92 #define USEC_PER_SECOND (G_GINT64_CONSTANT (1000000))
93 #define USEC_PER_MINUTE (G_GINT64_CONSTANT (60000000))
94 #define USEC_PER_HOUR (G_GINT64_CONSTANT (3600000000))
95 #define USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000))
96 #define USEC_PER_DAY (G_GINT64_CONSTANT (86400000000))
97 #define SEC_PER_DAY (G_GINT64_CONSTANT (86400))
99 #define GREGORIAN_LEAP(y) ((((y) % 4) == 0) && (!((((y) % 100) == 0) && (((y) % 400) != 0))))
100 #define JULIAN_YEAR(d) ((d)->julian / 365.25)
101 #define DAYS_PER_PERIOD (G_GINT64_CONSTANT (2914695))
103 #define GET_AMPM(d,l) ((g_date_time_get_hour (d) < 12) \
104 ? (l ? C_("GDateTime", "am") : C_("GDateTime", "AM")) \
105 : (l ? C_("GDateTime", "pm") : C_("GDateTime", "PM")))
107 #define WEEKDAY_ABBR(d) (get_weekday_name_abbr (g_date_time_get_day_of_week (datetime)))
108 #define WEEKDAY_FULL(d) (get_weekday_name (g_date_time_get_day_of_week (datetime)))
110 #define MONTH_ABBR(d) (get_month_name_abbr (g_date_time_get_month (datetime)))
111 #define MONTH_FULL(d) (get_month_name (g_date_time_get_month (datetime)))
113 /* Translators: this is the preferred format for expressing the date */
114 #define GET_PREFERRED_DATE(d) (g_date_time_printf ((d), C_("GDateTime", "%m/%d/%y")))
116 /* Translators: this is the preferred format for expressing the time */
117 #define GET_PREFERRED_TIME(d) (g_date_time_printf ((d), C_("GDateTime", "%H:%M:%S")))
119 typedef struct _GTimeZone GTimeZone;
123 /* 1 is 0001-01-01 in Proleptic Gregorian */
125 /* Microsecond timekeeping within Day */
128 /* TimeZone information, NULL is UTC */
131 volatile gint ref_count;
136 /* TZ abbreviation (e.g. PST) */
144 static const guint16 days_in_months[2][13] =
146 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
147 { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
150 static const guint16 days_in_year[2][13] =
152 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
153 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
157 get_month_name (gint month)
162 return C_("GDateTime", "January");
164 return C_("GDateTime", "February");
166 return C_("GDateTime", "March");
168 return C_("GDateTime", "April");
170 return C_("GDateTime", "May");
172 return C_("GDateTime", "June");
174 return C_("GDateTime", "July");
176 return C_("GDateTime", "August");
178 return C_("GDateTime", "September");
180 return C_("GDateTime", "October");
182 return C_("GDateTime", "November");
184 return C_("GDateTime", "December");
187 g_warning ("Invalid month number %d", month);
194 get_month_name_abbr (gint month)
199 return C_("GDateTime", "Jan");
201 return C_("GDateTime", "Feb");
203 return C_("GDateTime", "Mar");
205 return C_("GDateTime", "Apr");
207 return C_("GDateTime", "May");
209 return C_("GDateTime", "Jun");
211 return C_("GDateTime", "Jul");
213 return C_("GDateTime", "Aug");
215 return C_("GDateTime", "Sep");
217 return C_("GDateTime", "Oct");
219 return C_("GDateTime", "Nov");
221 return C_("GDateTime", "Dec");
224 g_warning ("Invalid month number %d", month);
231 get_weekday_name (gint day)
236 return C_("GDateTime", "Monday");
238 return C_("GDateTime", "Tuesday");
240 return C_("GDateTime", "Wednesday");
242 return C_("GDateTime", "Thursday");
244 return C_("GDateTime", "Friday");
246 return C_("GDateTime", "Saturday");
248 return C_("GDateTime", "Sunday");
251 g_warning ("Invalid week day number %d", day);
258 get_weekday_name_abbr (gint day)
263 return C_("GDateTime", "Mon");
265 return C_("GDateTime", "Tue");
267 return C_("GDateTime", "Wed");
269 return C_("GDateTime", "Thu");
271 return C_("GDateTime", "Fri");
273 return C_("GDateTime", "Sat");
275 return C_("GDateTime", "Sun");
278 g_warning ("Invalid week day number %d", day);
285 date_to_proleptic_gregorian (gint year,
291 days = (year - 1) * 365 + ((year - 1) / 4) - ((year - 1) / 100)
292 + ((year - 1) / 400);
294 days += days_in_year[0][month - 1];
295 if (GREGORIAN_LEAP (year) && month > 2)
304 g_date_time_add_days_internal (GDateTime *datetime,
307 datetime->days += days;
311 g_date_time_add_usec (GDateTime *datetime,
314 gint64 u = datetime->usec + usecs;
315 gint d = u / USEC_PER_DAY;
321 g_date_time_add_days_internal (datetime, d);
324 datetime->usec = USEC_PER_DAY + (u % USEC_PER_DAY);
326 datetime->usec = u % USEC_PER_DAY;
330 * g_date_time_add_ymd:
331 * @datetime: a #GDateTime
332 * @years: years to add, in the Gregorian calendar
333 * @months: months to add, in the Gregorian calendar
334 * @days: days to add, in the Gregorian calendar
336 * Updates @datetime by adding @years, @months and @days to it
338 * This function modifies the passed #GDateTime so public accessors
339 * should make always pass a copy
342 g_date_time_add_ymd (GDateTime *datetime,
347 gint y = g_date_time_get_year (datetime);
348 gint m = g_date_time_get_month (datetime);
349 gint d = g_date_time_get_day_of_month (datetime);
351 const guint16 *max_days;
355 /* subtract one day for leap years */
356 if (GREGORIAN_LEAP (y) && m == 2)
363 step = months > 0 ? 1 : -1;
364 for (i = 0; i < ABS (months); i++)
381 max_days = days_in_months[GREGORIAN_LEAP (y) ? 1 : 0];
385 datetime->days = date_to_proleptic_gregorian (y, m, d);
386 g_date_time_add_days_internal (datetime, days);
389 #define ZONEINFO_DIR "zoneinfo"
390 #define TZ_MAGIC "TZif"
391 #define TZ_MAGIC_LEN (strlen (TZ_MAGIC))
392 #define TZ_HEADER_SIZE 44
393 #define TZ_TIMECNT_OFFSET 32
394 #define TZ_TYPECNT_OFFSET 36
395 #define TZ_TRANSITIONS_OFFSET 44
397 #define TZ_TTINFO_SIZE 6
398 #define TZ_TTINFO_GMTOFF_OFFSET 0
399 #define TZ_TTINFO_ISDST_OFFSET 4
400 #define TZ_TTINFO_NAME_OFFSET 5
403 get_tzdata_path (const gchar *tz_name)
409 const gchar *tz_dir = g_getenv ("TZDIR");
412 retval = g_build_filename (tz_dir, tz_name, NULL);
414 retval = g_build_filename ("/", "usr", "share", ZONEINFO_DIR, tz_name, NULL);
418 /* an empty tz_name means "the current timezone file". tzset(3) defines
419 * it to be /usr/share/zoneinfo/localtime, and it also allows an
420 * /etc/localtime as a symlink to the localtime file under
421 * /usr/share/zoneinfo or to the correct timezone file. Fedora does not
422 * have /usr/share/zoneinfo/localtime, but it does have a real
425 * in any case, this path should resolve correctly.
427 retval = g_build_filename ("/", "etc", "localtime", NULL);
434 * Parses tzdata database times to get timezone info.
436 * @tz_name: Olson database name for the timezone
437 * @start: Time offset from epoch we want to know the timezone
438 * @_is_dst: Returns if this time in the timezone is in DST
439 * @_offset: Returns the offset from UTC for this timezone
440 * @_name: Returns the abreviated name for thie timezone
443 parse_tzdata (const gchar *tz_name,
450 gchar *filename, *contents;
452 guint32 timecnt, typecnt;
453 gint transitions_size, ttinfo_map_size;
454 guint8 *ttinfo_map, *ttinfos;
455 gint start_transition = -1;
456 guint32 *transitions;
463 filename = get_tzdata_path (tz_name);
465 /* XXX: should we be caching this in memory for faster access?
466 * and if so, how do we expire the cache?
469 if (!g_file_get_contents (filename, &contents, &length, &error))
477 if (length < TZ_HEADER_SIZE ||
478 (strncmp (contents, TZ_MAGIC, TZ_MAGIC_LEN) != 0))
484 timecnt = GUINT32_FROM_BE (*(guint32 *)(contents + TZ_TIMECNT_OFFSET));
485 typecnt = GUINT32_FROM_BE (*(guint32 *)(contents + TZ_TYPECNT_OFFSET));
487 transitions = (guint32 *)(contents + TZ_TRANSITIONS_OFFSET);
488 transitions_size = timecnt * sizeof (*transitions);
489 ttinfo_map = (void *)(contents + TZ_TRANSITIONS_OFFSET + transitions_size);
490 ttinfo_map_size = timecnt;
491 ttinfos = (void *)(ttinfo_map + ttinfo_map_size);
494 * Find the first transition that contains the 'start' time
496 for (i = 1; i < timecnt && start_transition == -1; i++)
498 gint32 transition_time = GINT32_FROM_BE (transitions[i]);
500 /* if is_utc is not set, we need to add this time offset to compare with
501 * start, because it is already on the timezone time */
506 off = *(gint32 *)(ttinfos + ttinfo_map[i] * TZ_TTINFO_SIZE +
507 TZ_TTINFO_GMTOFF_OFFSET);
508 off = GINT32_FROM_BE (off);
510 transition_time += off;
513 if (transition_time > start)
515 start_transition = ttinfo_map[i - 1];
520 if (start_transition == -1)
523 start_transition = ttinfo_map[timecnt - 1];
525 start_transition = 0;
528 /* Copy the data out of the corresponding ttinfo structs */
529 offset = *(gint32 *)(ttinfos + start_transition * TZ_TTINFO_SIZE +
530 TZ_TTINFO_GMTOFF_OFFSET);
531 offset = GINT32_FROM_BE (offset);
532 isdst = *(ttinfos + start_transition * TZ_TTINFO_SIZE +
533 TZ_TTINFO_ISDST_OFFSET);
534 name_offset = *(ttinfos + start_transition * TZ_TTINFO_SIZE +
535 TZ_TTINFO_NAME_OFFSET);
538 *_name = g_strdup ((gchar*) (ttinfos + TZ_TTINFO_SIZE * typecnt + name_offset));
552 * g_time_zone_new_from_epoc:
553 * @tz_name: The Olson's database timezone name
554 * @epoch: The epoch offset
555 * @is_utc: If the @epoch is in UTC or already in the @tz_name timezone
557 * Creates a new timezone
560 g_time_zone_new_from_epoch (const gchar *tz_name,
564 GTimeZone *tz = NULL;
569 if (parse_tzdata (tz_name, epoch, is_utc, &is_dst, &offset, &name))
571 tz = g_slice_new (GTimeZone);
580 #define SECS_PER_MINUTE (60)
581 #define SECS_PER_HOUR (60 * SECS_PER_MINUTE)
582 #define SECS_PER_DAY (24 * SECS_PER_HOUR)
583 #define SECS_PER_YEAR (365 * SECS_PER_DAY)
584 #define SECS_PER_JULIAN (DAYS_PER_PERIOD * SECS_PER_DAY)
587 g_date_time_secs_offset (const GDateTime * dt)
593 y = g_date_time_get_year (dt);
594 d = g_date_time_get_day_of_year (dt);
595 h = g_date_time_get_hour (dt);
596 m = g_date_time_get_minute (dt);
597 s = g_date_time_get_second (dt);
599 leaps = GREGORIAN_LEAP (y) ? 1 : 0;
600 for (i = 1970; i < y; i++)
602 if (GREGORIAN_LEAP (i))
607 secs += (y - 1970) * SECS_PER_YEAR;
608 secs += d * SECS_PER_DAY;
609 secs += (leaps - 1) * SECS_PER_DAY;
610 secs += h * SECS_PER_HOUR;
611 secs += m * SECS_PER_MINUTE;
615 secs -= dt->tz->offset;
621 * g_date_time_create_time_zone:
623 * @tz_name: the name of the timezone
625 * Creates a timezone from a #GDateTime (disregarding its own timezone).
626 * This function transforms the #GDateTime into seconds since the epoch
627 * and creates a timezone for it in the @tz_name zone.
629 * Return value: a newly created #GTimeZone
632 g_date_time_create_time_zone (GDateTime *dt,
633 const gchar *tz_name)
637 secs = g_date_time_secs_offset (dt);
639 return g_time_zone_new_from_epoch (tz_name, secs, FALSE);
643 g_date_time_new (void)
647 datetime = g_slice_new0 (GDateTime);
648 datetime->ref_count = 1;
654 g_time_zone_copy (const GTimeZone *time_zone)
658 if (G_UNLIKELY (time_zone == NULL))
661 tz = g_slice_new (GTimeZone);
662 memcpy (tz, time_zone, sizeof (GTimeZone));
664 tz->name = g_strdup (time_zone->name);
670 g_time_zone_free (GTimeZone *time_zone)
672 if (G_LIKELY (time_zone != NULL))
674 g_free (time_zone->name);
675 g_slice_free (GTimeZone, time_zone);
680 g_date_time_free (GDateTime *datetime)
682 if (G_UNLIKELY (datetime == NULL))
686 g_time_zone_free (datetime->tz);
688 g_slice_free (GDateTime, datetime);
692 g_date_time_get_week_number (const GDateTime *datetime,
697 gint a, b, c, d, e, f, g, n, s, month, day, year;
699 g_date_time_get_dmy (datetime, &day, &month, &year);
703 a = g_date_time_get_year (datetime) - 1;
704 b = (a / 4) - (a / 100) + (a / 400);
705 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400);
708 f = day - 1 + (31 * (month - 1));
713 b = (a / 4) - (a / 100) + (a / 400);
714 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400);
717 f = day + (((153 * (month - 3)) + 2) / 5) + 58 + s;
727 *week_number = 53 - ((g - s) / 5);
728 else if (n > 364 + s)
731 *week_number = (n / 7) + 1;
735 *day_of_week = d + 1;
738 *day_of_year = f + 1;
743 * @datetime: a #GDateTime
744 * @timespan: a #GTimeSpan
746 * Creates a copy of @datetime and adds the specified timespan to the copy.
748 * Return value: the newly created #GDateTime which should be freed with
749 * g_date_time_unref().
754 g_date_time_add (const GDateTime *datetime,
759 g_return_val_if_fail (datetime != NULL, NULL);
761 dt = g_date_time_copy (datetime);
762 g_date_time_add_usec (dt, timespan);
768 * g_date_time_add_years:
769 * @datetime: a #GDateTime
770 * @years: the number of years
772 * Creates a copy of @datetime and adds the specified number of years to the
775 * Return value: the newly created #GDateTime which should be freed with
776 * g_date_time_unref().
781 g_date_time_add_years (const GDateTime *datetime,
786 g_return_val_if_fail (datetime != NULL, NULL);
788 dt = g_date_time_copy (datetime);
789 g_date_time_add_ymd (dt, years, 0, 0);
795 * g_date_time_add_months:
796 * @datetime: a #GDateTime
797 * @months: the number of months
799 * Creates a copy of @datetime and adds the specified number of months to the
802 * Return value: the newly created #GDateTime which should be freed with
803 * g_date_time_unref().
808 g_date_time_add_months (const GDateTime *datetime,
813 g_return_val_if_fail (datetime != NULL, NULL);
815 dt = g_date_time_copy (datetime);
816 g_date_time_add_ymd (dt, 0, months, 0);
822 * g_date_time_add_weeks:
823 * @datetime: a #GDateTime
824 * @weeks: the number of weeks
826 * Creates a copy of @datetime and adds the specified number of weeks to the
829 * Return value: the newly created #GDateTime which should be freed with
830 * g_date_time_unref().
835 g_date_time_add_weeks (const GDateTime *datetime,
838 g_return_val_if_fail (datetime != NULL, NULL);
840 return g_date_time_add_days (datetime, weeks * 7);
844 * g_date_time_add_days:
845 * @datetime: a #GDateTime
846 * @days: the number of days
848 * Creates a copy of @datetime and adds the specified number of days to the
851 * Return value: the newly created #GDateTime which should be freed with
852 * g_date_time_unref().
857 g_date_time_add_days (const GDateTime *datetime,
862 g_return_val_if_fail (datetime != NULL, NULL);
864 dt = g_date_time_copy (datetime);
865 g_date_time_add_ymd (dt, 0, 0, days);
871 * g_date_time_add_hours:
872 * @datetime: a #GDateTime
873 * @hours: the number of hours to add
875 * Creates a copy of @datetime and adds the specified number of hours
877 * Return value: the newly created #GDateTime which should be freed with
878 * g_date_time_unref().
883 g_date_time_add_hours (const GDateTime *datetime,
888 g_return_val_if_fail (datetime != NULL, NULL);
890 dt = g_date_time_copy (datetime);
891 g_date_time_add_usec (dt, (gint64) hours * USEC_PER_HOUR);
897 * g_date_time_add_seconds:
898 * @datetime: a #GDateTime
899 * @seconds: the number of seconds to add
901 * Creates a copy of @datetime and adds the specified number of seconds.
903 * Return value: the newly created #GDateTime which should be freed with
904 * g_date_time_unref().
909 g_date_time_add_seconds (const GDateTime *datetime,
914 g_return_val_if_fail (datetime != NULL, NULL);
916 dt = g_date_time_copy (datetime);
917 g_date_time_add_usec (dt, (gint64) seconds * USEC_PER_SECOND);
923 * g_date_time_add_milliseconds:
924 * @datetime: a #GDateTime
925 * @milliseconds: the number of milliseconds to add
927 * Creates a copy of @datetime adding the specified number of milliseconds.
929 * Return value: the newly created #GDateTime which should be freed with
930 * g_date_time_unref().
935 g_date_time_add_milliseconds (const GDateTime *datetime,
940 g_return_val_if_fail (datetime != NULL, NULL);
942 dt = g_date_time_copy (datetime);
943 g_date_time_add_usec (dt, (gint64) milliseconds * USEC_PER_MILLISECOND);
949 * g_date_time_add_minutes:
950 * @datetime: a #GDateTime
951 * @minutes: the number of minutes to add
953 * Creates a copy of @datetime adding the specified number of minutes.
955 * Return value: the newly created #GDateTime which should be freed with
956 * g_date_time_unref().
961 g_date_time_add_minutes (const GDateTime *datetime,
966 g_return_val_if_fail (datetime != NULL, NULL);
968 dt = g_date_time_copy (datetime);
969 g_date_time_add_usec (dt, (gint64) minutes * USEC_PER_MINUTE);
975 * g_date_time_add_full:
976 * @datetime: a #GDateTime
977 * @years: the number of years to add
978 * @months: the number of months to add
979 * @days: the number of days to add
980 * @hours: the number of hours to add
981 * @minutes: the number of minutes to add
982 * @seconds: the number of seconds to add
984 * Creates a new #GDateTime adding the specified values to the current date and
987 * Return value: the newly created #GDateTime that should be freed with
988 * g_date_time_unref().
993 g_date_time_add_full (const GDateTime *datetime,
1004 g_return_val_if_fail (datetime != NULL, NULL);
1006 dt = g_date_time_copy (datetime);
1009 g_date_time_add_ymd (dt, years, months, days);
1012 usecs = (hours * USEC_PER_HOUR)
1013 + (minutes * USEC_PER_MINUTE)
1014 + (seconds * USEC_PER_SECOND);
1015 g_date_time_add_usec (dt, usecs);
1021 * g_date_time_compare:
1022 * @dt1: first #GDateTime to compare
1023 * @dt2: second #GDateTime to compare
1025 * qsort()-style comparison for #GDateTime<!-- -->'s. Both #GDateTime<-- -->'s
1026 * must be non-%NULL.
1028 * Return value: 0 for equal, less than zero if dt1 is less than dt2, greater
1029 * than zero if dt2 is greator than dt1.
1034 g_date_time_compare (gconstpointer dt1,
1037 const GDateTime *a, *b;
1042 if ((a->days == b->days )&&
1043 (a->usec == b->usec))
1047 else if ((a->days > b->days) ||
1048 ((a->days == b->days) && a->usec > b->usec))
1058 * @datetime: a #GDateTime
1060 * Creates a copy of @datetime.
1062 * Return value: the newly created #GDateTime which should be freed with
1063 * g_date_time_unref().
1068 g_date_time_copy (const GDateTime *datetime)
1072 g_return_val_if_fail (datetime != NULL, NULL);
1074 copied = g_date_time_new ();
1075 copied->days = datetime->days;
1076 copied->usec = datetime->usec;
1077 copied->tz = g_time_zone_copy (datetime->tz);
1084 * @datetime: a #GDateTime
1086 * Creates a new #GDateTime at Midnight on the date represented by @datetime.
1088 * Return value: the newly created #GDateTime which should be freed with
1089 * g_date_time_unref().
1094 g_date_time_day (const GDateTime *datetime)
1098 g_return_val_if_fail (datetime != NULL, NULL);
1100 date = g_date_time_copy (datetime);
1107 * g_date_time_difference:
1108 * @begin: a #GDateTime
1109 * @end: a #GDateTime
1111 * Calculates the known difference in time between @begin and @end.
1113 * Since the exact precision cannot always be known due to incomplete
1114 * historic information, an attempt is made to calculate the difference.
1116 * Return value: the difference between the two #GDateTime, as a time
1117 * span expressed in microseconds.
1122 g_date_time_difference (const GDateTime *begin,
1123 const GDateTime *end)
1125 g_return_val_if_fail (begin != NULL, 0);
1126 g_return_val_if_fail (end != NULL, 0);
1128 return (GTimeSpan) (((gint64) end->days - (gint64) begin->days)
1129 * USEC_PER_DAY) + ((gint64) end->usec - (gint64) begin->usec);
1133 * g_date_time_equal:
1134 * @dt1: a #GDateTime
1135 * @dt2: a #GDateTime
1137 * Checks to see if @dt1 and @dt2 are equal.
1139 * Equal here means that they represent the same moment after converting
1140 * them to the same timezone.
1142 * Return value: %TRUE if @dt1 and @dt2 are equal
1147 g_date_time_equal (gconstpointer dt1,
1150 const GDateTime *a, *b;
1151 GDateTime *a_utc, *b_utc;
1152 gint64 a_epoch, b_epoch;
1157 a_utc = g_date_time_to_utc (a);
1158 b_utc = g_date_time_to_utc (b);
1160 a_epoch = g_date_time_to_epoch (a_utc);
1161 b_epoch = g_date_time_to_epoch (b_utc);
1163 g_date_time_unref (a_utc);
1164 g_date_time_unref (b_utc);
1166 return a_epoch == b_epoch;
1170 * g_date_time_get_day_of_week:
1171 * @datetime: a #GDateTime
1173 * Retrieves the day of the week represented by @datetime within the gregorian
1174 * calendar. 1 is Sunday, 2 is Monday, etc.
1176 * Return value: the day of the week
1181 g_date_time_get_day_of_week (const GDateTime *datetime)
1189 g_return_val_if_fail (datetime != NULL, 0);
1192 * See Calendar FAQ Section 2.6 for algorithm information
1193 * http://www.tondering.dk/claus/cal/calendar29.txt
1196 g_date_time_get_dmy (datetime, &day, &month, &year);
1197 a = (14 - month) / 12;
1199 m = month + (12 * a) - 2;
1200 dow = ((day + y + (y / 4) - (y / 100) + (y / 400) + (31 * m) / 12) % 7);
1202 /* 1 is Monday and 7 is Sunday */
1203 return (dow == 0) ? 7 : dow;
1207 * g_date_time_get_day_of_month:
1208 * @datetime: a #GDateTime
1210 * Retrieves the day of the month represented by @datetime in the gregorian
1213 * Return value: the day of the month
1218 g_date_time_get_day_of_month (const GDateTime *datetime)
1222 const guint16 *days;
1225 g_return_val_if_fail (datetime != NULL, 0);
1227 days = days_in_year[g_date_time_is_leap_year (datetime) ? 1 : 0];
1228 g_date_time_get_week_number (datetime, NULL, NULL, &day_of_year);
1230 for (i = 1; i <= 12; i++)
1232 if (days [i] >= day_of_year)
1233 return day_of_year - last;
1237 g_warn_if_reached ();
1242 * g_date_time_get_day_of_year:
1243 * @datetime: a #GDateTime
1245 * Retrieves the day of the year represented by @datetime in the Gregorian
1248 * Return value: the day of the year
1253 g_date_time_get_day_of_year (const GDateTime *datetime)
1257 g_return_val_if_fail (datetime != NULL, 0);
1259 g_date_time_get_week_number (datetime, NULL, NULL, &doy);
1264 * g_date_time_get_dmy:
1265 * @datetime: a #GDateTime.
1266 * @day: (out): the return location for the day of the month, or %NULL.
1267 * @month: (out): the return location for the monty of the year, or %NULL.
1268 * @year: (out): the return location for the gregorian year, or %NULL.
1270 * Retrieves the Gregorian day, month, and year of a given #GDateTime.
1275 g_date_time_get_dmy (const GDateTime *datetime,
1283 gint remaining_days;
1290 g_return_if_fail (datetime != NULL);
1292 remaining_days = datetime->days;
1295 * We need to convert an offset in days to its year/month/day representation.
1296 * Leap years makes this a little trickier than it should be, so we use
1297 * 400, 100 and 4 years cycles here to get to the correct year.
1300 /* Our days offset starts sets 0001-01-01 as day 1, if it was day 0 our
1301 * math would be simpler, so let's do it */
1304 the_year = (remaining_days / DAYS_IN_400YEARS) * 400 + 1;
1305 remaining_days = remaining_days % DAYS_IN_400YEARS;
1307 y100_cycles = remaining_days / DAYS_IN_100YEARS;
1308 remaining_days = remaining_days % DAYS_IN_100YEARS;
1309 the_year += y100_cycles * 100;
1311 y4_cycles = remaining_days / DAYS_IN_4YEARS;
1312 remaining_days = remaining_days % DAYS_IN_4YEARS;
1313 the_year += y4_cycles * 4;
1315 y1_cycles = remaining_days / 365;
1316 the_year += y1_cycles;
1317 remaining_days = remaining_days % 365;
1319 if (y1_cycles == 4 || y100_cycles == 4) {
1320 g_assert (remaining_days == 0);
1322 /* special case that indicates that the date is actually one year before,
1323 * in the 31th of December */
1330 /* now get the month and the day */
1331 leap = y1_cycles == 3 && (y4_cycles != 24 || y100_cycles == 3);
1333 g_assert (leap == GREGORIAN_LEAP(the_year));
1335 the_month = (remaining_days + 50) >> 5;
1336 preceding = (days_in_year[0][the_month - 1] + (the_month > 2 && leap));
1337 if (preceding > remaining_days) {
1338 /* estimate is too large */
1340 preceding -= leap ? days_in_months[1][the_month] :
1341 days_in_months[0][the_month];
1343 remaining_days -= preceding;
1344 g_assert(0 <= remaining_days);
1346 the_day = remaining_days + 1;
1358 * g_date_time_get_hour:
1359 * @datetime: a #GDateTime
1361 * Retrieves the hour of the day represented by @datetime
1363 * Return value: the hour of the day
1368 g_date_time_get_hour (const GDateTime *datetime)
1370 g_return_val_if_fail (datetime != NULL, 0);
1372 return (datetime->usec / USEC_PER_HOUR);
1376 * g_date_time_get_julian:
1377 * @datetime: a #GDateTime
1378 * @period: (out): a location for the Julian period
1379 * @julian: (out): a location for the day in the Julian period
1380 * @hour: (out): a location for the hour of the day
1381 * @minute: (out): a location for the minute of the hour
1382 * @second: (out): a location for hte second of the minute
1384 * Retrieves the Julian period, day, hour, minute, and second which @datetime
1385 * represents in the Julian calendar.
1390 g_date_time_get_julian (const GDateTime *datetime,
1397 gint y, m, d, a, b, c, e, f, j;
1398 g_return_if_fail (datetime != NULL);
1400 g_date_time_get_dmy (datetime, &d, &m, &y);
1402 /* FIXME: This is probably not optimal and doesn't handle the fact that the
1403 * julian calendar has its 0 hour on midday */
1408 e = 365.25 * (y + 4716);
1409 f = 30.6001 * (m + 1);
1410 j = c + d + e + f - 1524;
1419 *hour = (datetime->usec / USEC_PER_HOUR);
1422 *minute = (datetime->usec % USEC_PER_HOUR) / USEC_PER_MINUTE;
1425 *second = (datetime->usec % USEC_PER_MINUTE) / USEC_PER_SECOND;
1429 * g_date_time_get_microsecond:
1430 * @datetime: a #GDateTime
1432 * Retrieves the microsecond of the date represented by @datetime
1434 * Return value: the microsecond of the second
1439 g_date_time_get_microsecond (const GDateTime *datetime)
1441 g_return_val_if_fail (datetime != NULL, 0);
1443 return (datetime->usec % USEC_PER_SECOND);
1447 * g_date_time_get_millisecond:
1448 * @datetime: a #GDateTime
1450 * Retrieves the millisecond of the date represented by @datetime
1452 * Return value: the millisecond of the second
1457 g_date_time_get_millisecond (const GDateTime *datetime)
1459 g_return_val_if_fail (datetime != NULL, 0);
1461 return (datetime->usec % USEC_PER_SECOND) / USEC_PER_MILLISECOND;
1465 * g_date_time_get_minute:
1466 * @datetime: a #GDateTime
1468 * Retrieves the minute of the hour represented by @datetime
1470 * Return value: the minute of the hour
1475 g_date_time_get_minute (const GDateTime *datetime)
1477 g_return_val_if_fail (datetime != NULL, 0);
1479 return (datetime->usec % USEC_PER_HOUR) / USEC_PER_MINUTE;
1483 * g_date_time_get_month:
1484 * @datetime: a #GDateTime
1486 * Retrieves the month of the year represented by @datetime in the Gregorian
1489 * Return value: the month represented by @datetime
1494 g_date_time_get_month (const GDateTime *datetime)
1498 g_return_val_if_fail (datetime != NULL, 0);
1500 g_date_time_get_dmy (datetime, NULL, &month, NULL);
1506 * g_date_time_get_second:
1507 * @datetime: a #GDateTime
1509 * Retrieves the second of the minute represented by @datetime
1511 * Return value: the second represented by @datetime
1516 g_date_time_get_second (const GDateTime *datetime)
1518 g_return_val_if_fail (datetime != NULL, 0);
1520 return (datetime->usec % USEC_PER_MINUTE) / USEC_PER_SECOND;
1524 * g_date_time_get_utc_offset:
1525 * @datetime: a #GDateTime
1527 * Retrieves the offset from UTC that the local timezone specified by
1528 * @datetime represents.
1530 * If @datetime represents UTC time, then the offset is zero.
1532 * Return value: the offset, expressed as a time span expressed in
1538 g_date_time_get_utc_offset (const GDateTime *datetime)
1542 g_return_val_if_fail (datetime != NULL, 0);
1544 if (datetime->tz != NULL)
1545 offset = datetime->tz->offset;
1547 return (gint64) offset * USEC_PER_SECOND;
1551 * g_date_time_get_timezone_name:
1552 * @datetime: a #GDateTime
1554 * Retrieves the Olson's database timezone name of the timezone specified
1557 * Return value: (transfer none): the name of the timezone. The returned
1558 * string is owned by the #GDateTime and it should not be modified or
1563 G_CONST_RETURN gchar *
1564 g_date_time_get_timezone_name (const GDateTime *datetime)
1566 g_return_val_if_fail (datetime != NULL, NULL);
1568 if (datetime->tz != NULL)
1569 return datetime->tz->name;
1575 * g_date_time_get_year:
1576 * @datetime: A #GDateTime
1578 * Retrieves the year represented by @datetime in the Gregorian calendar.
1580 * Return value: the year represented by @datetime
1585 g_date_time_get_year (const GDateTime *datetime)
1589 g_return_val_if_fail (datetime != NULL, 0);
1591 g_date_time_get_dmy (datetime, NULL, NULL, &year);
1598 * @datetime: a #GDateTime
1600 * Hashes @datetime into a #guint, suitable for use within #GHashTable.
1602 * Return value: a #guint containing the hash
1607 g_date_time_hash (gconstpointer datetime)
1609 return (guint) (*((guint64 *) datetime));
1613 * g_date_time_is_leap_year:
1614 * @datetime: a #GDateTime
1616 * Determines if @datetime represents a date known to fall within
1617 * a leap year in the Gregorian calendar.
1619 * Return value: %TRUE if @datetime is a leap year.
1624 g_date_time_is_leap_year (const GDateTime *datetime)
1628 g_return_val_if_fail (datetime != NULL, FALSE);
1630 year = g_date_time_get_year (datetime);
1632 return GREGORIAN_LEAP (year);
1636 * g_date_time_is_daylight_savings:
1637 * @datetime: a #GDateTime
1639 * Determines if @datetime represents a date known to fall within daylight
1640 * savings time in the gregorian calendar.
1642 * Return value: %TRUE if @datetime falls within daylight savings time.
1647 g_date_time_is_daylight_savings (const GDateTime *datetime)
1649 g_return_val_if_fail (datetime != NULL, FALSE);
1654 return datetime->tz->is_dst;
1658 * g_date_time_new_from_date:
1659 * @year: the Gregorian year
1660 * @month: the Gregorian month
1661 * @day: the day in the Gregorian month
1663 * Creates a new #GDateTime using the specified date within the Gregorian
1666 * Return value: the newly created #GDateTime or %NULL if it is outside of
1667 * the representable range.
1672 g_date_time_new_from_date (gint year,
1678 g_return_val_if_fail (year > -4712 && year <= 3268, NULL);
1679 g_return_val_if_fail (month > 0 && month <= 12, NULL);
1680 g_return_val_if_fail (day > 0 && day <= 31, NULL);
1682 dt = g_date_time_new ();
1684 dt->days = date_to_proleptic_gregorian (year, month, day);
1685 dt->tz = g_date_time_create_time_zone (dt, NULL);
1691 * g_date_time_new_from_epoch:
1692 * @t: seconds from the Unix epoch
1694 * Creates a new #GDateTime using the time since Jan 1, 1970 specified by @t.
1696 * Return value: the newly created #GDateTime
1701 g_date_time_new_from_epoch (gint64 t) /* IN */
1707 memset (&tm, 0, sizeof (tm));
1709 /* XXX: GLib should probably have a wrapper for this */
1710 #ifdef HAVE_LOCALTIME_R
1711 localtime_r (&tt, &tm);
1714 struct tm *ptm = localtime (&tt);
1718 /* Happens at least in Microsoft's C library if you pass a
1719 * negative time_t. Use 2000-01-01 as default date.
1721 #ifndef G_DISABLE_CHECKS
1722 g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, "ptm != NULL");
1730 memcpy ((void *) &tm, (void *) ptm, sizeof (struct tm));
1732 #endif /* HAVE_LOCALTIME_R */
1734 return g_date_time_new_full (tm.tm_year + 1900,
1744 * g_date_time_new_from_timeval:
1747 * Creates a new #GDateTime using the date and time specified by #GTimeVal.
1749 * Return value: the newly created #GDateTime
1754 g_date_time_new_from_timeval (GTimeVal *tv)
1756 GDateTime *datetime;
1758 g_return_val_if_fail (tv != NULL, NULL);
1760 datetime = g_date_time_new_from_epoch (tv->tv_sec);
1761 datetime->usec += tv->tv_usec;
1762 datetime->tz = g_date_time_create_time_zone (datetime, NULL);
1768 * g_date_time_new_full:
1769 * @year: the Gregorian year
1770 * @month: the Gregorian month
1771 * @day: the day of the Gregorian month
1772 * @hour: the hour of the day
1773 * @minute: the minute of the hour
1774 * @second: the second of the minute
1775 * @time_zone: (allow-none): the Olson's database timezone name, or %NULL
1776 * for local (e.g. America/New_York)
1778 * Creates a new #GDateTime using the date and times in the Gregorian calendar.
1780 * Return value: the newly created #GDateTime
1785 g_date_time_new_full (gint year,
1791 const gchar *time_zone)
1795 g_return_val_if_fail (hour >= 0 && hour < 24, NULL);
1796 g_return_val_if_fail (minute >= 0 && minute < 60, NULL);
1797 g_return_val_if_fail (second >= 0 && second <= 60, NULL);
1799 if ((dt = g_date_time_new_from_date (year, month, day)) == NULL)
1802 dt->usec = (hour * USEC_PER_HOUR)
1803 + (minute * USEC_PER_MINUTE)
1804 + (second * USEC_PER_SECOND);
1806 dt->tz = g_date_time_create_time_zone (dt, time_zone);
1807 if (time_zone != NULL && dt->tz == NULL)
1809 /* timezone creation failed */
1810 g_date_time_unref (dt);
1818 * g_date_time_new_now:
1820 * Creates a new #GDateTime representing the current date and time.
1822 * Return value: the newly created #GDateTime which should be freed with
1823 * g_date_time_unref().
1828 g_date_time_new_now (void)
1832 g_get_current_time (&tv);
1834 return g_date_time_new_from_timeval (&tv);
1838 * g_date_time_printf:
1839 * @datetime: A #GDateTime
1840 * @format: a valid UTF-8 string, containing the format for the #GDateTime
1842 * Creates a newly allocated string representing the requested @format.
1844 * The following format specifiers are supported:
1846 * %%a The abbreviated weekday name according to the current locale.
1847 * %%A The full weekday name according to the current locale.
1848 * %%b The abbreviated month name according to the current locale.
1849 * %%B The full month name according to the current locale.
1850 * %%d The day of the month as a decimal number (range 01 to 31).
1851 * %%e The day of the month as a decimal number (range 1 to 31).
1852 * %%F Equivalent to %Y-%m-%d (the ISO 8601 date format).
1853 * %%h Equivalent to %b.
1854 * %%H The hour as a decimal number using a 24-hour clock (range 00 to 23).
1855 * %%I The hour as a decimal number using a 12-hour clock (range 01 to 12).
1856 * %%j The day of the year as a decimal number (range 001 to 366).
1857 * %%k The hour (24-hour clock) as a decimal number (range 0 to 23);
1858 * single digits are preceded by a blank.
1859 * %%l The hour (12-hour clock) as a decimal number (range 1 to 12);
1860 * single digits are preceded by a blank.
1861 * %%m The month as a decimal number (range 01 to 12).
1862 * %%M The minute as a decimal number (range 00 to 59).
1863 * %%N The micro-seconds as a decimal number.
1864 * %%p Either "AM" or "PM" according to the given time value, or the
1865 * corresponding strings for the current locale. Noon is treated
1866 * as "PM" and midnight as "AM".
1867 * %%P Like %%p but lowercase: "am" or "pm" or a corresponding string for
1868 * the current locale.
1869 * %%r The time in a.m. or p.m. notation.
1870 * %%R The time in 24-hour notation (%H:%M).
1871 * %%s The number of seconds since the Epoch, that is, since 1970-01-01
1873 * %%S The second as a decimal number (range 00 to 60).
1874 * %%t A tab character.
1875 * %%u The day of the week as a decimal, range 1 to 7, Monday being 1.
1876 * %%W The week number of the current year as a decimal number.
1877 * %%x The preferred date representation for the current locale without
1879 * %%X The preferred date representation for the current locale without
1881 * %%y The year as a decimal number without the century.
1882 * %%Y The year as a decimal number including the century.
1883 * %%Z Alphabetic time zone abbreviation (e.g. EDT).
1884 * %%% A literal %% character.
1886 * Return value: a newly allocated string formatted to the requested format or
1887 * %NULL in the case that there was an error. The string should be freed
1893 g_date_time_printf (const GDateTime *datetime,
1894 const gchar *format)
1902 g_return_val_if_fail (datetime != NULL, NULL);
1903 g_return_val_if_fail (format != NULL, NULL);
1904 g_return_val_if_fail (g_utf8_validate (format, -1, NULL), NULL);
1906 outstr = g_string_sized_new (strlen (format) * 2);
1907 utf8len = g_utf8_strlen (format, -1);
1910 for (; *format; format = g_utf8_next_char(format))
1912 c = g_utf8_get_char (format);
1929 g_string_append (outstr, WEEKDAY_ABBR (datetime));
1932 g_string_append (outstr, WEEKDAY_FULL (datetime));
1935 g_string_append (outstr, MONTH_ABBR (datetime));
1938 g_string_append (outstr, MONTH_FULL (datetime));
1941 g_string_append_printf (outstr, "%02d", g_date_time_get_day_of_month (datetime));
1944 g_string_append_printf (outstr, "%2d", g_date_time_get_day_of_month (datetime));
1947 g_string_append_printf (outstr, "%d-%02d-%02d",
1948 g_date_time_get_year (datetime),
1949 g_date_time_get_month (datetime),
1950 g_date_time_get_day_of_month (datetime));
1953 g_string_append (outstr, MONTH_ABBR (datetime));
1956 g_string_append_printf (outstr, "%02d", g_date_time_get_hour (datetime));
1959 if (g_date_time_get_hour (datetime) == 0)
1960 g_string_append (outstr, "12");
1962 g_string_append_printf (outstr, "%02d", g_date_time_get_hour (datetime) % 12);
1965 g_string_append_printf (outstr, "%03d", g_date_time_get_day_of_year (datetime));
1968 g_string_append_printf (outstr, "%2d", g_date_time_get_hour (datetime));
1971 if (g_date_time_get_hour (datetime) == 0)
1972 g_string_append (outstr, "12");
1974 g_string_append_printf (outstr, "%2d", g_date_time_get_hour (datetime) % 12);
1977 g_string_append_printf (outstr, "%02d", g_date_time_get_month (datetime));
1980 g_string_append_printf (outstr, "%02d", g_date_time_get_minute (datetime));
1983 g_string_append_printf (outstr, "%"G_GUINT64_FORMAT, datetime->usec % USEC_PER_SECOND);
1986 g_string_append (outstr, GET_AMPM (datetime, FALSE));
1989 g_string_append (outstr, GET_AMPM (datetime, TRUE));
1993 gint hour = g_date_time_get_hour (datetime) % 12;
1996 g_string_append_printf (outstr, "%02d:%02d:%02d %s",
1998 g_date_time_get_minute (datetime),
1999 g_date_time_get_second (datetime),
2000 GET_AMPM (datetime, FALSE));
2004 g_string_append_printf (outstr, "%02d:%02d",
2005 g_date_time_get_hour (datetime),
2006 g_date_time_get_minute (datetime));
2009 g_string_append_printf (outstr, "%" G_GINT64_FORMAT, g_date_time_to_epoch (datetime));
2012 g_string_append_printf (outstr, "%02d", g_date_time_get_second (datetime));
2015 g_string_append_c (outstr, '\t');
2018 g_string_append_printf (outstr, "%d", g_date_time_get_day_of_week (datetime));
2021 g_string_append_printf (outstr, "%d", g_date_time_get_day_of_year (datetime) / 7);
2025 tmp = GET_PREFERRED_DATE (datetime);
2026 g_string_append (outstr, tmp);
2032 tmp = GET_PREFERRED_TIME (datetime);
2033 g_string_append (outstr, tmp);
2038 g_string_append_printf (outstr, "%02d", g_date_time_get_year (datetime) % 100);
2041 g_string_append_printf (outstr, "%d", g_date_time_get_year (datetime));
2044 if (datetime->tz != NULL)
2045 g_string_append_printf (outstr, "%s", datetime->tz->name);
2047 g_string_append_printf (outstr, "UTC");
2050 g_string_append_c (outstr, '%');
2053 g_string_append_c (outstr, '\n');
2061 g_string_append_unichar (outstr, c);
2065 return g_string_free (outstr, FALSE);
2068 g_string_free (outstr, TRUE);
2074 * @datetime: a #GDateTime
2076 * Atomically increments the reference count of @datetime by one.
2078 * Return value: the #GDateTime with the reference count increased
2083 g_date_time_ref (GDateTime *datetime)
2085 g_return_val_if_fail (datetime != NULL, NULL);
2086 g_return_val_if_fail (datetime->ref_count > 0, NULL);
2088 g_atomic_int_inc (&datetime->ref_count);
2094 * g_date_time_unref:
2095 * @datetime: a #GDateTime
2097 * Atomically decrements the reference count of @datetime by one.
2099 * When the reference count reaches zero, the resources allocated by
2100 * @datetime are freed
2105 g_date_time_unref (GDateTime *datetime)
2107 g_return_if_fail (datetime != NULL);
2108 g_return_if_fail (datetime->ref_count > 0);
2110 if (g_atomic_int_dec_and_test (&datetime->ref_count))
2111 g_date_time_free (datetime);
2115 * g_date_time_to_local:
2116 * @datetime: a #GDateTime
2118 * Creates a new #GDateTime with @datetime converted to local time.
2120 * Return value: the newly created #GDateTime
2125 g_date_time_to_local (const GDateTime *datetime)
2129 g_return_val_if_fail (datetime != NULL, NULL);
2131 dt = g_date_time_copy (datetime);
2134 dt->tz = g_date_time_create_time_zone (dt, NULL);
2138 g_date_time_add_usec (dt, dt->tz->offset * USEC_PER_SECOND);
2145 * g_date_time_to_epoch:
2146 * @datetime: a #GDateTime
2148 * Converts @datetime into an integer representing seconds since the
2151 * Return value: @datetime as seconds since the Unix epoch
2156 g_date_time_to_epoch (const GDateTime *datetime)
2160 g_return_val_if_fail (datetime != NULL, 0);
2162 if (datetime->days <= 0)
2165 result = (datetime->days - UNIX_EPOCH_START) * SEC_PER_DAY
2166 + datetime->usec / USEC_PER_SECOND
2167 - g_date_time_get_utc_offset (datetime) / 1000000;
2173 * g_date_time_to_timeval:
2174 * @datetime: a #GDateTime
2177 * Converts @datetime into a #GTimeVal and stores the result into @timeval.
2182 g_date_time_to_timeval (const GDateTime *datetime,
2185 g_return_if_fail (datetime != NULL);
2190 tv->tv_sec = g_date_time_to_epoch (datetime);
2191 tv->tv_usec = datetime->usec % USEC_PER_SECOND;
2195 * g_date_time_to_utc:
2196 * @datetime: a #GDateTime
2198 * Creates a new #GDateTime that reprents @datetime in Universal coordinated
2201 * Return value: the newly created #GDateTime which should be freed with
2202 * g_date_time_unref().
2207 g_date_time_to_utc (const GDateTime *datetime)
2212 g_return_val_if_fail (datetime != NULL, NULL);
2214 ts = g_date_time_get_utc_offset (datetime) * -1;
2215 dt = g_date_time_add (datetime, ts);
2222 * g_date_time_new_today:
2224 * Createsa new #GDateTime that represents Midnight on the current day.
2226 * Return value: the newly created #GDateTime which should be freed with
2227 * g_date_time_unref().
2232 g_date_time_new_today (void)
2236 dt = g_date_time_new_now ();
2243 * g_date_time_new_utc_now:
2245 * Creates a new #GDateTime that represents the current instant in Universal
2246 * Coordinated Time (UTC).
2248 * Return value: the newly created #GDateTime which should be freed with
2249 * g_date_time_unref().
2254 g_date_time_new_utc_now (void)
2256 GDateTime *utc, *now;
2258 now = g_date_time_new_now ();
2259 utc = g_date_time_to_utc (now);
2260 g_date_time_unref (now);
2266 * g_date_time_get_week_of_year:
2268 * Returns the numeric week of the respective year.
2270 * Return value: the week of the year
2275 g_date_time_get_week_of_year (const GDateTime *datetime)
2279 g_return_val_if_fail (datetime != NULL, 0);
2281 g_date_time_get_week_number (datetime, &weeknum, NULL, NULL);