Log message for revision 81039: * Move all timezone usage to use pytz * Add support to timezone aware datetime conversion * Correct capitalization of Brazil/DeNoronha All previous timezone names are tested against the new pytz based timezones. This test shows that the following zones changed when pytz support was added (i.e. not in this commit): t1 = time.mktime(datetime(2002, 1, 1).timetuple()) t2 = time.mktime(datetime(2002, 7, 1).timetuple()) expected_failures = [ # zone.info(t1) newzone.info(t1) zone.info(t2) newzone.info(t2) 'Jamaica', # (-18000, 0, 'EST') (-18000, 0, 'EST') (-14400, 1, 'EDT') (-18000, 0, 'EST') 'Turkey', # (10800, 0, 'EET') (7200, 0, 'EET') (14400, 1, 'EET DST') (10800, 1, 'EEST') 'Mexico/BajaSur', # (-25200, 0, 'MST') (-25200, 0, 'MST') (-25200, 0, 'MST') (-21600, 1, 'MDT') 'Mexico/General', # (-21600, 0, 'CST') (-21600, 0, 'CST') (-21600, 0, 'CST') (-18000, 1, 'CDT') 'Canada/Yukon', # (-32400, 0, 'YST') (-28800, 0, 'PST') (-28800, 1, 'YDT') (-25200, 1, 'PDT') 'Brazil/West', # (-10800, 1, 'WDT') (-14400, 0, 'AMT') (-14400, 0, 'WST') (-14400, 0, 'AMT') 'Brazil/Acre', # (-14400, 1, 'ADT') (-18000, 0, 'ACT') (-18000, 0, 'AST') (-18000, 0, 'ACT') ] The most likely explanation for this is that the old database was out of date.
Changed: U Zope/trunk/lib/python/DateTime/DateTime.py U Zope/trunk/lib/python/DateTime/DateTime.txt U Zope/trunk/lib/python/DateTime/DateTimeZone.py U Zope/trunk/lib/python/DateTime/pytz.txt U Zope/trunk/lib/python/DateTime/pytz_support.py A Zope/trunk/lib/python/DateTime/tests/legacy.py U Zope/trunk/lib/python/DateTime/tests/testDateTime.py -=- Modified: Zope/trunk/lib/python/DateTime/DateTime.py =================================================================== --- Zope/trunk/lib/python/DateTime/DateTime.py 2007-10-24 14:34:17 UTC (rev 81038) +++ Zope/trunk/lib/python/DateTime/DateTime.py 2007-10-24 15:19:13 UTC (rev 81039) @@ -22,7 +22,8 @@ from interfaces import IDateTime from interfaces import DateTimeError, SyntaxError, DateError, TimeError from zope.interface import implements -from pytz_support import PytzCache +from pytz_support import PytzCache +_cache = PytzCache default_datefmt = None @@ -108,206 +109,6 @@ ''', re.VERBOSE).match -class _timezone: - def __init__(self,data): - self.name,self.timect,self.typect, \ - self.ttrans,self.tindex,self.tinfo,self.az=data - - def default_index(self): - if self.timect == 0: return 0 - for i in range(self.typect): - if self.tinfo[i][1] == 0: return i - return 0 - - def index(self,t=None): - t=t or time() - if self.timect==0: idx=(0, 0, 0) - elif t < self.ttrans[0]: - i=self.default_index() - idx=(i, ord(self.tindex[0]),i) - elif t >= self.ttrans[-1]: - if self.timect > 1: - idx=(ord(self.tindex[-1]),ord(self.tindex[-1]), - ord(self.tindex[-2])) - else: - idx=(ord(self.tindex[-1]),ord(self.tindex[-1]), - self.default_index()) - else: - for i in range(self.timect-1): - if t < self.ttrans[i+1]: - if i==0: idx=(ord(self.tindex[0]),ord(self.tindex[1]), - self.default_index()) - else: idx=(ord(self.tindex[i]),ord(self.tindex[i+1]), - ord(self.tindex[i-1])) - break - return idx - - def info(self,t=None): - idx=self.index(t)[0] - zs =self.az[self.tinfo[idx][2]:] - return self.tinfo[idx][0],self.tinfo[idx][1],zs[:zs.find('\000')] - - -class _cache: - - _zlst=['Brazil/Acre','Brazil/East', #'Brazil/DeNoronha', - 'Brazil/West','Canada/Atlantic','Canada/Central', - 'Canada/Eastern','Canada/East-Saskatchewan', - 'Canada/Mountain','Canada/Newfoundland', - 'Canada/Pacific','Canada/Yukon', - 'Chile/Continental','Chile/EasterIsland','CST','Cuba', - 'Egypt','EST','GB-Eire','Greenwich','Hongkong','Iceland', - 'Iran','Israel','Jamaica','Japan','Mexico/BajaNorte', - 'Mexico/BajaSur','Mexico/General','MST','Poland','PST', - 'Singapore','Turkey','Universal','US/Alaska','US/Aleutian', - 'US/Arizona','US/Central','US/Eastern','US/East-Indiana', - 'US/Hawaii','US/Indiana-Starke','US/Michigan', - 'US/Mountain','US/Pacific','US/Samoa','UTC','UCT','GMT', - - 'GMT+0100','GMT+0200','GMT+0300','GMT+0400','GMT+0500', - 'GMT+0600','GMT+0700','GMT+0800','GMT+0900','GMT+1000', - 'GMT+1100','GMT+1200','GMT+1300','GMT-0100','GMT-0200', - 'GMT-0300','GMT-0400','GMT-0500','GMT-0600','GMT-0700', - 'GMT-0800','GMT-0900','GMT-1000','GMT-1100','GMT-1200', - 'GMT+1', - - 'GMT+0130', 'GMT+0230', 'GMT+0330', 'GMT+0430', 'GMT+0530', - 'GMT+0630', 'GMT+0730', 'GMT+0830', 'GMT+0930', 'GMT+1030', - 'GMT+1130', 'GMT+1230', - - 'GMT-0130', 'GMT-0230', 'GMT-0330', 'GMT-0430', 'GMT-0530', - 'GMT-0630', 'GMT-0730', 'GMT-0830', 'GMT-0930', 'GMT-1030', - 'GMT-1130', 'GMT-1230', - - 'UT','BST','MEST','SST','FST','WADT','EADT','NZDT', - 'WET','WAT','AT','AST','NT','IDLW','CET','MET', - 'MEWT','SWT','FWT','EET','EEST','BT','ZP4','ZP5','ZP6', - 'WAST','CCT','JST','EAST','GST','NZT','NZST','IDLE'] - - _zmap={'aest':'GMT+10', 'aedt':'GMT+11', - 'aus eastern standard time':'GMT+10', - 'sydney standard time':'GMT+10', - 'tasmania standard time':'GMT+10', - 'e. australia standard time':'GMT+10', - 'aus central standard time':'GMT+0930', - 'cen. australia standard time':'GMT+0930', - 'w. australia standard time':'GMT+8', - - 'brazil/acre':'Brazil/Acre', - #'brazil/denoronha':'Brazil/Denoronha', - 'brazil/east':'Brazil/East','brazil/west':'Brazil/West', - 'canada/atlantic':'Canada/Atlantic', - 'canada/central':'Canada/Central', - 'canada/eastern':'Canada/Eastern', - 'canada/east-saskatchewan':'Canada/East-Saskatchewan', - 'canada/mountain':'Canada/Mountain', - 'canada/newfoundland':'Canada/Newfoundland', - 'canada/pacific':'Canada/Pacific','canada/yukon':'Canada/Yukon', - 'central europe standard time':'GMT+1', - 'chile/continental':'Chile/Continental', - 'chile/easterisland':'Chile/EasterIsland', - 'cst':'US/Central','cuba':'Cuba','est':'US/Eastern','egypt':'Egypt', - 'eastern standard time':'US/Eastern', - 'us eastern standard time':'US/Eastern', - 'central standard time':'US/Central', - 'mountain standard time':'US/Mountain', - 'pacific standard time':'US/Pacific', - 'gb-eire':'GB-Eire','gmt':'GMT', - - 'gmt+0000':'GMT+0', 'gmt+0':'GMT+0', - - 'gmt+0100':'GMT+1', 'gmt+0200':'GMT+2', 'gmt+0300':'GMT+3', - 'gmt+0400':'GMT+4', 'gmt+0500':'GMT+5', 'gmt+0600':'GMT+6', - 'gmt+0700':'GMT+7', 'gmt+0800':'GMT+8', 'gmt+0900':'GMT+9', - 'gmt+1000':'GMT+10','gmt+1100':'GMT+11','gmt+1200':'GMT+12', - 'gmt+1300':'GMT+13', - 'gmt-0100':'GMT-1', 'gmt-0200':'GMT-2', 'gmt-0300':'GMT-3', - 'gmt-0400':'GMT-4', 'gmt-0500':'GMT-5', 'gmt-0600':'GMT-6', - 'gmt-0700':'GMT-7', 'gmt-0800':'GMT-8', 'gmt-0900':'GMT-9', - 'gmt-1000':'GMT-10','gmt-1100':'GMT-11','gmt-1200':'GMT-12', - - 'gmt+1': 'GMT+1', 'gmt+2': 'GMT+2', 'gmt+3': 'GMT+3', - 'gmt+4': 'GMT+4', 'gmt+5': 'GMT+5', 'gmt+6': 'GMT+6', - 'gmt+7': 'GMT+7', 'gmt+8': 'GMT+8', 'gmt+9': 'GMT+9', - 'gmt+10':'GMT+10','gmt+11':'GMT+11','gmt+12':'GMT+12', - 'gmt+13':'GMT+13', - 'gmt-1': 'GMT-1', 'gmt-2': 'GMT-2', 'gmt-3': 'GMT-3', - 'gmt-4': 'GMT-4', 'gmt-5': 'GMT-5', 'gmt-6': 'GMT-6', - 'gmt-7': 'GMT-7', 'gmt-8': 'GMT-8', 'gmt-9': 'GMT-9', - 'gmt-10':'GMT-10','gmt-11':'GMT-11','gmt-12':'GMT-12', - - 'gmt+130':'GMT+0130', 'gmt+0130':'GMT+0130', - 'gmt+230':'GMT+0230', 'gmt+0230':'GMT+0230', - 'gmt+330':'GMT+0330', 'gmt+0330':'GMT+0330', - 'gmt+430':'GMT+0430', 'gmt+0430':'GMT+0430', - 'gmt+530':'GMT+0530', 'gmt+0530':'GMT+0530', - 'gmt+630':'GMT+0630', 'gmt+0630':'GMT+0630', - 'gmt+730':'GMT+0730', 'gmt+0730':'GMT+0730', - 'gmt+830':'GMT+0830', 'gmt+0830':'GMT+0830', - 'gmt+930':'GMT+0930', 'gmt+0930':'GMT+0930', - 'gmt+1030':'GMT+1030', - 'gmt+1130':'GMT+1130', - 'gmt+1230':'GMT+1230', - - 'gmt-130':'GMT-0130', 'gmt-0130':'GMT-0130', - 'gmt-230':'GMT-0230', 'gmt-0230':'GMT-0230', - 'gmt-330':'GMT-0330', 'gmt-0330':'GMT-0330', - 'gmt-430':'GMT-0430', 'gmt-0430':'GMT-0430', - 'gmt-530':'GMT-0530', 'gmt-0530':'GMT-0530', - 'gmt-630':'GMT-0630', 'gmt-0630':'GMT-0630', - 'gmt-730':'GMT-0730', 'gmt-0730':'GMT-0730', - 'gmt-830':'GMT-0830', 'gmt-0830':'GMT-0830', - 'gmt-930':'GMT-0930', 'gmt-0930':'GMT-0930', - 'gmt-1030':'GMT-1030', - 'gmt-1130':'GMT-1130', - 'gmt-1230':'GMT-1230', - - 'greenwich':'Greenwich','hongkong':'Hongkong', - 'iceland':'Iceland','iran':'Iran','israel':'Israel', - 'jamaica':'Jamaica','japan':'Japan', - 'mexico/bajanorte':'Mexico/BajaNorte', - 'mexico/bajasur':'Mexico/BajaSur','mexico/general':'Mexico/General', - 'mst':'US/Mountain','pst':'US/Pacific','poland':'Poland', - 'singapore':'Singapore','turkey':'Turkey','universal':'Universal', - 'utc':'Universal','uct':'Universal','us/alaska':'US/Alaska', - 'us/aleutian':'US/Aleutian','us/arizona':'US/Arizona', - 'us/central':'US/Central','us/eastern':'US/Eastern', - 'us/east-indiana':'US/East-Indiana','us/hawaii':'US/Hawaii', - 'us/indiana-starke':'US/Indiana-Starke','us/michigan':'US/Michigan', - 'us/mountain':'US/Mountain','us/pacific':'US/Pacific', - 'us/samoa':'US/Samoa', - - 'ut':'Universal', - 'bst':'GMT+1', 'mest':'GMT+2', 'sst':'GMT+2', - 'fst':'GMT+2', 'wadt':'GMT+8', 'eadt':'GMT+11', 'nzdt':'GMT+13', - 'wet':'GMT', 'wat':'GMT-1', 'at':'GMT-2', 'ast':'GMT-4', - 'nt':'GMT-11', 'idlw':'GMT-12', 'cet':'GMT+1', 'cest':'GMT+2', - 'met':'GMT+1', - 'mewt':'GMT+1', 'swt':'GMT+1', 'fwt':'GMT+1', 'eet':'GMT+2', - 'eest':'GMT+3', - 'bt':'GMT+3', 'zp4':'GMT+4', 'zp5':'GMT+5', 'zp6':'GMT+6', - 'wast':'GMT+7', 'cct':'GMT+8', 'jst':'GMT+9', 'east':'GMT+10', - 'gst':'GMT+10', 'nzt':'GMT+12', 'nzst':'GMT+12', 'idle':'GMT+12', - 'ret':'GMT+4', 'ist': 'GMT+0530' - } - - def __init__(self): - self._db=DateTimeZone._data - self._d,self._zidx={},self._zmap.keys() - - def __getitem__(self,k): - try: - n=self._zmap[k.lower()] - except KeyError: - if numericTimeZoneMatch(k) == None: - raise DateTimeError,'Unrecognized timezone: %s' % k - return k - try: return self._d[n] - except KeyError: - z=self._d[n]=_timezone(self._db[n]) - return z - - def _findLocalTimeZoneName(isDST): if not daylight: # Daylight savings does not occur in this time zone. @@ -665,10 +466,10 @@ - New in 2.11: The DateTime function may now be invoked with a single argument - that is a datetime.datetime instance. Timezone naive DateTimes may - be converted back to timezone naive datetime.datetime objects with - asdatetime(). All DateTime instances may be converted to a timezone - naive datetime.datetime in UTC with utcdatetime(). + that is a datetime.datetime instance. DateTimes may be converted + back to datetime.datetime objects with asdatetime(). + DateTime instances may be converted to a timezone naive + datetime.datetime in UTC with utcdatetime(). - If the function is invoked with two numeric arguments, then the first is taken to be an integer year and the second @@ -734,7 +535,7 @@ will raise a DateError, while invalid time or timezone components will raise a DateTimeError. - The module function Timezones() will return a list of the + The module function Timezones() will return a list of the (common) timezones recognized by the DateTime module. Recognition of timezone names is case-insensitive. """ @@ -790,17 +591,26 @@ sc=sc+ms elif isinstance(arg, datetime): - yr,mo,dy,hr,mn,sc,tz,tznaive=self._parse_iso8601_preserving_tznaive(arg.isoformat()) - self._timezone_naive = tznaive + yr,mo,dy,hr,mn,sc,numerictz,tznaive=self._parse_iso8601_preserving_tznaive(arg.isoformat()) + if arg.tzinfo is None: + self._timezone_naive = True + tz = None + else: + self._timezone_naive = False + tz = arg.tzinfo.zone ms = sc - math.floor(sc) x = _calcDependentSecond2(yr,mo,dy,hr,mn,sc) if tz: - try: tz=self._tzinfo._zmap[tz.lower()] - except KeyError: - if numericTimeZoneMatch(tz) is None: + try: + zone = self._tzinfo[tz] + except DateTimeError: + try: + zone = self._tzinfo[numerictz] + except DateTimeError: raise DateTimeError, \ 'Unknown time zone in date: %s' % arg + tz = zone.tzinfo.zone else: tz = self._calcTimezoneName(x, ms) s,d,t,microsecs = _calcIndependentSecondEtc(tz, x, ms) @@ -988,7 +798,7 @@ # For backward compatibility only: _isDST = localtime(time())[8] _localzone = _isDST and _localzone1 or _localzone0 - _tzinfo = PytzCache(_cache()) + _tzinfo = PytzCache() def localZone(self, ltm=None): '''Returns the time zone on the given date. The time zone @@ -1799,16 +1609,15 @@ """Return a standard libary datetime.datetime """ tznaive = self.timezoneNaive() - if tznaive is True: - # we were either converted from an ISO8601 timezone naive string or - # a timezone naive datetime - second = int(self._second) - microsec = self.micros() % 1000000 - dt = datetime(self._year, self._month, self._day, self._hour, - self._minute, second, microsec) - return dt + if tznaive: + tzinfo = None else: - raise NotImplementedError('conversion of datetime aware DateTime to datetime unsupported') + tzinfo = self._tzinfo[self._tz].tzinfo + second = int(self._second) + microsec = self.micros() % 1000000 + dt = datetime(self._year, self._month, self._day, self._hour, + self._minute, second, microsec, tzinfo) + return dt def utcdatetime(self): """Convert the time to UTC then return a timezone naive datetime object""" @@ -2041,5 +1850,5 @@ # Module methods def Timezones(): """Return the list of recognized timezone names""" - return list(PytzCache(_cache())._zlst) + return PytzCache._zlst Modified: Zope/trunk/lib/python/DateTime/DateTime.txt =================================================================== --- Zope/trunk/lib/python/DateTime/DateTime.txt 2007-10-24 14:34:17 UTC (rev 81038) +++ Zope/trunk/lib/python/DateTime/DateTime.txt 2007-10-24 15:19:13 UTC (rev 81039) @@ -12,7 +12,7 @@ >>> from DateTime import Timezones >>> Timezones() # doctest: +ELLIPSIS - [...'Brazil/Acre', 'Brazil/DeNoronha', ..., 'NZST', 'IDLE'] + [...'Brazil/Acre'... 'Brazil/DeNoronha'... 'IDLE'... 'NZST'...] Class DateTime Modified: Zope/trunk/lib/python/DateTime/DateTimeZone.py =================================================================== --- Zope/trunk/lib/python/DateTime/DateTimeZone.py 2007-10-24 14:34:17 UTC (rev 81038) +++ Zope/trunk/lib/python/DateTime/DateTimeZone.py 2007-10-24 15:19:13 UTC (rev 81039) @@ -10,6 +10,9 @@ # FOR A PARTICULAR PURPOSE # ############################################################################## + +# This data is used only for testing legacy compatibility with pytz + _data={ Modified: Zope/trunk/lib/python/DateTime/pytz.txt =================================================================== --- Zope/trunk/lib/python/DateTime/pytz.txt 2007-10-24 14:34:17 UTC (rev 81038) +++ Zope/trunk/lib/python/DateTime/pytz.txt 2007-10-24 15:19:13 UTC (rev 81039) @@ -126,13 +126,13 @@ The _zlst attribute is a list of supported time zone names. >>> cache._zlst #doctest: +ELLIPSIS - ['Africa/Abidjan', 'Africa/Accra', ... 'NZT', 'NZST', 'IDLE'] + ['Africa/Abidjan'... 'Africa/Accra'... 'IDLE'... 'NZST'... 'NZT'...] The _zidx attribute is a list of lower-case and possibly abbreviated time zone names that can be mapped to offical zone names. >>> cache._zidx #doctest: +ELLIPSIS - ['australia/yancowinna', 'gmt+0500', ... 'europe/isle_of_man'] + ['australia/yancowinna'... 'gmt+0500'... 'europe/isle_of_man'...] Note that there are more items in _zidx than in _zlst since there are multiple names for some time zones. Modified: Zope/trunk/lib/python/DateTime/pytz_support.py =================================================================== --- Zope/trunk/lib/python/DateTime/pytz_support.py 2007-10-24 14:34:17 UTC (rev 81038) +++ Zope/trunk/lib/python/DateTime/pytz_support.py 2007-10-24 15:19:13 UTC (rev 81039) @@ -16,9 +16,192 @@ import pytz import pytz.reference +from pytz.tzinfo import StaticTzInfo, memorized_timedelta from datetime import datetime, timedelta import re +from interfaces import DateTimeError +EPOCH = datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc) + +_numeric_timezone_data = { +'GMT': ('GMT', 0, 1, [], '', [(0, 0, 0)], 'GMT\000'), +'GMT+0': ('GMT+0', 0, 1, [], '', [(0, 0, 0)], 'GMT+0000\000'), +'GMT+1': ('GMT+1', 0, 1, [], '', [(3600, 0, 0)], 'GMT+0100\000'), +'GMT+2': ('GMT+2', 0, 1, [], '', [(7200, 0, 0)], 'GMT+0200\000'), +'GMT+3': ('GMT+3', 0, 1, [], '', [(10800, 0, 0)], 'GMT+0300\000'), +'GMT+4': ('GMT+4', 0, 1, [], '', [(14400, 0, 0)], 'GMT+0400\000'), +'GMT+5': ('GMT+5', 0, 1, [], '', [(18000, 0, 0)], 'GMT+0500\000'), +'GMT+6': ('GMT+6', 0, 1, [], '', [(21600, 0, 0)], 'GMT+0600\000'), +'GMT+7': ('GMT+7', 0, 1, [], '', [(25200, 0, 0)], 'GMT+0700\000'), +'GMT+8': ('GMT+8', 0, 1, [], '', [(28800, 0, 0)], 'GMT+0800\000'), +'GMT+9': ('GMT+9', 0, 1, [], '', [(32400, 0, 0)], 'GMT+0900\000'), +'GMT+10': ('GMT+10', 0, 1, [], '', [(36000, 0, 0)], 'GMT+1000\000'), +'GMT+11': ('GMT+11', 0, 1, [], '', [(39600, 0, 0)], 'GMT+1100\000'), +'GMT+12': ('GMT+12', 0, 1, [], '', [(43200, 0, 0)], 'GMT+1200\000'), +'GMT+13': ('GMT+13', 0, 1, [], '', [(46800, 0, 0)], 'GMT+1300\000'), + +'GMT-1': ('GMT-1', 0, 1, [], '', [(-3600, 0, 0)], 'GMT-0100\000'), +'GMT-2': ('GMT-2', 0, 1, [], '', [(-7200, 0, 0)], 'GMT-0200\000'), +'GMT-3': ('GMT-3', 0, 1, [], '', [(-10800, 0, 0)], 'GMT-0300\000'), +'GMT-4': ('GMT-4', 0, 1, [], '', [(-14400, 0, 0)], 'GMT-0400\000'), +'GMT-5': ('GMT-5', 0, 1, [], '', [(-18000, 0, 0)], 'GMT-0500\000'), +'GMT-6': ('GMT-6', 0, 1, [], '', [(-21600, 0, 0)], 'GMT-0600\000'), +'GMT-7': ('GMT-7', 0, 1, [], '', [(-25200, 0, 0)], 'GMT-0700\000'), +'GMT-8': ('GMT-8', 0, 1, [], '', [(-28800, 0, 0)], 'GMT-0800\000'), +'GMT-9': ('GMT-9', 0, 1, [], '', [(-32400, 0, 0)], 'GMT-0900\000'), +'GMT-10': ('GMT-10', 0, 1, [], '', [(-36000, 0, 0)], 'GMT-1000\000'), +'GMT-11': ('GMT-11', 0, 1, [], '', [(-39600, 0, 0)], 'GMT-1100\000'), +'GMT-12': ('GMT-12', 0, 1, [], '', [(-43200, 0, 0)], 'GMT-1200\000'), + +'GMT+0130': ('GMT+0130', 0, 1, [], '', [(5400, 0, 0)], 'GMT+0130\000'), +'GMT+0230': ('GMT+0230', 0, 1, [], '', [(9000, 0, 0)], 'GMT+0230\000'), +'GMT+0330': ('GMT+0330', 0, 1, [], '', [(12600, 0, 0)], 'GMT+0330\000'), +'GMT+0430': ('GMT+0430', 0, 1, [], '', [(16200, 0, 0)], 'GMT+0430\000'), +'GMT+0530': ('GMT+0530', 0, 1, [], '', [(19800, 0, 0)], 'GMT+0530\000'), +'GMT+0630': ('GMT+0630', 0, 1, [], '', [(23400, 0, 0)], 'GMT+0630\000'), +'GMT+0730': ('GMT+0730', 0, 1, [], '', [(27000, 0, 0)], 'GMT+0730\000'), +'GMT+0830': ('GMT+0830', 0, 1, [], '', [(30600, 0, 0)], 'GMT+0830\000'), +'GMT+0930': ('GMT+0930', 0, 1, [], '', [(34200, 0, 0)], 'GMT+0930\000'), +'GMT+1030': ('GMT+1030', 0, 1, [], '', [(37800, 0, 0)], 'GMT+1030\000'), +'GMT+1130': ('GMT+1130', 0, 1, [], '', [(41400, 0, 0)], 'GMT+1130\000'), +'GMT+1230': ('GMT+1230', 0, 1, [], '', [(45000, 0, 0)], 'GMT+1230\000'), + +'GMT-0130': ('GMT-0130', 0, 1, [], '', [(-5400, 0, 0)], 'GMT-0130\000'), +'GMT-0230': ('GMT-0230', 0, 1, [], '', [(-9000, 0, 0)], 'GMT-0230\000'), +'GMT-0330': ('GMT-0330', 0, 1, [], '', [(-12600, 0, 0)], 'GMT-0330\000'), +'GMT-0430': ('GMT-0430', 0, 1, [], '', [(-16200, 0, 0)], 'GMT-0430\000'), +'GMT-0530': ('GMT-0530', 0, 1, [], '', [(-19800, 0, 0)], 'GMT-0530\000'), +'GMT-0630': ('GMT-0630', 0, 1, [], '', [(-23400, 0, 0)], 'GMT-0630\000'), +'GMT-0730': ('GMT-0730', 0, 1, [], '', [(-27000, 0, 0)], 'GMT-0730\000'), +'GMT-0830': ('GMT-0830', 0, 1, [], '', [(-30600, 0, 0)], 'GMT-0830\000'), +'GMT-0930': ('GMT-0930', 0, 1, [], '', [(-34200, 0, 0)], 'GMT-0930\000'), +'GMT-1030': ('GMT-1030', 0, 1, [], '', [(-37800, 0, 0)], 'GMT-1030\000'), +'GMT-1130': ('GMT-1130', 0, 1, [], '', [(-41400, 0, 0)], 'GMT-1130\000'), +'GMT-1230': ('GMT-1230', 0, 1, [], '', [(-45000, 0, 0)], 'GMT-1230\000'), + +} + +# These are the timezones not in pytz.common_timezones +_old_zlst = [ + +'AST', 'AT', 'BST', 'BT', 'CCT', +'CET', 'CST', 'Cuba', 'EADT', 'EAST', +'EEST', 'EET', 'EST', 'Egypt', 'FST', +'FWT', 'GB-Eire', 'GMT+0100', 'GMT+0130', 'GMT+0200', +'GMT+0230', 'GMT+0300', 'GMT+0330', 'GMT+0400', 'GMT+0430', +'GMT+0500', 'GMT+0530', 'GMT+0600', 'GMT+0630', 'GMT+0700', +'GMT+0730', 'GMT+0800', 'GMT+0830', 'GMT+0900', 'GMT+0930', +'GMT+1', 'GMT+1000', 'GMT+1030', 'GMT+1100', 'GMT+1130', +'GMT+1200', 'GMT+1230', 'GMT+1300', 'GMT-0100', 'GMT-0130', +'GMT-0200', 'GMT-0300', 'GMT-0400', 'GMT-0500', 'GMT-0600', +'GMT-0630', 'GMT-0700', 'GMT-0730', 'GMT-0800', 'GMT-0830', +'GMT-0900', 'GMT-0930', 'GMT-1000', 'GMT-1030', 'GMT-1100', +'GMT-1130', 'GMT-1200', 'GMT-1230', 'GST', 'Greenwich', +'Hongkong', 'IDLE', 'IDLW', 'Iceland', 'Iran', +'Israel', 'JST', 'Jamaica', 'Japan', 'MEST', +'MET', 'MEWT', 'MST', 'NT', 'NZDT', +'NZST', 'NZT', 'PST', 'Poland', 'SST', +'SWT', 'Singapore', 'Turkey', 'UCT', 'UT', +'Universal', 'WADT', 'WAST', 'WAT', 'WET', +'ZP4', 'ZP5', 'ZP6', + +] + +_old_zmap={ + +'aest':'GMT+10', 'aedt':'GMT+11', +'aus eastern standard time':'GMT+10', +'sydney standard time':'GMT+10', +'tasmania standard time':'GMT+10', +'e. australia standard time':'GMT+10', +'aus central standard time':'GMT+0930', +'cen. australia standard time':'GMT+0930', +'w. australia standard time':'GMT+8', + +'central europe standard time':'GMT+1', +'eastern standard time':'US/Eastern', +'us eastern standard time':'US/Eastern', +'central standard time':'US/Central', +'mountain standard time':'US/Mountain', +'pacific standard time':'US/Pacific', +'mst':'US/Mountain','pst':'US/Pacific', +'cst':'US/Central','est':'US/Eastern', + +'gmt+0000':'GMT+0', 'gmt+0':'GMT+0', + +'gmt+0100':'GMT+1', 'gmt+0200':'GMT+2', 'gmt+0300':'GMT+3', +'gmt+0400':'GMT+4', 'gmt+0500':'GMT+5', 'gmt+0600':'GMT+6', +'gmt+0700':'GMT+7', 'gmt+0800':'GMT+8', 'gmt+0900':'GMT+9', +'gmt+1000':'GMT+10','gmt+1100':'GMT+11','gmt+1200':'GMT+12', +'gmt+1300':'GMT+13', +'gmt-0100':'GMT-1', 'gmt-0200':'GMT-2', 'gmt-0300':'GMT-3', +'gmt-0400':'GMT-4', 'gmt-0500':'GMT-5', 'gmt-0600':'GMT-6', +'gmt-0700':'GMT-7', 'gmt-0800':'GMT-8', 'gmt-0900':'GMT-9', +'gmt-1000':'GMT-10','gmt-1100':'GMT-11','gmt-1200':'GMT-12', + +'gmt+1': 'GMT+1', 'gmt+2': 'GMT+2', 'gmt+3': 'GMT+3', +'gmt+4': 'GMT+4', 'gmt+5': 'GMT+5', 'gmt+6': 'GMT+6', +'gmt+7': 'GMT+7', 'gmt+8': 'GMT+8', 'gmt+9': 'GMT+9', +'gmt+10':'GMT+10','gmt+11':'GMT+11','gmt+12':'GMT+12', +'gmt+13':'GMT+13', +'gmt-1': 'GMT-1', 'gmt-2': 'GMT-2', 'gmt-3': 'GMT-3', +'gmt-4': 'GMT-4', 'gmt-5': 'GMT-5', 'gmt-6': 'GMT-6', +'gmt-7': 'GMT-7', 'gmt-8': 'GMT-8', 'gmt-9': 'GMT-9', +'gmt-10':'GMT-10','gmt-11':'GMT-11','gmt-12':'GMT-12', + +'gmt+130':'GMT+0130', 'gmt+0130':'GMT+0130', +'gmt+230':'GMT+0230', 'gmt+0230':'GMT+0230', +'gmt+330':'GMT+0330', 'gmt+0330':'GMT+0330', +'gmt+430':'GMT+0430', 'gmt+0430':'GMT+0430', +'gmt+530':'GMT+0530', 'gmt+0530':'GMT+0530', +'gmt+630':'GMT+0630', 'gmt+0630':'GMT+0630', +'gmt+730':'GMT+0730', 'gmt+0730':'GMT+0730', +'gmt+830':'GMT+0830', 'gmt+0830':'GMT+0830', +'gmt+930':'GMT+0930', 'gmt+0930':'GMT+0930', +'gmt+1030':'GMT+1030', +'gmt+1130':'GMT+1130', +'gmt+1230':'GMT+1230', + +'gmt-130':'GMT-0130', 'gmt-0130':'GMT-0130', +'gmt-230':'GMT-0230', 'gmt-0230':'GMT-0230', +'gmt-330':'GMT-0330', 'gmt-0330':'GMT-0330', +'gmt-430':'GMT-0430', 'gmt-0430':'GMT-0430', +'gmt-530':'GMT-0530', 'gmt-0530':'GMT-0530', +'gmt-630':'GMT-0630', 'gmt-0630':'GMT-0630', +'gmt-730':'GMT-0730', 'gmt-0730':'GMT-0730', +'gmt-830':'GMT-0830', 'gmt-0830':'GMT-0830', +'gmt-930':'GMT-0930', 'gmt-0930':'GMT-0930', +'gmt-1030':'GMT-1030', +'gmt-1130':'GMT-1130', +'gmt-1230':'GMT-1230', + +'ut':'Universal', +'bst':'GMT+1', 'mest':'GMT+2', 'sst':'GMT+2', +'fst':'GMT+2', 'wadt':'GMT+8', 'eadt':'GMT+11', 'nzdt':'GMT+13', +'wet':'GMT', 'wat':'GMT-1', 'at':'GMT-2', 'ast':'GMT-4', +'nt':'GMT-11', 'idlw':'GMT-12', 'cet':'GMT+1', 'cest':'GMT+2', +'met':'GMT+1', +'mewt':'GMT+1', 'swt':'GMT+1', 'fwt':'GMT+1', 'eet':'GMT+2', +'eest':'GMT+3', +'bt':'GMT+3', 'zp4':'GMT+4', 'zp5':'GMT+5', 'zp6':'GMT+6', +'wast':'GMT+7', 'cct':'GMT+8', 'jst':'GMT+9', 'east':'GMT+10', +'gst':'GMT+10', 'nzt':'GMT+12', 'nzst':'GMT+12', 'idle':'GMT+12', +'ret':'GMT+4', 'ist': 'GMT+0530' + +} + +def _static_timezone_factory(data): + zone = data[0] + cls = type(zone, (StaticTzInfo,), dict( + zone=zone, + _utcoffset=memorized_timedelta(data[5][0][0]), + _tzname=data[6][:-1] )) # strip the trailing null + return cls() + +_numeric_timezones = dict((key, _static_timezone_factory(data)) + for key, data in _numeric_timezone_data.items()) + + class Timezone: """ Timezone information returned by PytzCache.__getitem__ @@ -31,8 +214,8 @@ if t is None: dt = datetime.utcnow().replace(tzinfo=pytz.utc) else: - dt = datetime.utcfromtimestamp(t).replace(tzinfo=pytz.utc) - + dt = EPOCH + timedelta(0, t) # can't use utcfromtimestamp past 2038 + # need to normalize tzinfo for the datetime to deal with # daylight savings time. normalized_dt = self.tzinfo.normalize(dt.astimezone(self.tzinfo)) @@ -50,24 +233,20 @@ class PytzCache: """ - Wrapper for the DateTime._cache class that uses pytz for - timezone information where possible. + Reimplementation of the DateTime._cache class that uses for timezone info """ - def __init__(self, cache): - self.cache = cache - self._zlst = list(pytz.common_timezones) - for name in cache._zlst: - if name not in self._zlst: - self._zlst.append(name) - self._zmap = dict(cache._zmap) - self._zmap.update(dict([(name.lower(), name) - for name in pytz.common_timezones])) - self._zidx = self._zmap.keys() - + + _zlst = pytz.common_timezones + _old_zlst # used by DateTime.TimeZones + _zmap = dict((name.lower(), name) for name in pytz.all_timezones) + _zmap.update(_old_zmap) # These must take priority + _zidx = _zmap.keys() + def __getitem__(self, key): + name = self._zmap.get(key.lower(), key) # fallback to key try: - name = self._zmap[key.lower()] return Timezone(pytz.timezone(name)) - except (KeyError, pytz.UnknownTimeZoneError): - return self.cache[key] - + except pytz.UnknownTimeZoneError: + try: + return Timezone(_numeric_timezones[name]) + except KeyError: + raise DateTimeError,'Unrecognized timezone: %s' % key \ No newline at end of file Added: Zope/trunk/lib/python/DateTime/tests/legacy.py =================================================================== --- Zope/trunk/lib/python/DateTime/tests/legacy.py (rev 0) +++ Zope/trunk/lib/python/DateTime/tests/legacy.py 2007-10-24 15:19:13 UTC (rev 81039) @@ -0,0 +1,198 @@ +############################################################################## +# +# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## + +from DateTime.DateTimeZone import _data +from time import time + +class _timezone: + def __init__(self,data): + self.name,self.timect,self.typect, \ + self.ttrans,self.tindex,self.tinfo,self.az=data + + def default_index(self): + if self.timect == 0: return 0 + for i in range(self.typect): + if self.tinfo[i][1] == 0: return i + return 0 + + def index(self,t=None): + t=t or time() + if self.timect==0: idx=(0, 0, 0) + elif t < self.ttrans[0]: + i=self.default_index() + idx=(i, ord(self.tindex[0]),i) + elif t >= self.ttrans[-1]: + if self.timect > 1: + idx=(ord(self.tindex[-1]),ord(self.tindex[-1]), + ord(self.tindex[-2])) + else: + idx=(ord(self.tindex[-1]),ord(self.tindex[-1]), + self.default_index()) + else: + for i in range(self.timect-1): + if t < self.ttrans[i+1]: + if i==0: idx=(ord(self.tindex[0]),ord(self.tindex[1]), + self.default_index()) + else: idx=(ord(self.tindex[i]),ord(self.tindex[i+1]), + ord(self.tindex[i-1])) + break + return idx + + def info(self,t=None): + idx=self.index(t)[0] + zs =self.az[self.tinfo[idx][2]:] + return self.tinfo[idx][0],self.tinfo[idx][1],zs[:zs.find('\000')] + + +_zlst = ['Brazil/Acre','Brazil/DeNoronha','Brazil/East', + 'Brazil/West','Canada/Atlantic','Canada/Central', + 'Canada/Eastern','Canada/East-Saskatchewan', + 'Canada/Mountain','Canada/Newfoundland', + 'Canada/Pacific','Canada/Yukon', + 'Chile/Continental','Chile/EasterIsland','CST','Cuba', + 'Egypt','EST','GB-Eire','Greenwich','Hongkong','Iceland', + 'Iran','Israel','Jamaica','Japan','Mexico/BajaNorte', + 'Mexico/BajaSur','Mexico/General','MST','Poland','PST', + 'Singapore','Turkey','Universal','US/Alaska','US/Aleutian', + 'US/Arizona','US/Central','US/Eastern','US/East-Indiana', + 'US/Hawaii','US/Indiana-Starke','US/Michigan', + 'US/Mountain','US/Pacific','US/Samoa','UTC','UCT','GMT', + + 'GMT+0100','GMT+0200','GMT+0300','GMT+0400','GMT+0500', + 'GMT+0600','GMT+0700','GMT+0800','GMT+0900','GMT+1000', + 'GMT+1100','GMT+1200','GMT+1300','GMT-0100','GMT-0200', + 'GMT-0300','GMT-0400','GMT-0500','GMT-0600','GMT-0700', + 'GMT-0800','GMT-0900','GMT-1000','GMT-1100','GMT-1200', + 'GMT+1', + + 'GMT+0130', 'GMT+0230', 'GMT+0330', 'GMT+0430', 'GMT+0530', + 'GMT+0630', 'GMT+0730', 'GMT+0830', 'GMT+0930', 'GMT+1030', + 'GMT+1130', 'GMT+1230', + + 'GMT-0130', 'GMT-0230', 'GMT-0330', 'GMT-0430', 'GMT-0530', + 'GMT-0630', 'GMT-0730', 'GMT-0830', 'GMT-0930', 'GMT-1030', + 'GMT-1130', 'GMT-1230', + + 'UT','BST','MEST','SST','FST','WADT','EADT','NZDT', + 'WET','WAT','AT','AST','NT','IDLW','CET','MET', + 'MEWT','SWT','FWT','EET','EEST','BT','ZP4','ZP5','ZP6', + 'WAST','CCT','JST','EAST','GST','NZT','NZST','IDLE'] + +_zmap = {'aest':'GMT+1000', 'aedt':'GMT+1100', + 'aus eastern standard time':'GMT+1000', + 'sydney standard time':'GMT+1000', + 'tasmania standard time':'GMT+1000', + 'e. australia standard time':'GMT+1000', + 'aus central standard time':'GMT+0930', + 'cen. australia standard time':'GMT+0930', + 'w. australia standard time':'GMT+0800', + + 'brazil/acre':'Brazil/Acre', + 'brazil/denoronha':'Brazil/DeNoronha', + 'brazil/east':'Brazil/East','brazil/west':'Brazil/West', + 'canada/atlantic':'Canada/Atlantic', + 'canada/central':'Canada/Central', + 'canada/eastern':'Canada/Eastern', + 'canada/east-saskatchewan':'Canada/East-Saskatchewan', + 'canada/mountain':'Canada/Mountain', + 'canada/newfoundland':'Canada/Newfoundland', + 'canada/pacific':'Canada/Pacific','canada/yukon':'Canada/Yukon', + 'central europe standard time':'GMT+0100', + 'chile/continental':'Chile/Continental', + 'chile/easterisland':'Chile/EasterIsland', + 'cst':'US/Central','cuba':'Cuba','est':'US/Eastern','egypt':'Egypt', + 'eastern standard time':'US/Eastern', + 'us eastern standard time':'US/Eastern', + 'central standard time':'US/Central', + 'mountain standard time':'US/Mountain', + 'pacific standard time':'US/Pacific', + 'gb-eire':'GB-Eire','gmt':'GMT', + + 'gmt+0000':'GMT+0', 'gmt+0':'GMT+0', + + 'gmt+0100':'GMT+1', 'gmt+0200':'GMT+2', 'gmt+0300':'GMT+3', + 'gmt+0400':'GMT+4', 'gmt+0500':'GMT+5', 'gmt+0600':'GMT+6', + 'gmt+0700':'GMT+7', 'gmt+0800':'GMT+8', 'gmt+0900':'GMT+9', + 'gmt+1000':'GMT+10','gmt+1100':'GMT+11','gmt+1200':'GMT+12', + 'gmt+1300':'GMT+13', + 'gmt-0100':'GMT-1', 'gmt-0200':'GMT-2', 'gmt-0300':'GMT-3', + 'gmt-0400':'GMT-4', 'gmt-0500':'GMT-5', 'gmt-0600':'GMT-6', + 'gmt-0700':'GMT-7', 'gmt-0800':'GMT-8', 'gmt-0900':'GMT-9', + 'gmt-1000':'GMT-10','gmt-1100':'GMT-11','gmt-1200':'GMT-12', + + 'gmt+1': 'GMT+1', 'gmt+2': 'GMT+2', 'gmt+3': 'GMT+3', + 'gmt+4': 'GMT+4', 'gmt+5': 'GMT+5', 'gmt+6': 'GMT+6', + 'gmt+7': 'GMT+7', 'gmt+8': 'GMT+8', 'gmt+9': 'GMT+9', + 'gmt+10':'GMT+10','gmt+11':'GMT+11','gmt+12':'GMT+12', + 'gmt+13':'GMT+13', + 'gmt-1': 'GMT-1', 'gmt-2': 'GMT-2', 'gmt-3': 'GMT-3', + 'gmt-4': 'GMT-4', 'gmt-5': 'GMT-5', 'gmt-6': 'GMT-6', + 'gmt-7': 'GMT-7', 'gmt-8': 'GMT-8', 'gmt-9': 'GMT-9', + 'gmt-10':'GMT-10','gmt-11':'GMT-11','gmt-12':'GMT-12', + + 'gmt+130':'GMT+0130', 'gmt+0130':'GMT+0130', + 'gmt+230':'GMT+0230', 'gmt+0230':'GMT+0230', + 'gmt+330':'GMT+0330', 'gmt+0330':'GMT+0330', + 'gmt+430':'GMT+0430', 'gmt+0430':'GMT+0430', + 'gmt+530':'GMT+0530', 'gmt+0530':'GMT+0530', + 'gmt+630':'GMT+0630', 'gmt+0630':'GMT+0630', + 'gmt+730':'GMT+0730', 'gmt+0730':'GMT+0730', + 'gmt+830':'GMT+0830', 'gmt+0830':'GMT+0830', + 'gmt+930':'GMT+0930', 'gmt+0930':'GMT+0930', + 'gmt+1030':'GMT+1030', + 'gmt+1130':'GMT+1130', + 'gmt+1230':'GMT+1230', + + 'gmt-130':'GMT-0130', 'gmt-0130':'GMT-0130', + 'gmt-230':'GMT-0230', 'gmt-0230':'GMT-0230', + 'gmt-330':'GMT-0330', 'gmt-0330':'GMT-0330', + 'gmt-430':'GMT-0430', 'gmt-0430':'GMT-0430', + 'gmt-530':'GMT-0530', 'gmt-0530':'GMT-0530', + 'gmt-630':'GMT-0630', 'gmt-0630':'GMT-0630', + 'gmt-730':'GMT-0730', 'gmt-0730':'GMT-0730', + 'gmt-830':'GMT-0830', 'gmt-0830':'GMT-0830', + 'gmt-930':'GMT-0930', 'gmt-0930':'GMT-0930', + 'gmt-1030':'GMT-1030', + 'gmt-1130':'GMT-1130', + 'gmt-1230':'GMT-1230', + + 'greenwich':'Greenwich','hongkong':'Hongkong', + 'iceland':'Iceland','iran':'Iran','israel':'Israel', + 'jamaica':'Jamaica','japan':'Japan', + 'mexico/bajanorte':'Mexico/BajaNorte', + 'mexico/bajasur':'Mexico/BajaSur','mexico/general':'Mexico/General', + 'mst':'US/Mountain','pst':'US/Pacific','poland':'Poland', + 'singapore':'Singapore','turkey':'Turkey','universal':'Universal', + 'utc':'Universal','uct':'Universal','us/alaska':'US/Alaska', + 'us/aleutian':'US/Aleutian','us/arizona':'US/Arizona', + 'us/central':'US/Central','us/eastern':'US/Eastern', + 'us/east-indiana':'US/East-Indiana','us/hawaii':'US/Hawaii', + 'us/indiana-starke':'US/Indiana-Starke','us/michigan':'US/Michigan', + 'us/mountain':'US/Mountain','us/pacific':'US/Pacific', + 'us/samoa':'US/Samoa', + + 'ut':'Universal', + 'bst':'GMT+1', 'mest':'GMT+2', 'sst':'GMT+2', + 'fst':'GMT+2', 'wadt':'GMT+8', 'eadt':'GMT+11', 'nzdt':'GMT+13', + 'wet':'GMT', 'wat':'GMT-1', 'at':'GMT-2', 'ast':'GMT-4', + 'nt':'GMT-11', 'idlw':'GMT-12', 'cet':'GMT+1', 'cest':'GMT+2', + 'met':'GMT+1', + 'mewt':'GMT+1', 'swt':'GMT+1', 'fwt':'GMT+1', 'eet':'GMT+2', + 'eest':'GMT+3', + 'bt':'GMT+3', 'zp4':'GMT+4', 'zp5':'GMT+5', 'zp6':'GMT+6', + 'wast':'GMT+7', 'cct':'GMT+8', 'jst':'GMT+9', 'east':'GMT+10', + 'gst':'GMT+10', 'nzt':'GMT+12', 'nzst':'GMT+12', 'idle':'GMT+12', + 'ret':'GMT+4', 'ist': 'GMT+0530' + } + +timezones = dict((name, _timezone(data)) for name, data in _data.iteritems()) \ No newline at end of file Modified: Zope/trunk/lib/python/DateTime/tests/testDateTime.py =================================================================== --- Zope/trunk/lib/python/DateTime/tests/testDateTime.py 2007-10-24 14:34:17 UTC (rev 81038) +++ Zope/trunk/lib/python/DateTime/tests/testDateTime.py 2007-10-24 15:19:13 UTC (rev 81039) @@ -21,6 +21,7 @@ from DateTime import DateTime from datetime import datetime import pytz +import legacy try: __file__ @@ -505,14 +506,49 @@ dt4 = DateTime('2007-10-04T10:00:00+05:00') sdt4 = datetime(2007, 10, 4, 5, 0) self.assertEqual(dt4.utcdatetime(), sdt4) + self.assertEqual(dt4.asdatetime(), sdt4.replace(tzinfo=pytz.utc)) + + dt5 = DateTime('2007-10-23 10:00:00 US/Eastern') + tz = pytz.timezone('US/Eastern') + sdt5 = datetime(2007, 10, 23, 10, 0, tzinfo=tz) + dt6 = DateTime(sdt5) + self.assertEqual(dt5.asdatetime(), sdt5) + self.assertEqual(dt6.asdatetime(), sdt5) + self.assertEqual(dt5, dt6) + self.assertEqual(dt5.asdatetime().tzinfo, tz) + self.assertEqual(dt6.asdatetime().tzinfo, tz) def testLegacyTimezones(self): - # check that all the legacy timezone names can actually be looked up cache = _cache() - for key in cache._zmap.keys(): - tz = cache[key] - for key in cache._zlst: - tz = cache[key] + # The year is important here as timezones change over time + t1 = time.mktime(datetime(2002, 1, 1).timetuple()) + t2 = time.mktime(datetime(2002, 7, 1).timetuple()) + + for name in legacy._zlst + legacy._zmap.keys() + legacy._data.keys(): + self.failUnless(name.lower() in cache._zidx, 'legacy timezone %s cannot be looked up' % name) + + failures = [] + for name, zone in legacy.timezones.iteritems(): + newzone = cache[name] + # The name of the new zone might change (eg GMT+6 rather than GMT+0600) + if zone.info(t1)[:2] != newzone.info(t1)[:2] or zone.info(t2)[:2] != newzone.info(t2)[:2]: + failures.append(name) + + expected_failures = [ # zone.info(t1) newzone.info(t1) zone.info(t2) newzone.info(t2) + 'Jamaica', # (-18000, 0, 'EST') (-18000, 0, 'EST') (-14400, 1, 'EDT') (-18000, 0, 'EST') + 'Turkey', # (10800, 0, 'EET') (7200, 0, 'EET') (14400, 1, 'EET DST') (10800, 1, 'EEST') + 'Mexico/BajaSur', # (-25200, 0, 'MST') (-25200, 0, 'MST') (-25200, 0, 'MST') (-21600, 1, 'MDT') + 'Mexico/General', # (-21600, 0, 'CST') (-21600, 0, 'CST') (-21600, 0, 'CST') (-18000, 1, 'CDT') + 'Canada/Yukon', # (-32400, 0, 'YST') (-28800, 0, 'PST') (-28800, 1, 'YDT') (-25200, 1, 'PDT') + 'Brazil/West', # (-10800, 1, 'WDT') (-14400, 0, 'AMT') (-14400, 0, 'WST') (-14400, 0, 'AMT') + 'Brazil/Acre', # (-14400, 1, 'ADT') (-18000, 0, 'ACT') (-18000, 0, 'AST') (-18000, 0, 'ACT') + ] + + real_failures = list(set(failures).difference(set(expected_failures))) + + self.failIf(real_failures, '\n'.join(real_failures)) + + def test_suite(): _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins