# HG changeset patch # User Paul Boddie # Date 1438121939 -7200 # Node ID 3e15d39530663c418346bca4ab200564aea05457 # Parent 1d28f68285a3b832f7d0aca533c29f8935889b97 Introduced a dedicated function for getting time zones/regimes from datetimes. Changed the get_datetime_item and get_datetime_attributes functions to provide time zone attributes using the datetime primarily, falling back on any provided zone/regime information only if necessary. Added fallback time zones/regimes when getting period start and end item details. diff -r 1d28f68285a3 -r 3e15d3953066 imiptools/data.py --- a/imiptools/data.py Tue Jul 28 19:27:27 2015 +0200 +++ b/imiptools/data.py Wed Jul 29 00:18:59 2015 +0200 @@ -22,9 +22,9 @@ from bisect import bisect_left from datetime import date, datetime, timedelta from email.mime.text import MIMEText -from imiptools.dates import format_datetime, get_datetime, get_duration, \ - get_freebusy_period, get_period, get_tzid, \ - to_timezone, to_utc_datetime +from imiptools.dates import format_datetime, get_datetime, get_datetime_tzid, \ + get_duration, get_freebusy_period, get_period, \ + get_tzid, to_timezone, to_utc_datetime from imiptools.period import Period, RecurringPeriod, period_overlaps from vCalendar import iterwrite, parse, ParseError, to_dict, to_node from vRecurrence import get_parameters, get_rule @@ -367,8 +367,9 @@ else: value, attr = t dt = get_datetime(value, attr) - if dt.tzname() == "UTC": - attr["TZID"] = "UTC" + tzid = get_datetime_tzid(dt) + if tzid: + attr["TZID"] = tzid return dt, attr # Conversion functions. diff -r 1d28f68285a3 -r 3e15d3953066 imiptools/dates.py --- a/imiptools/dates.py Tue Jul 28 19:27:27 2015 +0200 +++ b/imiptools/dates.py Wed Jul 29 00:18:59 2015 +0200 @@ -260,6 +260,19 @@ else: return dt + timedelta(1) +def get_datetime_tzid(dt): + + "Return the time zone identifier from 'dt' or None if unknown." + + if not isinstance(dt, datetime): + return None + elif dt.tzname() == "UTC": + return "UTC" + elif dt.tzinfo and hasattr(dt.tzinfo, "zone"): + return dt.tzinfo.zone + else: + return None + def to_date(dt): "Return the date of 'dt'." @@ -295,15 +308,15 @@ else: return dt -def to_timezone(dt, name): +def to_timezone(dt, tzid): """ Return a datetime corresponding to 'dt' in the time regime having the given - 'name'. + 'tzid'. """ try: - tz = name and timezone(name) or None + tz = tzid and timezone(tzid) or None except UnknownTimeZoneError: tz = None return to_tz(dt, tz) @@ -328,6 +341,9 @@ (start, end) tuple containing datetimes in the UTC time zone, where dates are converted to points in time so that each day has a specific start and end point defined in UTC. + + Here, 'tzid' is used to "project" dates into a time zone of interest before + then being converted into UTC start and end datetimes. """ start = to_utc_datetime(start, tzid) @@ -362,14 +378,16 @@ def get_datetime_attributes(dt, tzid=None): - "Return attributes for 'dt' and 'tzid'." + """ + Return attributes for the 'dt' date or datetime object with 'tzid' + indicating the time zone if not otherwise defined. + """ if isinstance(dt, datetime): attr = {"VALUE" : "DATE-TIME"} + tzid = get_datetime_tzid(dt) or tzid if tzid: attr["TZID"] = tzid - elif dt.tzname() == "UTC": - attr["TZID"] = "UTC" return attr else: return {"VALUE" : "DATE"} @@ -380,12 +398,13 @@ """ Return an iCalendar-compatible string and attributes for 'dt' using any - specified 'tzid' to assert a particular time zone. + specified 'tzid' to assert a particular time zone if not otherwise defined. """ if not dt: return None, None - dt = to_timezone(dt, tzid) + if not get_datetime_tzid(dt): + dt = to_timezone(dt, tzid) value = format_datetime(dt) attr = get_datetime_attributes(dt, tzid) return value, attr diff -r 1d28f68285a3 -r 3e15d3953066 imiptools/period.py --- a/imiptools/period.py Tue Jul 28 19:27:27 2015 +0200 +++ b/imiptools/period.py Wed Jul 29 00:18:59 2015 +0200 @@ -83,10 +83,10 @@ return self.tzid def get_start_item(self): - return self.start, get_datetime_attributes(self.start) + return self.start, get_datetime_attributes(self.start, self.get_tzid()) def get_end_item(self): - return self.end, get_datetime_attributes(self.end) + return self.end, get_datetime_attributes(self.end, self.get_tzid()) def get_start_point(self): return to_utc_datetime(self.get_start(), self.get_tzid())