From f14de2403b7255d3703d0f558d481c164080fd1e Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Thu, 16 Sep 2010 15:37:11 -0400 Subject: [PATCH] Proper timezone support by saving the correct date in stories. Everything is now UTC, which means I'll need to add timezone support to accounts, which won't be fun. --- utils/dateutil/__init__.py | 9 - utils/dateutil/easter.py | 92 -- utils/dateutil/parser.py | 886 ------------- utils/dateutil/relativedelta.py | 432 ------- utils/dateutil/rrule.py | 1097 ----------------- utils/dateutil/tz.py | 951 -------------- utils/dateutil/tzwin.py | 180 --- utils/dateutil/zoneinfo/__init__.py | 87 -- utils/dateutil/zoneinfo/zoneinfo-2008e.tar.gz | Bin 163209 -> 0 bytes utils/story_functions.py | 19 +- 10 files changed, 1 insertion(+), 3752 deletions(-) delete mode 100644 utils/dateutil/__init__.py delete mode 100644 utils/dateutil/easter.py delete mode 100644 utils/dateutil/parser.py delete mode 100644 utils/dateutil/relativedelta.py delete mode 100644 utils/dateutil/rrule.py delete mode 100644 utils/dateutil/tz.py delete mode 100644 utils/dateutil/tzwin.py delete mode 100644 utils/dateutil/zoneinfo/__init__.py delete mode 100644 utils/dateutil/zoneinfo/zoneinfo-2008e.tar.gz diff --git a/utils/dateutil/__init__.py b/utils/dateutil/__init__.py deleted file mode 100644 index 8b4ac7dc8..000000000 --- a/utils/dateutil/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" -__version__ = "1.4.1" diff --git a/utils/dateutil/easter.py b/utils/dateutil/easter.py deleted file mode 100644 index d7944104b..000000000 --- a/utils/dateutil/easter.py +++ /dev/null @@ -1,92 +0,0 @@ -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import datetime - -__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"] - -EASTER_JULIAN = 1 -EASTER_ORTHODOX = 2 -EASTER_WESTERN = 3 - -def easter(year, method=EASTER_WESTERN): - """ - This method was ported from the work done by GM Arts, - on top of the algorithm by Claus Tondering, which was - based in part on the algorithm of Ouding (1940), as - quoted in "Explanatory Supplement to the Astronomical - Almanac", P. Kenneth Seidelmann, editor. - - This algorithm implements three different easter - calculation methods: - - 1 - Original calculation in Julian calendar, valid in - dates after 326 AD - 2 - Original method, with date converted to Gregorian - calendar, valid in years 1583 to 4099 - 3 - Revised method, in Gregorian calendar, valid in - years 1583 to 4099 as well - - These methods are represented by the constants: - - EASTER_JULIAN = 1 - EASTER_ORTHODOX = 2 - EASTER_WESTERN = 3 - - The default method is method 3. - - More about the algorithm may be found at: - - http://users.chariot.net.au/~gmarts/eastalg.htm - - and - - http://www.tondering.dk/claus/calendar.html - - """ - - if not (1 <= method <= 3): - raise ValueError, "invalid method" - - # g - Golden year - 1 - # c - Century - # h - (23 - Epact) mod 30 - # i - Number of days from March 21 to Paschal Full Moon - # j - Weekday for PFM (0=Sunday, etc) - # p - Number of days from March 21 to Sunday on or before PFM - # (-6 to 28 methods 1 & 3, to 56 for method 2) - # e - Extra days to add for method 2 (converting Julian - # date to Gregorian date) - - y = year - g = y % 19 - e = 0 - if method < 3: - # Old method - i = (19*g+15)%30 - j = (y+y//4+i)%7 - if method == 2: - # Extra dates to convert Julian to Gregorian date - e = 10 - if y > 1600: - e = e+y//100-16-(y//100-16)//4 - else: - # New method - c = y//100 - h = (c-c//4-(8*c+13)//25+19*g+15)%30 - i = h-(h//28)*(1-(h//28)*(29//(h+1))*((21-g)//11)) - j = (y+y//4+i+2-c+c//4)%7 - - # p can be from -6 to 56 corresponding to dates 22 March to 23 May - # (later dates apply to method 2, although 23 May never actually occurs) - p = i-j+e - d = 1+(p+27+(p+6)//40)%31 - m = 3+(p+26)//30 - return datetime.date(int(y),int(m),int(d)) - diff --git a/utils/dateutil/parser.py b/utils/dateutil/parser.py deleted file mode 100644 index 5d824e411..000000000 --- a/utils/dateutil/parser.py +++ /dev/null @@ -1,886 +0,0 @@ -# -*- coding:iso-8859-1 -*- -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import datetime -import string -import time -import sys -import os - -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - -import relativedelta -import tz - - -__all__ = ["parse", "parserinfo"] - - -# Some pointers: -# -# http://www.cl.cam.ac.uk/~mgk25/iso-time.html -# http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html -# http://www.w3.org/TR/NOTE-datetime -# http://ringmaster.arc.nasa.gov/tools/time_formats.html -# http://search.cpan.org/author/MUIR/Time-modules-2003.0211/lib/Time/ParseDate.pm -# http://stein.cshl.org/jade/distrib/docs/java.text.SimpleDateFormat.html - - -class _timelex(object): - - def __init__(self, instream): - if isinstance(instream, basestring): - instream = StringIO(instream) - self.instream = instream - self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' - 'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ' - 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ') - self.numchars = '0123456789' - self.whitespace = ' \t\r\n' - self.charstack = [] - self.tokenstack = [] - self.eof = False - - def get_token(self): - if self.tokenstack: - return self.tokenstack.pop(0) - seenletters = False - token = None - state = None - wordchars = self.wordchars - numchars = self.numchars - whitespace = self.whitespace - while not self.eof: - if self.charstack: - nextchar = self.charstack.pop(0) - else: - nextchar = self.instream.read(1) - while nextchar == '\x00': - nextchar = self.instream.read(1) - if not nextchar: - self.eof = True - break - elif not state: - token = nextchar - if nextchar in wordchars: - state = 'a' - elif nextchar in numchars: - state = '0' - elif nextchar in whitespace: - token = ' ' - break # emit token - else: - break # emit token - elif state == 'a': - seenletters = True - if nextchar in wordchars: - token += nextchar - elif nextchar == '.': - token += nextchar - state = 'a.' - else: - self.charstack.append(nextchar) - break # emit token - elif state == '0': - if nextchar in numchars: - token += nextchar - elif nextchar == '.': - token += nextchar - state = '0.' - else: - self.charstack.append(nextchar) - break # emit token - elif state == 'a.': - seenletters = True - if nextchar == '.' or nextchar in wordchars: - token += nextchar - elif nextchar in numchars and token[-1] == '.': - token += nextchar - state = '0.' - else: - self.charstack.append(nextchar) - break # emit token - elif state == '0.': - if nextchar == '.' or nextchar in numchars: - token += nextchar - elif nextchar in wordchars and token[-1] == '.': - token += nextchar - state = 'a.' - else: - self.charstack.append(nextchar) - break # emit token - if (state in ('a.', '0.') and - (seenletters or token.count('.') > 1 or token[-1] == '.')): - l = token.split('.') - token = l[0] - for tok in l[1:]: - self.tokenstack.append('.') - if tok: - self.tokenstack.append(tok) - return token - - def __iter__(self): - return self - - def next(self): - token = self.get_token() - if token is None: - raise StopIteration - return token - - def split(cls, s): - return list(cls(s)) - split = classmethod(split) - - -class _resultbase(object): - - def __init__(self): - for attr in self.__slots__: - setattr(self, attr, None) - - def _repr(self, classname): - l = [] - for attr in self.__slots__: - value = getattr(self, attr) - if value is not None: - l.append("%s=%s" % (attr, `value`)) - return "%s(%s)" % (classname, ", ".join(l)) - - def __repr__(self): - return self._repr(self.__class__.__name__) - - -class parserinfo(object): - - # m from a.m/p.m, t from ISO T separator - JUMP = [" ", ".", ",", ";", "-", "/", "'", - "at", "on", "and", "ad", "m", "t", "of", - "st", "nd", "rd", "th"] - - WEEKDAYS = [("Mon", "Monday"), - ("Tue", "Tuesday"), - ("Wed", "Wednesday"), - ("Thu", "Thursday"), - ("Fri", "Friday"), - ("Sat", "Saturday"), - ("Sun", "Sunday")] - MONTHS = [("Jan", "January"), - ("Feb", "February"), - ("Mar", "March"), - ("Apr", "April"), - ("May", "May"), - ("Jun", "June"), - ("Jul", "July"), - ("Aug", "August"), - ("Sep", "September"), - ("Oct", "October"), - ("Nov", "November"), - ("Dec", "December")] - HMS = [("h", "hour", "hours"), - ("m", "minute", "minutes"), - ("s", "second", "seconds")] - AMPM = [("am", "a"), - ("pm", "p")] - UTCZONE = ["UTC", "GMT", "Z"] - PERTAIN = ["of"] - TZOFFSET = {} - - def __init__(self, dayfirst=False, yearfirst=False): - self._jump = self._convert(self.JUMP) - self._weekdays = self._convert(self.WEEKDAYS) - self._months = self._convert(self.MONTHS) - self._hms = self._convert(self.HMS) - self._ampm = self._convert(self.AMPM) - self._utczone = self._convert(self.UTCZONE) - self._pertain = self._convert(self.PERTAIN) - - self.dayfirst = dayfirst - self.yearfirst = yearfirst - - self._year = time.localtime().tm_year - self._century = self._year//100*100 - - def _convert(self, lst): - dct = {} - for i in range(len(lst)): - v = lst[i] - if isinstance(v, tuple): - for v in v: - dct[v.lower()] = i - else: - dct[v.lower()] = i - return dct - - def jump(self, name): - return name.lower() in self._jump - - def weekday(self, name): - if len(name) >= 3: - try: - return self._weekdays[name.lower()] - except KeyError: - pass - return None - - def month(self, name): - if len(name) >= 3: - try: - return self._months[name.lower()]+1 - except KeyError: - pass - return None - - def hms(self, name): - try: - return self._hms[name.lower()] - except KeyError: - return None - - def ampm(self, name): - try: - return self._ampm[name.lower()] - except KeyError: - return None - - def pertain(self, name): - return name.lower() in self._pertain - - def utczone(self, name): - return name.lower() in self._utczone - - def tzoffset(self, name): - if name in self._utczone: - return 0 - return self.TZOFFSET.get(name) - - def convertyear(self, year): - if year < 100: - year += self._century - if abs(year-self._year) >= 50: - if year < self._year: - year += 100 - else: - year -= 100 - return year - - def validate(self, res): - # move to info - if res.year is not None: - res.year = self.convertyear(res.year) - if res.tzoffset == 0 and not res.tzname or res.tzname == 'Z': - res.tzname = "UTC" - res.tzoffset = 0 - elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname): - res.tzoffset = 0 - return True - - -class parser(object): - - def __init__(self, info=None): - self.info = info or parserinfo() - - def parse(self, timestr, default=None, - ignoretz=False, tzinfos=None, - **kwargs): - if not default: - default = datetime.datetime.now().replace(hour=0, minute=0, - second=0, microsecond=0) - res = self._parse(timestr, **kwargs) - if res is None: - raise ValueError, "unknown string format" - repl = {} - for attr in ["year", "month", "day", "hour", - "minute", "second", "microsecond"]: - value = getattr(res, attr) - if value is not None: - repl[attr] = value - ret = default.replace(**repl) - if res.weekday is not None and not res.day: - ret = ret+relativedelta.relativedelta(weekday=res.weekday) - if not ignoretz: - if callable(tzinfos) or tzinfos and res.tzname in tzinfos: - if callable(tzinfos): - tzdata = tzinfos(res.tzname, res.tzoffset) - else: - tzdata = tzinfos.get(res.tzname) - if isinstance(tzdata, datetime.tzinfo): - tzinfo = tzdata - elif isinstance(tzdata, basestring): - tzinfo = tz.tzstr(tzdata) - elif isinstance(tzdata, int): - tzinfo = tz.tzoffset(res.tzname, tzdata) - else: - raise ValueError, "offset must be tzinfo subclass, " \ - "tz string, or int offset" - ret = ret.replace(tzinfo=tzinfo) - elif res.tzname and res.tzname in time.tzname: - ret = ret.replace(tzinfo=tz.tzlocal()) - elif res.tzoffset == 0: - ret = ret.replace(tzinfo=tz.tzutc()) - elif res.tzoffset: - ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) - return ret - - class _result(_resultbase): - __slots__ = ["year", "month", "day", "weekday", - "hour", "minute", "second", "microsecond", - "tzname", "tzoffset"] - - def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False): - info = self.info - if dayfirst is None: - dayfirst = info.dayfirst - if yearfirst is None: - yearfirst = info.yearfirst - res = self._result() - l = _timelex.split(timestr) - try: - - # year/month/day list - ymd = [] - - # Index of the month string in ymd - mstridx = -1 - - len_l = len(l) - i = 0 - while i < len_l: - - # Check if it's a number - try: - value_repr = l[i] - value = float(value_repr) - except ValueError: - value = None - - if value is not None: - # Token is a number - len_li = len(l[i]) - i += 1 - if (len(ymd) == 3 and len_li in (2, 4) - and (i >= len_l or (l[i] != ':' and - info.hms(l[i]) is None))): - # 19990101T23[59] - s = l[i-1] - res.hour = int(s[:2]) - if len_li == 4: - res.minute = int(s[2:]) - elif len_li == 6 or (len_li > 6 and l[i-1].find('.') == 6): - # YYMMDD or HHMMSS[.ss] - s = l[i-1] - if not ymd and l[i-1].find('.') == -1: - ymd.append(info.convertyear(int(s[:2]))) - ymd.append(int(s[2:4])) - ymd.append(int(s[4:])) - else: - # 19990101T235959[.59] - res.hour = int(s[:2]) - res.minute = int(s[2:4]) - res.second, res.microsecond = _parsems(s[4:]) - elif len_li == 8: - # YYYYMMDD - s = l[i-1] - ymd.append(int(s[:4])) - ymd.append(int(s[4:6])) - ymd.append(int(s[6:])) - elif len_li in (12, 14): - # YYYYMMDDhhmm[ss] - s = l[i-1] - ymd.append(int(s[:4])) - ymd.append(int(s[4:6])) - ymd.append(int(s[6:8])) - res.hour = int(s[8:10]) - res.minute = int(s[10:12]) - if len_li == 14: - res.second = int(s[12:]) - elif ((i < len_l and info.hms(l[i]) is not None) or - (i+1 < len_l and l[i] == ' ' and - info.hms(l[i+1]) is not None)): - # HH[ ]h or MM[ ]m or SS[.ss][ ]s - if l[i] == ' ': - i += 1 - idx = info.hms(l[i]) - while True: - if idx == 0: - res.hour = int(value) - if value%1: - res.minute = int(60*(value%1)) - elif idx == 1: - res.minute = int(value) - if value%1: - res.second = int(60*(value%1)) - elif idx == 2: - res.second, res.microsecond = \ - _parsems(value_repr) - i += 1 - if i >= len_l or idx == 2: - break - # 12h00 - try: - value_repr = l[i] - value = float(value_repr) - except ValueError: - break - else: - i += 1 - idx += 1 - if i < len_l: - newidx = info.hms(l[i]) - if newidx is not None: - idx = newidx - elif i+1 < len_l and l[i] == ':': - # HH:MM[:SS[.ss]] - res.hour = int(value) - i += 1 - value = float(l[i]) - res.minute = int(value) - if value%1: - res.second = int(60*(value%1)) - i += 1 - if i < len_l and l[i] == ':': - res.second, res.microsecond = _parsems(l[i+1]) - i += 2 - elif i < len_l and l[i] in ('-', '/', '.'): - sep = l[i] - ymd.append(int(value)) - i += 1 - if i < len_l and not info.jump(l[i]): - try: - # 01-01[-01] - ymd.append(int(l[i])) - except ValueError: - # 01-Jan[-01] - value = info.month(l[i]) - if value is not None: - ymd.append(value) - assert mstridx == -1 - mstridx = len(ymd)-1 - else: - return None - i += 1 - if i < len_l and l[i] == sep: - # We have three members - i += 1 - value = info.month(l[i]) - if value is not None: - ymd.append(value) - mstridx = len(ymd)-1 - assert mstridx == -1 - else: - ymd.append(int(l[i])) - i += 1 - elif i >= len_l or info.jump(l[i]): - if i+1 < len_l and info.ampm(l[i+1]) is not None: - # 12 am - res.hour = int(value) - if res.hour < 12 and info.ampm(l[i+1]) == 1: - res.hour += 12 - elif res.hour == 12 and info.ampm(l[i+1]) == 0: - res.hour = 0 - i += 1 - else: - # Year, month or day - ymd.append(int(value)) - i += 1 - elif info.ampm(l[i]) is not None: - # 12am - res.hour = int(value) - if res.hour < 12 and info.ampm(l[i]) == 1: - res.hour += 12 - elif res.hour == 12 and info.ampm(l[i]) == 0: - res.hour = 0 - i += 1 - elif not fuzzy: - return None - else: - i += 1 - continue - - # Check weekday - value = info.weekday(l[i]) - if value is not None: - res.weekday = value - i += 1 - continue - - # Check month name - value = info.month(l[i]) - if value is not None: - ymd.append(value) - assert mstridx == -1 - mstridx = len(ymd)-1 - i += 1 - if i < len_l: - if l[i] in ('-', '/'): - # Jan-01[-99] - sep = l[i] - i += 1 - ymd.append(int(l[i])) - i += 1 - if i < len_l and l[i] == sep: - # Jan-01-99 - i += 1 - ymd.append(int(l[i])) - i += 1 - elif (i+3 < len_l and l[i] == l[i+2] == ' ' - and info.pertain(l[i+1])): - # Jan of 01 - # In this case, 01 is clearly year - try: - value = int(l[i+3]) - except ValueError: - # Wrong guess - pass - else: - # Convert it here to become unambiguous - ymd.append(info.convertyear(value)) - i += 4 - continue - - # Check am/pm - value = info.ampm(l[i]) - if value is not None: - if value == 1 and res.hour < 12: - res.hour += 12 - elif value == 0 and res.hour == 12: - res.hour = 0 - i += 1 - continue - - # Check for a timezone name - if (res.hour is not None and len(l[i]) <= 5 and - res.tzname is None and res.tzoffset is None and - not [x for x in l[i] if x not in string.ascii_uppercase]): - res.tzname = l[i] - res.tzoffset = info.tzoffset(res.tzname) - i += 1 - - # Check for something like GMT+3, or BRST+3. Notice - # that it doesn't mean "I am 3 hours after GMT", but - # "my time +3 is GMT". If found, we reverse the - # logic so that timezone parsing code will get it - # right. - if i < len_l and l[i] in ('+', '-'): - l[i] = ('+', '-')[l[i] == '+'] - res.tzoffset = None - if info.utczone(res.tzname): - # With something like GMT+3, the timezone - # is *not* GMT. - res.tzname = None - - continue - - # Check for a numbered timezone - if res.hour is not None and l[i] in ('+', '-'): - signal = (-1,1)[l[i] == '+'] - i += 1 - len_li = len(l[i]) - if len_li == 4: - # -0300 - res.tzoffset = int(l[i][:2])*3600+int(l[i][2:])*60 - elif i+1 < len_l and l[i+1] == ':': - # -03:00 - res.tzoffset = int(l[i])*3600+int(l[i+2])*60 - i += 2 - elif len_li <= 2: - # -[0]3 - res.tzoffset = int(l[i][:2])*3600 - else: - return None - i += 1 - res.tzoffset *= signal - - # Look for a timezone name between parenthesis - if (i+3 < len_l and - info.jump(l[i]) and l[i+1] == '(' and l[i+3] == ')' and - 3 <= len(l[i+2]) <= 5 and - not [x for x in l[i+2] - if x not in string.ascii_uppercase]): - # -0300 (BRST) - res.tzname = l[i+2] - i += 4 - continue - - # Check jumps - if not (info.jump(l[i]) or fuzzy): - return None - - i += 1 - - # Process year/month/day - len_ymd = len(ymd) - if len_ymd > 3: - # More than three members!? - return None - elif len_ymd == 1 or (mstridx != -1 and len_ymd == 2): - # One member, or two members with a month string - if mstridx != -1: - res.month = ymd[mstridx] - del ymd[mstridx] - if len_ymd > 1 or mstridx == -1: - if ymd[0] > 31: - res.year = ymd[0] - else: - res.day = ymd[0] - elif len_ymd == 2: - # Two members with numbers - if ymd[0] > 31: - # 99-01 - res.year, res.month = ymd - elif ymd[1] > 31: - # 01-99 - res.month, res.year = ymd - elif dayfirst and ymd[1] <= 12: - # 13-01 - res.day, res.month = ymd - else: - # 01-13 - res.month, res.day = ymd - if len_ymd == 3: - # Three members - if mstridx == 0: - res.month, res.day, res.year = ymd - elif mstridx == 1: - if ymd[0] > 31 or (yearfirst and ymd[2] <= 31): - # 99-Jan-01 - res.year, res.month, res.day = ymd - else: - # 01-Jan-01 - # Give precendence to day-first, since - # two-digit years is usually hand-written. - res.day, res.month, res.year = ymd - elif mstridx == 2: - # WTF!? - if ymd[1] > 31: - # 01-99-Jan - res.day, res.year, res.month = ymd - else: - # 99-01-Jan - res.year, res.day, res.month = ymd - else: - if ymd[0] > 31 or \ - (yearfirst and ymd[1] <= 12 and ymd[2] <= 31): - # 99-01-01 - res.year, res.month, res.day = ymd - elif ymd[0] > 12 or (dayfirst and ymd[1] <= 12): - # 13-01-01 - res.day, res.month, res.year = ymd - else: - # 01-13-01 - res.month, res.day, res.year = ymd - - except (IndexError, ValueError, AssertionError): - return None - - if not info.validate(res): - return None - return res - -DEFAULTPARSER = parser() -def parse(timestr, parserinfo=None, **kwargs): - if parserinfo: - return parser(parserinfo).parse(timestr, **kwargs) - else: - return DEFAULTPARSER.parse(timestr, **kwargs) - - -class _tzparser(object): - - class _result(_resultbase): - - __slots__ = ["stdabbr", "stdoffset", "dstabbr", "dstoffset", - "start", "end"] - - class _attr(_resultbase): - __slots__ = ["month", "week", "weekday", - "yday", "jyday", "day", "time"] - - def __repr__(self): - return self._repr("") - - def __init__(self): - _resultbase.__init__(self) - self.start = self._attr() - self.end = self._attr() - - def parse(self, tzstr): - res = self._result() - l = _timelex.split(tzstr) - try: - - len_l = len(l) - - i = 0 - while i < len_l: - # BRST+3[BRDT[+2]] - j = i - while j < len_l and not [x for x in l[j] - if x in "0123456789:,-+"]: - j += 1 - if j != i: - if not res.stdabbr: - offattr = "stdoffset" - res.stdabbr = "".join(l[i:j]) - else: - offattr = "dstoffset" - res.dstabbr = "".join(l[i:j]) - i = j - if (i < len_l and - (l[i] in ('+', '-') or l[i][0] in "0123456789")): - if l[i] in ('+', '-'): - # Yes, that's right. See the TZ variable - # documentation. - signal = (1,-1)[l[i] == '+'] - i += 1 - else: - signal = -1 - len_li = len(l[i]) - if len_li == 4: - # -0300 - setattr(res, offattr, - (int(l[i][:2])*3600+int(l[i][2:])*60)*signal) - elif i+1 < len_l and l[i+1] == ':': - # -03:00 - setattr(res, offattr, - (int(l[i])*3600+int(l[i+2])*60)*signal) - i += 2 - elif len_li <= 2: - # -[0]3 - setattr(res, offattr, - int(l[i][:2])*3600*signal) - else: - return None - i += 1 - if res.dstabbr: - break - else: - break - - if i < len_l: - for j in range(i, len_l): - if l[j] == ';': l[j] = ',' - - assert l[i] == ',' - - i += 1 - - if i >= len_l: - pass - elif (8 <= l.count(',') <= 9 and - not [y for x in l[i:] if x != ',' - for y in x if y not in "0123456789"]): - # GMT0BST,3,0,30,3600,10,0,26,7200[,3600] - for x in (res.start, res.end): - x.month = int(l[i]) - i += 2 - if l[i] == '-': - value = int(l[i+1])*-1 - i += 1 - else: - value = int(l[i]) - i += 2 - if value: - x.week = value - x.weekday = (int(l[i])-1)%7 - else: - x.day = int(l[i]) - i += 2 - x.time = int(l[i]) - i += 2 - if i < len_l: - if l[i] in ('-','+'): - signal = (-1,1)[l[i] == "+"] - i += 1 - else: - signal = 1 - res.dstoffset = (res.stdoffset+int(l[i]))*signal - elif (l.count(',') == 2 and l[i:].count('/') <= 2 and - not [y for x in l[i:] if x not in (',','/','J','M', - '.','-',':') - for y in x if y not in "0123456789"]): - for x in (res.start, res.end): - if l[i] == 'J': - # non-leap year day (1 based) - i += 1 - x.jyday = int(l[i]) - elif l[i] == 'M': - # month[-.]week[-.]weekday - i += 1 - x.month = int(l[i]) - i += 1 - assert l[i] in ('-', '.') - i += 1 - x.week = int(l[i]) - if x.week == 5: - x.week = -1 - i += 1 - assert l[i] in ('-', '.') - i += 1 - x.weekday = (int(l[i])-1)%7 - else: - # year day (zero based) - x.yday = int(l[i])+1 - - i += 1 - - if i < len_l and l[i] == '/': - i += 1 - # start time - len_li = len(l[i]) - if len_li == 4: - # -0300 - x.time = (int(l[i][:2])*3600+int(l[i][2:])*60) - elif i+1 < len_l and l[i+1] == ':': - # -03:00 - x.time = int(l[i])*3600+int(l[i+2])*60 - i += 2 - if i+1 < len_l and l[i+1] == ':': - i += 2 - x.time += int(l[i]) - elif len_li <= 2: - # -[0]3 - x.time = (int(l[i][:2])*3600) - else: - return None - i += 1 - - assert i == len_l or l[i] == ',' - - i += 1 - - assert i >= len_l - - except (IndexError, ValueError, AssertionError): - return None - - return res - - -DEFAULTTZPARSER = _tzparser() -def _parsetz(tzstr): - return DEFAULTTZPARSER.parse(tzstr) - - -def _parsems(value): - """Parse a I[.F] seconds value into (seconds, microseconds).""" - if "." not in value: - return int(value), 0 - else: - i, f = value.split(".") - return int(i), int(f.ljust(6, "0")[:6]) - - -# vim:ts=4:sw=4:et diff --git a/utils/dateutil/relativedelta.py b/utils/dateutil/relativedelta.py deleted file mode 100644 index 562a7d3c4..000000000 --- a/utils/dateutil/relativedelta.py +++ /dev/null @@ -1,432 +0,0 @@ -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import datetime -import calendar - -__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] - -class weekday(object): - __slots__ = ["weekday", "n"] - - def __init__(self, weekday, n=None): - self.weekday = weekday - self.n = n - - def __call__(self, n): - if n == self.n: - return self - else: - return self.__class__(self.weekday, n) - - def __eq__(self, other): - try: - if self.weekday != other.weekday or self.n != other.n: - return False - except AttributeError: - return False - return True - - def __repr__(self): - s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] - if not self.n: - return s - else: - return "%s(%+d)" % (s, self.n) - -MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) - -class relativedelta: - """ -The relativedelta type is based on the specification of the excelent -work done by M.-A. Lemburg in his mx.DateTime extension. However, -notice that this type does *NOT* implement the same algorithm as -his work. Do *NOT* expect it to behave like mx.DateTime's counterpart. - -There's two different ways to build a relativedelta instance. The -first one is passing it two date/datetime classes: - - relativedelta(datetime1, datetime2) - -And the other way is to use the following keyword arguments: - - year, month, day, hour, minute, second, microsecond: - Absolute information. - - years, months, weeks, days, hours, minutes, seconds, microseconds: - Relative information, may be negative. - - weekday: - One of the weekday instances (MO, TU, etc). These instances may - receive a parameter N, specifying the Nth weekday, which could - be positive or negative (like MO(+1) or MO(-2). Not specifying - it is the same as specifying +1. You can also use an integer, - where 0=MO. - - leapdays: - Will add given days to the date found, if year is a leap - year, and the date found is post 28 of february. - - yearday, nlyearday: - Set the yearday or the non-leap year day (jump leap days). - These are converted to day/month/leapdays information. - -Here is the behavior of operations with relativedelta: - -1) Calculate the absolute year, using the 'year' argument, or the - original datetime year, if the argument is not present. - -2) Add the relative 'years' argument to the absolute year. - -3) Do steps 1 and 2 for month/months. - -4) Calculate the absolute day, using the 'day' argument, or the - original datetime day, if the argument is not present. Then, - subtract from the day until it fits in the year and month - found after their operations. - -5) Add the relative 'days' argument to the absolute day. Notice - that the 'weeks' argument is multiplied by 7 and added to - 'days'. - -6) Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds, - microsecond/microseconds. - -7) If the 'weekday' argument is present, calculate the weekday, - with the given (wday, nth) tuple. wday is the index of the - weekday (0-6, 0=Mon), and nth is the number of weeks to add - forward or backward, depending on its signal. Notice that if - the calculated date is already Monday, for example, using - (0, 1) or (0, -1) won't change the day. - """ - - def __init__(self, dt1=None, dt2=None, - years=0, months=0, days=0, leapdays=0, weeks=0, - hours=0, minutes=0, seconds=0, microseconds=0, - year=None, month=None, day=None, weekday=None, - yearday=None, nlyearday=None, - hour=None, minute=None, second=None, microsecond=None): - if dt1 and dt2: - if not isinstance(dt1, datetime.date) or \ - not isinstance(dt2, datetime.date): - raise TypeError, "relativedelta only diffs datetime/date" - if type(dt1) is not type(dt2): - if not isinstance(dt1, datetime.datetime): - dt1 = datetime.datetime.fromordinal(dt1.toordinal()) - elif not isinstance(dt2, datetime.datetime): - dt2 = datetime.datetime.fromordinal(dt2.toordinal()) - self.years = 0 - self.months = 0 - self.days = 0 - self.leapdays = 0 - self.hours = 0 - self.minutes = 0 - self.seconds = 0 - self.microseconds = 0 - self.year = None - self.month = None - self.day = None - self.weekday = None - self.hour = None - self.minute = None - self.second = None - self.microsecond = None - self._has_time = 0 - - months = (dt1.year*12+dt1.month)-(dt2.year*12+dt2.month) - self._set_months(months) - dtm = self.__radd__(dt2) - if dt1 < dt2: - while dt1 > dtm: - months += 1 - self._set_months(months) - dtm = self.__radd__(dt2) - else: - while dt1 < dtm: - months -= 1 - self._set_months(months) - dtm = self.__radd__(dt2) - delta = dt1 - dtm - self.seconds = delta.seconds+delta.days*86400 - self.microseconds = delta.microseconds - else: - self.years = years - self.months = months - self.days = days+weeks*7 - self.leapdays = leapdays - self.hours = hours - self.minutes = minutes - self.seconds = seconds - self.microseconds = microseconds - self.year = year - self.month = month - self.day = day - self.hour = hour - self.minute = minute - self.second = second - self.microsecond = microsecond - - if type(weekday) is int: - self.weekday = weekdays[weekday] - else: - self.weekday = weekday - - yday = 0 - if nlyearday: - yday = nlyearday - elif yearday: - yday = yearday - if yearday > 59: - self.leapdays = -1 - if yday: - ydayidx = [31,59,90,120,151,181,212,243,273,304,334,366] - for idx, ydays in enumerate(ydayidx): - if yday <= ydays: - self.month = idx+1 - if idx == 0: - self.day = ydays - else: - self.day = yday-ydayidx[idx-1] - break - else: - raise ValueError, "invalid year day (%d)" % yday - - self._fix() - - def _fix(self): - if abs(self.microseconds) > 999999: - s = self.microseconds//abs(self.microseconds) - div, mod = divmod(self.microseconds*s, 1000000) - self.microseconds = mod*s - self.seconds += div*s - if abs(self.seconds) > 59: - s = self.seconds//abs(self.seconds) - div, mod = divmod(self.seconds*s, 60) - self.seconds = mod*s - self.minutes += div*s - if abs(self.minutes) > 59: - s = self.minutes//abs(self.minutes) - div, mod = divmod(self.minutes*s, 60) - self.minutes = mod*s - self.hours += div*s - if abs(self.hours) > 23: - s = self.hours//abs(self.hours) - div, mod = divmod(self.hours*s, 24) - self.hours = mod*s - self.days += div*s - if abs(self.months) > 11: - s = self.months//abs(self.months) - div, mod = divmod(self.months*s, 12) - self.months = mod*s - self.years += div*s - if (self.hours or self.minutes or self.seconds or self.microseconds or - self.hour is not None or self.minute is not None or - self.second is not None or self.microsecond is not None): - self._has_time = 1 - else: - self._has_time = 0 - - def _set_months(self, months): - self.months = months - if abs(self.months) > 11: - s = self.months//abs(self.months) - div, mod = divmod(self.months*s, 12) - self.months = mod*s - self.years = div*s - else: - self.years = 0 - - def __radd__(self, other): - if not isinstance(other, datetime.date): - raise TypeError, "unsupported type for add operation" - elif self._has_time and not isinstance(other, datetime.datetime): - other = datetime.datetime.fromordinal(other.toordinal()) - year = (self.year or other.year)+self.years - month = self.month or other.month - if self.months: - assert 1 <= abs(self.months) <= 12 - month += self.months - if month > 12: - year += 1 - month -= 12 - elif month < 1: - year -= 1 - month += 12 - day = min(calendar.monthrange(year, month)[1], - self.day or other.day) - repl = {"year": year, "month": month, "day": day} - for attr in ["hour", "minute", "second", "microsecond"]: - value = getattr(self, attr) - if value is not None: - repl[attr] = value - days = self.days - if self.leapdays and month > 2 and calendar.isleap(year): - days += self.leapdays - ret = (other.replace(**repl) - + datetime.timedelta(days=days, - hours=self.hours, - minutes=self.minutes, - seconds=self.seconds, - microseconds=self.microseconds)) - if self.weekday: - weekday, nth = self.weekday.weekday, self.weekday.n or 1 - jumpdays = (abs(nth)-1)*7 - if nth > 0: - jumpdays += (7-ret.weekday()+weekday)%7 - else: - jumpdays += (ret.weekday()-weekday)%7 - jumpdays *= -1 - ret += datetime.timedelta(days=jumpdays) - return ret - - def __rsub__(self, other): - return self.__neg__().__radd__(other) - - def __add__(self, other): - if not isinstance(other, relativedelta): - raise TypeError, "unsupported type for add operation" - return relativedelta(years=other.years+self.years, - months=other.months+self.months, - days=other.days+self.days, - hours=other.hours+self.hours, - minutes=other.minutes+self.minutes, - seconds=other.seconds+self.seconds, - microseconds=other.microseconds+self.microseconds, - leapdays=other.leapdays or self.leapdays, - year=other.year or self.year, - month=other.month or self.month, - day=other.day or self.day, - weekday=other.weekday or self.weekday, - hour=other.hour or self.hour, - minute=other.minute or self.minute, - second=other.second or self.second, - microsecond=other.second or self.microsecond) - - def __sub__(self, other): - if not isinstance(other, relativedelta): - raise TypeError, "unsupported type for sub operation" - return relativedelta(years=other.years-self.years, - months=other.months-self.months, - days=other.days-self.days, - hours=other.hours-self.hours, - minutes=other.minutes-self.minutes, - seconds=other.seconds-self.seconds, - microseconds=other.microseconds-self.microseconds, - leapdays=other.leapdays or self.leapdays, - year=other.year or self.year, - month=other.month or self.month, - day=other.day or self.day, - weekday=other.weekday or self.weekday, - hour=other.hour or self.hour, - minute=other.minute or self.minute, - second=other.second or self.second, - microsecond=other.second or self.microsecond) - - def __neg__(self): - return relativedelta(years=-self.years, - months=-self.months, - days=-self.days, - hours=-self.hours, - minutes=-self.minutes, - seconds=-self.seconds, - microseconds=-self.microseconds, - leapdays=self.leapdays, - year=self.year, - month=self.month, - day=self.day, - weekday=self.weekday, - hour=self.hour, - minute=self.minute, - second=self.second, - microsecond=self.microsecond) - - def __nonzero__(self): - return not (not self.years and - not self.months and - not self.days and - not self.hours and - not self.minutes and - not self.seconds and - not self.microseconds and - not self.leapdays and - self.year is None and - self.month is None and - self.day is None and - self.weekday is None and - self.hour is None and - self.minute is None and - self.second is None and - self.microsecond is None) - - def __mul__(self, other): - f = float(other) - return relativedelta(years=self.years*f, - months=self.months*f, - days=self.days*f, - hours=self.hours*f, - minutes=self.minutes*f, - seconds=self.seconds*f, - microseconds=self.microseconds*f, - leapdays=self.leapdays, - year=self.year, - month=self.month, - day=self.day, - weekday=self.weekday, - hour=self.hour, - minute=self.minute, - second=self.second, - microsecond=self.microsecond) - - def __eq__(self, other): - if not isinstance(other, relativedelta): - return False - if self.weekday or other.weekday: - if not self.weekday or not other.weekday: - return False - if self.weekday.weekday != other.weekday.weekday: - return False - n1, n2 = self.weekday.n, other.weekday.n - if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)): - return False - return (self.years == other.years and - self.months == other.months and - self.days == other.days and - self.hours == other.hours and - self.minutes == other.minutes and - self.seconds == other.seconds and - self.leapdays == other.leapdays and - self.year == other.year and - self.month == other.month and - self.day == other.day and - self.hour == other.hour and - self.minute == other.minute and - self.second == other.second and - self.microsecond == other.microsecond) - - def __ne__(self, other): - return not self.__eq__(other) - - def __div__(self, other): - return self.__mul__(1/float(other)) - - def __repr__(self): - l = [] - for attr in ["years", "months", "days", "leapdays", - "hours", "minutes", "seconds", "microseconds"]: - value = getattr(self, attr) - if value: - l.append("%s=%+d" % (attr, value)) - for attr in ["year", "month", "day", "weekday", - "hour", "minute", "second", "microsecond"]: - value = getattr(self, attr) - if value is not None: - l.append("%s=%s" % (attr, `value`)) - return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) - -# vim:ts=4:sw=4:et diff --git a/utils/dateutil/rrule.py b/utils/dateutil/rrule.py deleted file mode 100644 index 4c21d2d1d..000000000 --- a/utils/dateutil/rrule.py +++ /dev/null @@ -1,1097 +0,0 @@ -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import itertools -import datetime -import calendar -import thread -import sys - -__all__ = ["rrule", "rruleset", "rrulestr", - "YEARLY", "MONTHLY", "WEEKLY", "DAILY", - "HOURLY", "MINUTELY", "SECONDLY", - "MO", "TU", "WE", "TH", "FR", "SA", "SU"] - -# Every mask is 7 days longer to handle cross-year weekly periods. -M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30+ - [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7) -M365MASK = list(M366MASK) -M29, M30, M31 = range(1,30), range(1,31), range(1,32) -MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) -MDAY365MASK = list(MDAY366MASK) -M29, M30, M31 = range(-29,0), range(-30,0), range(-31,0) -NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) -NMDAY365MASK = list(NMDAY366MASK) -M366RANGE = (0,31,60,91,121,152,182,213,244,274,305,335,366) -M365RANGE = (0,31,59,90,120,151,181,212,243,273,304,334,365) -WDAYMASK = [0,1,2,3,4,5,6]*55 -del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31] -MDAY365MASK = tuple(MDAY365MASK) -M365MASK = tuple(M365MASK) - -(YEARLY, - MONTHLY, - WEEKLY, - DAILY, - HOURLY, - MINUTELY, - SECONDLY) = range(7) - -# Imported on demand. -easter = None -parser = None - -class weekday(object): - __slots__ = ["weekday", "n"] - - def __init__(self, weekday, n=None): - if n == 0: - raise ValueError, "Can't create weekday with n == 0" - self.weekday = weekday - self.n = n - - def __call__(self, n): - if n == self.n: - return self - else: - return self.__class__(self.weekday, n) - - def __eq__(self, other): - try: - if self.weekday != other.weekday or self.n != other.n: - return False - except AttributeError: - return False - return True - - def __repr__(self): - s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] - if not self.n: - return s - else: - return "%s(%+d)" % (s, self.n) - -MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) - -class rrulebase: - def __init__(self, cache=False): - if cache: - self._cache = [] - self._cache_lock = thread.allocate_lock() - self._cache_gen = self._iter() - self._cache_complete = False - else: - self._cache = None - self._cache_complete = False - self._len = None - - def __iter__(self): - if self._cache_complete: - return iter(self._cache) - elif self._cache is None: - return self._iter() - else: - return self._iter_cached() - - def _iter_cached(self): - i = 0 - gen = self._cache_gen - cache = self._cache - acquire = self._cache_lock.acquire - release = self._cache_lock.release - while gen: - if i == len(cache): - acquire() - if self._cache_complete: - break - try: - for j in range(10): - cache.append(gen.next()) - except StopIteration: - self._cache_gen = gen = None - self._cache_complete = True - break - release() - yield cache[i] - i += 1 - while i < self._len: - yield cache[i] - i += 1 - - def __getitem__(self, item): - if self._cache_complete: - return self._cache[item] - elif isinstance(item, slice): - if item.step and item.step < 0: - return list(iter(self))[item] - else: - return list(itertools.islice(self, - item.start or 0, - item.stop or sys.maxint, - item.step or 1)) - elif item >= 0: - gen = iter(self) - try: - for i in range(item+1): - res = gen.next() - except StopIteration: - raise IndexError - return res - else: - return list(iter(self))[item] - - def __contains__(self, item): - if self._cache_complete: - return item in self._cache - else: - for i in self: - if i == item: - return True - elif i > item: - return False - return False - - # __len__() introduces a large performance penality. - def count(self): - if self._len is None: - for x in self: pass - return self._len - - def before(self, dt, inc=False): - if self._cache_complete: - gen = self._cache - else: - gen = self - last = None - if inc: - for i in gen: - if i > dt: - break - last = i - else: - for i in gen: - if i >= dt: - break - last = i - return last - - def after(self, dt, inc=False): - if self._cache_complete: - gen = self._cache - else: - gen = self - if inc: - for i in gen: - if i >= dt: - return i - else: - for i in gen: - if i > dt: - return i - return None - - def between(self, after, before, inc=False): - if self._cache_complete: - gen = self._cache - else: - gen = self - started = False - l = [] - if inc: - for i in gen: - if i > before: - break - elif not started: - if i >= after: - started = True - l.append(i) - else: - l.append(i) - else: - for i in gen: - if i >= before: - break - elif not started: - if i > after: - started = True - l.append(i) - else: - l.append(i) - return l - -class rrule(rrulebase): - def __init__(self, freq, dtstart=None, - interval=1, wkst=None, count=None, until=None, bysetpos=None, - bymonth=None, bymonthday=None, byyearday=None, byeaster=None, - byweekno=None, byweekday=None, - byhour=None, byminute=None, bysecond=None, - cache=False): - rrulebase.__init__(self, cache) - global easter - if not dtstart: - dtstart = datetime.datetime.now().replace(microsecond=0) - elif not isinstance(dtstart, datetime.datetime): - dtstart = datetime.datetime.fromordinal(dtstart.toordinal()) - else: - dtstart = dtstart.replace(microsecond=0) - self._dtstart = dtstart - self._tzinfo = dtstart.tzinfo - self._freq = freq - self._interval = interval - self._count = count - if until and not isinstance(until, datetime.datetime): - until = datetime.datetime.fromordinal(until.toordinal()) - self._until = until - if wkst is None: - self._wkst = calendar.firstweekday() - elif type(wkst) is int: - self._wkst = wkst - else: - self._wkst = wkst.weekday - if bysetpos is None: - self._bysetpos = None - elif type(bysetpos) is int: - if bysetpos == 0 or not (-366 <= bysetpos <= 366): - raise ValueError("bysetpos must be between 1 and 366, " - "or between -366 and -1") - self._bysetpos = (bysetpos,) - else: - self._bysetpos = tuple(bysetpos) - for pos in self._bysetpos: - if pos == 0 or not (-366 <= pos <= 366): - raise ValueError("bysetpos must be between 1 and 366, " - "or between -366 and -1") - if not (byweekno or byyearday or bymonthday or - byweekday is not None or byeaster is not None): - if freq == YEARLY: - if not bymonth: - bymonth = dtstart.month - bymonthday = dtstart.day - elif freq == MONTHLY: - bymonthday = dtstart.day - elif freq == WEEKLY: - byweekday = dtstart.weekday() - # bymonth - if not bymonth: - self._bymonth = None - elif type(bymonth) is int: - self._bymonth = (bymonth,) - else: - self._bymonth = tuple(bymonth) - # byyearday - if not byyearday: - self._byyearday = None - elif type(byyearday) is int: - self._byyearday = (byyearday,) - else: - self._byyearday = tuple(byyearday) - # byeaster - if byeaster is not None: - if not easter: - from dateutil import easter - if type(byeaster) is int: - self._byeaster = (byeaster,) - else: - self._byeaster = tuple(byeaster) - else: - self._byeaster = None - # bymonthay - if not bymonthday: - self._bymonthday = () - self._bynmonthday = () - elif type(bymonthday) is int: - if bymonthday < 0: - self._bynmonthday = (bymonthday,) - self._bymonthday = () - else: - self._bymonthday = (bymonthday,) - self._bynmonthday = () - else: - self._bymonthday = tuple([x for x in bymonthday if x > 0]) - self._bynmonthday = tuple([x for x in bymonthday if x < 0]) - # byweekno - if byweekno is None: - self._byweekno = None - elif type(byweekno) is int: - self._byweekno = (byweekno,) - else: - self._byweekno = tuple(byweekno) - # byweekday / bynweekday - if byweekday is None: - self._byweekday = None - self._bynweekday = None - elif type(byweekday) is int: - self._byweekday = (byweekday,) - self._bynweekday = None - elif hasattr(byweekday, "n"): - if not byweekday.n or freq > MONTHLY: - self._byweekday = (byweekday.weekday,) - self._bynweekday = None - else: - self._bynweekday = ((byweekday.weekday, byweekday.n),) - self._byweekday = None - else: - self._byweekday = [] - self._bynweekday = [] - for wday in byweekday: - if type(wday) is int: - self._byweekday.append(wday) - elif not wday.n or freq > MONTHLY: - self._byweekday.append(wday.weekday) - else: - self._bynweekday.append((wday.weekday, wday.n)) - self._byweekday = tuple(self._byweekday) - self._bynweekday = tuple(self._bynweekday) - if not self._byweekday: - self._byweekday = None - elif not self._bynweekday: - self._bynweekday = None - # byhour - if byhour is None: - if freq < HOURLY: - self._byhour = (dtstart.hour,) - else: - self._byhour = None - elif type(byhour) is int: - self._byhour = (byhour,) - else: - self._byhour = tuple(byhour) - # byminute - if byminute is None: - if freq < MINUTELY: - self._byminute = (dtstart.minute,) - else: - self._byminute = None - elif type(byminute) is int: - self._byminute = (byminute,) - else: - self._byminute = tuple(byminute) - # bysecond - if bysecond is None: - if freq < SECONDLY: - self._bysecond = (dtstart.second,) - else: - self._bysecond = None - elif type(bysecond) is int: - self._bysecond = (bysecond,) - else: - self._bysecond = tuple(bysecond) - - if self._freq >= HOURLY: - self._timeset = None - else: - self._timeset = [] - for hour in self._byhour: - for minute in self._byminute: - for second in self._bysecond: - self._timeset.append( - datetime.time(hour, minute, second, - tzinfo=self._tzinfo)) - self._timeset.sort() - self._timeset = tuple(self._timeset) - - def _iter(self): - year, month, day, hour, minute, second, weekday, yearday, _ = \ - self._dtstart.timetuple() - - # Some local variables to speed things up a bit - freq = self._freq - interval = self._interval - wkst = self._wkst - until = self._until - bymonth = self._bymonth - byweekno = self._byweekno - byyearday = self._byyearday - byweekday = self._byweekday - byeaster = self._byeaster - bymonthday = self._bymonthday - bynmonthday = self._bynmonthday - bysetpos = self._bysetpos - byhour = self._byhour - byminute = self._byminute - bysecond = self._bysecond - - ii = _iterinfo(self) - ii.rebuild(year, month) - - getdayset = {YEARLY:ii.ydayset, - MONTHLY:ii.mdayset, - WEEKLY:ii.wdayset, - DAILY:ii.ddayset, - HOURLY:ii.ddayset, - MINUTELY:ii.ddayset, - SECONDLY:ii.ddayset}[freq] - - if freq < HOURLY: - timeset = self._timeset - else: - gettimeset = {HOURLY:ii.htimeset, - MINUTELY:ii.mtimeset, - SECONDLY:ii.stimeset}[freq] - if ((freq >= HOURLY and - self._byhour and hour not in self._byhour) or - (freq >= MINUTELY and - self._byminute and minute not in self._byminute) or - (freq >= SECONDLY and - self._bysecond and minute not in self._bysecond)): - timeset = () - else: - timeset = gettimeset(hour, minute, second) - - total = 0 - count = self._count - while True: - # Get dayset with the right frequency - dayset, start, end = getdayset(year, month, day) - - # Do the "hard" work ;-) - filtered = False - for i in dayset[start:end]: - if ((bymonth and ii.mmask[i] not in bymonth) or - (byweekno and not ii.wnomask[i]) or - (byweekday and ii.wdaymask[i] not in byweekday) or - (ii.nwdaymask and not ii.nwdaymask[i]) or - (byeaster and not ii.eastermask[i]) or - ((bymonthday or bynmonthday) and - ii.mdaymask[i] not in bymonthday and - ii.nmdaymask[i] not in bynmonthday) or - (byyearday and - ((i < ii.yearlen and i+1 not in byyearday - and -ii.yearlen+i not in byyearday) or - (i >= ii.yearlen and i+1-ii.yearlen not in byyearday - and -ii.nextyearlen+i-ii.yearlen - not in byyearday)))): - dayset[i] = None - filtered = True - - # Output results - if bysetpos and timeset: - poslist = [] - for pos in bysetpos: - if pos < 0: - daypos, timepos = divmod(pos, len(timeset)) - else: - daypos, timepos = divmod(pos-1, len(timeset)) - try: - i = [x for x in dayset[start:end] - if x is not None][daypos] - time = timeset[timepos] - except IndexError: - pass - else: - date = datetime.date.fromordinal(ii.yearordinal+i) - res = datetime.datetime.combine(date, time) - if res not in poslist: - poslist.append(res) - poslist.sort() - for res in poslist: - if until and res > until: - self._len = total - return - elif res >= self._dtstart: - total += 1 - yield res - if count: - count -= 1 - if not count: - self._len = total - return - else: - for i in dayset[start:end]: - if i is not None: - date = datetime.date.fromordinal(ii.yearordinal+i) - for time in timeset: - res = datetime.datetime.combine(date, time) - if until and res > until: - self._len = total - return - elif res >= self._dtstart: - total += 1 - yield res - if count: - count -= 1 - if not count: - self._len = total - return - - # Handle frequency and interval - fixday = False - if freq == YEARLY: - year += interval - if year > datetime.MAXYEAR: - self._len = total - return - ii.rebuild(year, month) - elif freq == MONTHLY: - month += interval - if month > 12: - div, mod = divmod(month, 12) - month = mod - year += div - if month == 0: - month = 12 - year -= 1 - if year > datetime.MAXYEAR: - self._len = total - return - ii.rebuild(year, month) - elif freq == WEEKLY: - if wkst > weekday: - day += -(weekday+1+(6-wkst))+self._interval*7 - else: - day += -(weekday-wkst)+self._interval*7 - weekday = wkst - fixday = True - elif freq == DAILY: - day += interval - fixday = True - elif freq == HOURLY: - if filtered: - # Jump to one iteration before next day - hour += ((23-hour)//interval)*interval - while True: - hour += interval - div, mod = divmod(hour, 24) - if div: - hour = mod - day += div - fixday = True - if not byhour or hour in byhour: - break - timeset = gettimeset(hour, minute, second) - elif freq == MINUTELY: - if filtered: - # Jump to one iteration before next day - minute += ((1439-(hour*60+minute))//interval)*interval - while True: - minute += interval - div, mod = divmod(minute, 60) - if div: - minute = mod - hour += div - div, mod = divmod(hour, 24) - if div: - hour = mod - day += div - fixday = True - filtered = False - if ((not byhour or hour in byhour) and - (not byminute or minute in byminute)): - break - timeset = gettimeset(hour, minute, second) - elif freq == SECONDLY: - if filtered: - # Jump to one iteration before next day - second += (((86399-(hour*3600+minute*60+second)) - //interval)*interval) - while True: - second += self._interval - div, mod = divmod(second, 60) - if div: - second = mod - minute += div - div, mod = divmod(minute, 60) - if div: - minute = mod - hour += div - div, mod = divmod(hour, 24) - if div: - hour = mod - day += div - fixday = True - if ((not byhour or hour in byhour) and - (not byminute or minute in byminute) and - (not bysecond or second in bysecond)): - break - timeset = gettimeset(hour, minute, second) - - if fixday and day > 28: - daysinmonth = calendar.monthrange(year, month)[1] - if day > daysinmonth: - while day > daysinmonth: - day -= daysinmonth - month += 1 - if month == 13: - month = 1 - year += 1 - if year > datetime.MAXYEAR: - self._len = total - return - daysinmonth = calendar.monthrange(year, month)[1] - ii.rebuild(year, month) - -class _iterinfo(object): - __slots__ = ["rrule", "lastyear", "lastmonth", - "yearlen", "nextyearlen", "yearordinal", "yearweekday", - "mmask", "mrange", "mdaymask", "nmdaymask", - "wdaymask", "wnomask", "nwdaymask", "eastermask"] - - def __init__(self, rrule): - for attr in self.__slots__: - setattr(self, attr, None) - self.rrule = rrule - - def rebuild(self, year, month): - # Every mask is 7 days longer to handle cross-year weekly periods. - rr = self.rrule - if year != self.lastyear: - self.yearlen = 365+calendar.isleap(year) - self.nextyearlen = 365+calendar.isleap(year+1) - firstyday = datetime.date(year, 1, 1) - self.yearordinal = firstyday.toordinal() - self.yearweekday = firstyday.weekday() - - wday = datetime.date(year, 1, 1).weekday() - if self.yearlen == 365: - self.mmask = M365MASK - self.mdaymask = MDAY365MASK - self.nmdaymask = NMDAY365MASK - self.wdaymask = WDAYMASK[wday:] - self.mrange = M365RANGE - else: - self.mmask = M366MASK - self.mdaymask = MDAY366MASK - self.nmdaymask = NMDAY366MASK - self.wdaymask = WDAYMASK[wday:] - self.mrange = M366RANGE - - if not rr._byweekno: - self.wnomask = None - else: - self.wnomask = [0]*(self.yearlen+7) - #no1wkst = firstwkst = self.wdaymask.index(rr._wkst) - no1wkst = firstwkst = (7-self.yearweekday+rr._wkst)%7 - if no1wkst >= 4: - no1wkst = 0 - # Number of days in the year, plus the days we got - # from last year. - wyearlen = self.yearlen+(self.yearweekday-rr._wkst)%7 - else: - # Number of days in the year, minus the days we - # left in last year. - wyearlen = self.yearlen-no1wkst - div, mod = divmod(wyearlen, 7) - numweeks = div+mod//4 - for n in rr._byweekno: - if n < 0: - n += numweeks+1 - if not (0 < n <= numweeks): - continue - if n > 1: - i = no1wkst+(n-1)*7 - if no1wkst != firstwkst: - i -= 7-firstwkst - else: - i = no1wkst - for j in range(7): - self.wnomask[i] = 1 - i += 1 - if self.wdaymask[i] == rr._wkst: - break - if 1 in rr._byweekno: - # Check week number 1 of next year as well - # TODO: Check -numweeks for next year. - i = no1wkst+numweeks*7 - if no1wkst != firstwkst: - i -= 7-firstwkst - if i < self.yearlen: - # If week starts in next year, we - # don't care about it. - for j in range(7): - self.wnomask[i] = 1 - i += 1 - if self.wdaymask[i] == rr._wkst: - break - if no1wkst: - # Check last week number of last year as - # well. If no1wkst is 0, either the year - # started on week start, or week number 1 - # got days from last year, so there are no - # days from last year's last week number in - # this year. - if -1 not in rr._byweekno: - lyearweekday = datetime.date(year-1,1,1).weekday() - lno1wkst = (7-lyearweekday+rr._wkst)%7 - lyearlen = 365+calendar.isleap(year-1) - if lno1wkst >= 4: - lno1wkst = 0 - lnumweeks = 52+(lyearlen+ - (lyearweekday-rr._wkst)%7)%7//4 - else: - lnumweeks = 52+(self.yearlen-no1wkst)%7//4 - else: - lnumweeks = -1 - if lnumweeks in rr._byweekno: - for i in range(no1wkst): - self.wnomask[i] = 1 - - if (rr._bynweekday and - (month != self.lastmonth or year != self.lastyear)): - ranges = [] - if rr._freq == YEARLY: - if rr._bymonth: - for month in rr._bymonth: - ranges.append(self.mrange[month-1:month+1]) - else: - ranges = [(0, self.yearlen)] - elif rr._freq == MONTHLY: - ranges = [self.mrange[month-1:month+1]] - if ranges: - # Weekly frequency won't get here, so we may not - # care about cross-year weekly periods. - self.nwdaymask = [0]*self.yearlen - for first, last in ranges: - last -= 1 - for wday, n in rr._bynweekday: - if n < 0: - i = last+(n+1)*7 - i -= (self.wdaymask[i]-wday)%7 - else: - i = first+(n-1)*7 - i += (7-self.wdaymask[i]+wday)%7 - if first <= i <= last: - self.nwdaymask[i] = 1 - - if rr._byeaster: - self.eastermask = [0]*(self.yearlen+7) - eyday = easter.easter(year).toordinal()-self.yearordinal - for offset in rr._byeaster: - self.eastermask[eyday+offset] = 1 - - self.lastyear = year - self.lastmonth = month - - def ydayset(self, year, month, day): - return range(self.yearlen), 0, self.yearlen - - def mdayset(self, year, month, day): - set = [None]*self.yearlen - start, end = self.mrange[month-1:month+1] - for i in range(start, end): - set[i] = i - return set, start, end - - def wdayset(self, year, month, day): - # We need to handle cross-year weeks here. - set = [None]*(self.yearlen+7) - i = datetime.date(year, month, day).toordinal()-self.yearordinal - start = i - for j in range(7): - set[i] = i - i += 1 - #if (not (0 <= i < self.yearlen) or - # self.wdaymask[i] == self.rrule._wkst): - # This will cross the year boundary, if necessary. - if self.wdaymask[i] == self.rrule._wkst: - break - return set, start, i - - def ddayset(self, year, month, day): - set = [None]*self.yearlen - i = datetime.date(year, month, day).toordinal()-self.yearordinal - set[i] = i - return set, i, i+1 - - def htimeset(self, hour, minute, second): - set = [] - rr = self.rrule - for minute in rr._byminute: - for second in rr._bysecond: - set.append(datetime.time(hour, minute, second, - tzinfo=rr._tzinfo)) - set.sort() - return set - - def mtimeset(self, hour, minute, second): - set = [] - rr = self.rrule - for second in rr._bysecond: - set.append(datetime.time(hour, minute, second, tzinfo=rr._tzinfo)) - set.sort() - return set - - def stimeset(self, hour, minute, second): - return (datetime.time(hour, minute, second, - tzinfo=self.rrule._tzinfo),) - - -class rruleset(rrulebase): - - class _genitem: - def __init__(self, genlist, gen): - try: - self.dt = gen() - genlist.append(self) - except StopIteration: - pass - self.genlist = genlist - self.gen = gen - - def next(self): - try: - self.dt = self.gen() - except StopIteration: - self.genlist.remove(self) - - def __cmp__(self, other): - return cmp(self.dt, other.dt) - - def __init__(self, cache=False): - rrulebase.__init__(self, cache) - self._rrule = [] - self._rdate = [] - self._exrule = [] - self._exdate = [] - - def rrule(self, rrule): - self._rrule.append(rrule) - - def rdate(self, rdate): - self._rdate.append(rdate) - - def exrule(self, exrule): - self._exrule.append(exrule) - - def exdate(self, exdate): - self._exdate.append(exdate) - - def _iter(self): - rlist = [] - self._rdate.sort() - self._genitem(rlist, iter(self._rdate).next) - for gen in [iter(x).next for x in self._rrule]: - self._genitem(rlist, gen) - rlist.sort() - exlist = [] - self._exdate.sort() - self._genitem(exlist, iter(self._exdate).next) - for gen in [iter(x).next for x in self._exrule]: - self._genitem(exlist, gen) - exlist.sort() - lastdt = None - total = 0 - while rlist: - ritem = rlist[0] - if not lastdt or lastdt != ritem.dt: - while exlist and exlist[0] < ritem: - exlist[0].next() - exlist.sort() - if not exlist or ritem != exlist[0]: - total += 1 - yield ritem.dt - lastdt = ritem.dt - ritem.next() - rlist.sort() - self._len = total - -class _rrulestr: - - _freq_map = {"YEARLY": YEARLY, - "MONTHLY": MONTHLY, - "WEEKLY": WEEKLY, - "DAILY": DAILY, - "HOURLY": HOURLY, - "MINUTELY": MINUTELY, - "SECONDLY": SECONDLY} - - _weekday_map = {"MO":0,"TU":1,"WE":2,"TH":3,"FR":4,"SA":5,"SU":6} - - def _handle_int(self, rrkwargs, name, value, **kwargs): - rrkwargs[name.lower()] = int(value) - - def _handle_int_list(self, rrkwargs, name, value, **kwargs): - rrkwargs[name.lower()] = [int(x) for x in value.split(',')] - - _handle_INTERVAL = _handle_int - _handle_COUNT = _handle_int - _handle_BYSETPOS = _handle_int_list - _handle_BYMONTH = _handle_int_list - _handle_BYMONTHDAY = _handle_int_list - _handle_BYYEARDAY = _handle_int_list - _handle_BYEASTER = _handle_int_list - _handle_BYWEEKNO = _handle_int_list - _handle_BYHOUR = _handle_int_list - _handle_BYMINUTE = _handle_int_list - _handle_BYSECOND = _handle_int_list - - def _handle_FREQ(self, rrkwargs, name, value, **kwargs): - rrkwargs["freq"] = self._freq_map[value] - - def _handle_UNTIL(self, rrkwargs, name, value, **kwargs): - global parser - if not parser: - from dateutil import parser - try: - rrkwargs["until"] = parser.parse(value, - ignoretz=kwargs.get("ignoretz"), - tzinfos=kwargs.get("tzinfos")) - except ValueError: - raise ValueError, "invalid until date" - - def _handle_WKST(self, rrkwargs, name, value, **kwargs): - rrkwargs["wkst"] = self._weekday_map[value] - - def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwarsg): - l = [] - for wday in value.split(','): - for i in range(len(wday)): - if wday[i] not in '+-0123456789': - break - n = wday[:i] or None - w = wday[i:] - if n: n = int(n) - l.append(weekdays[self._weekday_map[w]](n)) - rrkwargs["byweekday"] = l - - _handle_BYDAY = _handle_BYWEEKDAY - - def _parse_rfc_rrule(self, line, - dtstart=None, - cache=False, - ignoretz=False, - tzinfos=None): - if line.find(':') != -1: - name, value = line.split(':') - if name != "RRULE": - raise ValueError, "unknown parameter name" - else: - value = line - rrkwargs = {} - for pair in value.split(';'): - name, value = pair.split('=') - name = name.upper() - value = value.upper() - try: - getattr(self, "_handle_"+name)(rrkwargs, name, value, - ignoretz=ignoretz, - tzinfos=tzinfos) - except AttributeError: - raise ValueError, "unknown parameter '%s'" % name - except (KeyError, ValueError): - raise ValueError, "invalid '%s': %s" % (name, value) - return rrule(dtstart=dtstart, cache=cache, **rrkwargs) - - def _parse_rfc(self, s, - dtstart=None, - cache=False, - unfold=False, - forceset=False, - compatible=False, - ignoretz=False, - tzinfos=None): - global parser - if compatible: - forceset = True - unfold = True - s = s.upper() - if not s.strip(): - raise ValueError, "empty string" - if unfold: - lines = s.splitlines() - i = 0 - while i < len(lines): - line = lines[i].rstrip() - if not line: - del lines[i] - elif i > 0 and line[0] == " ": - lines[i-1] += line[1:] - del lines[i] - else: - i += 1 - else: - lines = s.split() - if (not forceset and len(lines) == 1 and - (s.find(':') == -1 or s.startswith('RRULE:'))): - return self._parse_rfc_rrule(lines[0], cache=cache, - dtstart=dtstart, ignoretz=ignoretz, - tzinfos=tzinfos) - else: - rrulevals = [] - rdatevals = [] - exrulevals = [] - exdatevals = [] - for line in lines: - if not line: - continue - if line.find(':') == -1: - name = "RRULE" - value = line - else: - name, value = line.split(':', 1) - parms = name.split(';') - if not parms: - raise ValueError, "empty property name" - name = parms[0] - parms = parms[1:] - if name == "RRULE": - for parm in parms: - raise ValueError, "unsupported RRULE parm: "+parm - rrulevals.append(value) - elif name == "RDATE": - for parm in parms: - if parm != "VALUE=DATE-TIME": - raise ValueError, "unsupported RDATE parm: "+parm - rdatevals.append(value) - elif name == "EXRULE": - for parm in parms: - raise ValueError, "unsupported EXRULE parm: "+parm - exrulevals.append(value) - elif name == "EXDATE": - for parm in parms: - if parm != "VALUE=DATE-TIME": - raise ValueError, "unsupported RDATE parm: "+parm - exdatevals.append(value) - elif name == "DTSTART": - for parm in parms: - raise ValueError, "unsupported DTSTART parm: "+parm - if not parser: - from dateutil import parser - dtstart = parser.parse(value, ignoretz=ignoretz, - tzinfos=tzinfos) - else: - raise ValueError, "unsupported property: "+name - if (forceset or len(rrulevals) > 1 or - rdatevals or exrulevals or exdatevals): - if not parser and (rdatevals or exdatevals): - from dateutil import parser - set = rruleset(cache=cache) - for value in rrulevals: - set.rrule(self._parse_rfc_rrule(value, dtstart=dtstart, - ignoretz=ignoretz, - tzinfos=tzinfos)) - for value in rdatevals: - for datestr in value.split(','): - set.rdate(parser.parse(datestr, - ignoretz=ignoretz, - tzinfos=tzinfos)) - for value in exrulevals: - set.exrule(self._parse_rfc_rrule(value, dtstart=dtstart, - ignoretz=ignoretz, - tzinfos=tzinfos)) - for value in exdatevals: - for datestr in value.split(','): - set.exdate(parser.parse(datestr, - ignoretz=ignoretz, - tzinfos=tzinfos)) - if compatible and dtstart: - set.rdate(dtstart) - return set - else: - return self._parse_rfc_rrule(rrulevals[0], - dtstart=dtstart, - cache=cache, - ignoretz=ignoretz, - tzinfos=tzinfos) - - def __call__(self, s, **kwargs): - return self._parse_rfc(s, **kwargs) - -rrulestr = _rrulestr() - -# vim:ts=4:sw=4:et diff --git a/utils/dateutil/tz.py b/utils/dateutil/tz.py deleted file mode 100644 index 0e28d6b33..000000000 --- a/utils/dateutil/tz.py +++ /dev/null @@ -1,951 +0,0 @@ -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import datetime -import struct -import time -import sys -import os - -relativedelta = None -parser = None -rrule = None - -__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", - "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"] - -try: - from dateutil.tzwin import tzwin, tzwinlocal -except (ImportError, OSError): - tzwin, tzwinlocal = None, None - -ZERO = datetime.timedelta(0) -EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal() - -class tzutc(datetime.tzinfo): - - def utcoffset(self, dt): - return ZERO - - def dst(self, dt): - return ZERO - - def tzname(self, dt): - return "UTC" - - def __eq__(self, other): - return (isinstance(other, tzutc) or - (isinstance(other, tzoffset) and other._offset == ZERO)) - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "%s()" % self.__class__.__name__ - - __reduce__ = object.__reduce__ - -class tzoffset(datetime.tzinfo): - - def __init__(self, name, offset): - self._name = name - self._offset = datetime.timedelta(seconds=offset) - - def utcoffset(self, dt): - return self._offset - - def dst(self, dt): - return ZERO - - def tzname(self, dt): - return self._name - - def __eq__(self, other): - return (isinstance(other, tzoffset) and - self._offset == other._offset) - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "%s(%s, %s)" % (self.__class__.__name__, - `self._name`, - self._offset.days*86400+self._offset.seconds) - - __reduce__ = object.__reduce__ - -class tzlocal(datetime.tzinfo): - - _std_offset = datetime.timedelta(seconds=-time.timezone) - if time.daylight: - _dst_offset = datetime.timedelta(seconds=-time.altzone) - else: - _dst_offset = _std_offset - - def utcoffset(self, dt): - if self._isdst(dt): - return self._dst_offset - else: - return self._std_offset - - def dst(self, dt): - if self._isdst(dt): - return self._dst_offset-self._std_offset - else: - return ZERO - - def tzname(self, dt): - return time.tzname[self._isdst(dt)] - - def _isdst(self, dt): - # We can't use mktime here. It is unstable when deciding if - # the hour near to a change is DST or not. - # - # timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour, - # dt.minute, dt.second, dt.weekday(), 0, -1)) - # return time.localtime(timestamp).tm_isdst - # - # The code above yields the following result: - # - #>>> import tz, datetime - #>>> t = tz.tzlocal() - #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() - #'BRDT' - #>>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname() - #'BRST' - #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() - #'BRST' - #>>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname() - #'BRDT' - #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() - #'BRDT' - # - # Here is a more stable implementation: - # - timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 - + dt.hour * 3600 - + dt.minute * 60 - + dt.second) - return time.localtime(timestamp+time.timezone).tm_isdst - - def __eq__(self, other): - if not isinstance(other, tzlocal): - return False - return (self._std_offset == other._std_offset and - self._dst_offset == other._dst_offset) - return True - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "%s()" % self.__class__.__name__ - - __reduce__ = object.__reduce__ - -class _ttinfo(object): - __slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"] - - def __init__(self): - for attr in self.__slots__: - setattr(self, attr, None) - - def __repr__(self): - l = [] - for attr in self.__slots__: - value = getattr(self, attr) - if value is not None: - l.append("%s=%s" % (attr, `value`)) - return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) - - def __eq__(self, other): - if not isinstance(other, _ttinfo): - return False - return (self.offset == other.offset and - self.delta == other.delta and - self.isdst == other.isdst and - self.abbr == other.abbr and - self.isstd == other.isstd and - self.isgmt == other.isgmt) - - def __ne__(self, other): - return not self.__eq__(other) - - def __getstate__(self): - state = {} - for name in self.__slots__: - state[name] = getattr(self, name, None) - return state - - def __setstate__(self, state): - for name in self.__slots__: - if name in state: - setattr(self, name, state[name]) - -class tzfile(datetime.tzinfo): - - # http://www.twinsun.com/tz/tz-link.htm - # ftp://elsie.nci.nih.gov/pub/tz*.tar.gz - - def __init__(self, fileobj): - if isinstance(fileobj, basestring): - self._filename = fileobj - fileobj = open(fileobj) - elif hasattr(fileobj, "name"): - self._filename = fileobj.name - else: - self._filename = `fileobj` - - # From tzfile(5): - # - # The time zone information files used by tzset(3) - # begin with the magic characters "TZif" to identify - # them as time zone information files, followed by - # sixteen bytes reserved for future use, followed by - # six four-byte values of type long, written in a - # ``standard'' byte order (the high-order byte - # of the value is written first). - - if fileobj.read(4) != "TZif": - raise ValueError, "magic not found" - - fileobj.read(16) - - ( - # The number of UTC/local indicators stored in the file. - ttisgmtcnt, - - # The number of standard/wall indicators stored in the file. - ttisstdcnt, - - # The number of leap seconds for which data is - # stored in the file. - leapcnt, - - # The number of "transition times" for which data - # is stored in the file. - timecnt, - - # The number of "local time types" for which data - # is stored in the file (must not be zero). - typecnt, - - # The number of characters of "time zone - # abbreviation strings" stored in the file. - charcnt, - - ) = struct.unpack(">6l", fileobj.read(24)) - - # The above header is followed by tzh_timecnt four-byte - # values of type long, sorted in ascending order. - # These values are written in ``standard'' byte order. - # Each is used as a transition time (as returned by - # time(2)) at which the rules for computing local time - # change. - - if timecnt: - self._trans_list = struct.unpack(">%dl" % timecnt, - fileobj.read(timecnt*4)) - else: - self._trans_list = [] - - # Next come tzh_timecnt one-byte values of type unsigned - # char; each one tells which of the different types of - # ``local time'' types described in the file is associated - # with the same-indexed transition time. These values - # serve as indices into an array of ttinfo structures that - # appears next in the file. - - if timecnt: - self._trans_idx = struct.unpack(">%dB" % timecnt, - fileobj.read(timecnt)) - else: - self._trans_idx = [] - - # Each ttinfo structure is written as a four-byte value - # for tt_gmtoff of type long, in a standard byte - # order, followed by a one-byte value for tt_isdst - # and a one-byte value for tt_abbrind. In each - # structure, tt_gmtoff gives the number of - # seconds to be added to UTC, tt_isdst tells whether - # tm_isdst should be set by localtime(3), and - # tt_abbrind serves as an index into the array of - # time zone abbreviation characters that follow the - # ttinfo structure(s) in the file. - - ttinfo = [] - - for i in range(typecnt): - ttinfo.append(struct.unpack(">lbb", fileobj.read(6))) - - abbr = fileobj.read(charcnt) - - # Then there are tzh_leapcnt pairs of four-byte - # values, written in standard byte order; the - # first value of each pair gives the time (as - # returned by time(2)) at which a leap second - # occurs; the second gives the total number of - # leap seconds to be applied after the given time. - # The pairs of values are sorted in ascending order - # by time. - - # Not used, for now - if leapcnt: - leap = struct.unpack(">%dl" % (leapcnt*2), - fileobj.read(leapcnt*8)) - - # Then there are tzh_ttisstdcnt standard/wall - # indicators, each stored as a one-byte value; - # they tell whether the transition times associated - # with local time types were specified as standard - # time or wall clock time, and are used when - # a time zone file is used in handling POSIX-style - # time zone environment variables. - - if ttisstdcnt: - isstd = struct.unpack(">%db" % ttisstdcnt, - fileobj.read(ttisstdcnt)) - - # Finally, there are tzh_ttisgmtcnt UTC/local - # indicators, each stored as a one-byte value; - # they tell whether the transition times associated - # with local time types were specified as UTC or - # local time, and are used when a time zone file - # is used in handling POSIX-style time zone envi- - # ronment variables. - - if ttisgmtcnt: - isgmt = struct.unpack(">%db" % ttisgmtcnt, - fileobj.read(ttisgmtcnt)) - - # ** Everything has been read ** - - # Build ttinfo list - self._ttinfo_list = [] - for i in range(typecnt): - gmtoff, isdst, abbrind = ttinfo[i] - # Round to full-minutes if that's not the case. Python's - # datetime doesn't accept sub-minute timezones. Check - # http://python.org/sf/1447945 for some information. - gmtoff = (gmtoff+30)//60*60 - tti = _ttinfo() - tti.offset = gmtoff - tti.delta = datetime.timedelta(seconds=gmtoff) - tti.isdst = isdst - tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)] - tti.isstd = (ttisstdcnt > i and isstd[i] != 0) - tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0) - self._ttinfo_list.append(tti) - - # Replace ttinfo indexes for ttinfo objects. - trans_idx = [] - for idx in self._trans_idx: - trans_idx.append(self._ttinfo_list[idx]) - self._trans_idx = tuple(trans_idx) - - # Set standard, dst, and before ttinfos. before will be - # used when a given time is before any transitions, - # and will be set to the first non-dst ttinfo, or to - # the first dst, if all of them are dst. - self._ttinfo_std = None - self._ttinfo_dst = None - self._ttinfo_before = None - if self._ttinfo_list: - if not self._trans_list: - self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0] - else: - for i in range(timecnt-1,-1,-1): - tti = self._trans_idx[i] - if not self._ttinfo_std and not tti.isdst: - self._ttinfo_std = tti - elif not self._ttinfo_dst and tti.isdst: - self._ttinfo_dst = tti - if self._ttinfo_std and self._ttinfo_dst: - break - else: - if self._ttinfo_dst and not self._ttinfo_std: - self._ttinfo_std = self._ttinfo_dst - - for tti in self._ttinfo_list: - if not tti.isdst: - self._ttinfo_before = tti - break - else: - self._ttinfo_before = self._ttinfo_list[0] - - # Now fix transition times to become relative to wall time. - # - # I'm not sure about this. In my tests, the tz source file - # is setup to wall time, and in the binary file isstd and - # isgmt are off, so it should be in wall time. OTOH, it's - # always in gmt time. Let me know if you have comments - # about this. - laststdoffset = 0 - self._trans_list = list(self._trans_list) - for i in range(len(self._trans_list)): - tti = self._trans_idx[i] - if not tti.isdst: - # This is std time. - self._trans_list[i] += tti.offset - laststdoffset = tti.offset - else: - # This is dst time. Convert to std. - self._trans_list[i] += laststdoffset - self._trans_list = tuple(self._trans_list) - - def _find_ttinfo(self, dt, laststd=0): - timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 - + dt.hour * 3600 - + dt.minute * 60 - + dt.second) - idx = 0 - for trans in self._trans_list: - if timestamp < trans: - break - idx += 1 - else: - return self._ttinfo_std - if idx == 0: - return self._ttinfo_before - if laststd: - while idx > 0: - tti = self._trans_idx[idx-1] - if not tti.isdst: - return tti - idx -= 1 - else: - return self._ttinfo_std - else: - return self._trans_idx[idx-1] - - def utcoffset(self, dt): - if not self._ttinfo_std: - return ZERO - return self._find_ttinfo(dt).delta - - def dst(self, dt): - if not self._ttinfo_dst: - return ZERO - tti = self._find_ttinfo(dt) - if not tti.isdst: - return ZERO - - # The documentation says that utcoffset()-dst() must - # be constant for every dt. - return tti.delta-self._find_ttinfo(dt, laststd=1).delta - - # An alternative for that would be: - # - # return self._ttinfo_dst.offset-self._ttinfo_std.offset - # - # However, this class stores historical changes in the - # dst offset, so I belive that this wouldn't be the right - # way to implement this. - - def tzname(self, dt): - if not self._ttinfo_std: - return None - return self._find_ttinfo(dt).abbr - - def __eq__(self, other): - if not isinstance(other, tzfile): - return False - return (self._trans_list == other._trans_list and - self._trans_idx == other._trans_idx and - self._ttinfo_list == other._ttinfo_list) - - def __ne__(self, other): - return not self.__eq__(other) - - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._filename`) - - def __reduce__(self): - if not os.path.isfile(self._filename): - raise ValueError, "Unpickable %s class" % self.__class__.__name__ - return (self.__class__, (self._filename,)) - -class tzrange(datetime.tzinfo): - - def __init__(self, stdabbr, stdoffset=None, - dstabbr=None, dstoffset=None, - start=None, end=None): - global relativedelta - if not relativedelta: - from dateutil import relativedelta - self._std_abbr = stdabbr - self._dst_abbr = dstabbr - if stdoffset is not None: - self._std_offset = datetime.timedelta(seconds=stdoffset) - else: - self._std_offset = ZERO - if dstoffset is not None: - self._dst_offset = datetime.timedelta(seconds=dstoffset) - elif dstabbr and stdoffset is not None: - self._dst_offset = self._std_offset+datetime.timedelta(hours=+1) - else: - self._dst_offset = ZERO - if dstabbr and start is None: - self._start_delta = relativedelta.relativedelta( - hours=+2, month=4, day=1, weekday=relativedelta.SU(+1)) - else: - self._start_delta = start - if dstabbr and end is None: - self._end_delta = relativedelta.relativedelta( - hours=+1, month=10, day=31, weekday=relativedelta.SU(-1)) - else: - self._end_delta = end - - def utcoffset(self, dt): - if self._isdst(dt): - return self._dst_offset - else: - return self._std_offset - - def dst(self, dt): - if self._isdst(dt): - return self._dst_offset-self._std_offset - else: - return ZERO - - def tzname(self, dt): - if self._isdst(dt): - return self._dst_abbr - else: - return self._std_abbr - - def _isdst(self, dt): - if not self._start_delta: - return False - year = datetime.datetime(dt.year,1,1) - start = year+self._start_delta - end = year+self._end_delta - dt = dt.replace(tzinfo=None) - if start < end: - return dt >= start and dt < end - else: - return dt >= start or dt < end - - def __eq__(self, other): - if not isinstance(other, tzrange): - return False - return (self._std_abbr == other._std_abbr and - self._dst_abbr == other._dst_abbr and - self._std_offset == other._std_offset and - self._dst_offset == other._dst_offset and - self._start_delta == other._start_delta and - self._end_delta == other._end_delta) - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "%s(...)" % self.__class__.__name__ - - __reduce__ = object.__reduce__ - -class tzstr(tzrange): - - def __init__(self, s): - global parser - if not parser: - from dateutil import parser - self._s = s - - res = parser._parsetz(s) - if res is None: - raise ValueError, "unknown string format" - - # Here we break the compatibility with the TZ variable handling. - # GMT-3 actually *means* the timezone -3. - if res.stdabbr in ("GMT", "UTC"): - res.stdoffset *= -1 - - # We must initialize it first, since _delta() needs - # _std_offset and _dst_offset set. Use False in start/end - # to avoid building it two times. - tzrange.__init__(self, res.stdabbr, res.stdoffset, - res.dstabbr, res.dstoffset, - start=False, end=False) - - if not res.dstabbr: - self._start_delta = None - self._end_delta = None - else: - self._start_delta = self._delta(res.start) - if self._start_delta: - self._end_delta = self._delta(res.end, isend=1) - - def _delta(self, x, isend=0): - kwargs = {} - if x.month is not None: - kwargs["month"] = x.month - if x.weekday is not None: - kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week) - if x.week > 0: - kwargs["day"] = 1 - else: - kwargs["day"] = 31 - elif x.day: - kwargs["day"] = x.day - elif x.yday is not None: - kwargs["yearday"] = x.yday - elif x.jyday is not None: - kwargs["nlyearday"] = x.jyday - if not kwargs: - # Default is to start on first sunday of april, and end - # on last sunday of october. - if not isend: - kwargs["month"] = 4 - kwargs["day"] = 1 - kwargs["weekday"] = relativedelta.SU(+1) - else: - kwargs["month"] = 10 - kwargs["day"] = 31 - kwargs["weekday"] = relativedelta.SU(-1) - if x.time is not None: - kwargs["seconds"] = x.time - else: - # Default is 2AM. - kwargs["seconds"] = 7200 - if isend: - # Convert to standard time, to follow the documented way - # of working with the extra hour. See the documentation - # of the tzinfo class. - delta = self._dst_offset-self._std_offset - kwargs["seconds"] -= delta.seconds+delta.days*86400 - return relativedelta.relativedelta(**kwargs) - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._s`) - -class _tzicalvtzcomp: - def __init__(self, tzoffsetfrom, tzoffsetto, isdst, - tzname=None, rrule=None): - self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom) - self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto) - self.tzoffsetdiff = self.tzoffsetto-self.tzoffsetfrom - self.isdst = isdst - self.tzname = tzname - self.rrule = rrule - -class _tzicalvtz(datetime.tzinfo): - def __init__(self, tzid, comps=[]): - self._tzid = tzid - self._comps = comps - self._cachedate = [] - self._cachecomp = [] - - def _find_comp(self, dt): - if len(self._comps) == 1: - return self._comps[0] - dt = dt.replace(tzinfo=None) - try: - return self._cachecomp[self._cachedate.index(dt)] - except ValueError: - pass - lastcomp = None - lastcompdt = None - for comp in self._comps: - if not comp.isdst: - # Handle the extra hour in DST -> STD - compdt = comp.rrule.before(dt-comp.tzoffsetdiff, inc=True) - else: - compdt = comp.rrule.before(dt, inc=True) - if compdt and (not lastcompdt or lastcompdt < compdt): - lastcompdt = compdt - lastcomp = comp - if not lastcomp: - # RFC says nothing about what to do when a given - # time is before the first onset date. We'll look for the - # first standard component, or the first component, if - # none is found. - for comp in self._comps: - if not comp.isdst: - lastcomp = comp - break - else: - lastcomp = comp[0] - self._cachedate.insert(0, dt) - self._cachecomp.insert(0, lastcomp) - if len(self._cachedate) > 10: - self._cachedate.pop() - self._cachecomp.pop() - return lastcomp - - def utcoffset(self, dt): - return self._find_comp(dt).tzoffsetto - - def dst(self, dt): - comp = self._find_comp(dt) - if comp.isdst: - return comp.tzoffsetdiff - else: - return ZERO - - def tzname(self, dt): - return self._find_comp(dt).tzname - - def __repr__(self): - return "" % `self._tzid` - - __reduce__ = object.__reduce__ - -class tzical: - def __init__(self, fileobj): - global rrule - if not rrule: - from dateutil import rrule - - if isinstance(fileobj, basestring): - self._s = fileobj - fileobj = open(fileobj) - elif hasattr(fileobj, "name"): - self._s = fileobj.name - else: - self._s = `fileobj` - - self._vtz = {} - - self._parse_rfc(fileobj.read()) - - def keys(self): - return self._vtz.keys() - - def get(self, tzid=None): - if tzid is None: - keys = self._vtz.keys() - if len(keys) == 0: - raise ValueError, "no timezones defined" - elif len(keys) > 1: - raise ValueError, "more than one timezone available" - tzid = keys[0] - return self._vtz.get(tzid) - - def _parse_offset(self, s): - s = s.strip() - if not s: - raise ValueError, "empty offset" - if s[0] in ('+', '-'): - signal = (-1,+1)[s[0]=='+'] - s = s[1:] - else: - signal = +1 - if len(s) == 4: - return (int(s[:2])*3600+int(s[2:])*60)*signal - elif len(s) == 6: - return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal - else: - raise ValueError, "invalid offset: "+s - - def _parse_rfc(self, s): - lines = s.splitlines() - if not lines: - raise ValueError, "empty string" - - # Unfold - i = 0 - while i < len(lines): - line = lines[i].rstrip() - if not line: - del lines[i] - elif i > 0 and line[0] == " ": - lines[i-1] += line[1:] - del lines[i] - else: - i += 1 - - tzid = None - comps = [] - invtz = False - comptype = None - for line in lines: - if not line: - continue - name, value = line.split(':', 1) - parms = name.split(';') - if not parms: - raise ValueError, "empty property name" - name = parms[0].upper() - parms = parms[1:] - if invtz: - if name == "BEGIN": - if value in ("STANDARD", "DAYLIGHT"): - # Process component - pass - else: - raise ValueError, "unknown component: "+value - comptype = value - founddtstart = False - tzoffsetfrom = None - tzoffsetto = None - rrulelines = [] - tzname = None - elif name == "END": - if value == "VTIMEZONE": - if comptype: - raise ValueError, \ - "component not closed: "+comptype - if not tzid: - raise ValueError, \ - "mandatory TZID not found" - if not comps: - raise ValueError, \ - "at least one component is needed" - # Process vtimezone - self._vtz[tzid] = _tzicalvtz(tzid, comps) - invtz = False - elif value == comptype: - if not founddtstart: - raise ValueError, \ - "mandatory DTSTART not found" - if tzoffsetfrom is None: - raise ValueError, \ - "mandatory TZOFFSETFROM not found" - if tzoffsetto is None: - raise ValueError, \ - "mandatory TZOFFSETFROM not found" - # Process component - rr = None - if rrulelines: - rr = rrule.rrulestr("\n".join(rrulelines), - compatible=True, - ignoretz=True, - cache=True) - comp = _tzicalvtzcomp(tzoffsetfrom, tzoffsetto, - (comptype == "DAYLIGHT"), - tzname, rr) - comps.append(comp) - comptype = None - else: - raise ValueError, \ - "invalid component end: "+value - elif comptype: - if name == "DTSTART": - rrulelines.append(line) - founddtstart = True - elif name in ("RRULE", "RDATE", "EXRULE", "EXDATE"): - rrulelines.append(line) - elif name == "TZOFFSETFROM": - if parms: - raise ValueError, \ - "unsupported %s parm: %s "%(name, parms[0]) - tzoffsetfrom = self._parse_offset(value) - elif name == "TZOFFSETTO": - if parms: - raise ValueError, \ - "unsupported TZOFFSETTO parm: "+parms[0] - tzoffsetto = self._parse_offset(value) - elif name == "TZNAME": - if parms: - raise ValueError, \ - "unsupported TZNAME parm: "+parms[0] - tzname = value - elif name == "COMMENT": - pass - else: - raise ValueError, "unsupported property: "+name - else: - if name == "TZID": - if parms: - raise ValueError, \ - "unsupported TZID parm: "+parms[0] - tzid = value - elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"): - pass - else: - raise ValueError, "unsupported property: "+name - elif name == "BEGIN" and value == "VTIMEZONE": - tzid = None - comps = [] - invtz = True - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._s`) - -if sys.platform != "win32": - TZFILES = ["/etc/localtime", "localtime"] - TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"] -else: - TZFILES = [] - TZPATHS = [] - -def gettz(name=None): - tz = None - if not name: - try: - name = os.environ["TZ"] - except KeyError: - pass - if name is None or name == ":": - for filepath in TZFILES: - if not os.path.isabs(filepath): - filename = filepath - for path in TZPATHS: - filepath = os.path.join(path, filename) - if os.path.isfile(filepath): - break - else: - continue - if os.path.isfile(filepath): - try: - tz = tzfile(filepath) - break - except (IOError, OSError, ValueError): - pass - else: - tz = tzlocal() - else: - if name.startswith(":"): - name = name[:-1] - if os.path.isabs(name): - if os.path.isfile(name): - tz = tzfile(name) - else: - tz = None - else: - for path in TZPATHS: - filepath = os.path.join(path, name) - if not os.path.isfile(filepath): - filepath = filepath.replace(' ','_') - if not os.path.isfile(filepath): - continue - try: - tz = tzfile(filepath) - break - except (IOError, OSError, ValueError): - pass - else: - tz = None - if tzwin: - try: - tz = tzwin(name) - except OSError: - pass - if not tz: - from dateutil.zoneinfo import gettz - tz = gettz(name) - if not tz: - for c in name: - # name must have at least one offset to be a tzstr - if c in "0123456789": - try: - tz = tzstr(name) - except ValueError: - pass - break - else: - if name in ("GMT", "UTC"): - tz = tzutc() - elif name in time.tzname: - tz = tzlocal() - return tz - -# vim:ts=4:sw=4:et diff --git a/utils/dateutil/tzwin.py b/utils/dateutil/tzwin.py deleted file mode 100644 index 073e0ff68..000000000 --- a/utils/dateutil/tzwin.py +++ /dev/null @@ -1,180 +0,0 @@ -# This code was originally contributed by Jeffrey Harris. -import datetime -import struct -import _winreg - -__author__ = "Jeffrey Harris & Gustavo Niemeyer " - -__all__ = ["tzwin", "tzwinlocal"] - -ONEWEEK = datetime.timedelta(7) - -TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones" -TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones" -TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation" - -def _settzkeyname(): - global TZKEYNAME - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - try: - _winreg.OpenKey(handle, TZKEYNAMENT).Close() - TZKEYNAME = TZKEYNAMENT - except WindowsError: - TZKEYNAME = TZKEYNAME9X - handle.Close() - -_settzkeyname() - -class tzwinbase(datetime.tzinfo): - """tzinfo class based on win32's timezones available in the registry.""" - - def utcoffset(self, dt): - if self._isdst(dt): - return datetime.timedelta(minutes=self._dstoffset) - else: - return datetime.timedelta(minutes=self._stdoffset) - - def dst(self, dt): - if self._isdst(dt): - minutes = self._dstoffset - self._stdoffset - return datetime.timedelta(minutes=minutes) - else: - return datetime.timedelta(0) - - def tzname(self, dt): - if self._isdst(dt): - return self._dstname - else: - return self._stdname - - def list(): - """Return a list of all time zones known to the system.""" - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - tzkey = _winreg.OpenKey(handle, TZKEYNAME) - result = [_winreg.EnumKey(tzkey, i) - for i in range(_winreg.QueryInfoKey(tzkey)[0])] - tzkey.Close() - handle.Close() - return result - list = staticmethod(list) - - def display(self): - return self._display - - def _isdst(self, dt): - dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek, - self._dsthour, self._dstminute, - self._dstweeknumber) - dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek, - self._stdhour, self._stdminute, - self._stdweeknumber) - if dston < dstoff: - return dston <= dt.replace(tzinfo=None) < dstoff - else: - return not dstoff <= dt.replace(tzinfo=None) < dston - - -class tzwin(tzwinbase): - - def __init__(self, name): - self._name = name - - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - tzkey = _winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name)) - keydict = valuestodict(tzkey) - tzkey.Close() - handle.Close() - - self._stdname = keydict["Std"].encode("iso-8859-1") - self._dstname = keydict["Dlt"].encode("iso-8859-1") - - self._display = keydict["Display"] - - # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm - tup = struct.unpack("=3l16h", keydict["TZI"]) - self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1 - self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1 - - (self._stdmonth, - self._stddayofweek, # Sunday = 0 - self._stdweeknumber, # Last = 5 - self._stdhour, - self._stdminute) = tup[4:9] - - (self._dstmonth, - self._dstdayofweek, # Sunday = 0 - self._dstweeknumber, # Last = 5 - self._dsthour, - self._dstminute) = tup[12:17] - - def __repr__(self): - return "tzwin(%s)" % repr(self._name) - - def __reduce__(self): - return (self.__class__, (self._name,)) - - -class tzwinlocal(tzwinbase): - - def __init__(self): - - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - - tzlocalkey = _winreg.OpenKey(handle, TZLOCALKEYNAME) - keydict = valuestodict(tzlocalkey) - tzlocalkey.Close() - - self._stdname = keydict["StandardName"].encode("iso-8859-1") - self._dstname = keydict["DaylightName"].encode("iso-8859-1") - - try: - tzkey = _winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname)) - _keydict = valuestodict(tzkey) - self._display = _keydict["Display"] - tzkey.Close() - except OSError: - self._display = None - - handle.Close() - - self._stdoffset = -keydict["Bias"]-keydict["StandardBias"] - self._dstoffset = self._stdoffset-keydict["DaylightBias"] - - - # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm - tup = struct.unpack("=8h", keydict["StandardStart"]) - - (self._stdmonth, - self._stddayofweek, # Sunday = 0 - self._stdweeknumber, # Last = 5 - self._stdhour, - self._stdminute) = tup[1:6] - - tup = struct.unpack("=8h", keydict["DaylightStart"]) - - (self._dstmonth, - self._dstdayofweek, # Sunday = 0 - self._dstweeknumber, # Last = 5 - self._dsthour, - self._dstminute) = tup[1:6] - - def __reduce__(self): - return (self.__class__, ()) - -def picknthweekday(year, month, dayofweek, hour, minute, whichweek): - """dayofweek == 0 means Sunday, whichweek 5 means last instance""" - first = datetime.datetime(year, month, 1, hour, minute) - weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1)) - for n in xrange(whichweek): - dt = weekdayone+(whichweek-n)*ONEWEEK - if dt.month == month: - return dt - -def valuestodict(key): - """Convert a registry key's values to a dictionary.""" - dict = {} - size = _winreg.QueryInfoKey(key)[1] - for i in range(size): - data = _winreg.EnumValue(key, i) - dict[data[0]] = data[1] - return dict diff --git a/utils/dateutil/zoneinfo/__init__.py b/utils/dateutil/zoneinfo/__init__.py deleted file mode 100644 index 9bed6264c..000000000 --- a/utils/dateutil/zoneinfo/__init__.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -Copyright (c) 2003-2005 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -from dateutil.tz import tzfile -from tarfile import TarFile -import os - -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -__all__ = ["setcachesize", "gettz", "rebuild"] - -CACHE = [] -CACHESIZE = 10 - -class tzfile(tzfile): - def __reduce__(self): - return (gettz, (self._filename,)) - -def getzoneinfofile(): - filenames = os.listdir(os.path.join(os.path.dirname(__file__))) - filenames.sort() - filenames.reverse() - for entry in filenames: - if entry.startswith("zoneinfo") and ".tar." in entry: - return os.path.join(os.path.dirname(__file__), entry) - return None - -ZONEINFOFILE = getzoneinfofile() - -del getzoneinfofile - -def setcachesize(size): - global CACHESIZE, CACHE - CACHESIZE = size - del CACHE[size:] - -def gettz(name): - tzinfo = None - if ZONEINFOFILE: - for cachedname, tzinfo in CACHE: - if cachedname == name: - break - else: - tf = TarFile.open(ZONEINFOFILE) - try: - zonefile = tf.extractfile(name) - except KeyError: - tzinfo = None - else: - tzinfo = tzfile(zonefile) - tf.close() - CACHE.insert(0, (name, tzinfo)) - del CACHE[CACHESIZE:] - return tzinfo - -def rebuild(filename, tag=None, format="gz"): - import tempfile, shutil - tmpdir = tempfile.mkdtemp() - zonedir = os.path.join(tmpdir, "zoneinfo") - moduledir = os.path.dirname(__file__) - if tag: tag = "-"+tag - targetname = "zoneinfo%s.tar.%s" % (tag, format) - try: - tf = TarFile.open(filename) - for name in tf.getnames(): - if not (name.endswith(".sh") or - name.endswith(".tab") or - name == "leapseconds"): - tf.extract(name, tmpdir) - filepath = os.path.join(tmpdir, name) - os.system("zic -d %s %s" % (zonedir, filepath)) - tf.close() - target = os.path.join(moduledir, targetname) - for entry in os.listdir(moduledir): - if entry.startswith("zoneinfo") and ".tar." in entry: - os.unlink(os.path.join(moduledir, entry)) - tf = TarFile.open(target, "w:%s" % format) - for entry in os.listdir(zonedir): - entrypath = os.path.join(zonedir, entry) - tf.add(entrypath, entry) - tf.close() - finally: - shutil.rmtree(tmpdir) diff --git a/utils/dateutil/zoneinfo/zoneinfo-2008e.tar.gz b/utils/dateutil/zoneinfo/zoneinfo-2008e.tar.gz deleted file mode 100644 index 65e4175f4a4bb008acd62264e3bee1ca9b2c01fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163209 zcmYIwby!qi)UHamfPgduLkmcEIJ7AIBn1RSK%|E57)1mDfsqs`DUp`$GDrad0i_0{ zyK5Nc-0gSo_uN0$d-mFUt#_@x_TGo%ob$*TOG+v(`(Ec7B=*eR%|Q(5*M75{~JN>NCzk6Q+KidZHP$RzAfh<>SOD5Wy^{rguZ94Rryc1%uS75 zt{{@8G1}igl-Dv?NE55Nh#z_6GQFa64)-8M|GY;9yYT>_E0E`Zz3t^1y9Nb2>LRD6 zt1IFPP1!qRQ>GZ7G>FM%mX`$NK_89bgF=IAbx|mbZQQFdCR=qi_>VNEWcyis?`5aq>75wi3P1 z6r&OAN!@*AYjLlsX0o?qgK@5sS{?D3%rx$)mnT7L@J65mWV>LiopgVzrSIe3A17~l zk4L@Dzb8}6-AV2+k6NeaHyGFtRUA_`DbN_NAV8PLmrGTCUBDz*dn^) zQ`n(Un)qj7*#9opO6U8dHE&qdQKd!4m0Y(_6qbSO>}Mnm=K9Tx)3L>OXX=%Iqo;}J z&PscRx=j%ZCJ{c(&vD7LqfR^pM%p?>321#7EK3WakP_jeK(?MtH|j)mV5Fy0l!n$9 zN9R06D2xLSFhD=*#9v@!pi`8C7QGtE+)NqaBS^aLHSc<$htNrTW$oicx_)qdl$X0; zKtm@j=1+8ty}KewFuvYPT!5p8u~`@Oq=rI~sBXtO!$7=nsy24=DK6&n ztI5TM1AXRsRLY|)qVr=sy}Fo?j-~ z2j%+y!p=({n>7%n+0H(v+17b`mQ-srHH3(#pZG1znVIO<5Ao`eUh;=vJg!}}Fla|r zIJFD9DEJ;##=VY-{`5;J&tF4f4P&*9ufVs>K61D$%Ex1bryENbtIJ|7?YNp^#G|42 z_bR9^69}R$ysfn{C#7vn6I<A}VnMsYlMEk}0QEXc;k@Qa9L&raf%2&HY zDbhKFh@xc8@iquZ_BdDF**KfN1zR}&RuCg! zd>8+VU3dJF#Bb$??62zTF@5OxNlQ;8QMXp%U8c^C4a~9CWpGf_z-7mJF)H;eDRWx4 zuAS!Kw5VVCXgbc|oP~feeCEWB zf40bvbX0szU4eR`h)vHgZg>JU_H%FTdZ-U}4N~4l(aKt0SfSk%un4R1gv{mA{>jlt_ONb-;;1Z%Ng2-rS92N?05wE10 z=_Qs!>BkU>KUgTCrU7E~Q|#$Tl$K_}gt$r>N>6a0{iSJ3g(DTW zakhoNtA|%pt;BZC{dXIYe`*|~k-O(!siCo=4^Q1u_VTyeOUDmfR0p~i6gG3kW9uf{ zn%62+OA6Z31Iu?-9%L;~Y_HZ&cSMo-Q&U#WX5rKt9W7{`HqH7yP+v@@Us7+siW(u} z<{ZE27%&s`bje1unl(Fsy;@oKlbF)L>h<%jFUW=S8s~bZ3>#+a?77Fm((a!Yj+;r| zl3^<7BA5$Z%ciMb$`ynb7ztP+rPMWb@8`|7^UVD_aq+ku=l& z<8%$ok)=D(9;#YaRqp(6{=t3AE~@a{pCi4!UnG?yxJy@l$FMXr8z&`bGmaTB#GLNl zH2-48n@o9&-n=BaBiCn82M_WevXid{rg20tGcfP zwd0jgS!vZ@61TxD0^ho@*W(k`dvz81K9=QA5h$10_>t70HU*1N=lc4y`ZBljoW+#- z7p47Eol{oR0xi$nY86@vtG27_`U;{_KNh{KFyGB*?5Iog8JsSwuRU|h(6?NDUGLCg z<5M0}F^X;AEI%}Om*-|x9#wICj-RUku5B@m-1_7u7HKgpw&t?#QB{0g`hfiwyR2EY zA9=CUd61us%c_>!8QUu<)mOkH11X}&(j z=(aYf+q}~qIK>f_W*Mv%|0}Zm-7_k8)gHQib$1v0I@(n0k?pbv=Pl-Wm!+2ZInwpt zCR|HnmCd_Gi~f_g%Bd4gZ5N~1zz&L5Zlka%$j+a)re2`3C#gm;Lc`Nk@t_dgSp|c-0%!;cxfKf9|o8?V_R=MXW=@MtT?|KgK!l!xRo4oJ~UN{9GoR!#1m=CT^9BCbjn(&8Yl z0-kcqBGDymh!Q{22giG9wrA#SyBSXgx}u2P2syj?!f8&kh*WSN$$Bp8 zmu~O5`}e#^sHPz1th-Gda6#gx@38jn!81|&6GCp<$URLfWVl#1L>LmCLlEC^G@Ug6F=nzW&G(W% zBrtV$UYO+`iH&D4?b)sgzH>hebD?~;;X2l7CKf|zKnv>pouY0|6u{b1h_c zG-!U)vVjnDyB&U}W#I4OZ9^5`An1?W8{Ce0=^nNnbLn30OwxY*NPllTurl1;2D%y2 zlaw{DSj0(!acB#_+~ufc3`qziIh)fr>N@=nk+*krv9Rqvx4qR^cr-ju;%hq}#YP;? zIZ=B>HRRZ3FMl~`K0v#{r87bC`~|1Y6zzqoXFmB^-+o<}!FE4&m;!<*>}i+!UX6&x zp10@SEhuDpV1B}yrc=y*mO89znRYMMKy)D>&C2YBjY>Ne&iO=e-pmZT7PcLR+S^Rh zeuUlqg<`>iKTlahHsMA?rD&BG-$zC@l^5`KO@5(x9 ze6DyZM3^1u5U9X0kQYj|BOy)^FtI^Y1-Xv+ccq*^Kviww8TYn^hhDDw*idI5F7fTn zygIRinkI*?4j+yZW}g<(&Yur`d$G!?K+z-oS(Lc-@%-&Q#MsnxrV1uXYx~D0dwJhk z!%M?07X!Y3^P2y@8T^u|WBkg6n7NQ@K%cThm)>;S6|u_<$$<0$$F70+CMs(rMslko z-Co7`IOnyzX2v+o`#oti(d6Vz961C&ZV7cGi35O{rX@&JCIT? zdo|{YM`g#gt~S)(waTC$Os!LDD7H#$$>_YaLQwc*<`SuO=~L^ysVdp7%^M-a73*8i z7oDs#i7U-66av}?3_hbU+$~+94cUa1P!Mgv%O+H~tkS7+K>os57whgB)rC8q6k+SS z80LlS;rPpoxHnhat(|ViPv%+bd6dUew>qf%@1^>0ytqi~quS}Hga^133dc_dRS^WR zvL3LxC>G0|V0Ny67G|2d^{e5M{E5kC={$Q6&v2D~wqjSuPOMUo!m2fCg-euDk559+ z3ldY!Y`Yh$Vc++|4`9PpAE@lQUgmHQS5-)U>1@gR`8;&p0Rw2nxl<9F#fv&VEla!x=*Qq zpQF+N+hz+zVEl2cTDILK3Iryw;2N%ak^gq}_XnX~Z&!~S2W+f~RDto#7O-LQuWeKF z>a*z8-#_WWSOE2syi5ocFxbBm7$2%g6c`_;6u=o`Yy)Ix&xSI04||`Z@Nn4N{Ay3&|JuXHe0K5mc0vD z=Exm7PhWv@TsDD>UaWw*bn-08`+Xjj+%dYxLK~fj$43J*By-g0?Uvgxy2#I6kEs17pU6;d8#uH|WG)7OB*L0>bj3BXDn0MjOEb|?w37-J69 z|8Y(MTAO?Tg6$dhlv)5|>)T%MC+)8QgozwvK70&_9{vXcFp{^CTFbElt$+c*630R2 zCojNgLJ~$ImQ4_-f2*As05~4{x8#Wc_>uycWdcy6bfeW(aY?>v#uz{dIHXlyt^jx< z4q(&_gmQ>f;x{dR0ifx*5`Qxzn5>m7nEs9*m~5~Tn2RS!_ekntS6e;TaP%BFA5X@? z`FK*-4dB=oK%5tVK~efH7kS`Vm+=qWf$jSkK(TTiq$~y|`_Nq;ka@ELvN(|Z<}N4< zs|K*8LV;qj)`4QNLa&whWjqHc=cE_|^<7P`16vBUZ2C)Uz$OAt$T!9!0I5wf;SD%2 zZ`WgTU;%;rDCJ_6`0IB#N#>p^A7uWn2l0L*6#&eU1nO_y2KB&|5CXNzD0EMsd`W(P zlepLW?_?T!Rl~|@N&Z0tC>Es;2t~jIGP0`R9*(}V2tv)ffvHV$0B9%#pkuToFMbpZ zY8U+KcwYGnShQ?#Oul^v$K=Uxa7@JWBn~ofdJ=-5DbjSUlXpSa22yx$EgBg7@C2Gn zH%aTMGhi^_2e4}oz(xcBigQWcQ_U8@;|%_J0&w=DUrK`<=Orh*s5HUu``SD^kAZ_i zsIP*tuR}Zlw1LVaqfZ3M+zixbllQ)U_6ZAo)*b+OXSgtLrw)?yGzV$!vH&N{EU0-; z+CSI@HRqROB+2;#``m!5pcbeXzZig39gvrHbh-6p6 z-X3%TM)zp|461^PSW<&BT3&$GbZQ4NW{v~ci~n;nX8<4#PSi}+F4tLhC75L!CD6>k zwwv+48mO=I9|*4WnJiGhw)N)KFb~Fq%z!np_yK1bbMxBuU;}9%Z+9jPg6tAxL3Rd| zpyCFp|9}XDD*`veZ<6ilUBfdVt6>wc`-isyl#7Bh<4Xj17Gwa3QwQp|)`HF1%Jxc$ z-`YF^fZM;;1uf{?0cUsaHHhH8a+5f$R2n#J{&Vf22ZP=$0Mfv5Ydr;Zd=|V#6owK4 zi#yK-z~c&lX9NJ`{+$gMV$k{q!h|RQHN=z-z#N!bNG>=MHZuRf8YE|vrUk&=9PtPy z$2BY%q1o$A?gt75i&xJ!5~$}H7TgNr2C%x>#r_^PEGQADooys%ssTU~*k{%RJa{H8~5}sU|XKuod3fQIJ`2|vW=F&vKlQ}!~u_4kj-01 zP+x9$a9T9mReHT+aIfC3-XNL+*5s{-Y@-{aAO?AsCTKkX!DGsHDJ$sEt2au(gGkI1 zQ{c7l4jg!Y05#DHvQ*D-{Vyf?7SOmpaJIdjxi6UWg1Zex(KM$WH-5NEB>{NjbvhWAoxfZ0s23gn!d4HOs0L&up zH08a9>*b%5Fb9@ls3FVi*DLoTt!RMHycj+hBO)bqIGa;J^lol(rYj2HxOwP}%P8YQ`J$Zb2N^&JJ0d5LMI`U^-JQ`Njf6we8 zeU#8Pw%3yw0DlhEf30Hkyv0;TqNduHAgC(5S9rvE;|9xY6Y_(~e>o>u|HGi+L+Aj@ z38@}I?btcq2awC$M)odazR~%R_+rDaiU94c>R(2B&>(^!Kip`29~utC4_jJ8B45{Y zR-nv*Xr75J?6pG_{%~l?KBpU7SwyqTF)i74&{3qYjLWIUj~PL`dfWYtrIO@s0ya;l z@=dJoX8)q6bG=jB%mulnp*=9EjoeQd>Ac!B#QBwfLd8*uY)`ac2nDzTvC8h}gGbjm zlb{wK-MSSB{Qf&OE%N=a19^Z`WiEuoEDfD=a(9}&jA|Ss?>AhyG#FRFUH>%vt`^A{ z`s~(6wCy*oVH+i$=CHbe`%>{K=T?iEjO5lnrfBve|IY7K!H08A?Ai%T2;9d46N{0y z$zIhaKhY_9p^kaf>uOlBg$28cx`+%GnDq{WX=?RP_i<2ujf*??i8~Fjm$l;3p=8< z|Be#Blr1_(T~i;^h2{jY(9F^~O7h-?s*~bsbxV&r8bNZ|Kr`1fRo&(FxFo!mw-e zpL|LoqakQ}V@GgP_2n|ED3{8wGO&jDc6r}h6#wN#hGx*nt6j+41ts_PgA=rCMR{fu zzj$x@0Ji|W#q)g0=MIYcIEhuA6I_9kcOl1C94Dq}RZ8*F#$PZ?wf){Y&hwF>!s%k7 z>%<1n0i^18>c6JSIg9hTfs2w${5zN{YBZL^dE49{)&H_TE_`?lrDpuhUSs&E52~mT zJl@^mtAtV>9H17yZEw|ZxC#ZH3_J9D^D=IV9w`^JdWifED!iN3E8MYDH|N|wo6292 zEn2yl)Z02N{P1x0miqvzxu&9XuCP9QQ*4vGe9K)}NwTu8mnNMjmb$IfNK+>I)<;fP zk+}^udor6>bp=t+giZP_%`9rBRwi)mL$i~@qhD)Uq}TVel4*`!znRufjW?8dJj!Lu zUqA>)aR$M=itrgdbSmf5iA*E1d87)adFsCZmUh zU|Hq}g_Z~#Jf)&Hw{{iOj>lwU_uhp)=vrTZcC(;ay&Xu`07C74F3+W^e<%0$sb{c1 zRgnQZbljEIM}a7;!ynsXIo3~bX8ji(&ViRjl#@^r@6HDN1@gz-po(F1MzsNz?$wQf zSttt*?|?4Iq7qrdpcnWIZSWe#hb;Pabl-LC>0d^!P1VJ9R1oD6%ArU~U@oRi(@tuc-)u$|H*{$mY*YENxAbDbXQ`~e;6d_Quv(?M<%aJwOPh_r zvrP9p^#}|hkLr0tmxu#C?m5oVR*(WeNV-0K^<4H_A}!AHuAcTxQmW59hOxIp92V+w zq<`qHuY=*RiTIyIjPT+6x%+jP80&w=3@fO)hI``JosQarnce$^y3Een+)%eOa=h9* zd=pyU5o~}Y?_NSH_~B+P8JCrpd^`+aqxN?>v&QT3tMO1?o4Pt@Xaq`l`d~AE6Qvqz z?|Lt&4#JEBb1^rLsrKMFT zXCArwQMPyQN0@%HRDNh)`6^@H=tJ&k!(Gv?(?EHLmt`n2Dt!l2nUMEie?HS=wp(0G zpuE2#$DC22^7NU^QR;~M0gL)!XJ|KLXqe2iO%dt(U*(Jz3^|XFCUI~=d+R*cau%-I zb_e5n1_d&=Qw_ms^G(ui6vcmjx0&eMSvCu|&Rj&)i#X1cZ4yMC*VyK5f4!1;ImeSA z{&|E~JuTB9?v6tPb2vw~gx_G;gSDW5tg7kDazt-)Qvc7Fhp%?V@Wv+(W$v!Ydo)Y9 zBK%>ki`N}ADxV_k@3&Q(MO{}nhH*Oh9P>rqycp{KeT{*t%4~xrSasNWt)@JpYF9TS z7o!wx2h~MU5=7caQfG!5+`NG-VpBT$aQoY?kZ*|4*0$m5AgjhXU6z@J!%vRsp~mqH zhB)#S15b*@t=_chc6N``uDm2cuvS@g4Tp(~QB=>S%)Iafuz)wn=-Mz&27YWpu@0?a z6?Z|Nrp|W?@zFG&%+bW6(qh#YY&!$%-G2 z#>Vi$7z~0Q(DMG$8BoamL}%z($i!fd5UN+R_8}`iyB0{xSMcPG7Kd1WgmETWu@1dq z6<DMXHHvA`*FEx`}9eU7b-lJdiF? zgG~415qB|N;-ht5T~pYU{O=<0l$LxG*PW6P!lCb^qh%@}OOou8aJ8D#)O{4rdPKu; zSz_W>URJTTdWWm00_wU@%?-*%juv08?!5KFtI9S({P{-^U)<;*oxktQp0DS0od2(Q z;vc_ytnqEJE4%dPAuBVS(WfuEsnT``++^<#Uqv0jmgOT`V5rOjXj;z_Mv`Fs#mm+$rkKEwe(|$J+KKa3g&%ubOqYx0_FTvU$C9=bN($% zSg3hLxGwqVT>re|=aeT@>mKM~=Ddk9!>EI2%X8J`Gnzo~hIRr{ErY}tzwNNxeKXY9 zFt0ZZsR#GC26KiI{<+cq4$rDVMAD;iq?@*HQ-R#65X^!6Q;u`uu?AsKgU(;S6V5oK zvg}Ny^UTfF4>FwA?lU(eP1^#OLzh!0SnpZ#r$`|WgFej76=iv8w;O)U+8!42SFw4< zExoG}s^8XtuJqc)ZhdrFBo?Z?V5OWqt%z-1uQF_GI?LYn+i{7UUewc=3!EDBXqXJ| z4d!1YvMe2|zd*6cDDCw!rayrfgdU88sdMPVivn^TMt^%0*?;A++M6!EI!oiUl2e_u zM^MCd9{M9Mdb+7Fnw)WluV4&TXJ3++kf=|=C^cV1JeF`Urmj;&`tPctQ$+sn`s&Un zT(a$+psL%uu;d&CF4a)oNYbSu+SB{z#e@fAx;jP4XnkRHjs-%YO)V^jY+Z`ryjUwo zNOkt6-LQc?EXxm}a2(--C0nPv{pxIJ8g{+T3Z*-(U%Ik2Y0WyhL?}%KvR6p{UH8+_iOtMOVzNl8xO zwoHlT)Fx(g7SAcx4g=3=wa^xQ!*)^vr1zeLI`Ed$ZSz3sBn5BPCyb3t4Poqb4Os=Y zPkf~zse8A+Z+X1t4*yS0z2$B9_g3@tlUb*~OVNMv=FolhqX*)&RkrKD@OposP4Jkz zUJNa5+{$ju3LVch3ct-$nR0ykGv;NsIfIRF&F^($%Waq0dbwvl6ZbStEVNCOOOxi^ zJsIy>WQo1`^|W5$VU6oxp6{Q4+4sKI?0WS!+rIto`E`G^t;UwuWH5=6_GzMKN#vvh_2i-CxV0j{n%*A04GH^S`07vw;yhl-wLxJTmMBjy3Si*L>aqO zl#bSyhGiiU3d<2bQ!jA8=ttN23-r`<(q5oNiEM?esO6^$eJ>JB@stKx( zM0^JyVpdbCUtEgXeWhDXq1v@Jkuh~Ol$q-=`m;33<}k)fkurFKl){Fp>i-EDxn&o- z=TYc4bK7p9-tJ9#5HagzTQCd3dugfqq3N05AD_tEW$-)Owaic@Z^y6Ru17sG{bM`M zvuLKBmBPMQBdl27T8<0qRd-m8zDQ{v(oVtNk&S!dYbxC0Gvz`lgiVrYoS?Ha>%qj$ zlC#FmRv5@cw#GV+<5m7TWS-&eAIh71-vb7WXaMADIL zGwv0hy{GDL$b-%l3ES%cO0Wt+#R;a?<#@#EjIeD}G)K4=@Hn zf#=)>5?VUTl#>4Y)sgWM)^k4}bPup8^anJlYcq=luMI9PC!qVeU@7Vdq1Xsx4zl8V zbcRjvf@)ncp_~X~EwbXwJijFehTZ{TSc*B9SVM%dA6YSu&XAd}!0VolLpr)&5|-kG z5SolIt|u!FS!~{u(AQbcME5J8)BF)ahicY4WW`(bhUZa@O~fAijnt&N6cGg^h*3h= zdN{iFjt-U!9(O%apHx>kqJRl8N{QZ#MAxe8U}117+QfKLUA>3`{@}~( zUD||377DAlb1wONF9~<+A-nuzWkX$j&M__rheJhfLjG)1k0O@C6ZRH?SXqkyQa_p7m{;eeRU79@^pBb!2oC(d zxH+J7ayzxnu>axCGY-3RxAZp*rYh2=nZaKlI{g*2TV4o$WAbEzdHhanTt$|?&}^Qm z(5%a4@zFDB-F5ST=Fx%j%F)g7>ki}L^l>J`8!6+~M>3{1yZL3F%~@3|xS?(fl&S0l zzP_Sr=odok{v=&@^Vd?rP3h0FSV9J4eC4U8#KQeu!r;UD8h@P(f5W%Q+3P`v_G##{ zF~bdZ&%E@mX};s=58j0AJkg;%Z!Xo%{qN!Koa+De<0#1^4le)x<`ycf@lui zmd=_{jf4VQ#HcvTDII-uPv<=!+=@Q2o=g|>>7ucFq+wd^AF=4^Ha_8WyS;5YaVtBz zP5onSptq#X1PPzA()kMQ-4^?-&Ob?&7jH*T63;n$47TV~Z6NRS4y4aR4`cADU{gzb z2GpiJ^N1*Ab6QnD#~C#P1>g->AX*m2o6|geGNBbv%O=z`66IcrDiPJkc7$EpJzHM= zDQaT4fAitu;MgH&rD|41!z3nU3fkGhVT1d(q1qO_3buEC$SpiSJbcU=vKE|xd=8UW zQM$wUoYUDizRb!6%Z+WS`bO+A%%6T_o<>Jjdm+BWX-ggU@Rrs}IR5>?Y3Pn*#qL98 ziXHFRpHsiSa|id~=FC@`HfZT0BPL54}=) zP)}PgR2?_&yY?n9Z2yVog#H45AG)6TW^=d;y z5IUnD4l~Z`XDL?jtxniDN@?A9oTxX;n%&J+kX4ky;}VsGHh;%~P8 zcQ-D*y!w6#6RP9FWBes7%Y^1~ago!vqBLkrMG9Z3z-w&aMf_b=#JMsE`}q#8W^&Sa zm?kX_Z z6$d@9BaCm76|2!1=E4iYb#-1Pp~(f%Ooj-dPZ7os#Xr1edWaCJb$3MKTT{Z>&n8*) ztt4BwxC1+~rq6e$5q>517_%@8*hfX?qTTmSnc_>qi$7jPrR-<%#MN}m-*lV| zb(S$O$N3_zD zjfSNX6@C=r6@7kx8u=DJd2Y9Dcl#DeMwmV_PCjVf9jOW2CPbL@V8Q+eNo~Peo{mLEM0;e-F6v0%mFLRQt zDHma`#WM|s8MdfjTDDOAST{k{PCr3xBt@!e4dFoRaret|Z(*AFO(8ZfRz5Zs@v(r$ zOQPks-BHQfrL!Y!!v6Z+O3>9oGX9#CZ#53@lVqQ|43))=XIgQ%tH=h2pNGu+SL6Gv z_8ei1K7aDq<*?9{>POmUU`AzQinNVLHYTL}ap>Uj59{}vV*SsMGyO$Pfm6EPE~nmu z+p0*Xom)!zO&5nMgKgrhQuTN}>C=`T7Y?64c42EBL%3eYs`IJ~%0nC8?u?uzsdqU- zLFqXvlu|ACM2dbW)IXP)-ot7+yh#%e{*T!%{`u&>d}!92CMC8-@3a8M9RAh8v(}ig z{Xov0xM6>%1VLzlcb};K#~ZOmWJ1Z$Jl~QpV~nLSZ!&U)6g*n*j*op1ny5-E38+ys ziGGhSNn{8$DI^apx$7ucE@X$1X#cSowC_;a*psGcA<>SjpV{}~w3<2^3B5a7i&|aH zpNoei*hc!~y`9?vdxeC{ch%2N6HPqy+v9$sMa&iaQp3I`c=1E6vIl;+;MkZ z*Y&ChzH%kqw?9f?j}=9XK7oaM$auEgo)9cGxo)2RBLPi$z4!k0^!KbV329k%duQb9 z-d{5}$og(p%?ZkCBP4VX61oV9y9fzAN}<(AvZarLRHB%YWa2cJL1 zMr4SAF5)+!i_8vmef!r{B{kAR?gX@cHRO+HiXPs?UN2Mm@HfMu_%|%QgDh@j$lrz; z2nA0288zhGGfNKw5-)mf)|agE=nVNOmYJU~4hu{k_Wph`Gc$5BPb^krJpPF45U+Rt#ogv*oI#irvoQRwG!h3nI2*;6H&tq z9uA$9H@{XMk`(l7IeY)OVpzyiCr_zX5>g}&EL?gnOnbz=C#Ke`#WYXd% z+y(v7Xd!{(e7t$y1yUBCyKO1@TyAzT*5aUC^uguNRY_sIW0v4Enzdf&R$5 z8=p8UK^GO!+S7nWW30=5j0f7B8L#iJ;1Xat`ftnuFxZFz2LFUKg$=!KJ@(_K#pU>* zrhGhPqJ3F(L@n2Pc=*7*=w3W$h@#_AqJ=xMQ06X+l6xyNyjxOhVrlv{v3%0;Gy9Y< z9_l3ny!^3eh=6yin9t90Vyu|ezAEpmYrw^It)Te3!DIN-F%qJvk3#|%C>JO=D7fGu z)Mu3q@hDG2>GY_?DX7-U{>#UU)=SmS+sDTb7HgfvD98No-~Ms)$?YGH8t=c}WqbBc z`lQ&_Z`LJJe&Hphx898#D|HX~Zq=e39-cjG{v0qVWZNf({4#o`PdwK9=u7p;<*Vhl z&R=6b=|-kZu|NKhQ+k(Hy)^c3o%gM%J1p7Ar_Lf{=&*#{2iLGXvKc6q2h}jPB2H6g8JJh#D zp47KFrjlKNw~HrkPMl4u{r1xxZaE8Tu7V4lc@HxRO)>{1+=~|;Z{GXT<>}@YHS@$Z zO6%TjHYDny+-N|lN9|PLag`V2@jfo&7k_4Isew{PzDl579`?r+a-(Ko@!slF8p*7L zSaI_x;tWxZI&mvX*JsVYN=nwf+PpprBZ=;r#X8DZ39ps6XE&8$v9Y)f)`rY+S%bF! zFjJwHp%)1?8;TUCrMvjn2chn7blo;p^+G#>GqHEljz31>_3kBvJblm6!g?Q-a@KtW zcT8R{&Wl}N|9T~9;8(bkpTol2f$0x#1YLSLk}+r=t{m~AVG4E8)79=|JD-W30Xv_i z6R4vW%E}zu8)St$Kz?FBz~4XflwbJOj*%%Qa@?hCsD7yqcKrAl+=LGFT00>9LkPnP z^#v;q^C6kiSRnan-8kqXIu5!@T)ZzPo!3WH*xhlYA={Mu>kPxE69=hzcxizVkuF_o zL1{b%x#1!zolDsq-_IqDFQNci3TVs{7Vl&FK*O8NaIvEUG{ym)>i_iIEa*m&y!>^h z$_Mi|E8g$u2BQuC9P2>iE2ZHg#P8u{1+3N3ERZr0Akqa5c`85@4=h%7Wv@5!=*2;b zfYC+|u`>h)(!jtmomWvR3$)Fv#FItih?$YX zZWP}gXIw)anCwk5ZJo*3N7l|bcZPy)D6sC=S;MEoZio*wY(!!HD3Hnn5ovr&G4RUN zb;i+1{_{%ubw(ot8Zvw!(oeWFzVtmHmj~Tqj}uv-^g>>%z&MyRe&BAe3w81SE@c6W zhBFRh3No*82Gh0yl(HqDxVoU>_&?kh&bUfhK*ZY2M4Io{4?r_CX4R5-<^Ak;eY?cG3me66vNsv>uhp?u26ks2N-CHn|- za<4A~XC@{mbW27+c?W6?E@Fe$mlya}JA8hi`Z%W{K2ODgevwxOawVo~naN4DLthdU z94&3!p1N>ar6$pfh_0M8m$?L6R$sEXnBad6C5HM~y2OW#i^!{&ntRuY+4s#hevmd8 zpG<9aurWVm5c@Q^8!%__yls@R5i&H}`x5Au3%(G4CF?fIX#RA9Axm1jG$!=1$jKn7 z+x~=h8E^A&b@I_82a$36cZEJXf)f(UFGU=zp$g&EnV*I`Gxk>J8OygAWRAv6lxEZ{ zox07M`-S_RODQV~jiC85-|dOH4Mtzf&AHE!gTv9;}<=GHzTrY6Tz56Iu7Z zX#KEQAt1KZXwyld)O;r}S6fy<>}-vA`4#8vheuaHgIi5jfa%&bekKASgg}UZ5QpM)SBg7H6qLQ1kstbA z5idPapI-_Gk_Y4qkiS5#Y0NKiN631?xIMhY@4h&ck&8AY&%Ef;%`}{sdXc14*x6)e z;g%h1LY}GDsap#=!;=CEJDG{}xl^w>UXhD7C(msAjH0W%A$QrOJ42fJXkJa!i}1dv z4;Pan$XN*;%K>uX1i1iVy>g9T_9~%1l8`iWhVr^x6O7Bl%Sdg0srz|n-{95dG*&`% z24Og#EIF4f1>t?%)?6(VbxCss+Baqi+Wj{3@Sg&ymX zPLHgFTkzT=5`S<8*uCto%TXREFtE8@63QuRuoyzEr$dRAkUW>?^fC!%NV=hR?eW}3 z;eYO>hGVVDrwqsOA=}c5bnl#2$5`H5t%|1mNtK2VRd~y)7kiS2K`L-0=ocwX4Cg!6v>glMls`;Fu-4~?G;2>39 zU64riM7EW_WzkpBtf$YOy3KBMtZ%IEJ_{ueDLO0rsZx`or6zuy~+NfDGIvcrnaKp zJh5XvHPH~iKDF|r$gRaOu44A(>eNZcW!a|3+MAQoDgs}2D8zaF*P_epq>+KS0?ARs z260)-kx&`#OHNRd+uYD_x8aXBxwv85&vS8YFbdRpeaf~Yu7^Dk!D5x_?wMtc) zMwExTLr>RbD~s!(x!qd?TE^AXxX@g`{{rY|=Q(?vqNFN6U1Z3%DYE-Hvo2JW+ege? z+kPCSFQt>zb%Tf>)l5J3D<_O7#6tB%4fY3Hkjqn3$x|Q^M@!ZE$WDVmZ2IO%=YXu1 z)Sg8ATguiCL{*0Tr#=dj|<`DIO8L_IgBOh*?lby0KiJN0TT8 z(`-5)_3*2p(vYv90YVFe9tZ;vCLqi}Sb?wu;pCdUj-_mhfBr}h&=>$Q0%8Wl5{L~D zJ0Omqn@mUdP@}AQY?Ew2*nw~W;Y7P!e-OWUy|?bQK+iD{>1cr-Um$frj)6$W03Apj zkmDF^tP3MB2jap6u1vksZ`#!>?6@W+VC&4i(s95RNF9)4Aky(b2T}**7>INN(1Fwe zIZp8EQ@#=!HAC`zhJv(@=J^c$_2ot}u6|Es2NJ z=G0)20}QHy!Ixl=2KL2M3{f|5N!qI%jSeB}Z6gC#^uS60SQ&kK(`a_*$4n)#bcFSL zVi3uTbKmhYyp%yFqprm7;fH@a=#AKJ{UBmoA*E2K`K$W-WA?SomwvD16#7ZSX+TvBzfD^-HrgH}}k{l@@$!%xYnMiwuN z2f%N-7yUn6PHI*P&VzIbspyMVeOFiyoZZ)_A&eSlrUm`;umfBU5*K&OIr`YkFc9y* zenWO7%Kv2Sl!DseaC3LR{XA#Z9vT){M78V9_`SDSNxXgBdu4WLJna9l^wj}TJ@3~b z{XrT5X#_;1M7ohi1f&HCr5ovH1r`BmkdRtw1Ob(9X{EcnyBl`zJA8ldA9wbdGv|q! zJFD*Qonu|&MC#KEWa>l>tSaVMIz4pwdBvCG|EXmBdDZ<^MW=HHKb8I9)%Uyxv7+C{ z#tYdm--c;=H`8fJT3o|EZf&sz4=`4XUX-Eh5&GcN_za5uc>v#dSo8Ui7DJCT(`3=M)fL}R!^=3Z_`elo^2-F# z*t%!)2#)(J$lC5Zg8&%QcLpIaw(kt06=aW6f@JJH-g!hZF+fQJ4WnwDJ07q{eL2?Y zX3krU(>zxC9x0^x@>P}j(!#u{LCN6t#h5{cD_(roG%M&>X6V+hBFt#V-j@5XR2}<- z*j(At(vuevmBklzT~?emKLO$pzP{Z%u)L+Si*VeCu+K^zJ5UQs>cVpacJ6itewS7r zIA8F+IeIKEZoQKGgFJ6klff8ShmL4q7S}{(Wr&TF}1+19U)J|di7P033dfCpYD3kOpMC$+z#T`!y-ETx(vd7LUke?V@d zu;U{Wq9RqP(M;`B>1M!_f z|63lYV_KMQ2Z~+P7V9k7S!f%1`@biR6tRrx`onK}R^!huuEdeB4_5ttvOxM`yV>T0 zcJ<_9X3G)~p~y6LflN9_Aa?(6OMTxKu?<>EVGv42I(T5@|BFF*cVDaXA#dQD_40BB z!@MXR@Z9k_3_Q1d0Ob{+64VnJA3KUg)8Cq>UT^D@tspK9)rPqiLe+{IX{vEABO9}w zVh$d%9p#+w_X=@%|Jy&5KYKp7M)6eudz^fMyM~ zN}*-&wB+3b>i#Ho;(N^AbF=%dnNURk$⋘MY7B(kDpNCaGsH~1=v&bK#fELA~DkB zLc!pug+}OLX^(XSx?c#D$<(0yB^4ozx5=43Qk&8d%0rGUNH+J2qo|k0V{>bXOCz`P z7*KXyJKSTaV4mtwodMc=;lUIGsm<&hb0G8PY}RX3<8*q zZTsT9{CBGGE?50cEBTsC#6x;72<$GCkzylBv&Of>*B2uf;cAIY@1P=BjOPi0@&XgA z=ns@2j+N)Y}Vl zdvmt~kWLenkO`gzn|W+Av-Y=c{*x=c=v-y$BR$9X!Vu@9QGs@tSbR`r0D4fF)6U0% zNvUzm<*q+3i*AMgVk16qT1}U(KD~J4pNT@=$e$|5oSDpPfv?TH!9E(WK7%SP_U7|l ze9VLSH^FDNjWLK}K8?@eU(CncJk*Sw9C$44FXPpMmLp^(j9jo5616aO8fk@2PNAhn zk&&cyXhah#d1NXRlykcE4d!`34jy{#IfH!~X^wcq{=KtPZvC}=F$FrJ6!z%<0*}EA zwoQr;9-a@ZiH)5eQ;VU zPvuCaZiF_z;;HgVH7PyOYc?2tdE%2=Ao@N%^zlgg>+x3uMJhTE zdh6JnoQ$6tDUDwb}8TXH~p378Eql+klM_fM+xdV41G-^%|c_IMy21OXTzhOL3w(KdgyTz_6PE&u9Ycs@KZ7|bZRBI8%wyjI|UkVaGQyWLy z*T&J|Vsi8`B;uOZ)1~Tw_}aHuRVq-~?4>*MeqVb;FHOi+l#s!Eo8LESedi})EF+X~ zWb+og=q#`$_0LO_;`&j$LOhqD!e9<_MeWeG zBvB5(ztHLH3$c^NTIjyi*+=)d^}yibLL5~)3;NlT?>2v>iB4uLym!exz7Bf{{>zDrY-52ZoFRRXMjV-s}E4h^7PetUcYdTv(=S4 z82++KD?MjqVJD8K#Z@MSv*6E;Ke8E&=n0ONA#Dk)eTA$16wX4)n0%k<->2AIS*2qp z7Ce&pNL=NYa27V1cygwHpJQ|7m5v{=gpwj?E3N5=~}cQjU!^ zS5nesVG$vXXIY9gOoFqh%EYrVDSwGIf2pL&%2G=jZ;q#2CCzOl6VJn>oDysPN=frE ziwIeKE}rr@oW()g+i)Jv;w%#{!laxLyGpnk&&D!^QG1G~jDnk^!_6_^=2&oZ9Jo0i z+#DZnP5?J2f}4}T&B@^A4}O|EQo_w2!p&)<9qHia3~+NMxH&W2oE2`)1~+Gin{&X; zx!~qJaC2U`IUn3y0B$Y>Hy44Mi%C05z|Ezk9bdrBW#Q)XaC1etxiZ{b1#Yfds9Y;S z5-(2@uSycHLlSR95^q5g?|@$GP7?2rUK>IZ4<6=8B#F-;iO(a6FCmGq%#vI=S5Tr* zR1#FQwtj$<##|$FlaK}bm zR?uCtB-bq_sA=OM{0cBHzX*idk(bd+Z6SeW5>z|DWQ-qQOqWAnzJ6Ma&DfNLo!a~@$6DFZcUid<% zKvcu+*=6>_z81<*K}?h9zj30gE1X3>XbDLjTC6<}=5cz1`0#86hO;pE9xu9@*YtT!Z5@f9 zRz$#J8opeh(|1w4n}uU>G{3h^O^Y*X-hocAX>`9X3fL}eBRqAne%&kRz*q~@Z{TOc zqHh82;>|ro-~p6R9PRmS-sVHZzQAS6@=gnp&5y-UK1BObbfI7{L+u&cCGUIg%U=>B zEins|a3tc=0r&Esk?SAzsIg!K${q9aE4}2Rm7*tx6y>+JqyA7q>}sD;jOM|bdzT%C ztSvmX0_{iK5-w=X@j0}YiER@tWs-mI2RJm+ox_lebcZw}r9lgZ9%#4Ye=-)U**Gzp zN1T~1=TJA!4ZZ?hfit2he-0@B!-2h)AiT{&zM(zP2&6hx)NB32AmxOCny8{!R9Dl% zf{6}1xSdKuqdm9^OJC$!_X=#j?{gnz`$qC`qOW|#3ome>&w5tZ$6BVf&=cFx?FF)f zyhG?C$NmrO>H$9kjM)panzoX&#jg}ZXr8ltWV1HIBU-t@3r

