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
This diff is collapsed.
...@@ -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.
......
This diff is collapsed.
##############################################################################
#
# 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