# HG changeset patch # User Paul Boddie # Date 1269821145 -7200 # Node ID 962e330c8c1003e1fd96c08a686a951f4a13ab32 # Parent eee0f0ee7c2378b5ab7606606340739ac8cb0f1d Introduced a default UTC conversion for Olson-based local times, choosing the time in the zone preceding any zone change in a regime. Added release notes. diff -r eee0f0ee7c23 -r 962e330c8c10 EventAggregatorSupport.py --- a/EventAggregatorSupport.py Mon Mar 22 23:56:39 2010 +0100 +++ b/EventAggregatorSupport.py Mon Mar 29 02:05:45 2010 +0200 @@ -1033,6 +1033,8 @@ date = self.as_date() # Add the minutes and hours. + # NOTE: This makes various assumptions and probably would not work + # NOTE: for general arithmetic. minute += minutes if minute < 0: @@ -1083,6 +1085,17 @@ minutes = int(match.group("minutes") or 0) * sign return hours, minutes + # Attempt to handle Olson time zone identifiers. + + dt = self.as_olson_datetime() + if dt: + seconds = dt.utcoffset().seconds + hours = seconds / 3600 + minutes = (seconds % 3600) / 60 + return hours, minutes + + # Otherwise return None. + return None def olson_identifier(self): @@ -1101,18 +1114,61 @@ else: return None + def _as_olson_datetime(self, hours=None): + + """ + Return a Python datetime object for this datetime interpreted using any + Olson time zone identifier and the given 'hours' offset, raising one of + the pytz exceptions in case of ambiguity. + """ + + olson = self.olson_identifier() + if olson and pytz: + tz = pytz.timezone(olson) + data = self.padded().as_tuple()[:6] + dt = datetime.datetime(*data) + + # With an hours offset, find a time probably in a previously + # applicable time zone. + + if hours is not None: + td = datetime.timedelta(0, hours * 3600) + dt += td + + ldt = tz.localize(dt, None) + + # With an hours offset, adjust the time to define it within the + # previously applicable time zone but at the presumably intended + # position. + + if hours is not None: + ldt -= td + + return ldt + else: + return None + + def as_olson_datetime(self): + + """ + Return a Python datetime object for this datetime interpreted using any + Olson time zone identifier, choosing the time from the zone before the + period of ambiguity. + """ + + try: + return self._as_olson_datetime() + except (pytz.UnknownTimeZoneError, pytz.AmbiguousTimeError): + return self._as_olson_datetime(-1) + def ambiguous(self): "Return whether the time is local and ambiguous." - olson = self.olson_identifier() - if olson and pytz: - try: - tz = pytz.timezone(olson) - data = self.padded().as_tuple()[:6] - dt = tz.localize(datetime.datetime(*data), None) - except (pytz.UnknownTimeZoneError, pytz.AmbiguousTimeError): - return 1 + try: + self._as_olson_datetime() + except (pytz.UnknownTimeZoneError, pytz.AmbiguousTimeError): + return 1 return 0 diff -r eee0f0ee7c23 -r 962e330c8c10 README.txt --- a/README.txt Mon Mar 22 23:56:39 2010 +0100 +++ b/README.txt Mon Mar 29 02:05:45 2010 +0200 @@ -26,6 +26,13 @@ Important Notices ----------------- +In release 0.6, support for event times has been introduced. Due to the +complicated nature of times, time zones, time regimes, and so on, the +behaviour of the software may change in future versions to support common +use-cases in a more convenient fashion. Please be aware that implicitly chosen +or generated time or time zone information may change for events, particularly +those whose times are ambiguous or ill-defined. + In release 0.5, the "download this calendar" and "subscribe to this calendar" links have been fixed to return only events within the specified period and to work with day- and month-relative calendars. Users who have bookmarks in their @@ -213,7 +220,8 @@ replace the link information provided by the RSS and iCalendar summaries. * Fixed the production of the summaries when pages with no available edit log information are to be included. - * Added support for event times and time zone/regime information. + * Added support for event times and time zone/regime information. This is + subject to revision. New in EventAggregator 0.5 (Changes since EventAggregator 0.4) --------------------------------------------------------------