[Zope-Checkins] SVN: Zope/trunk/lib/python/DateTime/ * Move all timezone usage to use pytz

Laurence Rowe l at lrowe.co.uk
Wed Oct 24 11:19:14 EDT 2007


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():



More information about the Zope-Checkins mailing list