|
from __future__ import annotations |
|
|
|
try: |
|
import winreg |
|
except ImportError: |
|
winreg = None |
|
|
|
import datetime |
|
from typing import Any, Dict, cast |
|
|
|
from babel.core import get_global |
|
from babel.localtime._helpers import _get_tzinfo_or_raise |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
tz_names: dict[str, str] = cast(Dict[str, str], get_global('windows_zone_mapping')) |
|
except RuntimeError: |
|
tz_names = {} |
|
|
|
|
|
def valuestodict(key) -> dict[str, Any]: |
|
"""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 |
|
|
|
|
|
def get_localzone_name() -> str: |
|
|
|
|
|
|
|
|
|
|
|
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) |
|
|
|
TZLOCALKEYNAME = r'SYSTEM\CurrentControlSet\Control\TimeZoneInformation' |
|
localtz = winreg.OpenKey(handle, TZLOCALKEYNAME) |
|
keyvalues = valuestodict(localtz) |
|
localtz.Close() |
|
if 'TimeZoneKeyName' in keyvalues: |
|
|
|
|
|
|
|
|
|
|
|
tzkeyname = keyvalues['TimeZoneKeyName'].split('\x00', 1)[0] |
|
else: |
|
|
|
|
|
|
|
tzwin = keyvalues['StandardName'] |
|
|
|
|
|
TZKEYNAME = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones' |
|
tzkey = winreg.OpenKey(handle, TZKEYNAME) |
|
|
|
|
|
tzkeyname = None |
|
for i in range(winreg.QueryInfoKey(tzkey)[0]): |
|
subkey = winreg.EnumKey(tzkey, i) |
|
sub = winreg.OpenKey(tzkey, subkey) |
|
data = valuestodict(sub) |
|
sub.Close() |
|
if data.get('Std', None) == tzwin: |
|
tzkeyname = subkey |
|
break |
|
|
|
tzkey.Close() |
|
handle.Close() |
|
|
|
if tzkeyname is None: |
|
raise LookupError('Can not find Windows timezone configuration') |
|
|
|
timezone = tz_names.get(tzkeyname) |
|
if timezone is None: |
|
|
|
|
|
timezone = tz_names.get(f"{tzkeyname} Standard Time") |
|
|
|
|
|
if timezone is None: |
|
raise LookupError(f"Can not find timezone {tzkeyname}") |
|
|
|
return timezone |
|
|
|
|
|
def _get_localzone() -> datetime.tzinfo: |
|
if winreg is None: |
|
raise LookupError( |
|
'Runtime support not available') |
|
|
|
return _get_tzinfo_or_raise(get_localzone_name()) |
|
|