Commit 000e05c0 authored by Sriram Karra's avatar Sriram Karra

Massage Outlook so as to sync Dates without year

Google Contacts allows the use of anniversary and birthdates
without an actual year value. That is not possible with Outlook
however. We work aroudn this by inserting a dummy year of 1887
and use it as a special value - adding it where Google does not
provide a year, and filter it out in the reverse direction.

To be able to do this we have to do some jumping through the

a) Outlook returns values in UTC, so when synched dates appear to
   shift by one day

b) the 1887 year is way earlier than the epoch. So we have to deal
   with this year value with a bit of care.
parent 5b1fbfbf
## Created : Sun Dec 04 19:42:50 IST 2011
## Last Modified : Thu May 17 17:25:39 IST 2012
## Last Modified : Fri Jun 01 17:41:07 IST 2012
## Copyright (C) 2011, 2012 Sriram Karra <>
......@@ -33,11 +33,22 @@ from win32com.mapi import mapi
import demjson, iso8601, winerror, win32api, pywintypes
def yyyy_mm_dd_to_pytime (date_str):
## FIXME: Temporary hack to ensure we have a yyyy-mm-dd format. Google
## allows the year to be skipped. Outlook crates a problem. We bridge the
## gap by inserting '1887' (birth year of Srinivasa Ramanujan)
res ='--(\d\d)-(\d\d)', date_str)
if res:
date_str = '1887-%s-%s' % (,
dt = datetime.strptime(date_str, '%Y-%m-%d')
return pywintypes.Time(dt.timetuple())
def pytime_to_yyyy_mm_dd (pyt):
return ('%04d-%02d-%02d' % (pyt.year, pyt.month,
if pyt.year == 1887:
## Undo the hack noted above.
return ('--%02d-%02d' % (pyt.month,
return ('%04d-%02d-%02d' % (pyt.year, pyt.month,
class OLContactError(Exception):
......@@ -609,11 +620,13 @@ class OLContact(Contact):
d = self._get_olprop(olpd, mt.PR_BIRTHDAY)
if d:
d = utils.utc_time_to_local_ts(d, ret_dt=True)
date = pytime_to_yyyy_mm_dd(d)
a = self._get_olprop(olpd, mt.PR_WEDDING_ANNIVERSARY)
if a:
a = utils.utc_time_to_local_ts(a, ret_dt=True)
date = pytime_to_yyyy_mm_dd(a)
## Created : Tue Jul 26 06:54:41 IST 2011
## Last Modified : Sat May 12 10:42:29 IST 2012
## Last Modified : Fri Jun 01 17:40:15 IST 2012
## Copyright (C) 2011, 2012 by Sriram Karra <>
......@@ -118,12 +118,28 @@ class LocalTimezone(tzinfo):
localtz = LocalTimezone()
def utc_time_to_local_ts (t):
"""Convert a time object which is in UTC into a timestamp in local
def utc_time_to_local_ts (t, ret_dt=False):
"""Convert a Pytime object which is in UTC into a timestamp in local
utc_ts = int(t)
utc_off = localtz.utcoffset(
d = datetime.fromtimestamp(utc_ts) + utc_off
If dt is True, then a datetime object is returned, else (this is the
default), an integer representing time since the epoch is returned."""
return _time.mktime(d.timetuple())
utc_off = localtz.utcoffset(
utc_ts = int(t)
dt = datetime.fromtimestamp(utc_ts)
except ValueError, e:
## Pytimes earlier than the epoch are a pain in the rear end.
dt = datetime(year=t.year,
d = dt + utc_off
if ret_dt:
return d
return _time.mktime(d.timetuple())
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment