[evolution-mapi] Bug #669817 - Events using incorrect timezone
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Bug #669817 - Events using incorrect timezone
- Date: Thu, 23 Feb 2012 18:12:45 +0000 (UTC)
commit 5de567e2847583171d7e767e4b18683c1123579c
Author: Milan Crha <mcrha redhat com>
Date: Thu Feb 23 19:11:20 2012 +0100
Bug #669817 - Events using incorrect timezone
src/libexchangemapi/e-mapi-cal-tz-utils.c | 94 +++++++++++++++++++++++++++++
src/libexchangemapi/e-mapi-cal-tz-utils.h | 2 +
src/libexchangemapi/e-mapi-cal-utils.c | 14 ++++-
3 files changed, 109 insertions(+), 1 deletions(-)
---
diff --git a/src/libexchangemapi/e-mapi-cal-tz-utils.c b/src/libexchangemapi/e-mapi-cal-tz-utils.c
index 23addbc..689311d 100644
--- a/src/libexchangemapi/e-mapi-cal-tz-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-tz-utils.c
@@ -80,6 +80,100 @@ e_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tz_location)
return retval;
}
+static struct icaltimetype
+tm_to_icaltimetype (struct tm *tm,
+ gboolean dst)
+{
+ struct icaltimetype itt;
+
+ memset (&itt, 0, sizeof (struct icaltimetype));
+
+ itt.second = 0;
+ itt.minute = 0;
+ itt.hour = 0;
+
+ itt.day = 1;
+ itt.month = dst ? 6 : 1;
+ itt.year = tm->tm_year + 1900;
+
+ itt.is_utc = 0;
+ itt.is_date = 0;
+
+ return itt;
+}
+
+static gint
+get_offset (icaltimezone *zone,
+ gboolean dst)
+{
+ struct tm local;
+ struct icaltimetype tt;
+ gint offset;
+ time_t now = time (NULL);
+
+ gmtime_r (&now, &local);
+ tt = tm_to_icaltimetype (&local, dst);
+ offset = icaltimezone_get_utc_offset (zone, &tt, NULL);
+
+ return offset / -60;
+}
+
+const gchar *
+e_mapi_cal_tz_util_ical_from_zone_struct (const guint8 *lpb,
+ guint32 cb)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ guint32 utcBias, stdBias, dstBias;
+ const gchar *res = NULL;
+
+ g_return_val_if_fail (lpb != NULL, NULL);
+
+ /* get the timezone by biases, which are the first 3*4 bytes */
+ if (cb < 12)
+ return NULL;
+
+ memcpy (&utcBias, lpb, 4); lpb += 4;
+ memcpy (&stdBias, lpb, 4); lpb += 4;
+ memcpy (&dstBias, lpb, 4); lpb += 4;
+
+ g_static_rec_mutex_lock (&mutex);
+ if (!e_mapi_cal_tz_util_populate ()) {
+ g_static_rec_mutex_unlock (&mutex);
+ return NULL;
+ }
+
+ g_hash_table_iter_init (&iter, mapi_to_ical);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ const gchar *location = value;
+ icaltimezone *zone;
+ gint offset;
+
+ zone = icaltimezone_get_builtin_timezone (location);
+ if (!zone)
+ continue;
+
+ offset = get_offset (zone, FALSE);
+ if (offset != utcBias || offset != utcBias + stdBias)
+ continue;
+
+ offset = get_offset (zone, TRUE);
+ if (offset != utcBias + dstBias)
+ continue;
+
+ /* pick shortest and alphabetically first timezone */
+ if (!res ||
+ strlen (res) > strlen (location) ||
+ (strlen (res) == strlen (location) &&
+ strcmp (location, res) < 0))
+ res = location;
+ }
+
+ g_static_rec_mutex_unlock (&mutex);
+
+ return res;
+}
+
void
e_mapi_cal_tz_util_destroy (void)
{
diff --git a/src/libexchangemapi/e-mapi-cal-tz-utils.h b/src/libexchangemapi/e-mapi-cal-tz-utils.h
index 9db6596..ba06d51 100644
--- a/src/libexchangemapi/e-mapi-cal-tz-utils.h
+++ b/src/libexchangemapi/e-mapi-cal-tz-utils.h
@@ -32,6 +32,8 @@ G_BEGIN_DECLS
const gchar * e_mapi_cal_tz_util_get_mapi_equivalent (const gchar *ical_tz_location);
const gchar * e_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tz_location);
+const gchar * e_mapi_cal_tz_util_ical_from_zone_struct(const guint8 *lpb,
+ guint32 cb);
gboolean e_mapi_cal_tz_util_populate (void);
void e_mapi_cal_tz_util_destroy (void);
void e_mapi_cal_tz_util_dump (void);
diff --git a/src/libexchangemapi/e-mapi-cal-utils.c b/src/libexchangemapi/e-mapi-cal-utils.c
index 6ebce46..66e86c1 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-utils.c
@@ -1003,7 +1003,7 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
if (location && *location)
icalcomponent_set_location (ical_comp, location);
- b = e_mapi_util_find_array_propval (&object->properties, PidLidAppointmentSubType);;
+ b = e_mapi_util_find_array_propval (&object->properties, PidLidAppointmentSubType);
all_day = b && *b;
bin = e_mapi_util_find_array_propval (&object->properties, PidLidAppointmentTimeZoneDefinitionStartDisplay);
@@ -1013,6 +1013,12 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
g_free (buf);
}
+ if (!dtstart_tz_location) {
+ bin = e_mapi_util_find_array_propval (&object->properties, PidLidTimeZoneStruct);
+ if (bin)
+ dtstart_tz_location = e_mapi_cal_tz_util_ical_from_zone_struct (bin->lpb, bin->cb);
+ }
+
if (e_mapi_util_find_array_datetime_propval (&t, &object->properties, PidLidAppointmentStartWhole) == MAPI_E_SUCCESS) {
icaltimezone *zone = dtstart_tz_location ? icaltimezone_get_builtin_timezone (dtstart_tz_location) : utc_zone;
prop = icalproperty_new_dtstart (icaltime_from_timet_with_zone (t.tv_sec, all_day, zone));
@@ -1030,6 +1036,12 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
g_free (buf);
}
+ if (!dtend_tz_location) {
+ bin = e_mapi_util_find_array_propval (&object->properties, PidLidTimeZoneStruct);
+ if (bin)
+ dtend_tz_location = e_mapi_cal_tz_util_ical_from_zone_struct (bin->lpb, bin->cb);
+ }
+
if (e_mapi_util_find_array_datetime_propval (&t, &object->properties, PidLidAppointmentEndWhole) == MAPI_E_SUCCESS) {
icaltimezone *zone;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]