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>
6 * Copyright © 2010 Codethink Limited
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of the
11 * licence, or (at your option) any later version.
13 * This is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 * License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 * Authors: Christian Hergert <chris@dronelabs.com>
24 * Thiago Santos <thiago.sousa.santos@collabora.co.uk>
25 * Emmanuele Bassi <ebassi@linux.intel.com>
26 * Ryan Lortie <desrt@desrt.ca>
29 /* Algorithms within this file are based on the Calendar FAQ by
30 * Claus Tondering. It can be found at
31 * http://www.tondering.dk/claus/cal/calendar29.txt
33 * Copyright and disclaimer
34 * ------------------------
35 * This document is Copyright (C) 2008 by Claus Tondering.
36 * E-mail: claus@tondering.dk. (Please include the word
37 * "calendar" in the subject line.)
38 * The document may be freely distributed, provided this
39 * copyright notice is included and no money is charged for
42 * This document is provided "as is". No warranties are made as
57 #include "gdatetime.h"
60 #include "gfileutils.h"
63 #include "gmappedfile.h"
64 #include "gstrfuncs.h"
65 #include "gtestutils.h"
67 #include "gtimezone.h"
74 #endif /* !G_OS_WIN32 */
79 * @short_description: A structure representing Date and Time
80 * @see_also: #GTimeZone
82 * #GDateTime is a structure that combines a Gregorian date and time
83 * into a single structure. It provides many conversion and methods to
84 * manipulate dates and times. Time precision is provided down to
85 * microseconds and the time can range (proleptically) from 0001-01-01
86 * 00:00:00 to 9999-12-31 23:59:59.999999. #GDateTime follows POSIX
87 * time in the sense that it is oblivious to leap seconds.
89 * #GDateTime is an immutable object; once it has been created it cannot
90 * be modified further. All modifiers will create a new #GDateTime.
91 * Nearly all such functions can fail due to the date or time going out
92 * of range, in which case %NULL will be returned.
94 * #GDateTime is reference counted: the reference count is increased by calling
95 * g_date_time_ref() and decreased by calling g_date_time_unref(). When the
96 * reference count drops to 0, the resources allocated by the #GDateTime
97 * structure are released.
99 * Many parts of the API may produce non-obvious results. As an
100 * example, adding two months to January 31st will yield March 31st
101 * whereas adding one month and then one month again will yield either
102 * March 28th or March 29th. Also note that adding 24 hours is not
103 * always the same as adding one day (since days containing daylight
104 * savings time transitions are either 23 or 25 hours in length).
106 * #GDateTime is available since GLib 2.26.
111 /* 1 is 0001-01-01 in Proleptic Gregorian */
114 /* Microsecond timekeeping within Day */
117 /* TimeZone information */
121 volatile gint ref_count;
124 /* Time conversion {{{1 */
126 #define UNIX_EPOCH_START 719163
127 #define INSTANT_TO_UNIX(instant) \
128 ((instant)/USEC_PER_SECOND - UNIX_EPOCH_START * SEC_PER_DAY)
129 #define UNIX_TO_INSTANT(unix) \
130 (((unix) + UNIX_EPOCH_START * SEC_PER_DAY) * USEC_PER_SECOND)
132 #define DAYS_IN_4YEARS 1461 /* days in 4 years */
133 #define DAYS_IN_100YEARS 36524 /* days in 100 years */
134 #define DAYS_IN_400YEARS 146097 /* days in 400 years */
136 #define USEC_PER_SECOND (G_GINT64_CONSTANT (1000000))
137 #define USEC_PER_MINUTE (G_GINT64_CONSTANT (60000000))
138 #define USEC_PER_HOUR (G_GINT64_CONSTANT (3600000000))
139 #define USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000))
140 #define USEC_PER_DAY (G_GINT64_CONSTANT (86400000000))
141 #define SEC_PER_DAY (G_GINT64_CONSTANT (86400))
143 #define GREGORIAN_LEAP(y) ((((y) % 4) == 0) && (!((((y) % 100) == 0) && (((y) % 400) != 0))))
144 #define JULIAN_YEAR(d) ((d)->julian / 365.25)
145 #define DAYS_PER_PERIOD (G_GINT64_CONSTANT (2914695))
147 #define GET_AMPM(d,l) ((g_date_time_get_hour (d) < 12) \
148 /* Translators: 'before midday' indicator */ \
149 ? (l ? C_("GDateTime", "am") \
150 /* Translators: 'before midday' indicator */ \
151 : C_("GDateTime", "AM")) \
152 /* Translators: 'after midday' indicator */ \
153 : (l ? C_("GDateTime", "pm") \
154 /* Translators: 'after midday' indicator */ \
155 : C_("GDateTime", "PM")))
157 #define WEEKDAY_ABBR(d) (get_weekday_name_abbr (g_date_time_get_day_of_week (datetime)))
158 #define WEEKDAY_FULL(d) (get_weekday_name (g_date_time_get_day_of_week (datetime)))
160 #define MONTH_ABBR(d) (get_month_name_abbr (g_date_time_get_month (datetime)))
161 #define MONTH_FULL(d) (get_month_name (g_date_time_get_month (datetime)))
163 /* Translators: this is the preferred format for expressing the date */
164 #define GET_PREFERRED_DATE(d) (g_date_time_format ((d), C_("GDateTime", "%m/%d/%y")))
166 /* Translators: this is the preferred format for expressing the time */
167 #define GET_PREFERRED_TIME(d) (g_date_time_format ((d), C_("GDateTime", "%H:%M:%S")))
169 #define SECS_PER_MINUTE (60)
170 #define SECS_PER_HOUR (60 * SECS_PER_MINUTE)
171 #define SECS_PER_DAY (24 * SECS_PER_HOUR)
172 #define SECS_PER_YEAR (365 * SECS_PER_DAY)
173 #define SECS_PER_JULIAN (DAYS_PER_PERIOD * SECS_PER_DAY)
175 static const guint16 days_in_months[2][13] =
177 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
178 { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
181 static const guint16 days_in_year[2][13] =
183 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
184 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
188 get_month_name (gint month)
193 return C_("full month name", "January");
195 return C_("full month name", "February");
197 return C_("full month name", "March");
199 return C_("full month name", "April");
201 return C_("full month name", "May");
203 return C_("full month name", "June");
205 return C_("full month name", "July");
207 return C_("full month name", "August");
209 return C_("full month name", "September");
211 return C_("full month name", "October");
213 return C_("full month name", "November");
215 return C_("full month name", "December");
218 g_warning ("Invalid month number %d", month);
225 get_month_name_abbr (gint month)
230 return C_("abbreviated month name", "Jan");
232 return C_("abbreviated month name", "Feb");
234 return C_("abbreviated month name", "Mar");
236 return C_("abbreviated month name", "Apr");
238 return C_("abbreviated month name", "May");
240 return C_("abbreviated month name", "Jun");
242 return C_("abbreviated month name", "Jul");
244 return C_("abbreviated month name", "Aug");
246 return C_("abbreviated month name", "Sep");
248 return C_("abbreviated month name", "Oct");
250 return C_("abbreviated month name", "Nov");
252 return C_("abbreviated month name", "Dec");
255 g_warning ("Invalid month number %d", month);
262 get_weekday_name (gint day)
267 return C_("full weekday name", "Monday");
269 return C_("full weekday name", "Tuesday");
271 return C_("full weekday name", "Wednesday");
273 return C_("full weekday name", "Thursday");
275 return C_("full weekday name", "Friday");
277 return C_("full weekday name", "Saturday");
279 return C_("full weekday name", "Sunday");
282 g_warning ("Invalid week day number %d", day);
289 get_weekday_name_abbr (gint day)
294 return C_("abbreviated weekday name", "Mon");
296 return C_("abbreviated weekday name", "Tue");
298 return C_("abbreviated weekday name", "Wed");
300 return C_("abbreviated weekday name", "Thu");
302 return C_("abbreviated weekday name", "Fri");
304 return C_("abbreviated weekday name", "Sat");
306 return C_("abbreviated weekday name", "Sun");
309 g_warning ("Invalid week day number %d", day);
316 ymd_to_days (gint year,
322 days = (year - 1) * 365 + ((year - 1) / 4) - ((year - 1) / 100)
323 + ((year - 1) / 400);
325 days += days_in_year[0][month - 1];
326 if (GREGORIAN_LEAP (year) && month > 2)
335 g_date_time_get_week_number (GDateTime *datetime,
340 gint a, b, c, d, e, f, g, n, s, month, day, year;
342 g_date_time_get_ymd (datetime, &year, &month, &day);
346 a = g_date_time_get_year (datetime) - 1;
347 b = (a / 4) - (a / 100) + (a / 400);
348 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400);
351 f = day - 1 + (31 * (month - 1));
356 b = (a / 4) - (a / 100) + (a / 400);
357 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400);
360 f = day + (((153 * (month - 3)) + 2) / 5) + 58 + s;
370 *week_number = 53 - ((g - s) / 5);
371 else if (n > 364 + s)
374 *week_number = (n / 7) + 1;
378 *day_of_week = d + 1;
381 *day_of_year = f + 1;
387 g_date_time_alloc (GTimeZone *tz)
391 datetime = g_slice_new0 (GDateTime);
392 datetime->tz = g_time_zone_ref (tz);
393 datetime->ref_count = 1;
400 * @datetime: a #GDateTime
402 * Atomically increments the reference count of @datetime by one.
404 * Return value: the #GDateTime with the reference count increased
409 g_date_time_ref (GDateTime *datetime)
411 g_return_val_if_fail (datetime != NULL, NULL);
412 g_return_val_if_fail (datetime->ref_count > 0, NULL);
414 g_atomic_int_inc (&datetime->ref_count);
421 * @datetime: a #GDateTime
423 * Atomically decrements the reference count of @datetime by one.
425 * When the reference count reaches zero, the resources allocated by
426 * @datetime are freed
431 g_date_time_unref (GDateTime *datetime)
433 g_return_if_fail (datetime != NULL);
434 g_return_if_fail (datetime->ref_count > 0);
436 if (g_atomic_int_dec_and_test (&datetime->ref_count))
438 g_time_zone_unref (datetime->tz);
439 g_slice_free (GDateTime, datetime);
443 /* Internal state transformers {{{1 */
445 * g_date_time_to_instant:
446 * @datetime: a #GDateTime
448 * Convert a @datetime into an instant.
450 * An instant is a number that uniquely describes a particular
451 * microsecond in time, taking time zone considerations into account.
452 * (ie: "03:00 -0400" is the same instant as "02:00 -0500").
454 * An instant is always positive but we use a signed return value to
455 * avoid troubles with C.
458 g_date_time_to_instant (GDateTime *datetime)
462 offset = g_time_zone_get_offset (datetime->tz, datetime->interval);
463 offset *= USEC_PER_SECOND;
465 return datetime->days * USEC_PER_DAY + datetime->usec - offset;
469 * g_date_time_from_instant:
471 * @instant: a instant in time
473 * Creates a #GDateTime from a time zone and an instant.
475 * This might fail if the time ends up being out of range.
478 g_date_time_from_instant (GTimeZone *tz,
484 if (instant < 0 || instant > G_GINT64_CONSTANT (1000000000000000000))
487 datetime = g_date_time_alloc (tz);
488 datetime->interval = g_time_zone_find_interval (tz,
489 G_TIME_TYPE_UNIVERSAL,
490 INSTANT_TO_UNIX (instant));
491 offset = g_time_zone_get_offset (datetime->tz, datetime->interval);
492 offset *= USEC_PER_SECOND;
496 datetime->days = instant / USEC_PER_DAY;
497 datetime->usec = instant % USEC_PER_DAY;
499 if (datetime->days < 1 || 3652059 < datetime->days)
501 g_date_time_unref (datetime);
510 * g_date_time_deal_with_date_change:
511 * @datetime: a #GDateTime
513 * This function should be called whenever the date changes by adding
514 * days, months or years. It does three things.
516 * First, we ensure that the date falls between 0001-01-01 and
517 * 9999-12-31 and return %FALSE if it does not.
519 * Next we update the ->interval field.
521 * Finally, we ensure that the resulting date and time pair exists (by
522 * ensuring that our time zone has an interval containing it) and
523 * adjusting as required. For example, if we have the time 02:30:00 on
524 * March 13 2010 in Toronto and we add 1 day to it, we would end up with
525 * 2:30am on March 14th, which doesn't exist. In that case, we bump the
529 g_date_time_deal_with_date_change (GDateTime *datetime)
535 if (datetime->days < 1 || datetime->days > 3652059)
538 was_dst = g_time_zone_is_dst (datetime->tz, datetime->interval);
540 full_time = datetime->days * USEC_PER_DAY + datetime->usec;
543 usec = full_time % USEC_PER_SECOND;
544 full_time /= USEC_PER_SECOND;
545 full_time -= UNIX_EPOCH_START * SEC_PER_DAY;
547 datetime->interval = g_time_zone_adjust_time (datetime->tz,
550 full_time += UNIX_EPOCH_START * SEC_PER_DAY;
551 full_time *= USEC_PER_SECOND;
554 datetime->days = full_time / USEC_PER_DAY;
555 datetime->usec = full_time % USEC_PER_DAY;
557 /* maybe daylight time caused us to shift to a different day,
558 * but it definitely didn't push us into a different year */
563 g_date_time_replace_days (GDateTime *datetime,
568 new = g_date_time_alloc (datetime->tz);
569 new->interval = datetime->interval;
570 new->usec = datetime->usec;
573 if (!g_date_time_deal_with_date_change (new))
575 g_date_time_unref (new);
582 /* now/unix/timeval Constructors {{{1 */
585 * g_date_time_new_from_timeval:
589 * Creates a #GDateTime corresponding to the given #GTimeVal @tv in the
590 * given time zone @tz.
592 * The time contained in a #GTimeVal is always stored in the form of
593 * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the
596 * This call can fail (returning %NULL) if @tv represents a time outside
597 * of the supported range of #GDateTime.
599 * You should release the return value by calling g_date_time_unref()
600 * when you are done with it.
602 * Returns: a new #GDateTime, or %NULL
607 g_date_time_new_from_timeval (GTimeZone *tz,
610 return g_date_time_from_instant (tz, tv->tv_usec +
611 UNIX_TO_INSTANT (tv->tv_sec));
615 * g_date_time_new_from_unix:
619 * Creates a #GDateTime corresponding to the given Unix time @t in the
620 * given time zone @tz.
622 * Unix time is the number of seconds that have elapsed since 1970-01-01
623 * 00:00:00 UTC, regardless of the time zone given.
625 * This call can fail (returning %NULL) if @t represents a time outside
626 * of the supported range of #GDateTime.
628 * You should release the return value by calling g_date_time_unref()
629 * when you are done with it.
631 * Returns: a new #GDateTime, or %NULL
636 g_date_time_new_from_unix (GTimeZone *tz,
639 return g_date_time_from_instant (tz, UNIX_TO_INSTANT (secs));
643 * g_date_time_new_now:
646 * Creates a #GDateTime corresponding to this exact instant in the given
647 * time zone @tz. The time is as accurate as the system allows, to a
648 * maximum accuracy of 1 microsecond.
650 * This function will always succeed unless the system clock is set to
651 * truly insane values (or unless GLib is still being used after the
654 * You should release the return value by calling g_date_time_unref()
655 * when you are done with it.
657 * Returns: a new #GDateTime, or %NULL
662 g_date_time_new_now (GTimeZone *tz)
666 g_get_current_time (&tv);
668 return g_date_time_new_from_timeval (tz, &tv);
672 * g_date_time_new_now_local:
674 * Creates a #GDateTime corresponding to this exact instant in the local
677 * This is equivalent to calling g_date_time_new_now() with the time
678 * zone returned by g_time_zone_new_local().
680 * Returns: a new #GDateTime, or %NULL
685 g_date_time_new_now_local (void)
690 local = g_time_zone_new_local ();
691 datetime = g_date_time_new_now (local);
692 g_time_zone_unref (local);
698 * g_date_time_new_now_utc:
700 * Creates a #GDateTime corresponding to this exact instant in UTC.
702 * This is equivalent to calling g_date_time_new_now() with the time
703 * zone returned by g_time_zone_new_utc().
705 * Returns: a new #GDateTime, or %NULL
710 g_date_time_new_now_utc (void)
715 utc = g_time_zone_new_utc ();
716 datetime = g_date_time_new_now (utc);
717 g_time_zone_unref (utc);
723 * g_date_time_new_from_unix_local:
726 * Creates a #GDateTime corresponding to the given Unix time @t in the
729 * Unix time is the number of seconds that have elapsed since 1970-01-01
730 * 00:00:00 UTC, regardless of the local time offset.
732 * This call can fail (returning %NULL) if @t represents a time outside
733 * of the supported range of #GDateTime.
735 * You should release the return value by calling g_date_time_unref()
736 * when you are done with it.
738 * Returns: a new #GDateTime, or %NULL
743 g_date_time_new_from_unix_local (gint64 t)
748 local = g_time_zone_new_local ();
749 datetime = g_date_time_new_from_unix (local, t);
750 g_time_zone_unref (local);
756 * g_date_time_new_from_unix_utc:
759 * Creates a #GDateTime corresponding to the given Unix time @t in UTC.
761 * Unix time is the number of seconds that have elapsed since 1970-01-01
764 * This call can fail (returning %NULL) if @t represents a time outside
765 * of the supported range of #GDateTime.
767 * You should release the return value by calling g_date_time_unref()
768 * when you are done with it.
770 * Returns: a new #GDateTime, or %NULL
775 g_date_time_new_from_unix_utc (gint64 t)
780 utc = g_time_zone_new_utc ();
781 datetime = g_date_time_new_from_unix (utc, t);
782 g_time_zone_unref (utc);
788 * g_date_time_new_from_timeval_local:
791 * Creates a #GDateTime corresponding to the given #GTimeVal @tv in the
794 * The time contained in a #GTimeVal is always stored in the form of
795 * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the
798 * This call can fail (returning %NULL) if @tv represents a time outside
799 * of the supported range of #GDateTime.
801 * You should release the return value by calling g_date_time_unref()
802 * when you are done with it.
804 * Returns: a new #GDateTime, or %NULL
809 g_date_time_new_from_timeval_local (const GTimeVal *tv)
814 local = g_time_zone_new_local ();
815 datetime = g_date_time_new_from_timeval (local, tv);
816 g_time_zone_unref (local);
822 * g_date_time_new_from_timeval_utc:
825 * Creates a #GDateTime corresponding to the given #GTimeVal @tv in UTC.
827 * The time contained in a #GTimeVal is always stored in the form of
828 * seconds elapsed since 1970-01-01 00:00:00 UTC.
830 * This call can fail (returning %NULL) if @tv represents a time outside
831 * of the supported range of #GDateTime.
833 * You should release the return value by calling g_date_time_unref()
834 * when you are done with it.
836 * Returns: a new #GDateTime, or %NULL
841 g_date_time_new_from_timeval_utc (const GTimeVal *tv)
846 utc = g_time_zone_new_utc ();
847 datetime = g_date_time_new_from_timeval (utc, tv);
848 g_time_zone_unref (utc);
853 /* full new functions {{{1 */
858 * @year: the year component of the date
859 * @month: the month component of the date
860 * @day: the day component of the date
861 * @hour: the hour component of the date
862 * @minute: the minute component of the date
863 * @seconds: the number of seconds past the minute
865 * Creates a new #GDateTime corresponding to the given date and time in
868 * The @year must be between 1 and 9999, @month between 1 and 12 and @day
869 * between 1 and 28, 29, 30 or 31 depending on the month and the year.
871 * @hour must be between 0 and 23 and @minute must be between 0 and 59.
873 * @seconds must be at least 0.0 and must be strictly less than 60.0.
874 * It will be rounded down to the nearest microsecond.
876 * If the given time is not representable in the given time zone (for
877 * example, 02:30 on March 14th 2010 in Toronto, due to daylight savings
878 * time) then the time will be rounded up to the nearest existing time
879 * (in this case, 03:00). If this matters to you then you should verify
880 * the return value for containing the same as the numbers you gave.
882 * In the case that the given time is ambiguous in the given time zone
883 * (for example, 01:30 on November 7th 2010 in Toronto, due to daylight
884 * savings time) then the time falling within standard (ie:
885 * non-daylight) time is taken.
887 * It not considered a programmer error for the values to this function
888 * to be out of range, but in the case that they are, the function will
891 * You should release the return value by calling g_date_time_unref()
892 * when you are done with it.
894 * Returns: a new #GDateTime, or %NULL
899 g_date_time_new (GTimeZone *tz,
910 datetime = g_date_time_alloc (tz);
911 datetime->days = ymd_to_days (year, month, day);
912 datetime->usec = (hour * USEC_PER_HOUR)
913 + (minute * USEC_PER_MINUTE)
914 + (gint64) (seconds * USEC_PER_SECOND);
916 full_time = SEC_PER_DAY *
917 (ymd_to_days (year, month, day) - UNIX_EPOCH_START) +
918 SECS_PER_HOUR * hour +
919 SECS_PER_MINUTE * minute +
922 datetime->interval = g_time_zone_adjust_time (datetime->tz,
923 G_TIME_TYPE_STANDARD,
926 full_time += UNIX_EPOCH_START * SEC_PER_DAY;
927 datetime->days = full_time / SEC_PER_DAY;
928 datetime->usec = (full_time % SEC_PER_DAY) * USEC_PER_SECOND;
929 datetime->usec += ((int) (seconds * USEC_PER_SECOND)) % USEC_PER_SECOND;
935 * g_date_time_new_local:
936 * @year: the year component of the date
937 * @month: the month component of the date
938 * @day: the day component of the date
939 * @hour: the hour component of the date
940 * @minute: the minute component of the date
941 * @seconds: the number of seconds past the minute
943 * Creates a new #GDateTime corresponding to the given date and time in
944 * the local time zone.
946 * This call is equivalent to calling g_date_time_new() with the time
947 * zone returned by g_time_zone_new_local().
949 * Returns: a #GDateTime, or %NULL
954 g_date_time_new_local (gint year,
964 local = g_time_zone_new_local ();
965 datetime = g_date_time_new (local, year, month, day, hour, minute, seconds);
966 g_time_zone_unref (local);
972 * g_date_time_new_utc:
973 * @year: the year component of the date
974 * @month: the month component of the date
975 * @day: the day component of the date
976 * @hour: the hour component of the date
977 * @minute: the minute component of the date
978 * @seconds: the number of seconds past the minute
980 * Creates a new #GDateTime corresponding to the given date and time in
983 * This call is equivalent to calling g_date_time_new() with the time
984 * zone returned by g_time_zone_new_utc().
986 * Returns: a #GDateTime, or %NULL
991 g_date_time_new_utc (gint year,
1001 utc = g_time_zone_new_utc ();
1002 datetime = g_date_time_new (utc, year, month, day, hour, minute, seconds);
1003 g_time_zone_unref (utc);
1012 * @datetime: a #GDateTime
1013 * @timespan: a #GTimeSpan
1015 * Creates a copy of @datetime and adds the specified timespan to the copy.
1017 * Return value: the newly created #GDateTime which should be freed with
1018 * g_date_time_unref().
1023 g_date_time_add (GDateTime *datetime,
1026 return g_date_time_from_instant (datetime->tz, timespan +
1027 g_date_time_to_instant (datetime));
1031 * g_date_time_add_years:
1032 * @datetime: a #GDateTime
1033 * @years: the number of years
1035 * Creates a copy of @datetime and adds the specified number of years to the
1038 * Return value: the newly created #GDateTime which should be freed with
1039 * g_date_time_unref().
1044 g_date_time_add_years (GDateTime *datetime,
1047 gint year, month, day;
1049 g_return_val_if_fail (datetime != NULL, NULL);
1051 if (years < -10000 || years > 10000)
1054 g_date_time_get_ymd (datetime, &year, &month, &day);
1057 /* only possible issue is if we've entered a year with no February 29
1059 if (month == 2 && day == 29 && !GREGORIAN_LEAP (year))
1062 return g_date_time_replace_days (datetime, ymd_to_days (year, month, day));
1066 * g_date_time_add_months:
1067 * @datetime: a #GDateTime
1068 * @months: the number of months
1070 * Creates a copy of @datetime and adds the specified number of months to the
1073 * Return value: the newly created #GDateTime which should be freed with
1074 * g_date_time_unref().
1079 g_date_time_add_months (GDateTime *datetime,
1082 gint year, month, day;
1084 g_return_val_if_fail (datetime != NULL, NULL);
1085 g_date_time_get_ymd (datetime, &year, &month, &day);
1087 if (months < -120000 || months > 120000)
1090 year += months / 12;
1091 month += months % 12;
1097 else if (month > 12)
1103 day = MIN (day, days_in_months[GREGORIAN_LEAP (year)][month]);
1105 return g_date_time_replace_days (datetime, ymd_to_days (year, month, day));
1109 * g_date_time_add_weeks:
1110 * @datetime: a #GDateTime
1111 * @weeks: the number of weeks
1113 * Creates a copy of @datetime and adds the specified number of weeks to the
1116 * Return value: the newly created #GDateTime which should be freed with
1117 * g_date_time_unref().
1122 g_date_time_add_weeks (GDateTime *datetime,
1125 g_return_val_if_fail (datetime != NULL, NULL);
1127 return g_date_time_add_days (datetime, weeks * 7);
1131 * g_date_time_add_days:
1132 * @datetime: a #GDateTime
1133 * @days: the number of days
1135 * Creates a copy of @datetime and adds the specified number of days to the
1138 * Return value: the newly created #GDateTime which should be freed with
1139 * g_date_time_unref().
1144 g_date_time_add_days (GDateTime *datetime,
1147 g_return_val_if_fail (datetime != NULL, NULL);
1149 if (days < -3660000 || days > 3660000)
1152 return g_date_time_replace_days (datetime, datetime->days + days);
1156 * g_date_time_add_hours:
1157 * @datetime: a #GDateTime
1158 * @hours: the number of hours to add
1160 * Creates a copy of @datetime and adds the specified number of hours
1162 * Return value: the newly created #GDateTime which should be freed with
1163 * g_date_time_unref().
1168 g_date_time_add_hours (GDateTime *datetime,
1171 return g_date_time_add (datetime, hours * USEC_PER_HOUR);
1175 * g_date_time_add_minutes:
1176 * @datetime: a #GDateTime
1177 * @minutes: the number of minutes to add
1179 * Creates a copy of @datetime adding the specified number of minutes.
1181 * Return value: the newly created #GDateTime which should be freed with
1182 * g_date_time_unref().
1187 g_date_time_add_minutes (GDateTime *datetime,
1190 return g_date_time_add (datetime, minutes * USEC_PER_MINUTE);
1195 * g_date_time_add_seconds:
1196 * @datetime: a #GDateTime
1197 * @seconds: the number of seconds to add
1199 * Creates a copy of @datetime and adds the specified number of seconds.
1201 * Return value: the newly created #GDateTime which should be freed with
1202 * g_date_time_unref().
1207 g_date_time_add_seconds (GDateTime *datetime,
1210 return g_date_time_add (datetime, seconds * USEC_PER_SECOND);
1214 * g_date_time_add_full:
1215 * @datetime: a #GDateTime
1216 * @years: the number of years to add
1217 * @months: the number of months to add
1218 * @days: the number of days to add
1219 * @hours: the number of hours to add
1220 * @minutes: the number of minutes to add
1221 * @seconds: the number of seconds to add
1223 * Creates a new #GDateTime adding the specified values to the current date and
1224 * time in @datetime.
1226 * Return value: the newly created #GDateTime that should be freed with
1227 * g_date_time_unref().
1232 g_date_time_add_full (GDateTime *datetime,
1240 gint year, month, day;
1245 g_return_val_if_fail (datetime != NULL, NULL);
1246 g_date_time_get_ymd (datetime, &year, &month, &day);
1248 months += years * 12;
1250 if (months < -120000 || months > 120000)
1253 if (days < -3660000 || days > 3660000)
1256 year += months / 12;
1257 month += months % 12;
1263 else if (month > 12)
1269 day = MIN (day, days_in_months[GREGORIAN_LEAP (year)][month]);
1271 /* full_time is now in unix (local) time */
1272 full_time = datetime->usec / USEC_PER_SECOND + SEC_PER_DAY *
1273 (ymd_to_days (year, month, day) + days - UNIX_EPOCH_START);
1275 interval = g_time_zone_adjust_time (datetime->tz,
1276 g_time_zone_is_dst (datetime->tz,
1277 datetime->interval),
1280 /* move to UTC unix time */
1281 full_time -= g_time_zone_get_offset (datetime->tz, interval);
1283 /* convert back to an instant, add back fractional seconds */
1284 full_time += UNIX_EPOCH_START * SEC_PER_DAY;
1285 full_time = full_time * USEC_PER_SECOND +
1286 datetime->usec % USEC_PER_SECOND;
1288 /* do the actual addition now */
1289 full_time += (hours * USEC_PER_HOUR) +
1290 (minutes * USEC_PER_MINUTE) +
1291 (gint64) (seconds * USEC_PER_SECOND);
1293 /* find the new interval */
1294 interval = g_time_zone_find_interval (datetime->tz,
1295 G_TIME_TYPE_UNIVERSAL,
1296 INSTANT_TO_UNIX (full_time));
1298 /* convert back into local time */
1299 full_time += USEC_PER_SECOND *
1300 g_time_zone_get_offset (datetime->tz, interval);
1302 /* split into days and usec of a new datetime */
1303 new = g_date_time_alloc (datetime->tz);
1304 new->interval = interval;
1305 new->days = full_time / USEC_PER_DAY;
1306 new->usec = full_time % USEC_PER_DAY;
1313 /* Compare, difference, hash, equal {{{1 */
1315 * g_date_time_compare:
1316 * @dt1: first #GDateTime to compare
1317 * @dt2: second #GDateTime to compare
1319 * #GCompareFunc-compatible comparison for #GDateTime<!-- -->'s. Both
1320 * #GDateTime<-- -->'s must be non-%NULL.
1322 * Return value: -1, 0 or 1 if @dt1 is less than, equal to or greater
1328 g_date_time_compare (gconstpointer dt1,
1333 difference = g_date_time_difference ((GDateTime *) dt1, (GDateTime *) dt2);
1338 else if (difference > 0)
1346 * g_date_time_difference:
1347 * @end: a #GDateTime
1348 * @begin: a #GDateTime
1350 * Calculates the difference in time between @end and @begin. The
1351 * #GTimeSpan that is returned is effectively @end - @begin (ie:
1352 * positive if the first simparameter is larger).
1354 * Return value: the difference between the two #GDateTime, as a time
1355 * span expressed in microseconds.
1360 g_date_time_difference (GDateTime *end,
1363 g_return_val_if_fail (begin != NULL, 0);
1364 g_return_val_if_fail (end != NULL, 0);
1366 return g_date_time_to_instant (end) -
1367 g_date_time_to_instant (begin);
1372 * @datetime: a #GDateTime
1374 * Hashes @datetime into a #guint, suitable for use within #GHashTable.
1376 * Return value: a #guint containing the hash
1381 g_date_time_hash (gconstpointer datetime)
1383 return g_date_time_to_instant ((GDateTime *) datetime);
1387 * g_date_time_equal:
1388 * @dt1: a #GDateTime
1389 * @dt2: a #GDateTime
1391 * Checks to see if @dt1 and @dt2 are equal.
1393 * Equal here means that they represent the same moment after converting
1394 * them to the same time zone.
1396 * Return value: %TRUE if @dt1 and @dt2 are equal
1401 g_date_time_equal (gconstpointer dt1,
1404 return g_date_time_difference ((GDateTime *) dt1, (GDateTime *) dt2) == 0;
1407 /* Year, Month, Day Getters {{{1 */
1409 * g_date_time_get_ymd:
1410 * @datetime: a #GDateTime.
1411 * @year: (out): the return location for the gregorian year, or %NULL.
1412 * @month: (out): the return location for the month of the year, or %NULL.
1413 * @day: (out): the return location for the day of the month, or %NULL.
1415 * Retrieves the Gregorian day, month, and year of a given #GDateTime.
1420 g_date_time_get_ymd (GDateTime *datetime,
1428 gint remaining_days;
1435 g_return_if_fail (datetime != NULL);
1437 remaining_days = datetime->days;
1440 * We need to convert an offset in days to its year/month/day representation.
1441 * Leap years makes this a little trickier than it should be, so we use
1442 * 400, 100 and 4 years cycles here to get to the correct year.
1445 /* Our days offset starts sets 0001-01-01 as day 1, if it was day 0 our
1446 * math would be simpler, so let's do it */
1449 the_year = (remaining_days / DAYS_IN_400YEARS) * 400 + 1;
1450 remaining_days = remaining_days % DAYS_IN_400YEARS;
1452 y100_cycles = remaining_days / DAYS_IN_100YEARS;
1453 remaining_days = remaining_days % DAYS_IN_100YEARS;
1454 the_year += y100_cycles * 100;
1456 y4_cycles = remaining_days / DAYS_IN_4YEARS;
1457 remaining_days = remaining_days % DAYS_IN_4YEARS;
1458 the_year += y4_cycles * 4;
1460 y1_cycles = remaining_days / 365;
1461 the_year += y1_cycles;
1462 remaining_days = remaining_days % 365;
1464 if (y1_cycles == 4 || y100_cycles == 4) {
1465 g_assert (remaining_days == 0);
1467 /* special case that indicates that the date is actually one year before,
1468 * in the 31th of December */
1475 /* now get the month and the day */
1476 leap = y1_cycles == 3 && (y4_cycles != 24 || y100_cycles == 3);
1478 g_assert (leap == GREGORIAN_LEAP(the_year));
1480 the_month = (remaining_days + 50) >> 5;
1481 preceding = (days_in_year[0][the_month - 1] + (the_month > 2 && leap));
1482 if (preceding > remaining_days)
1484 /* estimate is too large */
1486 preceding -= leap ? days_in_months[1][the_month]
1487 : days_in_months[0][the_month];
1490 remaining_days -= preceding;
1491 g_assert(0 <= remaining_days);
1493 the_day = remaining_days + 1;
1505 * g_date_time_get_year:
1506 * @datetime: A #GDateTime
1508 * Retrieves the year represented by @datetime in the Gregorian calendar.
1510 * Return value: the year represented by @datetime
1515 g_date_time_get_year (GDateTime *datetime)
1519 g_return_val_if_fail (datetime != NULL, 0);
1521 g_date_time_get_ymd (datetime, &year, NULL, NULL);
1527 * g_date_time_get_month:
1528 * @datetime: a #GDateTime
1530 * Retrieves the month of the year represented by @datetime in the Gregorian
1533 * Return value: the month represented by @datetime
1538 g_date_time_get_month (GDateTime *datetime)
1542 g_return_val_if_fail (datetime != NULL, 0);
1544 g_date_time_get_ymd (datetime, NULL, &month, NULL);
1550 * g_date_time_get_day_of_month:
1551 * @datetime: a #GDateTime
1553 * Retrieves the day of the month represented by @datetime in the gregorian
1556 * Return value: the day of the month
1561 g_date_time_get_day_of_month (GDateTime *datetime)
1565 const guint16 *days;
1568 g_return_val_if_fail (datetime != NULL, 0);
1570 days = days_in_year[GREGORIAN_LEAP (g_date_time_get_year (datetime)) ? 1 : 0];
1571 g_date_time_get_week_number (datetime, NULL, NULL, &day_of_year);
1573 for (i = 1; i <= 12; i++)
1575 if (days [i] >= day_of_year)
1576 return day_of_year - last;
1580 g_warn_if_reached ();
1584 /* Week of year / day of week getters {{{1 */
1586 * g_date_time_get_week_numbering_year:
1587 * @datetime: a #GDateTime
1589 * Returns the ISO 8601 week-numbering year in which the week containing
1592 * This function, taken together with g_date_time_get_week_of_year() and
1593 * g_date_time_get_day_of_week() can be used to determine the full ISO
1594 * week date on which @datetime falls.
1596 * This is usually equal to the normal Gregorian year (as returned by
1597 * g_date_time_get_year()), except as detailed below:
1599 * For Thursday, the week-numbering year is always equal to the usual
1600 * calendar year. For other days, the number is such that every day
1601 * within a complete week (Monday to Sunday) is contained within the
1602 * same week-numbering year.
1604 * For Monday, Tuesday and Wednesday occuring near the end of the year,
1605 * this may mean that the week-numbering year is one greater than the
1606 * calendar year (so that these days have the same week-numbering year
1607 * as the Thursday occuring early in the next year).
1609 * For Friday, Saturaday and Sunday occuring near the start of the year,
1610 * this may mean that the week-numbering year is one less than the
1611 * calendar year (so that these days have the same week-numbering year
1612 * as the Thursday occuring late in the previous year).
1614 * An equivalent description is that the week-numbering year is equal to
1615 * the calendar year containing the majority of the days in the current
1616 * week (Monday to Sunday).
1618 * Note that January 1 0001 in the proleptic Gregorian calendar is a
1619 * Monday, so this function never returns 0.
1621 * Returns: the ISO 8601 week-numbering year for @datetime
1626 g_date_time_get_week_numbering_year (GDateTime *datetime)
1628 gint year, month, day, weekday;
1630 g_date_time_get_ymd (datetime, &year, &month, &day);
1631 weekday = g_date_time_get_day_of_week (datetime);
1633 /* January 1, 2, 3 might be in the previous year if they occur after
1636 * Jan 1: Friday, Saturday, Sunday => day 1: weekday 5, 6, 7
1637 * Jan 2: Saturday, Sunday => day 2: weekday 6, 7
1638 * Jan 3: Sunday => day 3: weekday 7
1640 * So we have a special case if (day - weekday) <= -4
1642 if (month == 1 && (day - weekday) <= -4)
1645 /* December 29, 30, 31 might be in the next year if they occur before
1648 * Dec 31: Monday, Tuesday, Wednesday => day 31: weekday 1, 2, 3
1649 * Dec 30: Monday, Tuesday => day 30: weekday 1, 2
1650 * Dec 29: Monday => day 29: weekday 1
1652 * So we have a special case if (day - weekday) >= 28
1654 else if (month == 12 && (day - weekday) >= 28)
1662 * g_date_time_get_week_of_year:
1663 * @datetime: a #GDateTime
1665 * Returns the ISO 8601 week number for the week containing @datetime.
1666 * The ISO 8601 week number is the same for every day of the week (from
1667 * Moday through Sunday). That can produce some unusual results
1668 * (described below).
1670 * The first week of the year is week 1. This is the week that contains
1671 * the first Thursday of the year. Equivalently, this is the first week
1672 * that has more than 4 of its days falling within the calendar year.
1674 * The value 0 is never returned by this function. Days contained
1675 * within a year but occuring before the first ISO 8601 week of that
1676 * year are considered as being contained in the last week of the
1677 * previous year. Similarly, the final days of a calendar year may be
1678 * considered as being part of the first ISO 8601 week of the next year
1679 * if 4 or more days of that week are contained within the new year.
1681 * Returns: the ISO 8601 week number for @datetime.
1686 g_date_time_get_week_of_year (GDateTime *datetime)
1690 g_return_val_if_fail (datetime != NULL, 0);
1692 g_date_time_get_week_number (datetime, &weeknum, NULL, NULL);
1698 * g_date_time_get_day_of_week:
1699 * @datetime: a #GDateTime
1701 * Retrieves the ISO 8601 day of the week on which @datetime falls (1 is
1702 * Monday, 2 is Tuesday... 7 is Sunday).
1704 * Return value: the day of the week
1709 g_date_time_get_day_of_week (GDateTime *datetime)
1711 g_return_val_if_fail (datetime != NULL, 0);
1713 return (datetime->days - 1) % 7 + 1;
1716 /* Day of year getter {{{1 */
1718 * g_date_time_get_day_of_year:
1719 * @datetime: a #GDateTime
1721 * Retrieves the day of the year represented by @datetime in the Gregorian
1724 * Return value: the day of the year
1729 g_date_time_get_day_of_year (GDateTime *datetime)
1733 g_return_val_if_fail (datetime != NULL, 0);
1735 g_date_time_get_week_number (datetime, NULL, NULL, &doy);
1739 /* Time component getters {{{1 */
1742 * g_date_time_get_hour:
1743 * @datetime: a #GDateTime
1745 * Retrieves the hour of the day represented by @datetime
1747 * Return value: the hour of the day
1752 g_date_time_get_hour (GDateTime *datetime)
1754 g_return_val_if_fail (datetime != NULL, 0);
1756 return (datetime->usec / USEC_PER_HOUR);
1760 * g_date_time_get_minute:
1761 * @datetime: a #GDateTime
1763 * Retrieves the minute of the hour represented by @datetime
1765 * Return value: the minute of the hour
1770 g_date_time_get_minute (GDateTime *datetime)
1772 g_return_val_if_fail (datetime != NULL, 0);
1774 return (datetime->usec % USEC_PER_HOUR) / USEC_PER_MINUTE;
1778 * g_date_time_get_second:
1779 * @datetime: a #GDateTime
1781 * Retrieves the second of the minute represented by @datetime
1783 * Return value: the second represented by @datetime
1788 g_date_time_get_second (GDateTime *datetime)
1790 g_return_val_if_fail (datetime != NULL, 0);
1792 return (datetime->usec % USEC_PER_MINUTE) / USEC_PER_SECOND;
1796 * g_date_time_get_microsecond:
1797 * @datetime: a #GDateTime
1799 * Retrieves the microsecond of the date represented by @datetime
1801 * Return value: the microsecond of the second
1806 g_date_time_get_microsecond (GDateTime *datetime)
1808 g_return_val_if_fail (datetime != NULL, 0);
1810 return (datetime->usec % USEC_PER_SECOND);
1814 * g_date_time_get_seconds:
1815 * @datetime: a #GDateTime
1817 * Retrieves the number of seconds since the start of the last minute,
1818 * including the fractional part.
1820 * Returns: the number of seconds
1825 g_date_time_get_seconds (GDateTime *datetime)
1827 g_return_val_if_fail (datetime != NULL, 0);
1829 return (datetime->usec % USEC_PER_MINUTE) / 1000000.0;
1832 /* Exporters {{{1 */
1834 * g_date_time_to_unix:
1835 * @datetime: a #GDateTime
1837 * Gives the Unix time corresponding to @datetime, rounding down to the
1840 * Unix time is the number of seconds that have elapsed since 1970-01-01
1841 * 00:00:00 UTC, regardless of the time zone associated with @datetime.
1843 * Returns: the Unix time corresponding to @datetime
1848 g_date_time_to_unix (GDateTime *datetime)
1850 return INSTANT_TO_UNIX (g_date_time_to_instant (datetime));
1854 * g_date_time_to_timeval:
1855 * @datetime: a #GDateTime
1856 * @tv: a #GTimeVal to modify
1858 * Stores the instant in time that @datetime represents into @tv.
1860 * The time contained in a #GTimeVal is always stored in the form of
1861 * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the time
1862 * zone associated with @datetime.
1864 * On systems where 'long' is 32bit (ie: all 32bit systems and all
1865 * Windows systems), a #GTimeVal is incapable of storing the entire
1866 * range of values that #GDateTime is capable of expressing. On those
1867 * systems, this function returns %FALSE to indicate that the time is
1870 * On systems where 'long' is 64bit, this function never fails.
1872 * Returns: %TRUE if successful, else %FALSE
1877 g_date_time_to_timeval (GDateTime *datetime,
1880 tv->tv_sec = INSTANT_TO_UNIX (g_date_time_to_instant (datetime));
1881 tv->tv_usec = datetime->usec % USEC_PER_SECOND;
1886 /* Timezone queries {{{1 */
1888 * g_date_time_get_utc_offset:
1889 * @datetime: a #GDateTime
1891 * Determines the offset to UTC in effect at the time and in the time
1892 * zone of @datetime.
1894 * The offset is the number of microseconds that you add to UTC time to
1895 * arrive at local time for the time zone (ie: negative numbers for time
1896 * zones west of GMT, positive numbers for east).
1898 * If @datetime represents UTC time, then the offset is always zero.
1900 * Returns: the number of microseconds that should be added to UTC to
1901 * get the local time
1906 g_date_time_get_utc_offset (GDateTime *datetime)
1910 g_return_val_if_fail (datetime != NULL, 0);
1912 offset = g_time_zone_get_offset (datetime->tz, datetime->interval);
1914 return (gint64) offset * USEC_PER_SECOND;
1918 * g_date_time_get_timezone_abbreviation:
1919 * @datetime: a #GDateTime
1921 * Determines the time zone abbreviation to be used at the time and in
1922 * the time zone of @datetime.
1924 * For example, in Toronto this is currently "EST" during the winter
1925 * months and "EDT" during the summer months when daylight savings
1926 * time is in effect.
1928 * Returns: (transfer none): the time zone abbreviation. The returned
1929 * string is owned by the #GDateTime and it should not be
1935 g_date_time_get_timezone_abbreviation (GDateTime *datetime)
1937 g_return_val_if_fail (datetime != NULL, NULL);
1939 return g_time_zone_get_abbreviation (datetime->tz, datetime->interval);
1943 * g_date_time_is_daylight_savings:
1944 * @datetime: a #GDateTime
1946 * Determines if daylight savings time is in effect at the time and in
1947 * the time zone of @datetime.
1949 * Returns: %TRUE if daylight savings time is in effect
1954 g_date_time_is_daylight_savings (GDateTime *datetime)
1956 g_return_val_if_fail (datetime != NULL, FALSE);
1958 return g_time_zone_is_dst (datetime->tz, datetime->interval);
1961 /* Timezone convert {{{1 */
1963 * g_date_time_to_timezone:
1964 * @datetime: a #GDateTime
1965 * @tz: the new #GTimeZone
1967 * Create a new #GDateTime corresponding to the same instant in time as
1968 * @datetime, but in the time zone @tz.
1970 * This call can fail in the case that the time goes out of bounds. For
1971 * example, converting 0001-01-01 00:00:00 UTC to a time zone west of
1972 * Greenwich will fail (due to the year 0 being out of range).
1974 * You should release the return value by calling g_date_time_unref()
1975 * when you are done with it.
1977 * Returns: a new #GDateTime, or %NULL
1982 g_date_time_to_timezone (GDateTime *datetime,
1985 return g_date_time_from_instant (tz, g_date_time_to_instant (datetime));
1989 * g_date_time_to_local:
1990 * @datetime: a #GDateTime
1992 * Creates a new #GDateTime corresponding to the same instant in time as
1993 * @datetime, but in the local time zone.
1995 * This call is equivalent to calling g_date_time_to_timezone() with the
1996 * time zone returned by g_time_zone_new_local().
1998 * Returns: the newly created #GDateTime
2003 g_date_time_to_local (GDateTime *datetime)
2008 local = g_time_zone_new_local ();
2009 new = g_date_time_to_timezone (datetime, local);
2010 g_time_zone_unref (local);
2016 * g_date_time_to_utc:
2017 * @datetime: a #GDateTime
2019 * Creates a new #GDateTime corresponding to the same instant in time as
2020 * @datetime, but in UTC.
2022 * This call is equivalent to calling g_date_time_to_timezone() with the
2023 * time zone returned by g_time_zone_new_utc().
2025 * Returns: the newly created #GDateTime
2030 g_date_time_to_utc (GDateTime *datetime)
2035 utc = g_time_zone_new_utc ();
2036 new = g_date_time_to_timezone (datetime, utc);
2037 g_time_zone_unref (utc);
2044 * g_date_time_format:
2045 * @datetime: A #GDateTime
2046 * @format: a valid UTF-8 string, containing the format for the
2049 * Creates a newly allocated string representing the requested @format.
2051 * The following format specifiers are supported:
2054 * <varlistentry><term>
2055 * <literal>%%a</literal>:
2056 * </term><listitem><simpara>
2057 * the abbreviated weekday name according to the current locale
2058 * </simpara></listitem></varlistentry>
2059 * <varlistentry><term>
2060 * <literal>%%A</literal>:
2061 * </term><listitem><simpara>
2062 * the full weekday name according to the current locale
2063 * </simpara></listitem></varlistentry>
2064 * <varlistentry><term>
2065 * <literal>%%b</literal>:
2066 * </term><listitem><simpara>
2067 * the abbreviated month name according to the current locale
2068 * </simpara></listitem></varlistentry>
2069 * <varlistentry><term>
2070 * <literal>%%B</literal>:
2071 * </term><listitem><simpara>
2072 * the full month name according to the current locale
2073 * </simpara></listitem></varlistentry>
2074 * <varlistentry><term>
2075 * <literal>%%d</literal>:
2076 * </term><listitem><simpara>
2077 * the day of the month as a decimal number (range 01 to 31)
2078 * </simpara></listitem></varlistentry>
2079 * <varlistentry><term>
2080 * <literal>%%e</literal>:
2081 * </term><listitem><simpara>
2082 * the day of the month as a decimal number (range 1 to 31)
2083 * </simpara></listitem></varlistentry>
2084 * <varlistentry><term>
2085 * <literal>%%F</literal>:
2086 * </term><listitem><simpara>
2087 * equivalent to <literal>%%Y-%%m-%%d</literal> (the ISO 8601 date
2089 * </simpara></listitem></varlistentry>
2090 * <varlistentry><term>
2091 * <literal>%%h</literal>:
2092 * </term><listitem><simpara>
2093 * equivalent to <literal>%%b</literal>
2094 * </simpara></listitem></varlistentry>
2095 * <varlistentry><term>
2096 * <literal>%%H</literal>:
2097 * </term><listitem><simpara>
2098 * the hour as a decimal number using a 24-hour clock (range 00 to
2100 * </simpara></listitem></varlistentry>
2101 * <varlistentry><term>
2102 * <literal>%%I</literal>:
2103 * </term><listitem><simpara>
2104 * the hour as a decimal number using a 12-hour clock (range 01 to
2106 * </simpara></listitem></varlistentry>
2107 * <varlistentry><term>
2108 * <literal>%%j</literal>:
2109 * </term><listitem><simpara>
2110 * the day of the year as a decimal number (range 001 to 366)
2111 * </simpara></listitem></varlistentry>
2112 * <varlistentry><term>
2113 * <literal>%%k</literal>:
2114 * </term><listitem><simpara>
2115 * the hour (24-hour clock) as a decimal number (range 0 to 23);
2116 * single digits are preceded by a blank
2117 * </simpara></listitem></varlistentry>
2118 * <varlistentry><term>
2119 * <literal>%%l</literal>:
2120 * </term><listitem><simpara>
2121 * the hour (12-hour clock) as a decimal number (range 1 to 12);
2122 * single digits are preceded by a blank
2123 * </simpara></listitem></varlistentry>
2124 * <varlistentry><term>
2125 * <literal>%%m</literal>:
2126 * </term><listitem><simpara>
2127 * the month as a decimal number (range 01 to 12)
2128 * </simpara></listitem></varlistentry>
2129 * <varlistentry><term>
2130 * <literal>%%M</literal>:
2131 * </term><listitem><simpara>
2132 * the minute as a decimal number (range 00 to 59)
2133 * </simpara></listitem></varlistentry>
2134 * <varlistentry><term>
2135 * <literal>%%N</literal>:
2136 * </term><listitem><simpara>
2137 * the micro-seconds as a decimal number
2138 * </simpara></listitem></varlistentry>
2139 * <varlistentry><term>
2140 * <literal>%%p</literal>:
2141 * </term><listitem><simpara>
2142 * either "AM" or "PM" according to the given time value, or the
2143 * corresponding strings for the current locale. Noon is treated as
2144 * "PM" and midnight as "AM".
2145 * </simpara></listitem></varlistentry>
2146 * <varlistentry><term>
2147 * <literal>%%P</literal>:
2148 * </term><listitem><simpara>
2149 * like %%p but lowercase: "am" or "pm" or a corresponding string for
2150 * the current locale
2151 * </simpara></listitem></varlistentry>
2152 * <varlistentry><term>
2153 * <literal>%%r</literal>:
2154 * </term><listitem><simpara>
2155 * the time in a.m. or p.m. notation
2156 * </simpara></listitem></varlistentry>
2157 * <varlistentry><term>
2158 * <literal>%%R</literal>:
2159 * </term><listitem><simpara>
2160 * the time in 24-hour notation (<literal>%%H:%%M</literal>)
2161 * </simpara></listitem></varlistentry>
2162 * <varlistentry><term>
2163 * <literal>%%s</literal>:
2164 * </term><listitem><simpara>
2165 * the number of seconds since the Epoch, that is, since 1970-01-01
2167 * </simpara></listitem></varlistentry>
2168 * <varlistentry><term>
2169 * <literal>%%S</literal>:
2170 * </term><listitem><simpara>
2171 * the second as a decimal number (range 00 to 60)
2172 * </simpara></listitem></varlistentry>
2173 * <varlistentry><term>
2174 * <literal>%%t</literal>:
2175 * </term><listitem><simpara>
2177 * </simpara></listitem></varlistentry>
2178 * <varlistentry><term>
2179 * <literal>%%u</literal>:
2180 * </term><listitem><simpara>
2181 * the day of the week as a decimal, range 1 to 7, Monday being 1
2182 * </simpara></listitem></varlistentry>
2183 * <varlistentry><term>
2184 * <literal>%%W</literal>:
2185 * </term><listitem><simpara>
2186 * the week number of the current year as a decimal number
2187 * </simpara></listitem></varlistentry>
2188 * <varlistentry><term>
2189 * <literal>%%x</literal>:
2190 * </term><listitem><simpara>
2191 * the preferred date representation for the current locale without
2193 * </simpara></listitem></varlistentry>
2194 * <varlistentry><term>
2195 * <literal>%%X</literal>:
2196 * </term><listitem><simpara>
2197 * the preferred time representation for the current locale without
2199 * </simpara></listitem></varlistentry>
2200 * <varlistentry><term>
2201 * <literal>%%y</literal>:
2202 * </term><listitem><simpara>
2203 * the year as a decimal number without the century
2204 * </simpara></listitem></varlistentry>
2205 * <varlistentry><term>
2206 * <literal>%%Y</literal>:
2207 * </term><listitem><simpara>
2208 * the year as a decimal number including the century
2209 * </simpara></listitem></varlistentry>
2210 * <varlistentry><term>
2211 * <literal>%%z</literal>:
2212 * </term><listitem><simpara>
2213 * the time-zone as hour offset from UTC
2214 * </simpara></listitem></varlistentry>
2215 * <varlistentry><term>
2216 * <literal>%%Z</literal>:
2217 * </term><listitem><simpara>
2218 * the time zone or name or abbreviation
2219 * </simpara></listitem></varlistentry>
2220 * <varlistentry><term>
2221 * <literal>%%%</literal>:
2222 * </term><listitem><simpara>
2223 * a literal <literal>%%</literal> character
2224 * </simpara></listitem></varlistentry>
2227 * Returns: a newly allocated string formatted to the requested format
2228 * or %NULL in the case that there was an error. The string
2229 * should be freed with g_free().
2234 g_date_time_format (GDateTime *datetime,
2235 const gchar *format)
2242 g_return_val_if_fail (datetime != NULL, NULL);
2243 g_return_val_if_fail (format != NULL, NULL);
2244 g_return_val_if_fail (g_utf8_validate (format, -1, NULL), NULL);
2246 outstr = g_string_sized_new (strlen (format) * 2);
2249 for (; *format; format = g_utf8_next_char (format))
2251 c = g_utf8_get_char (format);
2268 g_string_append (outstr, WEEKDAY_ABBR (datetime));
2271 g_string_append (outstr, WEEKDAY_FULL (datetime));
2274 g_string_append (outstr, MONTH_ABBR (datetime));
2277 g_string_append (outstr, MONTH_FULL (datetime));
2280 g_string_append_printf (outstr, "%02d", g_date_time_get_day_of_month (datetime));
2283 g_string_append_printf (outstr, "%2d", g_date_time_get_day_of_month (datetime));
2286 g_string_append_printf (outstr, "%d-%02d-%02d",
2287 g_date_time_get_year (datetime),
2288 g_date_time_get_month (datetime),
2289 g_date_time_get_day_of_month (datetime));
2292 g_string_append (outstr, MONTH_ABBR (datetime));
2295 g_string_append_printf (outstr, "%02d", g_date_time_get_hour (datetime));
2298 if ((g_date_time_get_hour (datetime) % 12) == 0)
2299 g_string_append (outstr, "12");
2301 g_string_append_printf (outstr, "%02d", g_date_time_get_hour (datetime) % 12);
2304 g_string_append_printf (outstr, "%03d", g_date_time_get_day_of_year (datetime));
2307 g_string_append_printf (outstr, "%2d", g_date_time_get_hour (datetime));
2310 if ((g_date_time_get_hour (datetime) % 12) == 0)
2311 g_string_append (outstr, "12");
2313 g_string_append_printf (outstr, "%2d", g_date_time_get_hour (datetime) % 12);
2316 g_string_append_printf (outstr, "%02d", g_date_time_get_month (datetime));
2319 g_string_append_printf (outstr, "%02d", g_date_time_get_minute (datetime));
2322 g_string_append_printf (outstr, "%"G_GUINT64_FORMAT, datetime->usec % USEC_PER_SECOND);
2325 g_string_append (outstr, GET_AMPM (datetime, FALSE));
2328 g_string_append (outstr, GET_AMPM (datetime, TRUE));
2332 gint hour = g_date_time_get_hour (datetime) % 12;
2335 g_string_append_printf (outstr, "%02d:%02d:%02d %s",
2337 g_date_time_get_minute (datetime),
2338 g_date_time_get_second (datetime),
2339 GET_AMPM (datetime, FALSE));
2343 g_string_append_printf (outstr, "%02d:%02d",
2344 g_date_time_get_hour (datetime),
2345 g_date_time_get_minute (datetime));
2348 g_string_append_printf (outstr, "%" G_GINT64_FORMAT, g_date_time_to_unix (datetime));
2351 g_string_append_printf (outstr, "%02d", g_date_time_get_second (datetime));
2354 g_string_append_c (outstr, '\t');
2357 g_string_append_printf (outstr, "%d", g_date_time_get_day_of_week (datetime));
2360 g_string_append_printf (outstr, "%d", g_date_time_get_day_of_year (datetime) / 7);
2364 tmp = GET_PREFERRED_DATE (datetime);
2365 g_string_append (outstr, tmp);
2371 tmp = GET_PREFERRED_TIME (datetime);
2372 g_string_append (outstr, tmp);
2377 g_string_append_printf (outstr, "%02d", g_date_time_get_year (datetime) % 100);
2380 g_string_append_printf (outstr, "%d", g_date_time_get_year (datetime));
2383 if (datetime->tz != NULL)
2385 gint64 offset = g_date_time_get_utc_offset (datetime)
2388 g_string_append_printf (outstr, "%+03d%02d",
2389 (int) offset / 3600,
2390 (int) abs(offset) / 60 % 60);
2393 g_string_append (outstr, "+0000");
2396 g_string_append (outstr, g_date_time_get_timezone_abbreviation (datetime));
2399 g_string_append_c (outstr, '%');
2402 g_string_append_c (outstr, '\n');
2410 g_string_append_unichar (outstr, c);
2414 return g_string_free (outstr, FALSE);
2417 g_string_free (outstr, TRUE);
2423 /* vim:set foldmethod=marker: */