Merge branch 'datetime-usec' into 'main'

GDateTime: Add usec precision API for unix time

See merge request GNOME/glib!3770
This commit is contained in:
Philip Withnall 2023-12-20 15:50:56 +00:00
commit 43c83142a9
3 changed files with 121 additions and 8 deletions

View File

@ -1033,15 +1033,41 @@ g_date_time_new_now_utc (void)
GDateTime *
g_date_time_new_from_unix_local (gint64 t)
{
GDateTime *datetime;
GTimeZone *local;
if (t > G_MAXINT64 / USEC_PER_SECOND ||
t < G_MININT64 / USEC_PER_SECOND)
return NULL;
return g_date_time_new_from_unix_local_usec (t * USEC_PER_SECOND);
}
/**
* g_date_time_new_from_unix_local_usec: (constructor)
* @usecs: the Unix time in microseconds
*
* Creates a [struct@GLib.DateTime] corresponding to the given Unix time @t in the
* local time zone.
*
* Unix time is the number of microseconds that have elapsed since 1970-01-01
* 00:00:00 UTC, regardless of the local time offset.
*
* This call can fail (returning `NULL`) if @t represents a time outside
* of the supported range of #GDateTime.
*
* You should release the return value by calling [method@GLib.DateTime.unref]
* when you are done with it.
*
* Returns: (transfer full) (nullable): a new [struct@GLib.DateTime], or `NULL`
*
* Since: 2.80
**/
GDateTime *
g_date_time_new_from_unix_local_usec (gint64 usecs)
{
GDateTime *datetime;
GTimeZone *local;
local = g_time_zone_new_local ();
datetime = g_date_time_new_from_unix (local, t * USEC_PER_SECOND);
datetime = g_date_time_new_from_unix (local, usecs);
g_time_zone_unref (local);
return datetime;
@ -1069,15 +1095,40 @@ g_date_time_new_from_unix_local (gint64 t)
GDateTime *
g_date_time_new_from_unix_utc (gint64 t)
{
GDateTime *datetime;
GTimeZone *utc;
if (t > G_MAXINT64 / USEC_PER_SECOND ||
t < G_MININT64 / USEC_PER_SECOND)
return NULL;
return g_date_time_new_from_unix_utc_usec (t * USEC_PER_SECOND);
}
/**
* g_date_time_new_from_unix_utc: (constructor)
* @usecs: the Unix time in microseconds
*
* Creates a [struct@GLib.DateTime] corresponding to the given Unix time @t in UTC.
*
* Unix time is the number of microseconds that have elapsed since 1970-01-01
* 00:00:00 UTC.
*
* This call can fail (returning `NULL`) if @t represents a time outside
* of the supported range of #GDateTime.
*
* You should release the return value by calling [method@GLib.DateTime.unref]
* when you are done with it.
*
* Returns: (transfer full) (nullable): a new [struct@GLib.DateTime], or `NULL`
*
* Since: 2.80
**/
GDateTime *
g_date_time_new_from_unix_utc_usec (gint64 usecs)
{
GDateTime *datetime;
GTimeZone *utc;
utc = g_time_zone_new_utc ();
datetime = g_date_time_new_from_unix (utc, t * USEC_PER_SECOND);
datetime = g_date_time_new_from_unix (utc, usecs);
g_time_zone_unref (utc);
return datetime;
@ -2566,6 +2617,27 @@ g_date_time_to_unix (GDateTime *datetime)
return INSTANT_TO_UNIX (g_date_time_to_instant (datetime));
}
/**
* g_date_time_to_unix_usec:
* @datetime: a #GDateTime
*
* Gives the Unix time corresponding to @datetime, in microseconds.
*
* Unix time is the number of microseconds that have elapsed since 1970-01-01
* 00:00:00 UTC, regardless of the time zone associated with @datetime.
*
* Returns: the Unix time corresponding to @datetime
*
* Since: 2.80
**/
gint64
g_date_time_to_unix_usec (GDateTime *datetime)
{
g_return_val_if_fail (datetime != NULL, 0);
return INSTANT_TO_UNIX_USECS (g_date_time_to_instant (datetime));
}
/**
* g_date_time_to_timeval:
* @datetime: a #GDateTime

View File

@ -138,6 +138,11 @@ GDateTime * g_date_time_new_from_unix_local (gint64
GLIB_AVAILABLE_IN_ALL
GDateTime * g_date_time_new_from_unix_utc (gint64 t);
GLIB_AVAILABLE_IN_2_80
GDateTime * g_date_time_new_from_unix_local_usec (gint64 usecs);
GLIB_AVAILABLE_IN_2_80
GDateTime * g_date_time_new_from_unix_utc_usec (gint64 usecs);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
GLIB_DEPRECATED_IN_2_62_FOR(g_date_time_new_from_unix_local)
GDateTime * g_date_time_new_from_timeval_local (const GTimeVal *tv);
@ -265,6 +270,9 @@ gdouble g_date_time_get_seconds (GDateTi
GLIB_AVAILABLE_IN_ALL
gint64 g_date_time_to_unix (GDateTime *datetime);
GLIB_AVAILABLE_IN_2_80
gint64 g_date_time_to_unix_usec (GDateTime *datetime);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
GLIB_DEPRECATED_IN_2_62_FOR(g_date_time_to_unix)
gboolean g_date_time_to_timeval (GDateTime *datetime,

View File

@ -3392,6 +3392,38 @@ test_time_zone_caching (void)
g_assert_true (tz1 == tz2);
}
static void
test_date_time_unix_usec (void)
{
gint64 usecs = g_get_real_time ();
gint64 secs = usecs / G_USEC_PER_SEC;
GDateTime *dt;
GDateTime *local;
dt = g_date_time_new_from_unix_utc (secs);
g_assert_cmpint (g_date_time_to_unix_usec (dt), ==, secs * G_USEC_PER_SEC);
g_assert_cmpint (g_date_time_to_unix (dt), ==, secs);
g_date_time_unref (dt);
dt = g_date_time_new_from_unix_utc_usec (usecs);
g_assert_cmpint (g_date_time_to_unix_usec (dt), ==, usecs);
g_assert_cmpint (g_date_time_to_unix (dt), ==, secs);
g_date_time_unref (dt);
local = g_date_time_new_from_unix_local (secs);
dt = g_date_time_to_utc (local);
g_assert_cmpint (g_date_time_to_unix_usec (dt), ==, secs * G_USEC_PER_SEC);
g_assert_cmpint (g_date_time_to_unix (dt), ==, secs);
g_date_time_unref (dt);
g_date_time_unref (local);
local = g_date_time_new_from_unix_local_usec (usecs);
dt = g_date_time_to_utc (local);
g_assert_cmpint (g_date_time_to_unix_usec (dt), ==, usecs);
g_assert_cmpint (g_date_time_to_unix (dt), ==, secs);
g_date_time_unref (dt);
g_date_time_unref (local);
}
gint
main (gint argc,
@ -3476,6 +3508,7 @@ main (gint argc,
g_test_add_func ("/GDateTime/eras/japan", test_date_time_eras_japan);
g_test_add_func ("/GDateTime/eras/thailand", test_date_time_eras_thailand);
g_test_add_func ("/GDateTime/eras/parsing", test_date_time_eras_parsing);
g_test_add_func ("/GDateTime/unix_usec", test_date_time_unix_usec);
g_test_add_func ("/GTimeZone/find-interval", test_find_interval);
g_test_add_func ("/GTimeZone/adjust-time", test_adjust_time);