mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-14 14:49:21 +01:00
Update dateutil to latest version and include all files
Signed-off-by: James Vega <jamessan@users.sourceforge.net>
This commit is contained in:
parent
fea4cc2962
commit
5fda0df4a9
@ -1,8 +1,9 @@
|
||||
"""
|
||||
Copyright (c) 2003 Gustavo Niemeyer <niemeyer@conectiva.com>
|
||||
Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
This module offers extensions to the standard python 2.3+
|
||||
datetime module.
|
||||
"""
|
||||
__author__ = "Gustavo Niemeyer <niemeyer@conectiva.com>"
|
||||
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||
__license__ = "PSF License"
|
||||
__version__ = "1.4.1"
|
||||
|
92
plugins/Time/local/dateutil/easter.py
Normal file
92
plugins/Time/local/dateutil/easter.py
Normal file
@ -0,0 +1,92 @@
|
||||
"""
|
||||
Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
This module offers extensions to the standard python 2.3+
|
||||
datetime module.
|
||||
"""
|
||||
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||
__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))
|
||||
|
@ -1,26 +1,31 @@
|
||||
# -*- coding:iso-8859-1 -*-
|
||||
# Gotten from: http://moin.conectiva.com.br/DateUtil
|
||||
|
||||
"""
|
||||
Copyright (c) 2003 Gustavo Niemeyer <niemeyer@conectiva.com>
|
||||
Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
This module offers extensions to the standard python 2.3+
|
||||
datetime module.
|
||||
"""
|
||||
__author__ = "Gustavo Niemeyer <niemeyer@conectiva.com>"
|
||||
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||
__license__ = "PSF License"
|
||||
|
||||
import os.path
|
||||
import string
|
||||
import sys
|
||||
import time
|
||||
|
||||
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
|
||||
@ -30,12 +35,9 @@ __all__ = ["parse", "parserinfo"]
|
||||
# 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
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
class _timelex:
|
||||
class _timelex(object):
|
||||
|
||||
def __init__(self, instream):
|
||||
if isinstance(instream, basestring):
|
||||
instream = StringIO(instream)
|
||||
@ -64,6 +66,8 @@ class _timelex:
|
||||
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
|
||||
@ -139,6 +143,7 @@ class _timelex:
|
||||
return list(cls(s))
|
||||
split = classmethod(split)
|
||||
|
||||
|
||||
class _resultbase(object):
|
||||
|
||||
def __init__(self):
|
||||
@ -156,7 +161,8 @@ class _resultbase(object):
|
||||
def __repr__(self):
|
||||
return self._repr(self.__class__.__name__)
|
||||
|
||||
class parserinfo:
|
||||
|
||||
class parserinfo(object):
|
||||
|
||||
# m from a.m/p.m, t from ISO T separator
|
||||
JUMP = [" ", ".", ",", ";", "-", "/", "'",
|
||||
@ -204,7 +210,7 @@ class parserinfo:
|
||||
self.yearfirst = yearfirst
|
||||
|
||||
self._year = time.localtime().tm_year
|
||||
self._century = self._year/100*100
|
||||
self._century = self._year//100*100
|
||||
|
||||
def _convert(self, lst):
|
||||
dct = {}
|
||||
@ -281,10 +287,10 @@ class parserinfo:
|
||||
return True
|
||||
|
||||
|
||||
class parser:
|
||||
class parser(object):
|
||||
|
||||
def __init__(self, parserinfo=parserinfo):
|
||||
self.info = parserinfo()
|
||||
def __init__(self, info=None):
|
||||
self.info = info or parserinfo()
|
||||
|
||||
def parse(self, timestr, default=None,
|
||||
ignoretz=False, tzinfos=None,
|
||||
@ -355,15 +361,18 @@ class parser:
|
||||
|
||||
# Check if it's a number
|
||||
try:
|
||||
value = float(l[i])
|
||||
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 (i >= len_l or (l[i] != ':' and
|
||||
info.hms(l[i]) is None))):
|
||||
# 19990101T23[59]
|
||||
s = l[i-1]
|
||||
res.hour = int(s[:2])
|
||||
@ -380,10 +389,7 @@ class parser:
|
||||
# 19990101T235959[.59]
|
||||
res.hour = int(s[:2])
|
||||
res.minute = int(s[2:4])
|
||||
value = float(s[4:])
|
||||
res.second = int(value)
|
||||
if value%1:
|
||||
res.microsecond = int(1000000*(value%1))
|
||||
res.second, res.microsecond = _parsems(s[4:])
|
||||
elif len_li == 8:
|
||||
# YYYYMMDD
|
||||
s = l[i-1]
|
||||
@ -417,15 +423,15 @@ class parser:
|
||||
if value%1:
|
||||
res.second = int(60*(value%1))
|
||||
elif idx == 2:
|
||||
res.second = int(value)
|
||||
if value%1:
|
||||
res.microsecond = int(1000000*(value%1))
|
||||
res.second, res.microsecond = \
|
||||
_parsems(value_repr)
|
||||
i += 1
|
||||
if i >= len_l or idx == 2:
|
||||
break
|
||||
# 12h00
|
||||
try:
|
||||
value = float(l[i])
|
||||
value_repr = l[i]
|
||||
value = float(value_repr)
|
||||
except ValueError:
|
||||
break
|
||||
else:
|
||||
@ -445,10 +451,7 @@ class parser:
|
||||
res.second = int(60*(value%1))
|
||||
i += 1
|
||||
if i < len_l and l[i] == ':':
|
||||
value = float(l[i+1])
|
||||
res.second = int(value)
|
||||
if value%1:
|
||||
res.microsecond = int(1000000*(value%1))
|
||||
res.second, res.microsecond = _parsems(l[i+1])
|
||||
i += 2
|
||||
elif i < len_l and l[i] in ('-', '/', '.'):
|
||||
sep = l[i]
|
||||
@ -693,7 +696,8 @@ def parse(timestr, parserinfo=None, **kwargs):
|
||||
else:
|
||||
return DEFAULTPARSER.parse(timestr, **kwargs)
|
||||
|
||||
class _tzparser:
|
||||
|
||||
class _tzparser(object):
|
||||
|
||||
class _result(_resultbase):
|
||||
|
||||
@ -737,6 +741,8 @@ class _tzparser:
|
||||
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:
|
||||
@ -859,11 +865,22 @@ class _tzparser:
|
||||
|
||||
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
|
||||
|
@ -1,10 +1,10 @@
|
||||
"""
|
||||
Copyright (c) 2003 Gustavo Niemeyer <niemeyer@conectiva.com>
|
||||
Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
This module offers extensions to the standard python 2.3+
|
||||
datetime module.
|
||||
"""
|
||||
__author__ = "Gustavo Niemeyer <niemeyer@conectiva.com>"
|
||||
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||
__license__ = "PSF License"
|
||||
|
||||
import datetime
|
||||
@ -15,7 +15,7 @@ __all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
|
||||
class weekday(object):
|
||||
__slots__ = ["weekday", "n"]
|
||||
|
||||
def __init__(self, weekday, n=0):
|
||||
def __init__(self, weekday, n=None):
|
||||
self.weekday = weekday
|
||||
self.n = n
|
||||
|
||||
@ -201,27 +201,27 @@ Here is the behavior of operations with relativedelta:
|
||||
|
||||
def _fix(self):
|
||||
if abs(self.microseconds) > 999999:
|
||||
s = self.microseconds/abs(self.microseconds)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
s = self.months//abs(self.months)
|
||||
div, mod = divmod(self.months*s, 12)
|
||||
self.months = mod*s
|
||||
self.years += div*s
|
||||
@ -235,7 +235,7 @@ Here is the behavior of operations with relativedelta:
|
||||
def _set_months(self, months):
|
||||
self.months = months
|
||||
if abs(self.months) > 11:
|
||||
s = self.months/abs(self.months)
|
||||
s = self.months//abs(self.months)
|
||||
div, mod = divmod(self.months*s, 12)
|
||||
self.months = mod*s
|
||||
self.years = div*s
|
||||
@ -392,7 +392,7 @@ Here is the behavior of operations with relativedelta:
|
||||
if self.weekday.weekday != other.weekday.weekday:
|
||||
return False
|
||||
n1, n2 = self.weekday.n, other.weekday.n
|
||||
if n1 != n2 and not (n1 in (0, 1) and n2 in (0, 1)):
|
||||
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
|
||||
|
1097
plugins/Time/local/dateutil/rrule.py
Normal file
1097
plugins/Time/local/dateutil/rrule.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,29 @@
|
||||
"""
|
||||
Copyright (c) 2003 Gustavo Niemeyer <niemeyer@conectiva.com>
|
||||
Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
This module offers extensions to the standard python 2.3+
|
||||
datetime module.
|
||||
"""
|
||||
__author__ = "Gustavo Niemeyer <niemeyer@conectiva.com>"
|
||||
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||
__license__ = "PSF License"
|
||||
|
||||
import datetime
|
||||
import struct
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
||||
import relativedelta
|
||||
import parser
|
||||
rrule = None # XXX Where does this come from? Why isn't it here?
|
||||
relativedelta = None
|
||||
parser = None
|
||||
rrule = None
|
||||
|
||||
__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile",
|
||||
"tzrange", "tzstr", "tzical", "gettz"]
|
||||
__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()
|
||||
@ -42,6 +49,8 @@ class tzutc(datetime.tzinfo):
|
||||
def __repr__(self):
|
||||
return "%s()" % self.__class__.__name__
|
||||
|
||||
__reduce__ = object.__reduce__
|
||||
|
||||
class tzoffset(datetime.tzinfo):
|
||||
|
||||
def __init__(self, name, offset):
|
||||
@ -69,6 +78,8 @@ class tzoffset(datetime.tzinfo):
|
||||
`self._name`,
|
||||
self._offset.days*86400+self._offset.seconds)
|
||||
|
||||
__reduce__ = object.__reduce__
|
||||
|
||||
class tzlocal(datetime.tzinfo):
|
||||
|
||||
_std_offset = datetime.timedelta(seconds=-time.timezone)
|
||||
@ -136,6 +147,8 @@ class tzlocal(datetime.tzinfo):
|
||||
def __repr__(self):
|
||||
return "%s()" % self.__class__.__name__
|
||||
|
||||
__reduce__ = object.__reduce__
|
||||
|
||||
class _ttinfo(object):
|
||||
__slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"]
|
||||
|
||||
@ -164,6 +177,17 @@ class _ttinfo(object):
|
||||
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
|
||||
@ -171,12 +195,12 @@ class tzfile(datetime.tzinfo):
|
||||
|
||||
def __init__(self, fileobj):
|
||||
if isinstance(fileobj, basestring):
|
||||
self._s = fileobj
|
||||
self._filename = fileobj
|
||||
fileobj = open(fileobj)
|
||||
elif hasattr(fileobj, "name"):
|
||||
self._s = fileobj.name
|
||||
self._filename = fileobj.name
|
||||
else:
|
||||
self._s = `fileobj`
|
||||
self._filename = `fileobj`
|
||||
|
||||
# From tzfile(5):
|
||||
#
|
||||
@ -273,7 +297,7 @@ class tzfile(datetime.tzinfo):
|
||||
|
||||
# Not used, for now
|
||||
if leapcnt:
|
||||
leap = struct.unpack(">%dl" % leapcnt*2,
|
||||
leap = struct.unpack(">%dl" % (leapcnt*2),
|
||||
fileobj.read(leapcnt*8))
|
||||
|
||||
# Then there are tzh_ttisstdcnt standard/wall
|
||||
@ -305,11 +329,16 @@ class tzfile(datetime.tzinfo):
|
||||
# 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 = ttinfo[i][0]
|
||||
tti.delta = datetime.timedelta(seconds=ttinfo[i][0])
|
||||
tti.isdst = ttinfo[i][1]
|
||||
tti.abbr = abbr[ttinfo[i][2]:abbr.find('\x00', ttinfo[i][2])]
|
||||
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)
|
||||
@ -409,7 +438,7 @@ class tzfile(datetime.tzinfo):
|
||||
|
||||
# The documentation says that utcoffset()-dst() must
|
||||
# be constant for every dt.
|
||||
return self._find_ttinfo(dt, laststd=1).delta-tti.delta
|
||||
return tti.delta-self._find_ttinfo(dt, laststd=1).delta
|
||||
|
||||
# An alternative for that would be:
|
||||
#
|
||||
@ -436,13 +465,21 @@ class tzfile(datetime.tzinfo):
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%s)" % (self.__class__.__name__, `self._s`)
|
||||
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:
|
||||
@ -455,12 +492,12 @@ class tzrange(datetime.tzinfo):
|
||||
self._dst_offset = self._std_offset+datetime.timedelta(hours=+1)
|
||||
else:
|
||||
self._dst_offset = ZERO
|
||||
if start is None:
|
||||
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 end is None:
|
||||
if dstabbr and end is None:
|
||||
self._end_delta = relativedelta.relativedelta(
|
||||
hours=+1, month=10, day=31, weekday=relativedelta.SU(-1))
|
||||
else:
|
||||
@ -487,7 +524,7 @@ class tzrange(datetime.tzinfo):
|
||||
def _isdst(self, dt):
|
||||
if not self._start_delta:
|
||||
return False
|
||||
year = datetime.date(dt.year,1,1)
|
||||
year = datetime.datetime(dt.year,1,1)
|
||||
start = year+self._start_delta
|
||||
end = year+self._end_delta
|
||||
dt = dt.replace(tzinfo=None)
|
||||
@ -512,16 +549,25 @@ class tzrange(datetime.tzinfo):
|
||||
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.
|
||||
@ -529,9 +575,13 @@ class tzstr(tzrange):
|
||||
res.dstabbr, res.dstoffset,
|
||||
start=False, end=False)
|
||||
|
||||
self._start_delta = self._delta(res.start)
|
||||
if self._start_delta:
|
||||
self._end_delta = self._delta(res.end, isend=1)
|
||||
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 = {}
|
||||
@ -646,9 +696,10 @@ class _tzicalvtz(datetime.tzinfo):
|
||||
def __repr__(self):
|
||||
return "<tzicalvtz %s>" % `self._tzid`
|
||||
|
||||
__reduce__ = object.__reduce__
|
||||
|
||||
class tzical:
|
||||
def __init__(self, fileobj):
|
||||
# XXX This should be fixed, but doesn't seem to be in our dateutil.
|
||||
global rrule
|
||||
if not rrule:
|
||||
from dateutil import rrule
|
||||
@ -672,9 +723,9 @@ class tzical:
|
||||
if tzid is None:
|
||||
keys = self._vtz.keys()
|
||||
if len(keys) == 0:
|
||||
raise "no timezones defined"
|
||||
raise ValueError, "no timezones defined"
|
||||
elif len(keys) > 1:
|
||||
raise "more than one timezone available"
|
||||
raise ValueError, "more than one timezone available"
|
||||
tzid = keys[0]
|
||||
return self._vtz.get(tzid)
|
||||
|
||||
@ -711,6 +762,8 @@ class tzical:
|
||||
else:
|
||||
i += 1
|
||||
|
||||
tzid = None
|
||||
comps = []
|
||||
invtz = False
|
||||
comptype = None
|
||||
for line in lines:
|
||||
@ -753,10 +806,10 @@ class tzical:
|
||||
if not founddtstart:
|
||||
raise ValueError, \
|
||||
"mandatory DTSTART not found"
|
||||
if not tzoffsetfrom:
|
||||
if tzoffsetfrom is None:
|
||||
raise ValueError, \
|
||||
"mandatory TZOFFSETFROM not found"
|
||||
if not tzoffsetto:
|
||||
if tzoffsetto is None:
|
||||
raise ValueError, \
|
||||
"mandatory TZOFFSETFROM not found"
|
||||
# Process component
|
||||
@ -817,10 +870,12 @@ class tzical:
|
||||
def __repr__(self):
|
||||
return "%s(%s)" % (self.__class__.__name__, `self._s`)
|
||||
|
||||
TZFILES = ["/etc/localtime", "localtime"]
|
||||
TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"]
|
||||
|
||||
import os
|
||||
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
|
||||
@ -829,7 +884,7 @@ def gettz(name=None):
|
||||
name = os.environ["TZ"]
|
||||
except KeyError:
|
||||
pass
|
||||
if name is None:
|
||||
if name is None or name == ":":
|
||||
for filepath in TZFILES:
|
||||
if not os.path.isabs(filepath):
|
||||
filename = filepath
|
||||
@ -845,34 +900,52 @@ def gettz(name=None):
|
||||
break
|
||||
except (IOError, OSError, ValueError):
|
||||
pass
|
||||
else:
|
||||
if name and name[0] == ":":
|
||||
name = name[:-1]
|
||||
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:
|
||||
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
|
||||
tz = tzlocal()
|
||||
else:
|
||||
if name.startswith(":"):
|
||||
name = name[:-1]
|
||||
if os.path.isabs(name):
|
||||
if os.path.isfile(name):
|
||||
tz = tzfile(name)
|
||||
else:
|
||||
if name in ("GMT", "UTC"):
|
||||
tz = tzutc()
|
||||
elif name in time.tzname:
|
||||
tz = tzlocal()
|
||||
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
|
||||
|
180
plugins/Time/local/dateutil/tzwin.py
Normal file
180
plugins/Time/local/dateutil/tzwin.py
Normal file
@ -0,0 +1,180 @@
|
||||
# This code was originally contributed by Jeffrey Harris.
|
||||
import datetime
|
||||
import struct
|
||||
import _winreg
|
||||
|
||||
__author__ = "Jeffrey Harris & Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||
|
||||
__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
|
87
plugins/Time/local/dateutil/zoneinfo/__init__.py
Normal file
87
plugins/Time/local/dateutil/zoneinfo/__init__.py
Normal file
@ -0,0 +1,87 @@
|
||||
"""
|
||||
Copyright (c) 2003-2005 Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
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 <gustavo@niemeyer.net>"
|
||||
__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)
|
BIN
plugins/Time/local/dateutil/zoneinfo/zoneinfo-2008e.tar.gz
Normal file
BIN
plugins/Time/local/dateutil/zoneinfo/zoneinfo-2008e.tar.gz
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user