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
This commit is contained in:
Philip Withnall 2018-04-11 17:03:31 +01:00
parent a80117c371
commit cf24867b93
4 changed files with 74 additions and 0 deletions

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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 ();
}