mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-23 11:09:23 +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+
|
This module offers extensions to the standard python 2.3+
|
||||||
datetime module.
|
datetime module.
|
||||||
"""
|
"""
|
||||||
__author__ = "Gustavo Niemeyer <niemeyer@conectiva.com>"
|
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||||
__license__ = "PSF License"
|
__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 -*-
|
# -*- 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+
|
This module offers extensions to the standard python 2.3+
|
||||||
datetime module.
|
datetime module.
|
||||||
"""
|
"""
|
||||||
__author__ = "Gustavo Niemeyer <niemeyer@conectiva.com>"
|
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||||
__license__ = "PSF License"
|
__license__ = "PSF License"
|
||||||
|
|
||||||
import os.path
|
|
||||||
import string
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import string
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
from cStringIO import StringIO
|
||||||
|
except ImportError:
|
||||||
|
from StringIO import StringIO
|
||||||
|
|
||||||
import relativedelta
|
import relativedelta
|
||||||
import tz
|
import tz
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["parse", "parserinfo"]
|
__all__ = ["parse", "parserinfo"]
|
||||||
|
|
||||||
|
|
||||||
# Some pointers:
|
# Some pointers:
|
||||||
#
|
#
|
||||||
# http://www.cl.cam.ac.uk/~mgk25/iso-time.html
|
# 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://search.cpan.org/author/MUIR/Time-modules-2003.0211/lib/Time/ParseDate.pm
|
||||||
# http://stein.cshl.org/jade/distrib/docs/java.text.SimpleDateFormat.html
|
# 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):
|
def __init__(self, instream):
|
||||||
if isinstance(instream, basestring):
|
if isinstance(instream, basestring):
|
||||||
instream = StringIO(instream)
|
instream = StringIO(instream)
|
||||||
@ -64,6 +66,8 @@ class _timelex:
|
|||||||
nextchar = self.charstack.pop(0)
|
nextchar = self.charstack.pop(0)
|
||||||
else:
|
else:
|
||||||
nextchar = self.instream.read(1)
|
nextchar = self.instream.read(1)
|
||||||
|
while nextchar == '\x00':
|
||||||
|
nextchar = self.instream.read(1)
|
||||||
if not nextchar:
|
if not nextchar:
|
||||||
self.eof = True
|
self.eof = True
|
||||||
break
|
break
|
||||||
@ -139,6 +143,7 @@ class _timelex:
|
|||||||
return list(cls(s))
|
return list(cls(s))
|
||||||
split = classmethod(split)
|
split = classmethod(split)
|
||||||
|
|
||||||
|
|
||||||
class _resultbase(object):
|
class _resultbase(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -156,7 +161,8 @@ class _resultbase(object):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self._repr(self.__class__.__name__)
|
return self._repr(self.__class__.__name__)
|
||||||
|
|
||||||
class parserinfo:
|
|
||||||
|
class parserinfo(object):
|
||||||
|
|
||||||
# m from a.m/p.m, t from ISO T separator
|
# m from a.m/p.m, t from ISO T separator
|
||||||
JUMP = [" ", ".", ",", ";", "-", "/", "'",
|
JUMP = [" ", ".", ",", ";", "-", "/", "'",
|
||||||
@ -204,7 +210,7 @@ class parserinfo:
|
|||||||
self.yearfirst = yearfirst
|
self.yearfirst = yearfirst
|
||||||
|
|
||||||
self._year = time.localtime().tm_year
|
self._year = time.localtime().tm_year
|
||||||
self._century = self._year/100*100
|
self._century = self._year//100*100
|
||||||
|
|
||||||
def _convert(self, lst):
|
def _convert(self, lst):
|
||||||
dct = {}
|
dct = {}
|
||||||
@ -281,10 +287,10 @@ class parserinfo:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class parser:
|
class parser(object):
|
||||||
|
|
||||||
def __init__(self, parserinfo=parserinfo):
|
def __init__(self, info=None):
|
||||||
self.info = parserinfo()
|
self.info = info or parserinfo()
|
||||||
|
|
||||||
def parse(self, timestr, default=None,
|
def parse(self, timestr, default=None,
|
||||||
ignoretz=False, tzinfos=None,
|
ignoretz=False, tzinfos=None,
|
||||||
@ -355,15 +361,18 @@ class parser:
|
|||||||
|
|
||||||
# Check if it's a number
|
# Check if it's a number
|
||||||
try:
|
try:
|
||||||
value = float(l[i])
|
value_repr = l[i]
|
||||||
|
value = float(value_repr)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
value = None
|
value = None
|
||||||
|
|
||||||
if value is not None:
|
if value is not None:
|
||||||
# Token is a number
|
# Token is a number
|
||||||
len_li = len(l[i])
|
len_li = len(l[i])
|
||||||
i += 1
|
i += 1
|
||||||
if (len(ymd) == 3 and len_li in (2, 4)
|
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]
|
# 19990101T23[59]
|
||||||
s = l[i-1]
|
s = l[i-1]
|
||||||
res.hour = int(s[:2])
|
res.hour = int(s[:2])
|
||||||
@ -380,10 +389,7 @@ class parser:
|
|||||||
# 19990101T235959[.59]
|
# 19990101T235959[.59]
|
||||||
res.hour = int(s[:2])
|
res.hour = int(s[:2])
|
||||||
res.minute = int(s[2:4])
|
res.minute = int(s[2:4])
|
||||||
value = float(s[4:])
|
res.second, res.microsecond = _parsems(s[4:])
|
||||||
res.second = int(value)
|
|
||||||
if value%1:
|
|
||||||
res.microsecond = int(1000000*(value%1))
|
|
||||||
elif len_li == 8:
|
elif len_li == 8:
|
||||||
# YYYYMMDD
|
# YYYYMMDD
|
||||||
s = l[i-1]
|
s = l[i-1]
|
||||||
@ -417,15 +423,15 @@ class parser:
|
|||||||
if value%1:
|
if value%1:
|
||||||
res.second = int(60*(value%1))
|
res.second = int(60*(value%1))
|
||||||
elif idx == 2:
|
elif idx == 2:
|
||||||
res.second = int(value)
|
res.second, res.microsecond = \
|
||||||
if value%1:
|
_parsems(value_repr)
|
||||||
res.microsecond = int(1000000*(value%1))
|
|
||||||
i += 1
|
i += 1
|
||||||
if i >= len_l or idx == 2:
|
if i >= len_l or idx == 2:
|
||||||
break
|
break
|
||||||
# 12h00
|
# 12h00
|
||||||
try:
|
try:
|
||||||
value = float(l[i])
|
value_repr = l[i]
|
||||||
|
value = float(value_repr)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@ -445,10 +451,7 @@ class parser:
|
|||||||
res.second = int(60*(value%1))
|
res.second = int(60*(value%1))
|
||||||
i += 1
|
i += 1
|
||||||
if i < len_l and l[i] == ':':
|
if i < len_l and l[i] == ':':
|
||||||
value = float(l[i+1])
|
res.second, res.microsecond = _parsems(l[i+1])
|
||||||
res.second = int(value)
|
|
||||||
if value%1:
|
|
||||||
res.microsecond = int(1000000*(value%1))
|
|
||||||
i += 2
|
i += 2
|
||||||
elif i < len_l and l[i] in ('-', '/', '.'):
|
elif i < len_l and l[i] in ('-', '/', '.'):
|
||||||
sep = l[i]
|
sep = l[i]
|
||||||
@ -693,7 +696,8 @@ def parse(timestr, parserinfo=None, **kwargs):
|
|||||||
else:
|
else:
|
||||||
return DEFAULTPARSER.parse(timestr, **kwargs)
|
return DEFAULTPARSER.parse(timestr, **kwargs)
|
||||||
|
|
||||||
class _tzparser:
|
|
||||||
|
class _tzparser(object):
|
||||||
|
|
||||||
class _result(_resultbase):
|
class _result(_resultbase):
|
||||||
|
|
||||||
@ -737,6 +741,8 @@ class _tzparser:
|
|||||||
if (i < len_l and
|
if (i < len_l and
|
||||||
(l[i] in ('+', '-') or l[i][0] in "0123456789")):
|
(l[i] in ('+', '-') or l[i][0] in "0123456789")):
|
||||||
if l[i] in ('+', '-'):
|
if l[i] in ('+', '-'):
|
||||||
|
# Yes, that's right. See the TZ variable
|
||||||
|
# documentation.
|
||||||
signal = (1,-1)[l[i] == '+']
|
signal = (1,-1)[l[i] == '+']
|
||||||
i += 1
|
i += 1
|
||||||
else:
|
else:
|
||||||
@ -859,11 +865,22 @@ class _tzparser:
|
|||||||
|
|
||||||
except (IndexError, ValueError, AssertionError):
|
except (IndexError, ValueError, AssertionError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
DEFAULTTZPARSER = _tzparser()
|
DEFAULTTZPARSER = _tzparser()
|
||||||
def _parsetz(tzstr):
|
def _parsetz(tzstr):
|
||||||
return DEFAULTTZPARSER.parse(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
|
# 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+
|
This module offers extensions to the standard python 2.3+
|
||||||
datetime module.
|
datetime module.
|
||||||
"""
|
"""
|
||||||
__author__ = "Gustavo Niemeyer <niemeyer@conectiva.com>"
|
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||||
__license__ = "PSF License"
|
__license__ = "PSF License"
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
@ -15,7 +15,7 @@ __all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
|
|||||||
class weekday(object):
|
class weekday(object):
|
||||||
__slots__ = ["weekday", "n"]
|
__slots__ = ["weekday", "n"]
|
||||||
|
|
||||||
def __init__(self, weekday, n=0):
|
def __init__(self, weekday, n=None):
|
||||||
self.weekday = weekday
|
self.weekday = weekday
|
||||||
self.n = n
|
self.n = n
|
||||||
|
|
||||||
@ -201,27 +201,27 @@ Here is the behavior of operations with relativedelta:
|
|||||||
|
|
||||||
def _fix(self):
|
def _fix(self):
|
||||||
if abs(self.microseconds) > 999999:
|
if abs(self.microseconds) > 999999:
|
||||||
s = self.microseconds/abs(self.microseconds)
|
s = self.microseconds//abs(self.microseconds)
|
||||||
div, mod = divmod(self.microseconds*s, 1000000)
|
div, mod = divmod(self.microseconds*s, 1000000)
|
||||||
self.microseconds = mod*s
|
self.microseconds = mod*s
|
||||||
self.seconds += div*s
|
self.seconds += div*s
|
||||||
if abs(self.seconds) > 59:
|
if abs(self.seconds) > 59:
|
||||||
s = self.seconds/abs(self.seconds)
|
s = self.seconds//abs(self.seconds)
|
||||||
div, mod = divmod(self.seconds*s, 60)
|
div, mod = divmod(self.seconds*s, 60)
|
||||||
self.seconds = mod*s
|
self.seconds = mod*s
|
||||||
self.minutes += div*s
|
self.minutes += div*s
|
||||||
if abs(self.minutes) > 59:
|
if abs(self.minutes) > 59:
|
||||||
s = self.minutes/abs(self.minutes)
|
s = self.minutes//abs(self.minutes)
|
||||||
div, mod = divmod(self.minutes*s, 60)
|
div, mod = divmod(self.minutes*s, 60)
|
||||||
self.minutes = mod*s
|
self.minutes = mod*s
|
||||||
self.hours += div*s
|
self.hours += div*s
|
||||||
if abs(self.hours) > 23:
|
if abs(self.hours) > 23:
|
||||||
s = self.hours/abs(self.hours)
|
s = self.hours//abs(self.hours)
|
||||||
div, mod = divmod(self.hours*s, 24)
|
div, mod = divmod(self.hours*s, 24)
|
||||||
self.hours = mod*s
|
self.hours = mod*s
|
||||||
self.days += div*s
|
self.days += div*s
|
||||||
if abs(self.months) > 11:
|
if abs(self.months) > 11:
|
||||||
s = self.months/abs(self.months)
|
s = self.months//abs(self.months)
|
||||||
div, mod = divmod(self.months*s, 12)
|
div, mod = divmod(self.months*s, 12)
|
||||||
self.months = mod*s
|
self.months = mod*s
|
||||||
self.years += div*s
|
self.years += div*s
|
||||||
@ -235,7 +235,7 @@ Here is the behavior of operations with relativedelta:
|
|||||||
def _set_months(self, months):
|
def _set_months(self, months):
|
||||||
self.months = months
|
self.months = months
|
||||||
if abs(self.months) > 11:
|
if abs(self.months) > 11:
|
||||||
s = self.months/abs(self.months)
|
s = self.months//abs(self.months)
|
||||||
div, mod = divmod(self.months*s, 12)
|
div, mod = divmod(self.months*s, 12)
|
||||||
self.months = mod*s
|
self.months = mod*s
|
||||||
self.years = div*s
|
self.years = div*s
|
||||||
@ -392,7 +392,7 @@ Here is the behavior of operations with relativedelta:
|
|||||||
if self.weekday.weekday != other.weekday.weekday:
|
if self.weekday.weekday != other.weekday.weekday:
|
||||||
return False
|
return False
|
||||||
n1, n2 = self.weekday.n, other.weekday.n
|
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 False
|
||||||
return (self.years == other.years and
|
return (self.years == other.years and
|
||||||
self.months == other.months 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+
|
This module offers extensions to the standard python 2.3+
|
||||||
datetime module.
|
datetime module.
|
||||||
"""
|
"""
|
||||||
__author__ = "Gustavo Niemeyer <niemeyer@conectiva.com>"
|
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||||
__license__ = "PSF License"
|
__license__ = "PSF License"
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import struct
|
import struct
|
||||||
import time
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
import relativedelta
|
relativedelta = None
|
||||||
import parser
|
parser = None
|
||||||
rrule = None # XXX Where does this come from? Why isn't it here?
|
rrule = None
|
||||||
|
|
||||||
__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile",
|
__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
|
||||||
"tzrange", "tzstr", "tzical", "gettz"]
|
"tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
from dateutil.tzwin import tzwin, tzwinlocal
|
||||||
|
except (ImportError, OSError):
|
||||||
|
tzwin, tzwinlocal = None, None
|
||||||
|
|
||||||
ZERO = datetime.timedelta(0)
|
ZERO = datetime.timedelta(0)
|
||||||
EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()
|
EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()
|
||||||
@ -42,6 +49,8 @@ class tzutc(datetime.tzinfo):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s()" % self.__class__.__name__
|
return "%s()" % self.__class__.__name__
|
||||||
|
|
||||||
|
__reduce__ = object.__reduce__
|
||||||
|
|
||||||
class tzoffset(datetime.tzinfo):
|
class tzoffset(datetime.tzinfo):
|
||||||
|
|
||||||
def __init__(self, name, offset):
|
def __init__(self, name, offset):
|
||||||
@ -69,6 +78,8 @@ class tzoffset(datetime.tzinfo):
|
|||||||
`self._name`,
|
`self._name`,
|
||||||
self._offset.days*86400+self._offset.seconds)
|
self._offset.days*86400+self._offset.seconds)
|
||||||
|
|
||||||
|
__reduce__ = object.__reduce__
|
||||||
|
|
||||||
class tzlocal(datetime.tzinfo):
|
class tzlocal(datetime.tzinfo):
|
||||||
|
|
||||||
_std_offset = datetime.timedelta(seconds=-time.timezone)
|
_std_offset = datetime.timedelta(seconds=-time.timezone)
|
||||||
@ -136,6 +147,8 @@ class tzlocal(datetime.tzinfo):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s()" % self.__class__.__name__
|
return "%s()" % self.__class__.__name__
|
||||||
|
|
||||||
|
__reduce__ = object.__reduce__
|
||||||
|
|
||||||
class _ttinfo(object):
|
class _ttinfo(object):
|
||||||
__slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"]
|
__slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"]
|
||||||
|
|
||||||
@ -164,6 +177,17 @@ class _ttinfo(object):
|
|||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
return not self.__eq__(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):
|
class tzfile(datetime.tzinfo):
|
||||||
|
|
||||||
# http://www.twinsun.com/tz/tz-link.htm
|
# http://www.twinsun.com/tz/tz-link.htm
|
||||||
@ -171,12 +195,12 @@ class tzfile(datetime.tzinfo):
|
|||||||
|
|
||||||
def __init__(self, fileobj):
|
def __init__(self, fileobj):
|
||||||
if isinstance(fileobj, basestring):
|
if isinstance(fileobj, basestring):
|
||||||
self._s = fileobj
|
self._filename = fileobj
|
||||||
fileobj = open(fileobj)
|
fileobj = open(fileobj)
|
||||||
elif hasattr(fileobj, "name"):
|
elif hasattr(fileobj, "name"):
|
||||||
self._s = fileobj.name
|
self._filename = fileobj.name
|
||||||
else:
|
else:
|
||||||
self._s = `fileobj`
|
self._filename = `fileobj`
|
||||||
|
|
||||||
# From tzfile(5):
|
# From tzfile(5):
|
||||||
#
|
#
|
||||||
@ -273,7 +297,7 @@ class tzfile(datetime.tzinfo):
|
|||||||
|
|
||||||
# Not used, for now
|
# Not used, for now
|
||||||
if leapcnt:
|
if leapcnt:
|
||||||
leap = struct.unpack(">%dl" % leapcnt*2,
|
leap = struct.unpack(">%dl" % (leapcnt*2),
|
||||||
fileobj.read(leapcnt*8))
|
fileobj.read(leapcnt*8))
|
||||||
|
|
||||||
# Then there are tzh_ttisstdcnt standard/wall
|
# Then there are tzh_ttisstdcnt standard/wall
|
||||||
@ -305,11 +329,16 @@ class tzfile(datetime.tzinfo):
|
|||||||
# Build ttinfo list
|
# Build ttinfo list
|
||||||
self._ttinfo_list = []
|
self._ttinfo_list = []
|
||||||
for i in range(typecnt):
|
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 = _ttinfo()
|
||||||
tti.offset = ttinfo[i][0]
|
tti.offset = gmtoff
|
||||||
tti.delta = datetime.timedelta(seconds=ttinfo[i][0])
|
tti.delta = datetime.timedelta(seconds=gmtoff)
|
||||||
tti.isdst = ttinfo[i][1]
|
tti.isdst = isdst
|
||||||
tti.abbr = abbr[ttinfo[i][2]:abbr.find('\x00', ttinfo[i][2])]
|
tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)]
|
||||||
tti.isstd = (ttisstdcnt > i and isstd[i] != 0)
|
tti.isstd = (ttisstdcnt > i and isstd[i] != 0)
|
||||||
tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0)
|
tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0)
|
||||||
self._ttinfo_list.append(tti)
|
self._ttinfo_list.append(tti)
|
||||||
@ -409,7 +438,7 @@ class tzfile(datetime.tzinfo):
|
|||||||
|
|
||||||
# The documentation says that utcoffset()-dst() must
|
# The documentation says that utcoffset()-dst() must
|
||||||
# be constant for every dt.
|
# 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:
|
# An alternative for that would be:
|
||||||
#
|
#
|
||||||
@ -436,13 +465,21 @@ class tzfile(datetime.tzinfo):
|
|||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
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):
|
class tzrange(datetime.tzinfo):
|
||||||
|
|
||||||
def __init__(self, stdabbr, stdoffset=None,
|
def __init__(self, stdabbr, stdoffset=None,
|
||||||
dstabbr=None, dstoffset=None,
|
dstabbr=None, dstoffset=None,
|
||||||
start=None, end=None):
|
start=None, end=None):
|
||||||
|
global relativedelta
|
||||||
|
if not relativedelta:
|
||||||
|
from dateutil import relativedelta
|
||||||
self._std_abbr = stdabbr
|
self._std_abbr = stdabbr
|
||||||
self._dst_abbr = dstabbr
|
self._dst_abbr = dstabbr
|
||||||
if stdoffset is not None:
|
if stdoffset is not None:
|
||||||
@ -455,12 +492,12 @@ class tzrange(datetime.tzinfo):
|
|||||||
self._dst_offset = self._std_offset+datetime.timedelta(hours=+1)
|
self._dst_offset = self._std_offset+datetime.timedelta(hours=+1)
|
||||||
else:
|
else:
|
||||||
self._dst_offset = ZERO
|
self._dst_offset = ZERO
|
||||||
if start is None:
|
if dstabbr and start is None:
|
||||||
self._start_delta = relativedelta.relativedelta(
|
self._start_delta = relativedelta.relativedelta(
|
||||||
hours=+2, month=4, day=1, weekday=relativedelta.SU(+1))
|
hours=+2, month=4, day=1, weekday=relativedelta.SU(+1))
|
||||||
else:
|
else:
|
||||||
self._start_delta = start
|
self._start_delta = start
|
||||||
if end is None:
|
if dstabbr and end is None:
|
||||||
self._end_delta = relativedelta.relativedelta(
|
self._end_delta = relativedelta.relativedelta(
|
||||||
hours=+1, month=10, day=31, weekday=relativedelta.SU(-1))
|
hours=+1, month=10, day=31, weekday=relativedelta.SU(-1))
|
||||||
else:
|
else:
|
||||||
@ -487,7 +524,7 @@ class tzrange(datetime.tzinfo):
|
|||||||
def _isdst(self, dt):
|
def _isdst(self, dt):
|
||||||
if not self._start_delta:
|
if not self._start_delta:
|
||||||
return False
|
return False
|
||||||
year = datetime.date(dt.year,1,1)
|
year = datetime.datetime(dt.year,1,1)
|
||||||
start = year+self._start_delta
|
start = year+self._start_delta
|
||||||
end = year+self._end_delta
|
end = year+self._end_delta
|
||||||
dt = dt.replace(tzinfo=None)
|
dt = dt.replace(tzinfo=None)
|
||||||
@ -512,16 +549,25 @@ class tzrange(datetime.tzinfo):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s(...)" % self.__class__.__name__
|
return "%s(...)" % self.__class__.__name__
|
||||||
|
|
||||||
|
__reduce__ = object.__reduce__
|
||||||
|
|
||||||
class tzstr(tzrange):
|
class tzstr(tzrange):
|
||||||
|
|
||||||
def __init__(self, s):
|
def __init__(self, s):
|
||||||
|
global parser
|
||||||
|
if not parser:
|
||||||
|
from dateutil import parser
|
||||||
self._s = s
|
self._s = s
|
||||||
|
|
||||||
res = parser._parsetz(s)
|
res = parser._parsetz(s)
|
||||||
if res is None:
|
if res is None:
|
||||||
raise ValueError, "unknown string format"
|
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
|
# We must initialize it first, since _delta() needs
|
||||||
# _std_offset and _dst_offset set. Use False in start/end
|
# _std_offset and _dst_offset set. Use False in start/end
|
||||||
# to avoid building it two times.
|
# to avoid building it two times.
|
||||||
@ -529,9 +575,13 @@ class tzstr(tzrange):
|
|||||||
res.dstabbr, res.dstoffset,
|
res.dstabbr, res.dstoffset,
|
||||||
start=False, end=False)
|
start=False, end=False)
|
||||||
|
|
||||||
self._start_delta = self._delta(res.start)
|
if not res.dstabbr:
|
||||||
if self._start_delta:
|
self._start_delta = None
|
||||||
self._end_delta = self._delta(res.end, isend=1)
|
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):
|
def _delta(self, x, isend=0):
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
@ -646,9 +696,10 @@ class _tzicalvtz(datetime.tzinfo):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<tzicalvtz %s>" % `self._tzid`
|
return "<tzicalvtz %s>" % `self._tzid`
|
||||||
|
|
||||||
|
__reduce__ = object.__reduce__
|
||||||
|
|
||||||
class tzical:
|
class tzical:
|
||||||
def __init__(self, fileobj):
|
def __init__(self, fileobj):
|
||||||
# XXX This should be fixed, but doesn't seem to be in our dateutil.
|
|
||||||
global rrule
|
global rrule
|
||||||
if not rrule:
|
if not rrule:
|
||||||
from dateutil import rrule
|
from dateutil import rrule
|
||||||
@ -672,9 +723,9 @@ class tzical:
|
|||||||
if tzid is None:
|
if tzid is None:
|
||||||
keys = self._vtz.keys()
|
keys = self._vtz.keys()
|
||||||
if len(keys) == 0:
|
if len(keys) == 0:
|
||||||
raise "no timezones defined"
|
raise ValueError, "no timezones defined"
|
||||||
elif len(keys) > 1:
|
elif len(keys) > 1:
|
||||||
raise "more than one timezone available"
|
raise ValueError, "more than one timezone available"
|
||||||
tzid = keys[0]
|
tzid = keys[0]
|
||||||
return self._vtz.get(tzid)
|
return self._vtz.get(tzid)
|
||||||
|
|
||||||
@ -711,6 +762,8 @@ class tzical:
|
|||||||
else:
|
else:
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
tzid = None
|
||||||
|
comps = []
|
||||||
invtz = False
|
invtz = False
|
||||||
comptype = None
|
comptype = None
|
||||||
for line in lines:
|
for line in lines:
|
||||||
@ -753,10 +806,10 @@ class tzical:
|
|||||||
if not founddtstart:
|
if not founddtstart:
|
||||||
raise ValueError, \
|
raise ValueError, \
|
||||||
"mandatory DTSTART not found"
|
"mandatory DTSTART not found"
|
||||||
if not tzoffsetfrom:
|
if tzoffsetfrom is None:
|
||||||
raise ValueError, \
|
raise ValueError, \
|
||||||
"mandatory TZOFFSETFROM not found"
|
"mandatory TZOFFSETFROM not found"
|
||||||
if not tzoffsetto:
|
if tzoffsetto is None:
|
||||||
raise ValueError, \
|
raise ValueError, \
|
||||||
"mandatory TZOFFSETFROM not found"
|
"mandatory TZOFFSETFROM not found"
|
||||||
# Process component
|
# Process component
|
||||||
@ -817,10 +870,12 @@ class tzical:
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s(%s)" % (self.__class__.__name__, `self._s`)
|
return "%s(%s)" % (self.__class__.__name__, `self._s`)
|
||||||
|
|
||||||
TZFILES = ["/etc/localtime", "localtime"]
|
if sys.platform != "win32":
|
||||||
TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"]
|
TZFILES = ["/etc/localtime", "localtime"]
|
||||||
|
TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"]
|
||||||
import os
|
else:
|
||||||
|
TZFILES = []
|
||||||
|
TZPATHS = []
|
||||||
|
|
||||||
def gettz(name=None):
|
def gettz(name=None):
|
||||||
tz = None
|
tz = None
|
||||||
@ -829,7 +884,7 @@ def gettz(name=None):
|
|||||||
name = os.environ["TZ"]
|
name = os.environ["TZ"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
if name is None:
|
if name is None or name == ":":
|
||||||
for filepath in TZFILES:
|
for filepath in TZFILES:
|
||||||
if not os.path.isabs(filepath):
|
if not os.path.isabs(filepath):
|
||||||
filename = filepath
|
filename = filepath
|
||||||
@ -845,34 +900,52 @@ def gettz(name=None):
|
|||||||
break
|
break
|
||||||
except (IOError, OSError, ValueError):
|
except (IOError, OSError, ValueError):
|
||||||
pass
|
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:
|
else:
|
||||||
for c in name:
|
tz = tzlocal()
|
||||||
# name must have at least one offset to be a tzstr
|
else:
|
||||||
if c in "0123456789":
|
if name.startswith(":"):
|
||||||
try:
|
name = name[:-1]
|
||||||
tz = tzstr(name)
|
if os.path.isabs(name):
|
||||||
except ValueError:
|
if os.path.isfile(name):
|
||||||
pass
|
tz = tzfile(name)
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
if name in ("GMT", "UTC"):
|
tz = None
|
||||||
tz = tzutc()
|
else:
|
||||||
elif name in time.tzname:
|
for path in TZPATHS:
|
||||||
tz = tzlocal()
|
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
|
return tz
|
||||||
|
|
||||||
# vim:ts=4:sw=4:et
|
# 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