[glib] gtimezone: Add g_time_zone_new_offset() convenience constructor



commit cf24867b931501d387402f050f9c85516c97d7a0
Author: Philip Withnall <withnall endlessm com>
Date:   Wed Apr 11 17:03:31 2018 +0100

    gtimezone: Add g_time_zone_new_offset() convenience constructor
    
    This includes tests.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=676923

 docs/reference/glib/glib-sections.txt |  1 +
 glib/gtimezone.c                      | 36 +++++++++++++++++++++++++++++++++++
 glib/gtimezone.h                      |  2 ++
 glib/tests/gdatetime.c                | 35 ++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index c02b22a67..f6322f052 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -1648,6 +1648,7 @@ g_time_zone_ref
 g_time_zone_new
 g_time_zone_new_local
 g_time_zone_new_utc
+g_time_zone_new_offset
 <SUBSECTION>
 GTimeType
 g_time_zone_find_interval
diff --git a/glib/gtimezone.c b/glib/gtimezone.c
index 311fe0289..b08119b13 100644
--- a/glib/gtimezone.c
+++ b/glib/gtimezone.c
@@ -1562,6 +1562,42 @@ g_time_zone_new_local (void)
   return g_time_zone_new (getenv ("TZ"));
 }
 
+/**
+ * g_time_zone_new_offset:
+ * @seconds: offset to UTC, in seconds
+ *
+ * Creates a #GTimeZone corresponding to the given constant offset from UTC,
+ * in seconds.
+ *
+ * This is equivalent to calling g_time_zone_new() with a string in the form
+ * `[+|-]hh[:mm[:ss]]`.
+ *
+ * Returns: (transfer full): a timezone at the given offset from UTC
+ * Since: 2.58
+ */
+GTimeZone *
+g_time_zone_new_offset (gint32 seconds)
+{
+  GTimeZone *tz = NULL;
+  gchar *identifier = NULL;
+
+  /* Seemingly, we should be using @seconds directly to set the
+   * #TransitionInfo.gmt_offset to avoid all this string building and parsing.
+   * However, we always need to set the #GTimeZone.name to a constructed
+   * string anyway, so we might as well reuse its code. */
+  identifier = g_strdup_printf ("%c%02u:%02u:%02u",
+                                (seconds >= 0) ? '+' : '-',
+                                (ABS (seconds) / 60) / 60,
+                                (ABS (seconds) / 60) % 60,
+                                ABS (seconds) % 60);
+  tz = g_time_zone_new (identifier);
+  g_free (identifier);
+
+  g_assert (g_time_zone_get_offset (tz, 0) == seconds);
+
+  return tz;
+}
+
 #define TRANSITION(n)         g_array_index (tz->transitions, Transition, n)
 #define TRANSITION_INFO(n)    g_array_index (tz->t_info, TransitionInfo, n)
 
diff --git a/glib/gtimezone.h b/glib/gtimezone.h
index dd10390ab..4e8b10a71 100644
--- a/glib/gtimezone.h
+++ b/glib/gtimezone.h
@@ -58,6 +58,8 @@ GLIB_AVAILABLE_IN_ALL
 GTimeZone *             g_time_zone_new_utc                             (void);
 GLIB_AVAILABLE_IN_ALL
 GTimeZone *             g_time_zone_new_local                           (void);
+GLIB_AVAILABLE_IN_2_58
+GTimeZone *             g_time_zone_new_offset                          (gint32       seconds);
 
 GLIB_AVAILABLE_IN_ALL
 GTimeZone *             g_time_zone_ref                                 (GTimeZone   *tz);
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index 1bd8203ad..b102205b9 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -2362,6 +2362,40 @@ test_identifier (void)
   g_free (old_tz);
 }
 
+/* Test various calls to g_time_zone_new_offset(). */
+static void
+test_new_offset (void)
+{
+  const gint32 vectors[] =
+    {
+      -10000,
+      -3600,
+      -61,
+      -60,
+      -59,
+      0,
+      59,
+      60,
+      61,
+      3600,
+      10000,
+    };
+  gsize i;
+
+  for (i = 0; i < G_N_ELEMENTS (vectors); i++)
+    {
+      GTimeZone *tz = NULL;
+
+      g_test_message ("Vector %" G_GSIZE_FORMAT ": %d", i, vectors[i]);
+
+      tz = g_time_zone_new_offset (vectors[i]);
+      g_assert_nonnull (tz);
+      g_assert_cmpstr (g_time_zone_get_identifier (tz), !=, "UTC");
+      g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, vectors[i]);
+      g_time_zone_unref (tz);
+    }
+}
+
 gint
 main (gint   argc,
       gchar *argv[])
@@ -2424,6 +2458,7 @@ main (gint   argc,
   g_test_add_func ("/GTimeZone/posix-parse", test_posix_parse);
   g_test_add_func ("/GTimeZone/floating-point", test_GDateTime_floating_point);
   g_test_add_func ("/GTimeZone/identifier", test_identifier);
+  g_test_add_func ("/GTimeZone/new-offset", test_new_offset);
 
   return g_test_run ();
 }


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