Commit 622aa860 authored by Laurence Rowe's avatar Laurence Rowe

* 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.
parent cb8db59c
...@@ -23,6 +23,7 @@ from interfaces import IDateTime ...@@ -23,6 +23,7 @@ from interfaces import IDateTime
from interfaces import DateTimeError, SyntaxError, DateError, TimeError from interfaces import DateTimeError, SyntaxError, DateError, TimeError
from zope.interface import implements from zope.interface import implements
from pytz_support import PytzCache from pytz_support import PytzCache
_cache = PytzCache
default_datefmt = None default_datefmt = None
...@@ -108,206 +109,6 @@ iso8601Match = re.compile(r''' ...@@ -108,206 +109,6 @@ iso8601Match = re.compile(r'''
''', re.VERBOSE).match ''', 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): def _findLocalTimeZoneName(isDST):
if not daylight: if not daylight:
# Daylight savings does not occur in this time zone. # Daylight savings does not occur in this time zone.
...@@ -665,10 +466,10 @@ class DateTime: ...@@ -665,10 +466,10 @@ class DateTime:
- New in 2.11: - New in 2.11:
The DateTime function may now be invoked with a single argument The DateTime function may now be invoked with a single argument
that is a datetime.datetime instance. Timezone naive DateTimes may that is a datetime.datetime instance. DateTimes may be converted
be converted back to timezone naive datetime.datetime objects with back to datetime.datetime objects with asdatetime().
asdatetime(). All DateTime instances may be converted to a timezone DateTime instances may be converted to a timezone naive
naive datetime.datetime in UTC with utcdatetime(). datetime.datetime in UTC with utcdatetime().
- If the function is invoked with two numeric arguments, then - If the function is invoked with two numeric arguments, then
the first is taken to be an integer year and the second the first is taken to be an integer year and the second
...@@ -734,7 +535,7 @@ class DateTime: ...@@ -734,7 +535,7 @@ class DateTime:
will raise a DateError, while invalid time or timezone components will raise a DateError, while invalid time or timezone components
will raise a DateTimeError. 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 timezones recognized by the DateTime module. Recognition of
timezone names is case-insensitive. timezone names is case-insensitive.
""" """
...@@ -790,17 +591,26 @@ class DateTime: ...@@ -790,17 +591,26 @@ class DateTime:
sc=sc+ms sc=sc+ms
elif isinstance(arg, datetime): elif isinstance(arg, datetime):
yr,mo,dy,hr,mn,sc,tz,tznaive=self._parse_iso8601_preserving_tznaive(arg.isoformat()) yr,mo,dy,hr,mn,sc,numerictz,tznaive=self._parse_iso8601_preserving_tznaive(arg.isoformat())
self._timezone_naive = tznaive 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) ms = sc - math.floor(sc)
x = _calcDependentSecond2(yr,mo,dy,hr,mn,sc) x = _calcDependentSecond2(yr,mo,dy,hr,mn,sc)
if tz: if tz:
try: tz=self._tzinfo._zmap[tz.lower()] try:
except KeyError: zone = self._tzinfo[tz]
if numericTimeZoneMatch(tz) is None: except DateTimeError:
try:
zone = self._tzinfo[numerictz]
except DateTimeError:
raise DateTimeError, \ raise DateTimeError, \
'Unknown time zone in date: %s' % arg 'Unknown time zone in date: %s' % arg
tz = zone.tzinfo.zone
else: else:
tz = self._calcTimezoneName(x, ms) tz = self._calcTimezoneName(x, ms)
s,d,t,microsecs = _calcIndependentSecondEtc(tz, x, ms) s,d,t,microsecs = _calcIndependentSecondEtc(tz, x, ms)
...@@ -988,7 +798,7 @@ class DateTime: ...@@ -988,7 +798,7 @@ class DateTime:
# For backward compatibility only: # For backward compatibility only:
_isDST = localtime(time())[8] _isDST = localtime(time())[8]
_localzone = _isDST and _localzone1 or _localzone0 _localzone = _isDST and _localzone1 or _localzone0
_tzinfo = PytzCache(_cache()) _tzinfo = PytzCache()
def localZone(self, ltm=None): def localZone(self, ltm=None):
'''Returns the time zone on the given date. The time zone '''Returns the time zone on the given date. The time zone
...@@ -1799,16 +1609,15 @@ class DateTime: ...@@ -1799,16 +1609,15 @@ class DateTime:
"""Return a standard libary datetime.datetime """Return a standard libary datetime.datetime
""" """
tznaive = self.timezoneNaive() tznaive = self.timezoneNaive()
if tznaive is True: if tznaive:
# we were either converted from an ISO8601 timezone naive string or tzinfo = None
# a timezone naive datetime else:
tzinfo = self._tzinfo[self._tz].tzinfo
second = int(self._second) second = int(self._second)
microsec = self.micros() % 1000000 microsec = self.micros() % 1000000
dt = datetime(self._year, self._month, self._day, self._hour, dt = datetime(self._year, self._month, self._day, self._hour,
self._minute, second, microsec) self._minute, second, microsec, tzinfo)
return dt return dt
else:
raise NotImplementedError('conversion of datetime aware DateTime to datetime unsupported')
def utcdatetime(self): def utcdatetime(self):
"""Convert the time to UTC then return a timezone naive datetime object""" """Convert the time to UTC then return a timezone naive datetime object"""
...@@ -2041,5 +1850,5 @@ class strftimeFormatter: ...@@ -2041,5 +1850,5 @@ class strftimeFormatter:
# Module methods # Module methods
def Timezones(): def Timezones():
"""Return the list of recognized timezone names""" """Return the list of recognized timezone names"""
return list(PytzCache(_cache())._zlst) return PytzCache._zlst
...@@ -12,7 +12,7 @@ Returns the list of recognized timezone names: ...@@ -12,7 +12,7 @@ Returns the list of recognized timezone names:
>>> from DateTime import Timezones >>> from DateTime import Timezones
>>> Timezones() # doctest: +ELLIPSIS >>> Timezones() # doctest: +ELLIPSIS
[...'Brazil/Acre', 'Brazil/DeNoronha', ..., 'NZST', 'IDLE'] [...'Brazil/Acre'... 'Brazil/DeNoronha'... 'IDLE'... 'NZST'...]
Class DateTime Class DateTime
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE
# #
############################################################################## ##############################################################################
# This data is used only for testing legacy compatibility with pytz
_data={ _data={
......
...@@ -126,13 +126,13 @@ class. ...@@ -126,13 +126,13 @@ class.
The _zlst attribute is a list of supported time zone names. The _zlst attribute is a list of supported time zone names.
>>> cache._zlst #doctest: +ELLIPSIS >>> 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 The _zidx attribute is a list of lower-case and possibly abbreviated
time zone names that can be mapped to offical zone names. time zone names that can be mapped to offical zone names.
>>> cache._zidx #doctest: +ELLIPSIS >>> 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 Note that there are more items in _zidx than in _zlst since there are
multiple names for some time zones. multiple names for some time zones.
......
...@@ -16,8 +16,191 @@ Pytz timezone support. ...@@ -16,8 +16,191 @@ Pytz timezone support.
import pytz import pytz
import pytz.reference import pytz.reference
from pytz.tzinfo import StaticTzInfo, memorized_timedelta
from datetime import datetime, timedelta from datetime import datetime, timedelta
import re 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: class Timezone:
""" """
...@@ -31,7 +214,7 @@ class Timezone: ...@@ -31,7 +214,7 @@ class Timezone:
if t is None: if t is None:
dt = datetime.utcnow().replace(tzinfo=pytz.utc) dt = datetime.utcnow().replace(tzinfo=pytz.utc)
else: 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 # need to normalize tzinfo for the datetime to deal with
# daylight savings time. # daylight savings time.
...@@ -50,24 +233,20 @@ class Timezone: ...@@ -50,24 +233,20 @@ class Timezone:
class PytzCache: class PytzCache:
""" """
Wrapper for the DateTime._cache class that uses pytz for Reimplementation of the DateTime._cache class that uses for timezone info
timezone information where possible.
""" """
def __init__(self, cache):
self.cache = cache _zlst = pytz.common_timezones + _old_zlst # used by DateTime.TimeZones
self._zlst = list(pytz.common_timezones) _zmap = dict((name.lower(), name) for name in pytz.all_timezones)
for name in cache._zlst: _zmap.update(_old_zmap) # These must take priority
if name not in self._zlst: _zidx = _zmap.keys()
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()
def __getitem__(self, key): def __getitem__(self, key):
name = self._zmap.get(key.lower(), key) # fallback to key
try: try:
name = self._zmap[key.lower()]
return Timezone(pytz.timezone(name)) return Timezone(pytz.timezone(name))
except (KeyError, pytz.UnknownTimeZoneError): except pytz.UnknownTimeZoneError:
return self.cache[key] try:
return Timezone(_numeric_timezones[name])
except KeyError:
raise DateTimeError,'Unrecognized timezone: %s' % key
\ No newline at end of file
##############################################################################
#
# 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
...@@ -21,6 +21,7 @@ from DateTime.DateTime import _findLocalTimeZoneName, _cache ...@@ -21,6 +21,7 @@ from DateTime.DateTime import _findLocalTimeZoneName, _cache
from DateTime import DateTime from DateTime import DateTime
from datetime import datetime from datetime import datetime
import pytz import pytz
import legacy
try: try:
__file__ __file__
...@@ -505,14 +506,49 @@ class DateTimeTests(unittest.TestCase): ...@@ -505,14 +506,49 @@ class DateTimeTests(unittest.TestCase):
dt4 = DateTime('2007-10-04T10:00:00+05:00') dt4 = DateTime('2007-10-04T10:00:00+05:00')
sdt4 = datetime(2007, 10, 4, 5, 0) sdt4 = datetime(2007, 10, 4, 5, 0)
self.assertEqual(dt4.utcdatetime(), sdt4) 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): def testLegacyTimezones(self):
# check that all the legacy timezone names can actually be looked up
cache = _cache() cache = _cache()
for key in cache._zmap.keys(): # The year is important here as timezones change over time
tz = cache[key] t1 = time.mktime(datetime(2002, 1, 1).timetuple())
for key in cache._zlst: t2 = time.mktime(datetime(2002, 7, 1).timetuple())
tz = cache[key]
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(): def test_suite():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment