[tracker/localtime: 2/5] libtracker-common: Add TrackerDateTime to store time with UTC offset



commit e1b75ceb3e3105a9c6739bd6c3d7d45a8dfacc57
Author: Jürg Billeter <j bitron ch>
Date:   Wed Feb 17 13:28:46 2010 +0100

    libtracker-common: Add TrackerDateTime to store time with UTC offset

 src/libtracker-common/libtracker-common.vapi      |    2 +-
 src/libtracker-common/tracker-type-utils.c        |  130 ++++++++++++++++++++-
 src/libtracker-common/tracker-type-utils.h        |   18 +++-
 src/libtracker-data/tracker-sparql-query.vala     |    2 +-
 src/plugins/evolution/tracker-evolution-plugin.c  |    2 +-
 tests/libtracker-common/tracker-type-utils-test.c |   10 +-
 6 files changed, 151 insertions(+), 13 deletions(-)
---
diff --git a/src/libtracker-common/libtracker-common.vapi b/src/libtracker-common/libtracker-common.vapi
index 9be6d09..c80a3f2 100644
--- a/src/libtracker-common/libtracker-common.vapi
+++ b/src/libtracker-common/libtracker-common.vapi
@@ -65,6 +65,6 @@ namespace Tracker {
 	}
 
 	[CCode (cheader_filename = "libtracker-common/tracker-type-utils.h")]
-	public int string_to_date (string date_string);
+	public int string_to_date (string date_string, out int offset);
 }
 
diff --git a/src/libtracker-common/tracker-type-utils.c b/src/libtracker-common/tracker-type-utils.c
index f5bf266..215ac22 100644
--- a/src/libtracker-common/tracker-type-utils.c
+++ b/src/libtracker-common/tracker-type-utils.c
@@ -370,7 +370,7 @@ tracker_date_to_time_string (const gchar *date_string)
 	if (str) {
 		time_t t;
 
-		t = tracker_string_to_date (str);
+		t = tracker_string_to_date (str, NULL);
 
 		g_free (str);
 
@@ -383,7 +383,8 @@ tracker_date_to_time_string (const gchar *date_string)
 }
 
 time_t
-tracker_string_to_date (const gchar *date_string)
+tracker_string_to_date (const gchar *date_string,
+                        gint        *offset_p)
 {
 	static GRegex *regex = NULL;
 
@@ -391,6 +392,7 @@ tracker_string_to_date (const gchar *date_string)
 	gchar      *match;
 	struct tm tm;
 	time_t    t;
+	gint offset;
 
 	g_return_val_if_fail (date_string, -1);
 
@@ -454,24 +456,34 @@ tracker_string_to_date (const gchar *date_string)
 		t  = mktime (&tm);
 		t -= timezone;
 
+		offset = 0;
+
 		match = g_match_info_fetch (match_info, 9);
 		if (match) {
 			/* non-UTC timezone */
-			t -= atoi (match) * 3600;
+			offset = atoi (match) * 3600;
 			g_free (match);
 
 			match = g_match_info_fetch (match_info, 10);
-			t -= atoi (match) * 60;
+			offset += atoi (match) * 60;
 			g_free (match);
+
+			t -= offset;
 		}
 	} else {
 		/* local time */
 		tm.tm_isdst = -1;
 		t = mktime (&tm);
+
+		offset = -timezone + (tm.tm_isdst > 0 ? 3600 : 0);
 	}
 
 	g_match_info_free (match_info);
 
+	if (offset_p) {
+		*offset_p = offset;
+	}
+
 	return t;
 }
 
@@ -787,3 +799,113 @@ tracker_string_boolean_to_string_gint (const gchar *value)
 		return g_strdup (value);
 	}
 }
+
+static void
+tracker_date_time_value_init (GValue *value)
+{
+	value->data[0].v_int64 = 0;
+	value->data[1].v_int = 0;
+}
+
+static void
+tracker_date_time_value_copy (const GValue *src_value,
+                              GValue       *dest_value)
+{
+	dest_value->data[0].v_int64 = src_value->data[0].v_int64;
+	dest_value->data[1].v_int = src_value->data[1].v_int;
+}
+
+GType
+tracker_date_time_get_type (void)
+{
+	static GType tracker_date_time_type_id = 0;
+	if (G_UNLIKELY (tracker_date_time_type_id == 0)) {
+		static const GTypeValueTable value_table = {
+			tracker_date_time_value_init,
+			NULL,
+			tracker_date_time_value_copy
+		};
+		static const GTypeInfo type_info = {
+			0,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			0,
+			0,
+			NULL,
+			&value_table
+		};
+		static const GTypeFundamentalInfo fundamental_info = {
+			0
+		};
+		tracker_date_time_type_id = g_type_register_fundamental (
+			g_type_fundamental_next (),
+			"TrackerDateTime",
+			&type_info,
+			&fundamental_info,
+			0);
+	}
+	return tracker_date_time_type_id;
+}
+
+void
+tracker_date_time_set (GValue *value,
+                       gint64  time,
+                       gint    offset)
+{
+	g_return_if_fail (G_VALUE_HOLDS (value, TRACKER_TYPE_DATE_TIME));
+
+	value->data[0].v_int64 = time;
+	value->data[1].v_int = offset;
+}
+
+void
+tracker_date_time_set_from_string (GValue      *value,
+                                   const gchar *date_time_string)
+{
+	gint64 time;
+	gint offset;
+
+	time = tracker_string_to_date (date_time_string, &offset);
+	tracker_date_time_set (value, time, offset);
+}
+
+gint64
+tracker_date_time_get_time (const GValue *value)
+{
+	g_return_val_if_fail (G_VALUE_HOLDS (value, TRACKER_TYPE_DATE_TIME), 0);
+
+	/* UTC timestamp */
+	return value->data[0].v_int64;
+}
+
+gint
+tracker_date_time_get_offset (const GValue *value)
+{
+	g_return_val_if_fail (G_VALUE_HOLDS (value, TRACKER_TYPE_DATE_TIME), 0);
+
+	/* UTC offset */
+	return value->data[1].v_int;
+}
+
+gint
+tracker_date_time_get_local_date (const GValue *value)
+{
+	gint64 local_timestamp;
+
+	/* return number of days since epoch */
+	local_timestamp = tracker_date_time_get_time (value) + tracker_date_time_get_offset (value);
+	return local_timestamp / 3600 / 24;
+}
+
+gint
+tracker_date_time_get_local_time (const GValue *value)
+{
+	gint64 local_timestamp;
+
+	/* return local time of day */
+	local_timestamp = tracker_date_time_get_time (value) + tracker_date_time_get_offset (value);
+	return local_timestamp % (24 * 3600);
+}
diff --git a/src/libtracker-common/tracker-type-utils.h b/src/libtracker-common/tracker-type-utils.h
index 4d5ae19..c7d40f2 100644
--- a/src/libtracker-common/tracker-type-utils.h
+++ b/src/libtracker-common/tracker-type-utils.h
@@ -22,6 +22,7 @@
 #define __LIBTRACKER_COMMON_TYPE_UTILS_H__
 
 #include <glib.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
@@ -29,11 +30,26 @@ G_BEGIN_DECLS
 #error "only <libtracker-common/tracker-common.h> must be included directly."
 #endif
 
+#define TRACKER_TYPE_DATE_TIME                 (tracker_date_time_get_type ())
+
+GType    tracker_date_time_get_type            (void);
+
+void     tracker_date_time_set                 (GValue       *value,
+                                                gint64        time,
+                                                gint          offset);
+void     tracker_date_time_set_from_string     (GValue       *value,
+                                                const gchar  *date_time_string);
+gint64   tracker_date_time_get_time            (const GValue *value);
+gint     tracker_date_time_get_offset          (const GValue *value);
+gint     tracker_date_time_get_local_date      (const GValue *value);
+gint     tracker_date_time_get_local_time      (const GValue *value);
+
 gchar *  tracker_date_format                   (const gchar  *date_string);
 gchar *  tracker_date_format_to_iso8601        (const gchar  *date_string,
                                                 const gchar  *format);
 gchar *  tracker_date_to_time_string           (const gchar  *date_string);
-time_t   tracker_string_to_date                        (const gchar  *date_string);
+time_t   tracker_string_to_date                (const gchar  *date_string,
+                                                gint         *offset);
 gchar *  tracker_date_to_string                        (time_t        date_time);
 gchar *  tracker_glong_to_string               (glong         i);
 gchar *  tracker_gint_to_string                        (gint          i);
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index 7cb1f01..a9fa3c3 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -567,7 +567,7 @@ public class Tracker.SparqlQuery : Object {
 					throw new SparqlError.TYPE ("`%s' is not a valid boolean".printf (binding.literal));
 				}
 			} else if (binding.data_type == PropertyType.DATETIME) {
-				stmt.bind_int (i, string_to_date (binding.literal));
+				stmt.bind_int (i, string_to_date (binding.literal, null));
 			} else if (binding.data_type == PropertyType.INTEGER) {
 				stmt.bind_int (i, binding.literal.to_int ());
 			} else {
diff --git a/src/plugins/evolution/tracker-evolution-plugin.c b/src/plugins/evolution/tracker-evolution-plugin.c
index c465eca..328cf45 100644
--- a/src/plugins/evolution/tracker-evolution-plugin.c
+++ b/src/plugins/evolution/tracker-evolution-plugin.c
@@ -1724,7 +1724,7 @@ on_register_client_qry (GPtrArray *results,
 			} else {
 				for (i = 0; i < results->len; i++) {
 					const gchar **str = g_ptr_array_index (results, i);
-					info->last_checkout = (guint64) tracker_string_to_date (str[0]);
+					info->last_checkout = (guint64) tracker_string_to_date (str[0], NULL);
 					break;
 				}
 			}
diff --git a/tests/libtracker-common/tracker-type-utils-test.c b/tests/libtracker-common/tracker-type-utils-test.c
index 1034b3a..a015db5 100644
--- a/tests/libtracker-common/tracker-type-utils-test.c
+++ b/tests/libtracker-common/tracker-type-utils-test.c
@@ -85,7 +85,7 @@ test_string_to_date (void)
 
 	expected = g_date_new_dmy (16, G_DATE_JUNE, 2008);
 
-	result_time_t = tracker_string_to_date (input);
+	result_time_t = tracker_string_to_date (input, NULL);
 
 	result = g_date_new ();
 	g_date_set_time_t (result, result_time_t);
@@ -100,18 +100,18 @@ test_string_to_date (void)
 	g_assert_cmpint (g_date_get_month (expected), ==, g_date_get_month (result));
 
 	if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR)) {
-		result_time_t = tracker_string_to_date (NULL);
+		result_time_t = tracker_string_to_date (NULL, NULL);
 	}
 	g_test_trap_assert_failed ();
 
-	result_time_t = tracker_string_to_date ("");
+	result_time_t = tracker_string_to_date ("", NULL);
 	g_assert_cmpint (result_time_t, ==, -1);
 
-	result_time_t = tracker_string_to_date ("i am not a date");
+	result_time_t = tracker_string_to_date ("i am not a date", NULL);
 	g_assert_cmpint (result_time_t, ==, -1);
 
 	/* Fails! Check the code
-	   result_time_t = tracker_string_to_date ("2008-06-32T04:23:10+0000");
+	   result_time_t = tracker_string_to_date ("2008-06-32T04:23:10+0000", NULL);
 	   g_assert_cmpint (result_time_t, ==, -1);
 	*/
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]