123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- ##############################################################################
- #
- # Copyright (c) 2007 Zope Foundation and Contributors.
- #
- # 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 import datetime, timedelta
- import pytz
- import pytz.reference
- from pytz.tzinfo import StaticTzInfo, memorized_timedelta
- 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', 'edt': 'GMT-4',
- }
- # some timezone definitions of the "-0400" are not working
- # when upgrading
- for hour in range(0, 13):
- hour = hour
- fhour = str(hour)
- if len(fhour) == 1:
- fhour = '0' + fhour
- _old_zmap['-%s00' % fhour] = 'GMT-%i' % hour
- _old_zmap['+%s00' % fhour] = 'GMT+%i' % hour
- 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__
- Adapts datetime.tzinfo object to DateTime._timezone interface
- """
- def __init__(self, tzinfo):
- self.tzinfo = tzinfo
- def info(self, t=None):
- if t is None:
- dt = datetime.utcnow().replace(tzinfo=pytz.utc)
- else:
- # can't use utcfromtimestamp past 2038
- dt = EPOCH + timedelta(0, t)
- # need to normalize tzinfo for the datetime to deal with
- # daylight savings time.
- normalized_dt = self.tzinfo.normalize(dt.astimezone(self.tzinfo))
- normalized_tzinfo = normalized_dt.tzinfo
- offset = normalized_tzinfo.utcoffset(normalized_dt)
- secs = offset.days * 24 * 60 * 60 + offset.seconds
- dst = normalized_tzinfo.dst(normalized_dt)
- if dst == timedelta(0):
- is_dst = 0
- else:
- is_dst = 1
- return secs, is_dst, normalized_tzinfo.tzname(normalized_dt)
- class PytzCache:
- """
- Reimplementation of the DateTime._cache class that uses for timezone info
- """
- _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:
- return Timezone(pytz.timezone(name))
- except pytz.UnknownTimeZoneError:
- try:
- return Timezone(_numeric_timezones[name])
- except KeyError:
- raise DateTimeError('Unrecognized timezone: %s' % key)
|