[libgda] Fixed bug #712143
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Fixed bug #712143
- Date: Sun, 17 Nov 2013 16:17:49 +0000 (UTC)
commit c5021e4238b99652ac80a73e95ae442cbf8f9df6
Author: Vivien Malerba <malerba gnome-db org>
Date: Sat Nov 16 15:03:09 2013 +0100
Fixed bug #712143
libgda/gda-value.c | 80 +++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 64 insertions(+), 16 deletions(-)
---
diff --git a/libgda/gda-value.c b/libgda/gda-value.c
index 7ad6e58..80a930d 100644
--- a/libgda/gda-value.c
+++ b/libgda/gda-value.c
@@ -1627,13 +1627,43 @@ gda_value_new_blob_from_file (const gchar *filename)
return value;
}
+/*
+ * Warning: modifies @gmttm and loctm
+ *
+ * Returns: the offset, or G_MAXLONG in case of error
+ */
+static glong
+compute_tz_offset (struct tm *gmttm, struct tm *loctm)
+{
+ time_t lt, gt;
+ if (! gmttm || !loctm)
+ return G_MAXLONG;
+
+ gmttm->tm_isdst = 0;
+ loctm->tm_isdst = 0;
+
+ lt = mktime (loctm);
+ if (lt == -1)
+ return G_MAXLONG;
+ gt = mktime (gmttm);
+ if (gt == -1)
+ return G_MAXLONG;
+
+ glong off;
+ off = lt - gt;
+ if ((off >= 24 * 3600) || (off <= - 24 * 3600))
+ return G_MAXLONG;
+ else
+ return off;
+}
+
/**
* gda_value_new_timestamp_from_timet: (skip)
* @val: value to set for the new #GValue.
*
* Makes a new #GValue of type #GDA_TYPE_TIMESTAMP with value @val
- * (of type time_t). The returned timestamp has a timezone initialized with the
- * current timezone, taking into account the daylight savings.
+ * (of type time_t). The returned timestamp's value is relative to the current
+ * timezone (i.e. is localtime).
*
* For example, to get a time stamp representing the current date and time, use:
*
@@ -1641,30 +1671,46 @@ gda_value_new_blob_from_file (const gchar *filename)
* ts = gda_value_new_timestamp_from_timet (time (NULL));
* </code>
*
- * Returns: (transfer full): the newly created #GValue.
+ * Returns: (transfer full): the newly created #GValue, or %NULL in case of error
*
* Free-function: gda_value_free
*/
GValue *
gda_value_new_timestamp_from_timet (time_t val)
{
- GValue *value;
-
- struct tm *ltm;
+ GValue *value = NULL;
+ struct tm *ltm = NULL;
+ glong tz = 0;
- value = g_new0 (GValue, 1);
#ifdef HAVE_LOCALTIME_R
- struct tm tmpstm;
+ struct tm gmttm, loctm;
tzset ();
- ltm = localtime_r ((const time_t *) &val, &tmpstm);
-#elif HAVE_LOCALTIME_S
- struct tm tmpstm;
- if (localtime_s (&tmpstm, (const time_t *) &val) == 0)
- ltm = &tmpstm;
- else
+ 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
- ltm = localtime ((const time_t *) &val);
+ 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) {
@@ -1676,7 +1722,9 @@ gda_value_new_timestamp_from_timet (time_t val)
tstamp.minute = ltm->tm_min;
tstamp.second = ltm->tm_sec;
tstamp.fraction = 0;
- tstamp.timezone = - timezone + daylight * 3600;
+ tstamp.timezone = tz;
+
+ value = g_new0 (GValue, 1);
gda_value_set_timestamp (value, (const GdaTimestamp *) &tstamp);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]