NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

win.py (7435B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\dateutil\tz\win.py
      2 import datetime
      3 import struct
      4 from six.moves import winreg
      5 from six import text_type
      6 try:
      7     import ctypes
      8     from ctypes import wintypes
      9 except ValueError:
     10     raise ImportError('Running tzwin on non-Windows system')
     11 
     12 from ._common import tzname_in_python2, _tzinfo
     13 from ._common import tzrangebase
     14 __all__ = ['tzwin', 'tzwinlocal', 'tzres']
     15 ONEWEEK = datetime.timedelta(7)
     16 TZKEYNAMENT = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones'
     17 TZKEYNAME9X = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones'
     18 TZLOCALKEYNAME = 'SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation'
     19 
     20 def _settzkeyname():
     21     handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
     22     try:
     23         winreg.OpenKey(handle, TZKEYNAMENT).Close()
     24         TZKEYNAME = TZKEYNAMENT
     25     except WindowsError:
     26         TZKEYNAME = TZKEYNAME9X
     27 
     28     handle.Close()
     29     return TZKEYNAME
     30 
     31 
     32 TZKEYNAME = _settzkeyname()
     33 
     34 class tzres(object):
     35     p_wchar = ctypes.POINTER(wintypes.WCHAR)
     36 
     37     def __init__(self, tzres_loc = 'tzres.dll'):
     38         user32 = ctypes.WinDLL('user32')
     39         user32.LoadStringW.argtypes = (wintypes.HINSTANCE,
     40          wintypes.UINT,
     41          wintypes.LPWSTR,
     42          ctypes.c_int)
     43         self.LoadStringW = user32.LoadStringW
     44         self._tzres = ctypes.WinDLL(tzres_loc)
     45         self.tzres_loc = tzres_loc
     46 
     47     def load_name(self, offset):
     48         resource = self.p_wchar()
     49         lpBuffer = ctypes.cast(ctypes.byref(resource), wintypes.LPWSTR)
     50         nchar = self.LoadStringW(self._tzres._handle, offset, lpBuffer, 0)
     51         return resource[:nchar]
     52 
     53     def name_from_string(self, tzname_str):
     54         if not tzname_str.startswith('@'):
     55             return tzname_str
     56         name_splt = tzname_str.split(',-')
     57         try:
     58             offset = int(name_splt[1])
     59         except:
     60             raise ValueError('Malformed timezone string.')
     61 
     62         return self.load_name(offset)
     63 
     64 
     65 class tzwinbase(tzrangebase):
     66 
     67     def __init__(self):
     68         raise NotImplementedError('tzwinbase is an abstract base class')
     69 
     70     def __eq__(self, other):
     71         if not isinstance(other, tzwinbase):
     72             return NotImplemented
     73         return self._std_offset == other._std_offset and self._dst_offset == other._dst_offset and self._stddayofweek == other._stddayofweek and self._dstdayofweek == other._dstdayofweek and self._stdweeknumber == other._stdweeknumber and self._dstweeknumber == other._dstweeknumber and self._stdhour == other._stdhour and self._dsthour == other._dsthour and self._stdminute == other._stdminute and self._dstminute == other._dstminute and self._std_abbr == other._std_abbr and self._dst_abbr == other._dst_abbr
     74 
     75     @staticmethod
     76     def list():
     77         with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
     78             with winreg.OpenKey(handle, TZKEYNAME) as tzkey:
     79                 result = [ winreg.EnumKey(tzkey, i) for i in range(winreg.QueryInfoKey(tzkey)[0]) ]
     80         return result
     81 
     82     def display(self):
     83         return self._display
     84 
     85     def transitions(self, year):
     86         if not self.hasdst:
     87             return None
     88         dston = picknthweekday(year, self._dstmonth, self._dstdayofweek, self._dsthour, self._dstminute, self._dstweeknumber)
     89         dstoff = picknthweekday(year, self._stdmonth, self._stddayofweek, self._stdhour, self._stdminute, self._stdweeknumber)
     90         dstoff -= self._dst_base_offset
     91         return (dston, dstoff)
     92 
     93     def _get_hasdst(self):
     94         return self._dstmonth != 0
     95 
     96     @property
     97     def _dst_base_offset(self):
     98         return self._dst_base_offset_
     99 
    100 
    101 class tzwin(tzwinbase):
    102 
    103     def __init__(self, name):
    104         self._name = name
    105         with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
    106             tzkeyname = text_type('{kn}\\{name}').format(kn=TZKEYNAME, name=name)
    107             with winreg.OpenKey(handle, tzkeyname) as tzkey:
    108                 keydict = valuestodict(tzkey)
    109         self._std_abbr = keydict['Std']
    110         self._dst_abbr = keydict['Dlt']
    111         self._display = keydict['Display']
    112         tup = struct.unpack('=3l16h', keydict['TZI'])
    113         stdoffset = -tup[0] - tup[1]
    114         dstoffset = stdoffset - tup[2]
    115         self._std_offset = datetime.timedelta(minutes=stdoffset)
    116         self._dst_offset = datetime.timedelta(minutes=dstoffset)
    117         self._stdmonth, self._stddayofweek, self._stdweeknumber, self._stdhour, self._stdminute = tup[4:9]
    118         self._dstmonth, self._dstdayofweek, self._dstweeknumber, self._dsthour, self._dstminute = tup[12:17]
    119         self._dst_base_offset_ = self._dst_offset - self._std_offset
    120         self.hasdst = self._get_hasdst()
    121 
    122     def __repr__(self):
    123         return 'tzwin(%s)' % repr(self._name)
    124 
    125     def __reduce__(self):
    126         return (self.__class__, (self._name,))
    127 
    128 
    129 class tzwinlocal(tzwinbase):
    130 
    131     def __init__(self):
    132         with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
    133             with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey:
    134                 keydict = valuestodict(tzlocalkey)
    135             self._std_abbr = keydict['StandardName']
    136             self._dst_abbr = keydict['DaylightName']
    137             try:
    138                 tzkeyname = text_type('{kn}\\{sn}').format(kn=TZKEYNAME, sn=self._std_abbr)
    139                 with winreg.OpenKey(handle, tzkeyname) as tzkey:
    140                     _keydict = valuestodict(tzkey)
    141                     self._display = _keydict['Display']
    142             except OSError:
    143                 self._display = None
    144 
    145         stdoffset = -keydict['Bias'] - keydict['StandardBias']
    146         dstoffset = stdoffset - keydict['DaylightBias']
    147         self._std_offset = datetime.timedelta(minutes=stdoffset)
    148         self._dst_offset = datetime.timedelta(minutes=dstoffset)
    149         tup = struct.unpack('=8h', keydict['StandardStart'])
    150         self._stdmonth, self._stdweeknumber, self._stdhour, self._stdminute = tup[1:5]
    151         self._stddayofweek = tup[7]
    152         tup = struct.unpack('=8h', keydict['DaylightStart'])
    153         self._dstmonth, self._dstweeknumber, self._dsthour, self._dstminute = tup[1:5]
    154         self._dstdayofweek = tup[7]
    155         self._dst_base_offset_ = self._dst_offset - self._std_offset
    156         self.hasdst = self._get_hasdst()
    157 
    158     def __repr__(self):
    159         return 'tzwinlocal()'
    160 
    161     def __str__(self):
    162         return 'tzwinlocal(%s)' % repr(self._std_abbr)
    163 
    164     def __reduce__(self):
    165         return (self.__class__, ())
    166 
    167 
    168 def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
    169     first = datetime.datetime(year, month, 1, hour, minute)
    170     weekdayone = first.replace(day=(dayofweek - first.isoweekday()) % 7 + 1)
    171     wd = weekdayone + (whichweek - 1) * ONEWEEK
    172     if wd.month != month:
    173         wd -= ONEWEEK
    174     return wd
    175 
    176 
    177 def valuestodict(key):
    178     dout = {}
    179     size = winreg.QueryInfoKey(key)[1]
    180     tz_res = None
    181     for i in range(size):
    182         key_name, value, dtype = winreg.EnumValue(key, i)
    183         if dtype == winreg.REG_DWORD or dtype == winreg.REG_DWORD_LITTLE_ENDIAN:
    184             if value & 2147483648L:
    185                 value = value - 4294967296L
    186         elif dtype == winreg.REG_SZ:
    187             if value.startswith('@tzres'):
    188                 tz_res = tz_res or tzres()
    189                 value = tz_res.name_from_string(value)
    190             value = value.rstrip('\x00')
    191         dout[key_name] = value
    192 
    193     return dout