From 41728c3853076225ee43157f6ecc02bb4af73db3 Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Wed, 15 Feb 2012 15:05:54 +0100 Subject: [PATCH] add basic timezone support for datetimes --- src/icalendar/cal.py | 6 +++++- src/icalendar/prop.py | 31 +++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/icalendar/cal.py b/src/icalendar/cal.py index 26442c1..2a01e7c 100644 --- a/src/icalendar/cal.py +++ b/src/icalendar/cal.py @@ -377,7 +377,11 @@ class Component(CaselessDict): factory = types_factory.for_property(name) component = stack[-1] try: - vals = factory(factory.from_ical(vals)) + if name in ('DTSTART', 'DTEND') and 'TZID' in params: # TODO: add DUE, FREEBUSY + vals = factory(factory.from_ical(vals, params['TZID'])) + print vals.to_ical() + else: + vals = factory(factory.from_ical(vals)) except ValueError: if not component.ignore_exceptions: raise diff --git a/src/icalendar/prop.py b/src/icalendar/prop.py index 9f19c29..81759ba 100644 --- a/src/icalendar/prop.py +++ b/src/icalendar/prop.py @@ -47,6 +47,7 @@ SequenceTypes = [TupleType, ListType] import re import time as _time import binascii +import pytz # from this package from icalendar.caselessdict import CaselessDict @@ -443,13 +444,13 @@ class vDDDTypes: else: raise ValueError('Unknown date type') - def from_ical(ical): + def from_ical(ical, timezone=None): "Parses the data format from ical text format" u = ical.upper() if u.startswith('-P') or u.startswith('P'): return vDuration.from_ical(ical) try: - return vDatetime.from_ical(ical) + return vDatetime.from_ical(ical, timezone=timezone) except: return vDate.from_ical(ical) from_ical = staticmethod(from_ical) @@ -526,6 +527,9 @@ class vDatetime: >>> vDatetime(utc).to_ical() '20010101T000000Z' + >>> dat = vDatetime.from_ical('20101010T000000', 'Europe/Vienna') + >>> vDatetime.to_ical(dat) + 'TZID=Europe/Vienna;20101010T000000' """ def __init__(self, dt): @@ -533,16 +537,25 @@ class vDatetime: self.params = Parameters() def to_ical(self): - if self.dt.tzinfo: - utc_time = self.dt - self.dt.tzinfo.utcoffset(self.dt) - return utc_time.strftime("%Y%m%dT%H%M%SZ") + if str(self.dt.tzinfo) == 'UTC': + return self.dt.strftime("%Y%m%dT%H%M%SZ") + elif self.dt.tzinfo: + return "TZID=%s;%s" % (self.dt.tzinfo, self.dt.strftime("%Y%m%dT%H%M%S")) return self.dt.strftime("%Y%m%dT%H%M%S") - def from_ical(ical): + def from_ical(ical, timezone=None): """ Parses the data format from ical text format. """ - import pdb; pdb.set_trace() + # TODO: ical string should better contain also the TZID property. + if timezone: + try: + timezone = pytz.timezone(timezone) + except pytz.UnknownTimeZoneError: + # We only support timezones from the Olson Database. + timezone=None + timezone = pytz.timezone('Europe/Vienna') + try: timetuple = map(int, (( ical[:4], # year @@ -552,7 +565,9 @@ class vDatetime: ical[11:13], # minute ical[13:15], # second ))) - if not ical[15:]: + if timezone: + return datetime(*timetuple, tzinfo=timezone) + elif not ical[15:]: return datetime(*timetuple) elif ical[15:16] == 'Z': timetuple += [0, UTC]