Skip to content

Commit

Permalink
gdatetime: Add g_date_time_format_iso8601() convenience function
Browse files Browse the repository at this point in the history
This is a simple wrapper around g_date_time_format_iso8601() which
always produces ISO 8601 dates, without people having to remember the
format string for them (and with the convenience of terminating UTC
dates with ‘Z’ rather than ‘+00’).

Signed-off-by: Philip Withnall <withnall@endlessm.com>

Helps: #1438
  • Loading branch information
pwithnall committed Jul 29, 2019
1 parent 8f385b8 commit dbabd2b
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/reference/glib/glib-sections.txt
Expand Up @@ -1983,6 +1983,7 @@ g_date_time_to_utc

<SUBSECTION>
g_date_time_format
g_date_time_format_iso8601
</SECTION>

<SECTION>
Expand Down
43 changes: 43 additions & 0 deletions glib/gdatetime.c
Expand Up @@ -3393,6 +3393,49 @@ g_date_time_format (GDateTime *datetime,
return g_string_free (outstr, FALSE);
}

/**
* g_date_time_format_iso8601:
* @datetime: A #GDateTime
*
* Format @datetime in [ISO 8601 format](https://en.wikipedia.org/wiki/ISO_8601),
* including the date, time and time zone, and return that as a UTF-8 encoded
* string.
*
* Returns: a newly allocated string formatted in ISO 8601 format
* or %NULL in the case that there was an error. The string
* should be freed with g_free().
* Since: 2.62
*/
gchar *
g_date_time_format_iso8601 (GDateTime *datetime)
{
GString *outstr = NULL;
gchar *main_date = NULL;
gint64 offset;

/* Main date and time. */
main_date = g_date_time_format (datetime, "%Y-%m-%dT%H:%M:%S");
outstr = g_string_new (main_date);
g_free (main_date);

/* Timezone. Format it as `%:::z` unless the offset is zero, in which case
* we can simply use `Z`. */
offset = g_date_time_get_utc_offset (datetime);

if (offset == 0)
{
g_string_append_c (outstr, 'Z');
}
else
{
gchar *time_zone = g_date_time_format (datetime, "%:::z");
g_string_append (outstr, time_zone);
g_free (time_zone);
}

return g_string_free (outstr, FALSE);
}


/* Epilogue {{{1 */
/* vim:set foldmethod=marker: */
2 changes: 2 additions & 0 deletions glib/gdatetime.h
Expand Up @@ -262,6 +262,8 @@ GDateTime * g_date_time_to_utc (GDateTi
GLIB_AVAILABLE_IN_ALL
gchar * g_date_time_format (GDateTime *datetime,
const gchar *format) G_GNUC_MALLOC;
GLIB_AVAILABLE_IN_2_62
gchar * g_date_time_format_iso8601 (GDateTime *datetime) G_GNUC_MALLOC;

G_END_DECLS

Expand Down
25 changes: 25 additions & 0 deletions glib/tests/gdatetime.c
Expand Up @@ -2066,6 +2066,30 @@ test_z (void)
g_time_zone_unref (tz);
}

static void
test_format_iso8601 (void)
{
GTimeZone *tz = NULL;
GDateTime *dt = NULL;
gchar *p = NULL;

tz = g_time_zone_new_utc ();
dt = g_date_time_new (tz, 2019, 6, 26, 15, 1, 5);
p = g_date_time_format_iso8601 (dt);
g_assert_cmpstr (p, ==, "2019-06-26T15:01:05Z");
g_free (p);
g_date_time_unref (dt);
g_time_zone_unref (tz);

tz = g_time_zone_new_offset (-60 * 60);
dt = g_date_time_new (tz, 2019, 6, 26, 15, 1, 5);
p = g_date_time_format_iso8601 (dt);
g_assert_cmpstr (p, ==, "2019-06-26T15:01:05-01");
g_free (p);
g_date_time_unref (dt);
g_time_zone_unref (tz);
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-y2k"
static void
Expand Down Expand Up @@ -2556,6 +2580,7 @@ main (gint argc,
g_test_add_func ("/GDateTime/printf", test_GDateTime_printf);
g_test_add_func ("/GDateTime/non_utf8_printf", test_non_utf8_printf);
g_test_add_func ("/GDateTime/format_unrepresentable", test_format_unrepresentable);
g_test_add_func ("/GDateTime/format_iso8601", test_format_iso8601);
g_test_add_func ("/GDateTime/strftime", test_strftime);
g_test_add_func ("/GDateTime/strftime/error_handling", test_GDateTime_strftime_error_handling);
g_test_add_func ("/GDateTime/modifiers", test_modifiers);
Expand Down

0 comments on commit dbabd2b

Please sign in to comment.