Spaces:
Runtime error
Runtime error
| 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 | |
| # When building the cldr data on windows this module gets imported. | |
| # Because at that point there is no global.dat yet this call will | |
| # fail. We want to catch it down in that case then and just assume | |
| # the mapping was empty. | |
| 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: | |
| # Windows is special. It has unique time zone names (in several | |
| # meanings of the word) available, but unfortunately, they can be | |
| # translated to the language of the operating system, so we need to | |
| # do a backwards lookup, by going through all time zones and see which | |
| # one matches. | |
| 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: | |
| # Windows 7 (and Vista?) | |
| # For some reason this returns a string with loads of NUL bytes at | |
| # least on some systems. I don't know if this is a bug somewhere, I | |
| # just work around it. | |
| tzkeyname = keyvalues['TimeZoneKeyName'].split('\x00', 1)[0] | |
| else: | |
| # Windows 2000 or XP | |
| # This is the localized name: | |
| tzwin = keyvalues['StandardName'] | |
| # Open the list of timezones to look up the real name: | |
| TZKEYNAME = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones' | |
| tzkey = winreg.OpenKey(handle, TZKEYNAME) | |
| # Now, match this value to Time Zone information | |
| 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: | |
| # Nope, that didn't work. Try adding 'Standard Time', | |
| # it seems to work a lot of times: | |
| timezone = tz_names.get(f"{tzkeyname} Standard Time") | |
| # Return what we have. | |
| 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()) | |