GNOME Bugzilla – Bug 410663
g_timegm implementation
Last modified: 2014-01-20 05:15:35 UTC
I would like a portable function that does equivalent to "timegm", translate from a "struct tm" in UTC (aka GMT) to a unixtime. I will attach a patch for the function. Many implementations on the web are surprisingly inefficient and complicated, or hacky, but there's a very simple correspondence between UTC and unixtime which can make this function simple and self-contained.
Created attachment 83087 [details] implementation of gtimegm This is a simple portable implementation of timegm(). Most other implementations use hackery or binary-searching-- this uses a simple correspondence between UTC and unixtime.
This patch looks nice and I could actually make use of this feature in at least two projects. I'm going to write test cases for this function.
Is gulong the right return type? I think we should maybe return time_t or guint64. And do we care about dates before 1970? This appears to botch those. (I wrote this patch -- i use it in my gsk library (under that prefix, of course) -- but honestly don't remember writing this bug report, so I just was checking it over) obviously the g_assert() should be g_warn_if_fail ()s.
A returh type of guint64 is definitely what should be used IMHO. No need to intentionally continue the Y2038 problems in new APIs.
(In reply to comment #4) > A returh type of guint64 is definitely what should be used IMHO. No need to > intentionally continue the Y2038 problems in new APIs. (In reply to comment #3) > Is gulong the right return type? I think we should maybe return time_t or > guint64. And do we care about dates before 1970? This appears to botch those. IMHO we should return time_t. We already have in in our API (eg. g_date_set_time_t()) and it is signed (I'd agree to gint64 as well). > obviously the g_assert() should be g_warn_if_fail ()s. Yeah, and the compile warnings should be fixed ("t" vs. "tm").
Yeah but there are platforms where time_t is 32 bits. (The most used presumably being 32-bit Windows using the system C library msvcrt.dll, which is what the "official" 32-bit Windows GTK+ stack binaries use.) (In the newer cokpiler-specific MS C libraries, time_t is 64 bits.) gint64 would be better IMHO. (Sure, then there is a problem if people want to pass a 64-bit return value from this new function on to C library or GLib functions that take a (32-bit) time_t. Perhaps we should deprectate the GLib API that uses time_t and create parallels that use gint64...) Of course, one can just ignore this and hope that by Y2038 such platforms, and GTK+ stack using apps for them, will be as rare as the dodo.
(In reply to comment #6) > Yeah but there are platforms where time_t is 32 bits. (The most used presumably > being 32-bit Windows using the system C library msvcrt.dll, which is what the > "official" 32-bit Windows GTK+ stack binaries use.) (In the newer > cokpiler-specific MS C libraries, time_t is 64 bits.) Thanks for the information, Tor. > gint64 would be better IMHO. (Sure, then there is a problem if people want to > pass a 64-bit return value from this new function on to C library or GLib > functions that take a (32-bit) time_t. Perhaps we should deprectate the GLib > API that uses time_t and create parallels that use gint64...) I totally agree here and added that information to bug 101538. > Of course, one can just ignore this and hope that by Y2038 such platforms, and > GTK+ stack using apps for them, will be as rare as the dodo. Deprecating and removing before 2038 sounds good as well. I'm pretty confident we'll see glib-3.0 until before 2038 ;-)
Created attachment 146428 [details] [review] Proposed patch v1 Here's a patch that applies against master. Please review for flaws.
Notes: * this function is pretty close to working for dates before 1970, just a few variables must change type (to signed). * i think the g_return_if_fail()s should be g_warn_if_fail(). In most cases (the month check is an exception) the error conditions are pretty minor, and likely even work as the user might have expected.
This has been superseded by GDateTime