nsLfe{fO&1=1%|-_JhSe@9*!LjqKV$c9xkKAx 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 V5-{>7NBo>pO&&Kgl`>J0`X7o!tu+7u diff --git a/utils/story_functions.py b/utils/story_functions.py index 3e762b394..07c5c92b9 100644 --- a/utils/story_functions.py +++ b/utils/story_functions.py @@ -1,6 +1,5 @@ from django.utils.dateformat import DateFormat import datetime -from utils.dateutil.parser import parse as dateutil_parse from django.utils.http import urlquote def format_story_link_date__short(date): @@ -33,23 +32,7 @@ def _extract_date_tuples(date): return parsed_date, date_tuple, today_tuple, yesterday_tuple def pre_process_story(entry): - date_published = entry.get('published', entry.get('updated')) - if not date_published: - date_published = str(datetime.datetime.now()) - entry['published_now'] = True - if not isinstance(date_published, datetime.datetime): - date_published = dateutil_parse(date_published) - # Change the date to UTC and remove timezone info since - # MySQL doesn't support it. - timezone_diff = datetime.datetime.utcnow() - datetime.datetime.now() - date_published_offset = date_published.utcoffset() - if date_published_offset: - date_published = (date_published - date_published_offset - - timezone_diff).replace(tzinfo=None) - else: - date_published = date_published.replace(tzinfo=None) - - entry['published'] = date_published + entry['published'] = datetime.datetime(*entry.get('published_parsed', entry.get('updated_parsed', datetime.datetime.utcnow()))[:6]) entry_link = entry.get('link', '') protocol_index = entry_link.find("://")