aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/tzlocal/win32.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/tzlocal/win32.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/tzlocal/win32.py')
-rw-r--r--.venv/lib/python3.12/site-packages/tzlocal/win32.py144
1 files changed, 144 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/tzlocal/win32.py b/.venv/lib/python3.12/site-packages/tzlocal/win32.py
new file mode 100644
index 00000000..cfcdba53
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/tzlocal/win32.py
@@ -0,0 +1,144 @@
+import logging
+from datetime import datetime
+
+try:
+ import _winreg as winreg
+except ImportError:
+ import winreg
+
+import zoneinfo
+
+from tzlocal import utils
+from tzlocal.windows_tz import win_tz
+
+_cache_tz = None
+_cache_tz_name = None
+
+log = logging.getLogger("tzlocal")
+
+
+def valuestodict(key):
+ """Convert a registry key's values to a dictionary."""
+ result = {}
+ size = winreg.QueryInfoKey(key)[1]
+ for i in range(size):
+ data = winreg.EnumValue(key, i)
+ result[data[0]] = data[1]
+ return result
+
+
+def _get_dst_info(tz):
+ # Find the offset for when it doesn't have DST:
+ dst_offset = std_offset = None
+ has_dst = False
+ year = datetime.now().year
+ for dt in (datetime(year, 1, 1), datetime(year, 6, 1)):
+ if tz.dst(dt).total_seconds() == 0.0:
+ # OK, no DST during winter, get this offset
+ std_offset = tz.utcoffset(dt).total_seconds()
+ else:
+ has_dst = True
+
+ return has_dst, std_offset, dst_offset
+
+
+def _get_localzone_name():
+ # 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.
+ tzenv = utils._tz_name_from_env()
+ if tzenv:
+ return tzenv
+
+ log.debug("Looking up time zone info from registry")
+ 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 later
+
+ # 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:
+ # Don't support XP any longer
+ raise LookupError("Can not find Windows timezone configuration")
+
+ timezone = win_tz.get(tzkeyname)
+ if timezone is None:
+ # Nope, that didn't work. Try adding "Standard Time",
+ # it seems to work a lot of times:
+ timezone = win_tz.get(tzkeyname + " Standard Time")
+
+ # Return what we have.
+ if timezone is None:
+ raise zoneinfo.ZoneInfoNotFoundError(tzkeyname)
+
+ if keyvalues.get("DynamicDaylightTimeDisabled", 0) == 1:
+ # DST is disabled, so don't return the timezone name,
+ # instead return Etc/GMT+offset
+
+ tz = zoneinfo.ZoneInfo(timezone)
+ has_dst, std_offset, dst_offset = _get_dst_info(tz)
+ if not has_dst:
+ # The DST is turned off in the windows configuration,
+ # but this timezone doesn't have DST so it doesn't matter
+ return timezone
+
+ if std_offset is None:
+ raise zoneinfo.ZoneInfoNotFoundError(
+ f"{tzkeyname} claims to not have a non-DST time!?"
+ )
+
+ if std_offset % 3600:
+ # I can't convert this to an hourly offset
+ raise zoneinfo.ZoneInfoNotFoundError(
+ f"tzlocal can't support disabling DST in the {timezone} zone."
+ )
+
+ # This has whole hours as offset, return it as Etc/GMT
+ return f"Etc/GMT{-std_offset//3600:+.0f}"
+
+ return timezone
+
+
+def get_localzone_name() -> str:
+ """Get the zoneinfo timezone name that matches the Windows-configured timezone."""
+ global _cache_tz_name
+ if _cache_tz_name is None:
+ _cache_tz_name = _get_localzone_name()
+
+ return _cache_tz_name
+
+
+def get_localzone() -> zoneinfo.ZoneInfo:
+ """Returns the zoneinfo-based tzinfo object that matches the Windows-configured timezone."""
+
+ global _cache_tz
+ if _cache_tz is None:
+ _cache_tz = zoneinfo.ZoneInfo(get_localzone_name())
+
+ if not utils._tz_name_from_env():
+ # If the timezone does NOT come from a TZ environment variable,
+ # verify that it's correct. If it's from the environment,
+ # we accept it, this is so you can run tests with different timezones.
+ utils.assert_tz_offset(_cache_tz, error=False)
+
+ return _cache_tz
+
+
+def reload_localzone() -> zoneinfo.ZoneInfo:
+ """Reload the cached localzone. You need to call this if the timezone has changed."""
+ global _cache_tz
+ global _cache_tz_name
+ _cache_tz_name = _get_localzone_name()
+ _cache_tz = zoneinfo.ZoneInfo(_cache_tz_name)
+ utils.assert_tz_offset(_cache_tz, error=False)
+ return _cache_tz