summaryrefslogtreecommitdiff
path: root/dateutil
diff options
context:
space:
mode:
authorniemeyer <>2005-02-24 17:23:24 +0000
committerniemeyer <>2005-02-24 17:23:24 +0000
commite2b6346687c19f305b9c4a2d57826bf1bab6b275 (patch)
tree568560548a3e2781aadc23096e104abe3a186a7b /dateutil
parentdebf3cd82a0aa85949c84eefa13eab5fd5be3949 (diff)
downloaddateutil-e2b6346687c19f305b9c4a2d57826bf1bab6b275.tar.gz
- More improvements in tzwin.
- New NEWS file. - Updated README with tzwin information.
Diffstat (limited to 'dateutil')
-rw-r--r--dateutil/tz.py29
-rw-r--r--dateutil/tzwin.py245
2 files changed, 153 insertions, 121 deletions
diff --git a/dateutil/tz.py b/dateutil/tz.py
index da4a0c0..9f1e0e2 100644
--- a/dateutil/tz.py
+++ b/dateutil/tz.py
@@ -21,11 +21,9 @@ __all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
"tzstr", "tzical", "tzwin", "gettz"]
try:
- import _winreg
-except ImportError:
- tzwin = None
-else:
- from dateutil.tzwin import tzwin
+ from dateutil.tzwin import tzwin, tzwinlocal
+except (ImportError, OSError):
+ tzwin, tzwinlocal = None, None
ZERO = datetime.timedelta(0)
EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()
@@ -856,8 +854,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"]
+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
@@ -885,7 +887,7 @@ def gettz(name=None):
else:
if name.startswith(":"):
name = name[:-1]
- if name.startswith("/"):
+ if os.path.isabs(name):
if os.path.isfile(name):
tz = tzfile(name)
else:
@@ -903,8 +905,15 @@ def gettz(name=None):
except (IOError, OSError, ValueError):
pass
else:
- from dateutil.zoneinfo import gettz
- tz = gettz(name)
+ 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
diff --git a/dateutil/tzwin.py b/dateutil/tzwin.py
index 1cb1bab..63aed1d 100644
--- a/dateutil/tzwin.py
+++ b/dateutil/tzwin.py
@@ -1,134 +1,163 @@
-# This code was kindly provided by Jeffrey Harris.
-import _winreg
-import struct
+# This code was originally contributed by Jeffrey Harris.
import datetime
+import struct
+import _winreg
+
+__all__ = ["tzwin", "tzwinlocal"]
-TIMEZONESKEY = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
-TIMEZONEINFOKEY = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
-HANDLE = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
-LOCALKEY = _winreg.OpenKey(HANDLE, TIMEZONEINFOKEY)
-TZPARENT = _winreg.OpenKey(HANDLE, TIMEZONESKEY)
-TZPARENTSIZE = _winreg.QueryInfoKey(TZPARENT)[0]
ONEWEEK = datetime.timedelta(7)
-class tzwin(datetime.tzinfo):
- """tzinfo class based on win32's timezones available in the registry.
-
- >>> local = tzwin('Central Standard Time')
- >>> oct1 = datetime.datetime(month=10, year=2004, day=1, tzinfo=local)
- >>> dec1 = datetime.datetime(month=12, year=2004, day=1, tzinfo=local)
- >>> oct1.dst()
- datetime.timedelta(0, 3600)
- >>> dec1.dst()
- datetime.timedelta(0)
- >>> braz = tzwin('E. South America Standard Time')
- >>> braz.dst(oct1)
- datetime.timedelta(0)
- >>> braz.dst(dec1)
- datetime.timedelta(0, 3600)
-
- """
- def __init__(self, name):
- self._info = _tzwininfo(name)
-
+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._info.dstoffset)
+ return datetime.timedelta(minutes=self._dstoffset)
else:
- return datetime.timedelta(minutes=self._info.stdoffset)
+ return datetime.timedelta(minutes=self._stdoffset)
def dst(self, dt):
if self._isdst(dt):
- minutes = self._info.dstoffset - self._info.stdoffset
+ 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._info.dstname
+ return self._dstname
else:
- return self._info.stdname
+ return self._stdname
def list():
"""Return a list of all time zones known to the system."""
- return [_winreg.EnumKey(TZPARENT, i) for i in range(TZPARENTSIZE)]
+ 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):
- i = self._info
- dston = picknthweekday(dt.year, i.dstmonth, i.dstdayofweek,
- i.dsthour, i.dstminute, i.dstweeknumber)
- dstoff = picknthweekday(dt.year, i.stdmonth, i.stddayofweek,
- i.stdhour, i.stdminute, i.stdweeknumber)
+ 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._dstname = str(keydict["Dlt"])
+ self._stdname = str(keydict["Std"])
+
+ 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._info.display)
-
- __reduce__ = object.__reduce__
+ return "tzwin(%s)" % repr(self._name)
+
+ def __reduce__(self):
+ return (self.__class__, (self._name,))
+
-class _tzwininfo(object):
- """Read a registry key for a timezone, expose its contents."""
+class tzwinlocal(tzwinbase):
- def __init__(self, path):
- """Load path, or if path is empty, load local time."""
- if path:
- keydict=valuestodict(_winreg.OpenKey(TZPARENT, path))
- self.display = keydict['Display']
- self.dstname = keydict['Dlt']
- self.stdname = keydict['Std']
-
- #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
-
- offset=3
- self.stdmonth = tup[1 + offset]
- self.stddayofweek = tup[2 + offset] #Sunday=0
- self.stdweeknumber = tup[3 + offset] #Last = 5
- self.stdhour = tup[4 + offset]
- self.stdminute = tup[5 + offset]
-
- offset=11
- self.dstmonth = tup[1 + offset]
- self.dstdayofweek = tup[2 + offset] #Sunday=0
- self.dstweeknumber = tup[3 + offset] #Last = 5
- self.dsthour = tup[4 + offset]
- self.dstminute = tup[5 + offset]
-
- else:
- keydict=valuestodict(LOCALKEY)
-
- self.stdname = keydict['StandardName']
- self.dstname = keydict['DaylightName']
-
- sourcekey=_winreg.OpenKey(TZPARENT, self.stdname)
- self.display = valuestodict(sourcekey)['Display']
-
- 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'])
-
- offset=0
- self.stdmonth = tup[1 + offset]
- self.stddayofweek = tup[2 + offset] #Sunday=0
- self.stdweeknumber = tup[3 + offset] #Last = 5
- self.stdhour = tup[4 + offset]
- self.stdminute = tup[5 + offset]
-
- tup = struct.unpack('=8h', keydict['DaylightStart'])
- self.dstmonth = tup[1 + offset]
- self.dstdayofweek = tup[2 + offset] #Sunday=0
- self.dstweeknumber = tup[3 + offset] #Last = 5
- self.dsthour = tup[4 + offset]
- self.dstminute = tup[5 + offset]
+ def __init__(self):
+
+ handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
+
+ tzlocalkey = _winreg.OpenKey(handle, TZLOCALKEYNAME)
+ keydict = valuestodict(tzlocalkey)
+ tzlocalkey.Close()
+
+ self._stdname = str(keydict["StandardName"])
+ self._dstname = str(keydict["DaylightName"])
+
+ 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"""
@@ -141,15 +170,9 @@ def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
def valuestodict(key):
"""Convert a registry key's values to a dictionary."""
- dict={}
- size=_winreg.QueryInfoKey(key)[1]
- for i in xrange(size):
- dict[_winreg.EnumValue(key, i)[0]]=_winreg.EnumValue(key, i)[1]
+ dict = {}
+ size = _winreg.QueryInfoKey(key)[1]
+ for i in range(size):
+ data = _winreg.EnumValue(key, i)
+ dict[data[0]] = data[1]
return dict
-
-def _test():
- import tzwin, doctest
- doctest.testmod(tzwin, verbose=0)
-
-if __name__ == '__main__':
- _test()