| 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()) |
|
|