1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
from __future__ import annotations
import datetime
import os
import time
import typing
import zoneinfo
from contextlib import contextmanager
import pytest
@contextmanager
def stub_timezone_ctx(tzname: str | None) -> typing.Generator[None]:
"""
Switch to a locally-known timezone specified by `tzname`.
On exit, restore the previous timezone.
If `tzname` is `None`, do nothing.
"""
if tzname is None:
yield
return
# Only supported on Unix
if not hasattr(time, "tzset"):
pytest.skip("Timezone patching is not supported")
# Make sure the new timezone exists
try:
zoneinfo.ZoneInfo(tzname)
except zoneinfo.ZoneInfoNotFoundError:
raise ValueError(f"Invalid timezone specified: {tzname!r}")
# Get the current timezone
old_tzname = datetime.datetime.now().astimezone().tzname()
if old_tzname is None:
raise OSError("Cannot determine current timezone")
os.environ["TZ"] = tzname
time.tzset()
yield
os.environ["TZ"] = old_tzname
time.tzset()
|