# HG changeset patch # User Paul Boddie # Date 1268603628 -3600 # Node ID 59caeb446995a4cf2e7a3ff972db492957932252 # Parent 3b719c63fd172de896991b3c308366ea0efe22ad Removed time zone abbreviations and improved UTC offset parsing. Added UTC offset calculation for Olson identifier-derived time zones; unfortunately, pytz version 2007k seems to return incorrect offsets for "Europe/Helsinki" (with a datetime of '2010-03-14 22:52:26.311507', it returns 6000 seconds, not 7200 seconds as dateutil is able to). diff -r 3b719c63fd17 -r 59caeb446995 EventAggregatorSupport.py --- a/EventAggregatorSupport.py Sun Mar 14 21:06:15 2010 +0100 +++ b/EventAggregatorSupport.py Sun Mar 14 22:53:48 2010 +0100 @@ -50,13 +50,17 @@ month_regexp_str = ur'(?P[0-9]{4})-(?P[0-9]{2})' date_regexp_str = ur'(?P[0-9]{4})-(?P[0-9]{2})-(?P[0-9]{2})' time_regexp_str = ur'(?P[0-2][0-9]):(?P[0-5][0-9])(?::(?P[0-6][0-9]))?' -timezone_regexp_str = ur'(?P[A-Z]{3,}|[a-zA-Z]+/[-_a-zA-Z]+|[-+][0-9]{1,4})' +timezone_olson_str = ur'(?P[a-zA-Z]+/[-_a-zA-Z]+)' +timezone_offset_str = ur'(?:UTC)?(?P[-+])(?P[0-9]{2})(?::?(?P[0-9]{2}))?' +timezone_regexp_str = ur'(?P' + timezone_olson_str + '|' + timezone_offset_str + ')' datetime_regexp_str = date_regexp_str + ur'(?:\s+' + time_regexp_str + ur'(?:\s+' + timezone_regexp_str + ur')?)?' month_regexp = re.compile(month_regexp_str, re.UNICODE) date_regexp = re.compile(date_regexp_str, re.UNICODE) time_regexp = re.compile(time_regexp_str, re.UNICODE) datetime_regexp = re.compile(datetime_regexp_str, re.UNICODE) +timezone_olson_regexp = re.compile(timezone_olson_str, re.UNICODE) +timezone_offset_regexp = re.compile(timezone_offset_str, re.UNICODE) verbatim_regexp = re.compile(ur'(?:' ur'<.*?)\)>>' @@ -1053,25 +1057,31 @@ zone = self.time_zone() - # Only attempt to return a UTC offset where an explicit offset has been - # set. + # Attempt to return a UTC offset where an explicit offset has been set. - if zone and zone[0] in "-+": - digits = zone[1:] - if zone[0] == "-": + match = timezone_offset_regexp.match(zone) + if match: + if match.group("sign") == "-": sign = -1 else: sign = 1 - if 1 <= len(digits) <= 2: - return int(digits) * sign, 0 - elif len(digits) == 3: - hours = int(digits[:1]) * sign - minutes = int(digits[1:]) * sign - return hours, minutes - elif len(digits) == 4: - hours = int(digits[:2]) * sign - minutes = int(digits[2:]) * sign + hours = int(match.group("hours")) * sign + minutes = int(match.group("minutes") or 0) * sign + return hours, minutes + + # Attempt to return an offset where an Olson identifier has been given. + + match = timezone_olson_regexp.match(zone) + if match: + if pytz is not None: + tz = pytz.timezone(match.group("olson")) + + # NOTE: Using internal attribute. + + seconds = tz._utcoffset.seconds + hours = seconds / 3600 + minutes = (seconds - hours * 3600) / 60 return hours, minutes return None @@ -1147,9 +1157,9 @@ if m: groups = list(m.groups()) - # Convert all but the zone to integer or None. + # Convert date and time data to integer or None. - return DateTime(map(int_or_none, groups[:-1]) + groups[-1:]) + return DateTime(map(int_or_none, groups[:6]) + [m.group("zone")]) else: return None