[libgda] GdaTime: ported to GDateTime; default to UTC
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] GdaTime: ported to GDateTime; default to UTC
- Date: Wed, 13 Feb 2019 17:50:45 +0000 (UTC)
commit 3d9de62c4afd637ae6750e113dd972fddc0f86fa
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date: Wed Feb 13 10:52:03 2019 -0600
GdaTime: ported to GDateTime; default to UTC
GdaTime now internally holds a GDateTime, set
to epoch date 1970-1-1. When saving data to
data base it defaults to UTC time, because that
is the default on SQLite and may other applications.
Added new API to GdaTime, so for UI is possible
to show time always in local time, UTC or with time
zone. Is possible to manipulate time using GTimeZone.
NEWS | 3 +-
libgda/gda-util.c | 33 +--
libgda/gda-value.c | 531 +++++++++++++++++++------------------
libgda/gda-value.h | 8 +
libgda/handlers/gda-handler-time.c | 68 +----
tests/test-sql-renderer.c | 8 +-
6 files changed, 304 insertions(+), 347 deletions(-)
---
diff --git a/NEWS b/NEWS
index 51a0bfeb5..f01e55de1 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ libgda 5.91.0
- GdaHandler now supports value transformation, if possible, before set it
- Ported almost all public API to use g_autoptr() and remove public private struct
- GdaHolder now is GdaAttributeManager free, replaced by GObect properties
+ - GdaTime ported to GDateTime, with improved time handling and defaulting to UTC time
- Fixed segfaults
- Fixed meta data generation engine
- Fixed PostgresSQL provider meta data generation integration
@@ -1907,4 +1908,4 @@ libgda 0.8.100, 2002-01-06
- extended test suite with new connection tests (Gonzalo)
- fixed #67242 orbit-idl not generating files when IDL changes (Gonzalo)
- fixed lost-counter in data retrieval (Gonzalo)
-
+
\ No newline at end of file
diff --git a/libgda/gda-util.c b/libgda/gda-util.c
index 794c0a518..7b9f40fc1 100644
--- a/libgda/gda-util.c
+++ b/libgda/gda-util.c
@@ -3204,16 +3204,10 @@ _parse_iso8601_time (GdaTime *timegda, const gchar *value, gchar sep, glong time
gchar *stz = NULL;
gchar *fs = NULL;
gdouble seconds = 0.0;
- glong fraction = 0.0;
- /* https://en.wikipedia.org/wiki/ISO_8601 */
- /* Any invalid Time Zone designator set time zone to local*/
- GTimeZone *tz = g_time_zone_new_local ();
- gda_time_set_timezone (timegda, g_time_zone_get_offset (tz, 0));
+ glong fraction = 0;
+ int h, m, s;
+ GTimeZone *tz;
- gda_time_set_hour (timegda, 0);
- gda_time_set_minute (timegda, 0);
- gda_time_set_second (timegda, 0);
- gda_time_set_fraction (timegda, 0);
if ((*value < '0') || (*value > '9'))
return FALSE;
@@ -3225,7 +3219,7 @@ _parse_iso8601_time (GdaTime *timegda, const gchar *value, gchar sep, glong time
if (tmp > 23)
return FALSE;
}
- gda_time_set_hour (timegda, tmp);
+ h = tmp;
if ((sep && *endptr != sep) || !*endptr)
return FALSE;
@@ -3237,7 +3231,7 @@ _parse_iso8601_time (GdaTime *timegda, const gchar *value, gchar sep, glong time
if (tmp > 59)
return FALSE;
}
- gda_time_set_minute (timegda, tmp);
+ m = tmp;
if ((sep && *endptr != sep) || !*endptr)
return FALSE;
@@ -3251,22 +3245,21 @@ _parse_iso8601_time (GdaTime *timegda, const gchar *value, gchar sep, glong time
*out_endptr = stz;
return FALSE;
}
- gda_time_set_second (timegda, (gint) seconds);
- /* Strip fraction */
- fraction = (glong) ((seconds - (gint) seconds) * 1000000);
- g_free (fs);
- gda_time_set_fraction (timegda, fraction);
+ tz = g_time_zone_new_local ();
if (stz != NULL) {
g_time_zone_unref (tz);
tz = g_time_zone_new (stz);
- if (tz != NULL) {
- gda_time_set_timezone (timegda, g_time_zone_get_offset (tz, 0));
+ if (tz == NULL) {
+ tz = g_time_zone_new_local ();
}
for (; *endptr; endptr++);
}
+ GDateTime *dt = g_date_time_new (tz, 1978, 1, 1, h, m, seconds);
+
+ gda_time_set_from_date_time (timegda, dt);
+
+ g_time_zone_unref (tz);
- if (tz != NULL)
- g_time_zone_unref (tz);
*out_endptr = endptr;
return TRUE;
}
diff --git a/libgda/gda-value.c b/libgda/gda-value.c
index de82baa78..b252ebe43 100644
--- a/libgda/gda-value.c
+++ b/libgda/gda-value.c
@@ -1445,126 +1445,24 @@ gda_numeric_get_string (const GdaNumeric *numeric)
static void
time_to_string (const GValue *src, GValue *dest)
{
- GdaTime *gdatime;
-
- g_return_if_fail (G_VALUE_HOLDS_STRING (dest) &&
- GDA_VALUE_HOLDS_TIME (src));
-
- gdatime = (GdaTime *) gda_value_get_time ((GValue *) src);
-
- if (gdatime) {
- GString *string;
- string = g_string_new ("");
- g_string_append_printf (string, "%02u:%02u:%02u",
- gda_time_get_hour (gdatime),
- gda_time_get_minute (gdatime),
- gda_time_get_second (gdatime));
- if (gda_time_get_fraction (gdatime) != 0)
- g_string_append_printf (string, ".%lu", gda_time_get_fraction (gdatime));
-
- if (gda_time_get_timezone (gdatime) != GDA_TIMEZONE_INVALID)
- g_string_append_printf (string, "%+02d", (int) gda_time_get_timezone (gdatime) /
3600);
-
- g_value_take_string (dest, string->str);
- g_string_free (string, FALSE);
+ gchar *str = gda_value_stringify (src);
+ if (g_strcmp0 ("", str) == 0) {
+ g_value_set_string (dest, "00:00:00+0");
+ } else {
+ g_value_set_string (dest, str);
}
- else
- g_value_set_string (dest, "00:00:00");
+ g_free (str);
}
/* Transform a String GValue to a GdaTime from a string like "12:30:15+01" */
static void
string_to_time (const GValue *src, GValue *dest)
{
- /* FIXME: add more checks*/
- GdaTime *timegda;
- const gchar *as_string;
- const gchar *ptr;
-
- g_return_if_fail (G_VALUE_HOLDS_STRING (src) &&
- GDA_VALUE_HOLDS_TIME (dest));
-
- as_string = g_value_get_string (src);
- if (!as_string)
- return;
- timegda = gda_time_new ();
-
- /* hour */
- gda_time_set_timezone (timegda, GDA_TIMEZONE_INVALID);
- ptr = as_string;
- if ((*ptr >= '0') && (*ptr <= '9') &&
- (*(ptr+1) >= '0') && (*(ptr+1) <= '9'))
- gda_time_set_hour (timegda, (*ptr - '0') * 10 + *(ptr+1) - '0');
- else {
- gda_time_free (timegda);
- return;
- }
-
- /* minute */
- ptr += 2;
- if (! *ptr) {
- gda_time_free (timegda);
- return;
- }
- if (*ptr == ':')
- ptr++;
- if ((*ptr >= '0') && (*ptr <= '9') &&
- (*(ptr+1) >= '0') && (*(ptr+1) <= '9'))
- gda_time_set_minute (timegda, (*ptr - '0') * 10 + *(ptr+1) - '0');
- else{
- gda_time_free (timegda);
- return;
- }
-
- /* second */
- ptr += 2;
- gda_time_set_second (timegda, 0);
- if (! *ptr) {
- if ((gda_time_get_hour (timegda) <= 24) && (gda_time_get_minute (timegda) <= 60))
- gda_value_set_time (dest, timegda);
- gda_time_free (timegda);
- return;
- }
- if (*ptr == ':')
- ptr++;
- if ((*ptr >= '0') && (*ptr <= '9') &&
- (*(ptr+1) >= '0') && (*(ptr+1) <= '9'))
- gda_time_set_second (timegda, (*ptr - '0') * 10 + *(ptr+1) - '0');
-
- /* extra */
- ptr += 2;
- if (! *ptr) {
- if ((gda_time_get_hour (timegda) <= 24) && (gda_time_get_minute (timegda) <= 60) &&
- (gda_time_get_second (timegda) <= 60))
- gda_value_set_time (dest, timegda);
- gda_time_free (timegda);
- return;
- }
-
- if (*ptr == '.') {
- gulong fraction = 0;
-
- ptr ++;
- while (*ptr && (*ptr >= '0') && (*ptr <= '9')) {
- fraction = fraction * 10 + *ptr - '0';
- ptr++;
- }
- }
-
- if ((*ptr == '+') || (*ptr == '-')) {
- glong sign = (*ptr == '+') ? 1 : -1;
- gda_time_set_timezone (timegda, 0);
- while (*ptr && (*ptr >= '0') && (*ptr <= '9')) {
- gda_time_set_timezone (timegda, gda_time_get_timezone (timegda) * 10 + sign * ((*ptr)
- '0'));
- ptr++;
- }
- gda_time_set_timezone (timegda, gda_time_get_timezone (timegda) * 3600);
- }
-
- /* checks */
- if ((gda_time_get_hour (timegda) <= 24) || (gda_time_get_minute (timegda) <= 60) ||
(gda_time_get_second (timegda) <= 60))
- gda_value_set_time (dest, timegda);
- gda_time_free (timegda);
+ const gchar *str = g_value_get_string (src);
+ GdaTime *time = gda_time_new ();
+ gda_parse_iso8601_time (time, str);
+ g_value_set_boxed (dest, time);
+ gda_time_free (time);
}
/**
@@ -1576,11 +1474,7 @@ string_to_time (const GValue *src, GValue *dest)
* @timezone: number of seconds added to the GMT timezone
*/
struct _GdaTime {
- gushort hour;
- gushort minute;
- gushort second;
- gulong fraction;
- GTimeSpan timezone;
+ GDateTime *dt;
};
GType
@@ -1609,19 +1503,9 @@ GdaTime*
gda_time_copy (const GdaTime* time)
{
- GdaTime *src = (GdaTime*) time;
- GdaTime *copy = NULL;
-
- g_return_val_if_fail (src, NULL);
-
- copy = g_new0 (GdaTime, 1);
- copy->hour = src->hour;
- copy->minute = src->minute;
- copy->second = src->second;
- copy->fraction = src->fraction;
- copy->timezone = src->timezone;
-
- return copy;
+ GdaTime *c = g_new0(GdaTime, 1);
+ c->dt = g_date_time_add_days (time->dt, 0);
+ return c;
}
/**
@@ -1633,6 +1517,7 @@ gda_time_copy (const GdaTime* time)
void
gda_time_free (GdaTime* boxed)
{
+ g_date_time_unref (boxed->dt);
g_free (boxed);
}
@@ -1659,14 +1544,80 @@ gda_value_take_time (GValue *value, GdaTime *time)
/**
* gda_time_new:
*
- * Creates a new #GdaTime structure.
+ * Creates a new #GdaTime with time now local.
*
* Returns: (transfer full): a new #GdaTime structure
*/
GdaTime*
gda_time_new (void)
{
- return g_new0 (GdaTime, 1);
+ GdaTime *t = g_new0 (GdaTime, 1);
+ t->dt = g_date_time_new_now_local ();
+ return t;
+}
+
+
+/**
+ * gda_time_to_string:
+ *
+ * Creates a string representation of a #GdaTime in local time
+ * with the timezone designation.
+ *
+ * Returns: (transfer full): a new string
+ * Since: 6.0
+ */
+gchar*
+gda_time_to_string (GdaTime *time)
+{
+ gchar *str;
+ GTimeZone *tz = g_time_zone_new_local ();
+ GDateTime *ndt = g_date_time_to_timezone (time->dt, tz);
+ str = g_date_time_format (ndt, "%H:%M:%S%:::z");
+ g_time_zone_unref (tz);
+ g_date_time_unref (ndt);
+ return str;
+}
+
+/**
+ * gda_time_to_string_local:
+ *
+ * Creates a string representation of a #GdaTime in local time
+ * without timezone designation.
+ *
+ * Returns: (transfer full): a new string
+ * Since: 6.0
+ */
+gchar*
+gda_time_to_string_local (GdaTime *time)
+{
+ gchar *str;
+ GTimeZone *tz = g_time_zone_new_local ();
+ GDateTime *ndt = g_date_time_to_timezone (time->dt, tz);
+ str = g_date_time_format (ndt, "%H:%M:%S");
+ g_time_zone_unref (tz);
+ g_date_time_unref (ndt);
+ return str;
+}
+
+/**
+ * gda_time_to_string_utc:
+ *
+ * Creates a string representation of a #GdaTime in UTC time
+ * with time zone indication.
+ *
+ * Returns: (transfer full): a new string
+ * Since: 6.0
+ */
+gchar*
+gda_time_to_string_utc (GdaTime *time)
+{
+ gchar *str;
+ GTimeZone *tz = g_time_zone_new_utc ();
+ GDateTime *ndt = g_date_time_to_timezone (time->dt, tz);
+ str = g_date_time_format (ndt, "%H:%M:%S%:::z");
+ g_time_zone_unref (tz);
+ g_date_time_unref (ndt);
+ return str;
}
/**
@@ -1675,7 +1626,7 @@ gda_time_new (void)
* @minute: minutes
* @second: seconds
* @fraction: fraction of seconds
- * @timezone: timezone used
+ * @timezone: timezone in seconds added to UTC
*
* Returns: (transfer full): the a new value storing a time
*/
@@ -1683,13 +1634,82 @@ GdaTime*
gda_time_new_from_values (gushort hour, gushort minute, gushort second, gulong fraction, glong timezone)
{
GdaTime* time = g_new0 (GdaTime, 1);
- time->hour = hour;
- time->minute = minute;
- time->second = second;
- time->fraction = fraction;
- time->timezone = timezone;
+ gda_time_set_from_values (time, hour, minute, second, fraction, timezone);
return time;
}
+
+/**
+ * gda_time_set_from_values:
+ * @time: a #GdaTime object to set values to
+ * @hour: hours
+ * @minute: minutes
+ * @second: seconds
+ * @fraction: fraction of seconds
+ * @timezone: timezone in seconds added to UTC
+ *
+ * Returns: (transfer full): the a new value storing a time
+ * Since: 6.0
+ */
+void
+gda_time_set_from_values (GdaTime *time, gushort hour, gushort minute, gushort second, gulong fraction,
glong timezone)
+{
+ gdouble seconds = 0.0;
+ gchar *sec = g_strdup_printf ("%d.%lu", second, fraction);
+ seconds = g_ascii_strtod (sec, NULL);
+ g_free (sec);
+ gint h = timezone / 3600;
+ gint m = (timezone - h * 3600) / 60;
+ gint s = (timezone - h * 3600 - m * 60);
+ gint sig = h;
+ if (m < 0) {
+ m = -1 * m;
+ }
+ if (s < 0) {
+ s = -1 * s;
+ }
+ if (h < 0) {
+ h = -1 * h;
+ }
+ gchar *stz = g_strdup_printf ("%s%02d:%02d:%02d", sig < 0 ? "-" : "+", h, m, s);
+ GTimeZone *tz = g_time_zone_new (stz);
+ g_free (stz);
+
+ time->dt = g_date_time_new (tz,
+ 1970,
+ 1,
+ 1,
+ (gint) hour,
+ (gint) minute,
+ seconds);
+}
+
+/**
+ * gda_time_new_from_date_time:
+ * @dt: a #GDateTime to get time from
+ *
+ * Returns: (transfer full): the a new value storing a time
+ * Since: 6.0
+ */
+GdaTime*
+gda_time_new_from_date_time (GDateTime *dt)
+{
+ GdaTime* time = g_new0 (GdaTime, 1);
+ time->dt = g_date_time_add_days (dt, 0);
+ return time;
+}
+
+/**
+ * gda_time_set_from_date_time:
+ * @dt: a #GDateTime to get time from
+ *
+ * Returns: (transfer full): the a new value storing a time
+ * Since: 6.0
+ */
+void
+gda_time_set_from_date_time (GdaTime *time, GDateTime *dt)
+{
+ time->dt = g_date_time_add_days (dt, 0);
+}
/**
* gda_time_get_hour:
* @time: a #GdaTime value to get hours from
@@ -1700,7 +1720,7 @@ gushort
gda_time_get_hour (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
- return time->hour;
+ return (gushort) g_date_time_get_hour (time->dt);
}
/**
* gda_time_set_hour:
@@ -1713,7 +1733,11 @@ void
gda_time_set_hour (GdaTime* time, gushort hour)
{
g_return_if_fail (time != NULL);
- time->hour = hour;
+ gda_time_new_from_values (hour,
+ gda_time_get_minute (time),
+ gda_time_get_second (time),
+ gda_time_get_fraction (time),
+ gda_time_get_timezone (time));
}
/**
* gda_time_get_minute:
@@ -1725,7 +1749,7 @@ gushort
gda_time_get_minute (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
- return time->minute;
+ return (gushort) g_date_time_get_minute (time->dt);
}
/**
* gda_time_set_minute:
@@ -1738,7 +1762,11 @@ void
gda_time_set_minute (GdaTime* time, gushort minute)
{
g_return_if_fail (time != NULL);
- time->minute = minute;
+ gda_time_new_from_values (gda_time_get_hour (time),
+ minute,
+ gda_time_get_second (time),
+ gda_time_get_fraction (time),
+ gda_time_get_timezone (time));
}
/**
* gda_time_get_second:
@@ -1750,7 +1778,7 @@ gushort
gda_time_get_second (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
- return time->second;
+ return (gushort) g_date_time_get_second (time->dt);
}
/**
* gda_time_set_second:
@@ -1763,7 +1791,11 @@ void
gda_time_set_second (GdaTime* time, gushort second)
{
g_return_if_fail (time != NULL);
- time->second = second;
+ gda_time_new_from_values (gda_time_get_hour (time),
+ gda_time_get_minute (time),
+ second,
+ gda_time_get_fraction (time),
+ gda_time_get_timezone (time));
}
/**
* gda_time_get_fraction:
@@ -1775,7 +1807,14 @@ gulong
gda_time_get_fraction (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
- return time->fraction;
+ gdouble v = g_date_time_get_seconds (time->dt) - g_date_time_get_second (time->dt);
+ gchar *str = g_strdup_printf ("%0.6f", v);
+ for (int i = 0; i < 2; i++) {
+ str[i] = ' ';
+ }
+ gulong f = (gulong) g_ascii_strtoll ((const gchar*) str, NULL, 10);
+ g_free (str);
+ return f;
}
/**
* gda_time_set_fraction:
@@ -1788,7 +1827,11 @@ void
gda_time_set_fraction (GdaTime* time, gulong fraction)
{
g_return_if_fail (time != NULL);
- time->fraction = fraction;
+ gda_time_new_from_values (gda_time_get_hour (time),
+ gda_time_get_minute (time),
+ gda_time_get_second (time),
+ fraction,
+ gda_time_get_timezone (time));
}
/**
* gda_time_get_timezone:
@@ -1802,8 +1845,26 @@ glong
gda_time_get_timezone (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
- return time->timezone;
+ glong tz = (glong) (g_date_time_get_utc_offset (time->dt) / 1000000);
+ return tz;
}
+/**
+ * gda_time_get_tz:
+ * @time: a #GdaTime value to get time zone from
+ *
+ * Returns a #GTimeZone in use in this @time.
+ *
+ * Since: 6.0
+ */
+GTimeZone*
+gda_time_get_tz (const GdaTime* time)
+{
+ g_return_val_if_fail (time != NULL, 0);
+ const gchar *stz = g_date_time_get_timezone_abbreviation (time->dt);
+ GTimeZone *tz = g_time_zone_new (stz);
+ return tz;
+}
+
/**
* gda_time_set_timezone:
* @time: a #GdaTime value to set time zone to
@@ -1815,7 +1876,11 @@ void
gda_time_set_timezone (GdaTime* time, glong timezone)
{
g_return_if_fail (time != NULL);
- time->timezone = timezone;
+ gda_time_new_from_values (gda_time_get_hour (time),
+ gda_time_get_minute (time),
+ gda_time_get_second (time),
+ gda_time_get_fraction (time),
+ timezone);
}
/**
@@ -1824,6 +1889,7 @@ gda_time_set_timezone (GdaTime* time, glong timezone)
*
* Returns: #TRUE if #GdaTime is valid; %FALSE otherwise.
*
+ * Deprecated: 6.0
* Since: 4.2
*/
gboolean
@@ -1831,14 +1897,6 @@ gda_time_valid (const GdaTime *time)
{
g_return_val_if_fail (time, FALSE);
- if ((time->hour > 23) ||
- (time->minute > 59) ||
- (time->second > 59))
- return FALSE;
- if ((time->fraction >= 1000000) ||
- (time->timezone <= -12 * 3600) ||
- (time->timezone >= 12 * 3600))
- return FALSE;
return TRUE;
}
@@ -1860,35 +1918,47 @@ gda_time_change_timezone (GdaTime *time, glong ntz)
{
g_return_if_fail (time);
g_return_if_fail (gda_time_valid (time));
- g_return_if_fail ((ntz > - 12 * 3600) && (ntz < 12 * 3600));
-
- if (time->timezone == ntz)
- return;
-
- if (time->timezone != GDA_TIMEZONE_INVALID) {
- glong nsec;
- nsec = time->hour * 3600 + time->minute * 60 + time->second - time->timezone + ntz;
- if (nsec < 0)
- nsec += 86400;
- else if (nsec >= 86400)
- nsec -= 86400;
- /* hours */
- gint n;
- n = nsec / 3600;
- time->hour = (gushort) n;
+ gint h = ntz / 3600;
+ gint m = (ntz - h * 3600) / 60;
+ gint s = (ntz - h * 3600 - m * 60);
+ gint sig = h;
+ if (m < 0) {
+ m = -1 * m;
+ }
+ if (s < 0) {
+ s = -1 * s;
+ }
+ if (h < 0) {
+ h = -1 * h;
+ }
+ gchar *stz = g_strdup_printf ("%s%02d:%02d:%02d", sig < 0 ? "-" : "+", h, m, s);
+ GTimeZone *tz = g_time_zone_new (stz);
+ g_free (stz);
+ GDateTime *ndt = time->dt;
+ time->dt = g_date_time_to_timezone (time->dt, tz);
+ g_date_time_unref (ndt);
+}
- /* minutes */
- nsec -= n * 3600;
- n = nsec / 60;
- time->minute = (gushort) n;
- /* seconds */
- nsec -= n * 60;
- time->second = (gushort) nsec;
- }
+/**
+ * gda_time_to_timezone:
+ * @time: a valid #GdaTime
+ * @ntz: a new #GTimeZone to use
+ *
+ * Translate @time's to give timezone
+ *
+ * Since: 6.0
+ */
+void
+gda_time_to_timezone (GdaTime *time, GTimeZone *ntz)
+{
+ g_return_if_fail (time);
+ g_return_if_fail (gda_time_valid (time));
- time->timezone = ntz;
+ GDateTime *ndt = time->dt;
+ time->dt = g_date_time_to_timezone (time->dt, ntz);
+ g_date_time_unref (ndt);
}
/**
@@ -2025,42 +2095,6 @@ gda_value_new_blob_from_file (const gchar *filename)
return value;
}
-/*
- * Warning: DOES NOT modify @gmttm and loctm
- *
- * Returns: the offset, or G_MAXLONG in case of error
- */
-static glong
-compute_tz_offset (struct tm *gmttm, struct tm *loctm)
-{
- if (! gmttm || !loctm)
- return G_MAXLONG;
-
- struct tm cgmttm, cloctm;
- cgmttm = *gmttm;
- cloctm = *loctm;
-
- time_t lt, gt;
- cgmttm.tm_isdst = 0;
- cloctm.tm_isdst = 0;
-
- lt = mktime (&cloctm);
- if (lt == -1)
- return G_MAXLONG;
- gt = mktime (&cgmttm);
- if (gt == -1)
- return G_MAXLONG;
- glong off;
- off = lt - gt;
- /*g_print ("%s(): %02d:%02d:%02d %d\n", __FUNCTION__,
- loctm->tm_hour, loctm->tm_min, loctm->tm_sec, (gint) (off / 3600));*/
-
- if ((off >= 24 * 3600) || (off <= - 24 * 3600))
- return G_MAXLONG;
- else
- return off;
-}
-
/**
* gda_value_new_date_time:
*
@@ -2139,54 +2173,12 @@ gda_value_new_date_time_from_timet (time_t val)
GValue *
gda_value_new_time_from_timet (time_t val)
{
- GValue *value = NULL;
- struct tm *ltm = NULL;
- glong tz = 0;
-
-#ifdef HAVE_LOCALTIME_R
- struct tm gmttm, loctm;
- tzset ();
- ltm = localtime_r ((const time_t *) &val, &loctm);
- tz = compute_tz_offset (gmtime_r ((const time_t *) &val, &gmttm), &loctm);
- if (tz == G_MAXLONG)
- ltm = NULL;
-#elif HAVE_LOCALTIME_S
- struct tm gmttm, loctm;
- if ((localtime_s (&loctm, (const time_t *) &val) == 0) &&
- (gmtime_s (&gmttm, (const time_t *) &val) == 0)) {
- tz = compute_tz_offset (&gmttm, &loctm);
- if (tz != G_MAXLONG)
- ltm = &loctm;
- }
-#else
- struct tm gmttm, loctm;
- ltm = gmtime ((const time_t *) &val);
- if (ltm) {
- gmttm = *ltm;
- ltm = localtime ((const time_t *) &val);
- if (ltm) {
- loctm = *ltm;
- tz = compute_tz_offset (&gmttm, &loctm);
- if (tz == G_MAXLONG)
- ltm = NULL;
- }
- }
-
-#endif
-
- if (ltm) {
- GdaTime tim;
- tim.hour = ltm->tm_hour;
- tim.minute = ltm->tm_min;
- tim.second = ltm->tm_sec;
- tim.fraction = 0;
- tim.timezone = tz;
-
- value = g_new0 (GValue, 1);
- gda_value_set_time (value, (const GdaTime *) &tim);
- }
+ GValue *value = gda_value_new (GDA_TYPE_TIME);
+ GDateTime *dt = g_date_time_new_from_unix_local (val);
+ GdaTime *t = gda_time_new_from_date_time (dt);
+ gda_value_set_time (value, t);
- return value;
+ return value;
}
/**
@@ -2812,6 +2804,15 @@ gda_value_stringify (const GValue *value)
else
return g_strdup ("0000-00-00");
}
+ else if (g_type_is_a (type, GDA_TYPE_TIME)) {
+ GdaTime *gts;
+ gts = (GdaTime*) g_value_get_boxed (value);
+ if (gts != NULL) {
+ return gda_time_to_string_utc (gts);
+ } else {
+ return "00:00:00+0";
+ }
+ }
else if (g_type_is_a (type, G_TYPE_DATE_TIME)) {
GDateTime *ts;
ts = (GDateTime*) g_value_get_boxed (value);
diff --git a/libgda/gda-value.h b/libgda/gda-value.h
index 8fff3c605..7461c5c86 100644
--- a/libgda/gda-value.h
+++ b/libgda/gda-value.h
@@ -99,10 +99,13 @@ typedef struct _GdaTime GdaTime;
GType gda_time_get_type (void) G_GNUC_CONST;
GdaTime* gda_time_new (void);
+GdaTime* gda_time_new_from_date_time (GDateTime *dt);
GdaTime* gda_time_new_from_values (gushort hour, gushort minute, gushort second,
gulong fraction, glong timezone);
GdaTime* gda_time_copy (const GdaTime* time);
void gda_time_free (GdaTime* time);
+void gda_time_set_from_date_time (GdaTime *time, GDateTime *dt);
+void gda_time_set_from_values (GdaTime *time, gushort hour, gushort minute,
gushort second, gulong fraction, glong timezone);
gushort gda_time_get_hour (const GdaTime* time);
void gda_time_set_hour (GdaTime* time, gushort hour);
gushort gda_time_get_minute (const GdaTime* time);
@@ -111,11 +114,16 @@ gushort gda_time_get_second (const GdaTime* time);
void gda_time_set_second (GdaTime* time, gushort second);
gulong gda_time_get_fraction (const GdaTime *time);
void gda_time_set_fraction (GdaTime* time, gulong fraction);
+GTimeZone* gda_time_get_tz (const GdaTime *time);
glong gda_time_get_timezone (const GdaTime *time);
void gda_time_set_timezone (GdaTime* time, glong timezone);
gboolean gda_time_valid (const GdaTime *time);
void gda_time_change_timezone (GdaTime *time, glong ntz);
+void gda_time_to_timezone (GdaTime *time, GTimeZone *ntz);
+gchar* gda_time_to_string (GdaTime *time);
+gchar* gda_time_to_string_local (GdaTime *time);
+gchar* gda_time_to_string_utc (GdaTime *time);
/**
* GdaBinary: (ref-func gda_binary_new) (unref-func gda_binary_free) (get-value-func gda_value_get_binary)
(set-value-func gda_value_set_binary)
diff --git a/libgda/handlers/gda-handler-time.c b/libgda/handlers/gda-handler-time.c
index 4b16e0a84..6a41f0810 100644
--- a/libgda/handlers/gda-handler-time.c
+++ b/libgda/handlers/gda-handler-time.c
@@ -535,20 +535,13 @@ gda_handler_time_get_sql_from_value (GdaDataHandler *iface, const GValue *value)
}
}
else if (type == GDA_TYPE_TIME) {
- const GdaTime *tim;
- GString *string;
- string = g_string_new ("");
- tim = gda_value_get_time ((GValue *) value);
- g_string_append_c (string, '\'');
- g_string_append_printf (string, "%02d:%02d:%02d",
- gda_time_get_hour (tim),
- gda_time_get_minute (tim),
- gda_time_get_second (tim));
- if (gda_time_get_timezone (tim) != GDA_TIMEZONE_INVALID)
- g_string_append_printf (string, "%+02d",
- (int) gda_time_get_timezone (tim) / 3600);
- g_string_append_c (string, '\'');
- retval = g_string_free (string, FALSE);
+ GdaTime *gdat;
+ gchar *str;
+
+ gdat = (GdaTime*) g_value_get_boxed ((GValue *) value);
+ str = gda_time_to_string_utc (gdat);
+ retval = g_strdup_printf ("'%s'", str);
+ g_free (str);
}
else if (g_type_is_a (type, G_TYPE_DATE_TIME)) {
GDateTime *gdats;
@@ -556,52 +549,13 @@ gda_handler_time_get_sql_from_value (GdaDataHandler *iface, const GValue *value)
gdats = (GDateTime*) g_value_get_boxed ((GValue *) value);
if (gdats != NULL)
retval = g_date_time_format (gdats, "'%FT%H:%M:%S%:::z'");
- else
- retval = g_strdup ("NULL");
- }
- else if (type == G_TYPE_DATE_TIME) { // FIXME: Remove
- GDateTime *ts;
- GDate *vdate;
-
- ts = g_value_get_boxed ((GValue *) value);
- if (ts) {
- gint y, m, d;
- g_date_time_get_ymd (ts, &y, &m, &d);
- vdate = g_date_new_dmy (d, m, y);
- str = render_date_locale (vdate, hdl->sql_locale);
- g_date_free (vdate);
-
- if (str) {
- GString *string;
- string = g_string_new ("");
- g_string_append_printf (string, "%02u:%02u:%02u",
- g_date_time_get_hour (ts),
- g_date_time_get_minute (ts),
- g_date_time_get_second (ts));
- if (g_date_time_get_microsecond (ts) != 0)
- g_string_append_printf (string, ".%d", g_date_time_get_microsecond
(ts));
-
- GTimeSpan span;
- span = g_date_time_get_utc_offset (ts);
- if (span > 0)
- g_string_append_printf (string, "+%02d",
- (int) (span / G_TIME_SPAN_HOUR));
- else
- g_string_append_printf (string, "-%02d",
- (int) (-span / G_TIME_SPAN_HOUR));
-
- retval = g_strdup_printf ("'%sT%s'", str, string->str);
- g_free (str);
- g_string_free (string, TRUE);
- }
- else
- retval = g_strdup ("NULL");
- }
else
retval = g_strdup ("NULL");
}
- else
- g_assert_not_reached ();
+ else {
+ g_warning (_("Time data handler can create an SQL representation of a value not holding time
type."));
+ retval = g_strdup ("NULL");
+ }
return retval;
}
diff --git a/tests/test-sql-renderer.c b/tests/test-sql-renderer.c
index 97781dcde..a0d4d981c 100644
--- a/tests/test-sql-renderer.c
+++ b/tests/test-sql-renderer.c
@@ -112,7 +112,7 @@ do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
}
}
gchar *expected;
- expected = "('@@@@@@@@@@T17:10:23+02', '16:09:22-3')";
+ expected = "('@@@@@@@@@@T17:10:23+02', '19:09:22+00')";
if (cnc)
sql = gda_connection_statement_to_sql (cnc, stmt, params, 0, NULL, &error);
else
@@ -136,7 +136,7 @@ do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
}
g_free (sql);
- expected = "('@@@@@@@@@@T15:10:23+00', '19:09:22')";
+ expected = "('@@@@@@@@@@T15:10:23+00', '19:09:22+00')";
if (cnc)
sql = gda_connection_statement_to_sql (cnc, stmt, params, GDA_STATEMENT_SQL_TIMEZONE_TO_GMT,
NULL, &error);
else
@@ -198,7 +198,7 @@ do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
goto endtest;
}
- expected = "('@@@@@@@@@@T17:10:23+02', '16:09:22-3')";
+ expected = "('@@@@@@@@@@T17:10:23+02', '19:09:22+00')";
if (cnc)
sql = gda_connection_statement_to_sql (cnc, stmt, params, 0, NULL, &error);
else
@@ -222,7 +222,7 @@ do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
}
g_free (sql);
- expected = "('@@@@@@@@@@T15:10:23+00', '19:09:22')";
+ expected = "('@@@@@@@@@@T15:10:23+00', '19:09:22+00')";
if (cnc)
sql = gda_connection_statement_to_sql (cnc, stmt, params, GDA_STATEMENT_SQL_TIMEZONE_TO_GMT,
NULL, &error);
else
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]