[glib: 1/26] gdatetime: Add g_date_time_format_iso8601() convenience function



commit dbabd2b8a745bfed4890f2d6cbd7d7848bc4f034
Author: Philip Withnall <withnall endlessm com>
Date:   Fri Jul 26 13:39:07 2019 +0100

    gdatetime: Add g_date_time_format_iso8601() convenience function
    
    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

 docs/reference/glib/glib-sections.txt |  1 +
 glib/gdatetime.c                      | 43 +++++++++++++++++++++++++++++++++++
 glib/gdatetime.h                      |  2 ++
 glib/tests/gdatetime.c                | 25 ++++++++++++++++++++
 4 files changed, 71 insertions(+)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index f70d86977..a5e64a1c1 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -1983,6 +1983,7 @@ g_date_time_to_utc
 
 <SUBSECTION>
 g_date_time_format
+g_date_time_format_iso8601
 </SECTION>
 
 <SECTION>
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index c286954c4..5b09c1854 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -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: */
diff --git a/glib/gdatetime.h b/glib/gdatetime.h
index 65f9965ac..af42c7fc6 100644
--- a/glib/gdatetime.h
+++ b/glib/gdatetime.h
@@ -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
 
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index 32dd69283..3ab1d6a0f 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -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
@@ -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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]