diff --git a/homeassistant/components/ambient_network/sensor.py b/homeassistant/components/ambient_network/sensor.py index c28b69229d8..028a8f69264 100644 --- a/homeassistant/components/ambient_network/sensor.py +++ b/homeassistant/components/ambient_network/sensor.py @@ -309,7 +309,9 @@ class AmbientNetworkSensor(AmbientNetworkEntity, SensorEntity): # Treatments for special units. if value is not None and self.device_class == SensorDeviceClass.TIMESTAMP: - value = datetime.fromtimestamp(value / 1000, tz=dt_util.DEFAULT_TIME_ZONE) + value = datetime.fromtimestamp( + value / 1000, tz=dt_util.get_default_time_zone() + ) self._attr_available = value is not None self._attr_native_value = value diff --git a/homeassistant/components/caldav/coordinator.py b/homeassistant/components/caldav/coordinator.py index 380471284de..3a10b567167 100644 --- a/homeassistant/components/caldav/coordinator.py +++ b/homeassistant/components/caldav/coordinator.py @@ -196,7 +196,9 @@ class CalDavUpdateCoordinator(DataUpdateCoordinator[CalendarEvent | None]): """Return a datetime.""" if isinstance(obj, datetime): return CalDavUpdateCoordinator.to_local(obj) - return datetime.combine(obj, time.min).replace(tzinfo=dt_util.DEFAULT_TIME_ZONE) + return datetime.combine(obj, time.min).replace( + tzinfo=dt_util.get_default_time_zone() + ) @staticmethod def to_local(obj: datetime | date) -> datetime | date: diff --git a/homeassistant/components/datetime/__init__.py b/homeassistant/components/datetime/__init__.py index b1be0a0d08d..f2b8526ced6 100644 --- a/homeassistant/components/datetime/__init__.py +++ b/homeassistant/components/datetime/__init__.py @@ -36,9 +36,7 @@ async def _async_set_value(entity: DateTimeEntity, service_call: ServiceCall) -> """Service call wrapper to set a new date/time.""" value: datetime = service_call.data[ATTR_DATETIME] if value.tzinfo is None: - value = value.replace( - tzinfo=dt_util.get_time_zone(entity.hass.config.time_zone) - ) + value = value.replace(tzinfo=dt_util.get_default_time_zone()) return await entity.async_set_value(value) diff --git a/homeassistant/components/ecobee/switch.py b/homeassistant/components/ecobee/switch.py index 44528a5f421..607585887f0 100644 --- a/homeassistant/components/ecobee/switch.py +++ b/homeassistant/components/ecobee/switch.py @@ -2,6 +2,7 @@ from __future__ import annotations +from datetime import tzinfo import logging from typing import Any @@ -29,12 +30,17 @@ async def async_setup_entry( data: EcobeeData = hass.data[DOMAIN] async_add_entities( - ( - EcobeeVentilator20MinSwitch(data, index) + [ + EcobeeVentilator20MinSwitch( + data, + index, + (await dt_util.async_get_time_zone(thermostat["location"]["timeZone"])) + or dt_util.get_default_time_zone(), + ) for index, thermostat in enumerate(data.ecobee.thermostats) if thermostat["settings"]["ventilatorType"] != "none" - ), - True, + ], + update_before_add=True, ) @@ -48,15 +54,14 @@ class EcobeeVentilator20MinSwitch(EcobeeBaseEntity, SwitchEntity): self, data: EcobeeData, thermostat_index: int, + operating_timezone: tzinfo, ) -> None: """Initialize ecobee ventilator platform.""" super().__init__(data, thermostat_index) self._attr_unique_id = f"{self.base_unique_id}_ventilator_20m_timer" self._attr_is_on = False self.update_without_throttle = False - self._operating_timezone = dt_util.get_time_zone( - self.thermostat["location"]["timeZone"] - ) + self._operating_timezone = operating_timezone async def async_update(self) -> None: """Get the latest state from the thermostat.""" diff --git a/homeassistant/components/electric_kiwi/sensor.py b/homeassistant/components/electric_kiwi/sensor.py index 39bcd5ca503..7672466106b 100644 --- a/homeassistant/components/electric_kiwi/sensor.py +++ b/homeassistant/components/electric_kiwi/sensor.py @@ -91,13 +91,13 @@ def _check_and_move_time(hop: Hop, time: str) -> datetime: date_time = datetime.combine( dt_util.start_of_local_day(), datetime.strptime(time, "%I:%M %p").time(), - dt_util.DEFAULT_TIME_ZONE, + dt_util.get_default_time_zone(), ) end_time = datetime.combine( dt_util.start_of_local_day(), datetime.strptime(hop.end.end_time, "%I:%M %p").time(), - dt_util.DEFAULT_TIME_ZONE, + dt_util.get_default_time_zone(), ) if end_time < dt_util.now(): diff --git a/homeassistant/components/gardena_bluetooth/sensor.py b/homeassistant/components/gardena_bluetooth/sensor.py index f2bddd3a91a..3e6ddf9a2df 100644 --- a/homeassistant/components/gardena_bluetooth/sensor.py +++ b/homeassistant/components/gardena_bluetooth/sensor.py @@ -120,9 +120,7 @@ class GardenaBluetoothSensor(GardenaBluetoothDescriptorEntity, SensorEntity): def _handle_coordinator_update(self) -> None: value = self.coordinator.get_cached(self.entity_description.char) if isinstance(value, datetime): - value = value.replace( - tzinfo=dt_util.get_time_zone(self.hass.config.time_zone) - ) + value = value.replace(tzinfo=dt_util.get_default_time_zone()) self._attr_native_value = value if char := self.entity_description.connected_state: diff --git a/homeassistant/components/google/calendar.py b/homeassistant/components/google/calendar.py index 599ed6c09d1..f51bf64d400 100644 --- a/homeassistant/components/google/calendar.py +++ b/homeassistant/components/google/calendar.py @@ -341,11 +341,11 @@ class GoogleCalendarEntity( if isinstance(dtstart, datetime): start = DateOrDatetime( date_time=dt_util.as_local(dtstart), - timezone=str(dt_util.DEFAULT_TIME_ZONE), + timezone=str(dt_util.get_default_time_zone()), ) end = DateOrDatetime( date_time=dt_util.as_local(dtend), - timezone=str(dt_util.DEFAULT_TIME_ZONE), + timezone=str(dt_util.get_default_time_zone()), ) else: start = DateOrDatetime(date=dtstart) diff --git a/homeassistant/components/google/coordinator.py b/homeassistant/components/google/coordinator.py index d7ac60045de..19198041c05 100644 --- a/homeassistant/components/google/coordinator.py +++ b/homeassistant/components/google/coordinator.py @@ -38,7 +38,7 @@ def _truncate_timeline(timeline: Timeline, max_events: int) -> Timeline: truncated = list(itertools.islice(upcoming, max_events)) return Timeline( [ - SortableItemValue(event.timespan_of(dt_util.DEFAULT_TIME_ZONE), event) + SortableItemValue(event.timespan_of(dt_util.get_default_time_zone()), event) for event in truncated ] ) @@ -73,7 +73,7 @@ class CalendarSyncUpdateCoordinator(DataUpdateCoordinator[Timeline]): raise UpdateFailed(f"Error communicating with API: {err}") from err timeline = await self.sync.store_service.async_get_timeline( - dt_util.DEFAULT_TIME_ZONE + dt_util.get_default_time_zone() ) self._upcoming_timeline = _truncate_timeline(timeline, MAX_UPCOMING_EVENTS) return timeline diff --git a/homeassistant/components/google/diagnostics.py b/homeassistant/components/google/diagnostics.py index 0313e61bc8e..1a6f498b4cd 100644 --- a/homeassistant/components/google/diagnostics.py +++ b/homeassistant/components/google/diagnostics.py @@ -45,7 +45,7 @@ async def async_get_config_entry_diagnostics( """Return diagnostics for a config entry.""" payload: dict[str, Any] = { "now": dt_util.now().isoformat(), - "timezone": str(dt_util.DEFAULT_TIME_ZONE), + "timezone": str(dt_util.get_default_time_zone()), "system_timezone": str(datetime.datetime.now().astimezone().tzinfo), } diff --git a/homeassistant/components/growatt_server/sensor.py b/homeassistant/components/growatt_server/sensor.py index c41d3ac486f..9c680b5d4f8 100644 --- a/homeassistant/components/growatt_server/sensor.py +++ b/homeassistant/components/growatt_server/sensor.py @@ -239,7 +239,7 @@ class GrowattData: date_now = dt_util.now().date() last_updated_time = dt_util.parse_time(str(sorted_keys[-1])) mix_detail["lastdataupdate"] = datetime.datetime.combine( - date_now, last_updated_time, dt_util.DEFAULT_TIME_ZONE + date_now, last_updated_time, dt_util.get_default_time_zone() ) # Dashboard data is largely inaccurate for mix system but it is the only diff --git a/homeassistant/components/homeassistant/triggers/time.py b/homeassistant/components/homeassistant/triggers/time.py index 6d035683f71..5441683b86f 100644 --- a/homeassistant/components/homeassistant/triggers/time.py +++ b/homeassistant/components/homeassistant/triggers/time.py @@ -119,7 +119,7 @@ async def async_attach_trigger( hour, minute, second, - tzinfo=dt_util.DEFAULT_TIME_ZONE, + tzinfo=dt_util.get_default_time_zone(), ) # Only set up listener if time is now or in the future. if trigger_dt >= dt_util.now(): diff --git a/homeassistant/components/input_datetime/__init__.py b/homeassistant/components/input_datetime/__init__.py index 9546b51ee4f..11aab52e6a4 100644 --- a/homeassistant/components/input_datetime/__init__.py +++ b/homeassistant/components/input_datetime/__init__.py @@ -237,11 +237,11 @@ class InputDatetime(collection.CollectionEntity, RestoreEntity): # If the user passed in an initial value with a timezone, convert it to right tz if current_datetime.tzinfo is not None: self._current_datetime = current_datetime.astimezone( - dt_util.DEFAULT_TIME_ZONE + dt_util.get_default_time_zone() ) else: self._current_datetime = current_datetime.replace( - tzinfo=dt_util.DEFAULT_TIME_ZONE + tzinfo=dt_util.get_default_time_zone() ) @classmethod @@ -295,7 +295,7 @@ class InputDatetime(collection.CollectionEntity, RestoreEntity): ) self._current_datetime = current_datetime.replace( - tzinfo=dt_util.DEFAULT_TIME_ZONE + tzinfo=dt_util.get_default_time_zone() ) @property @@ -409,7 +409,7 @@ class InputDatetime(collection.CollectionEntity, RestoreEntity): time = self._current_datetime.time() self._current_datetime = py_datetime.datetime.combine( - date, time, dt_util.DEFAULT_TIME_ZONE + date, time, dt_util.get_default_time_zone() ) self.async_write_ha_state() diff --git a/homeassistant/components/knx/datetime.py b/homeassistant/components/knx/datetime.py index 47d9b9f55b2..2a1a9e2f9c9 100644 --- a/homeassistant/components/knx/datetime.py +++ b/homeassistant/components/knx/datetime.py @@ -80,7 +80,7 @@ class KNXDateTime(KnxEntity, DateTimeEntity, RestoreEntity): ): self._device.remote_value.value = ( datetime.fromisoformat(last_state.state) - .astimezone(dt_util.DEFAULT_TIME_ZONE) + .astimezone(dt_util.get_default_time_zone()) .timetuple() ) @@ -96,9 +96,11 @@ class KNXDateTime(KnxEntity, DateTimeEntity, RestoreEntity): hour=time_struct.tm_hour, minute=time_struct.tm_min, second=min(time_struct.tm_sec, 59), # account for leap seconds - tzinfo=dt_util.DEFAULT_TIME_ZONE, + tzinfo=dt_util.get_default_time_zone(), ) async def async_set_value(self, value: datetime) -> None: """Change the value.""" - await self._device.set(value.astimezone(dt_util.DEFAULT_TIME_ZONE).timetuple()) + await self._device.set( + value.astimezone(dt_util.get_default_time_zone()).timetuple() + ) diff --git a/homeassistant/components/litterrobot/time.py b/homeassistant/components/litterrobot/time.py index 4e5e80a8ca6..e2ada80b234 100644 --- a/homeassistant/components/litterrobot/time.py +++ b/homeassistant/components/litterrobot/time.py @@ -45,7 +45,7 @@ LITTER_ROBOT_3_SLEEP_START = RobotTimeEntityDescription[LitterRobot3]( entity_category=EntityCategory.CONFIG, value_fn=lambda robot: _as_local_time(robot.sleep_mode_start_time), set_fn=lambda robot, value: robot.set_sleep_mode( - robot.sleep_mode_enabled, value.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE) + robot.sleep_mode_enabled, value.replace(tzinfo=dt_util.get_default_time_zone()) ), ) diff --git a/homeassistant/components/local_calendar/diagnostics.py b/homeassistant/components/local_calendar/diagnostics.py index c3b9e5d151c..52c685e4929 100644 --- a/homeassistant/components/local_calendar/diagnostics.py +++ b/homeassistant/components/local_calendar/diagnostics.py @@ -18,7 +18,7 @@ async def async_get_config_entry_diagnostics( """Return diagnostics for a config entry.""" payload: dict[str, Any] = { "now": dt_util.now().isoformat(), - "timezone": str(dt_util.DEFAULT_TIME_ZONE), + "timezone": str(dt_util.get_default_time_zone()), "system_timezone": str(datetime.datetime.now().astimezone().tzinfo), } store = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/local_todo/todo.py b/homeassistant/components/local_todo/todo.py index 548b4fa87fe..a5f40c26738 100644 --- a/homeassistant/components/local_todo/todo.py +++ b/homeassistant/components/local_todo/todo.py @@ -134,7 +134,7 @@ class LocalTodoListEntity(TodoListEntity): self._attr_unique_id = unique_id def _new_todo_store(self) -> TodoStore: - return TodoStore(self._calendar, tzinfo=dt_util.DEFAULT_TIME_ZONE) + return TodoStore(self._calendar, tzinfo=dt_util.get_default_time_zone()) async def async_update(self) -> None: """Update entity state based on the local To-do items.""" diff --git a/homeassistant/components/met/coordinator.py b/homeassistant/components/met/coordinator.py index ef73e1b52ab..3887a29f83c 100644 --- a/homeassistant/components/met/coordinator.py +++ b/homeassistant/components/met/coordinator.py @@ -80,7 +80,7 @@ class MetWeatherData: if not resp: raise CannotConnect self.current_weather_data = self._weather_data.get_current_weather() - time_zone = dt_util.DEFAULT_TIME_ZONE + time_zone = dt_util.get_default_time_zone() self.daily_forecast = self._weather_data.get_forecast(time_zone, False, 0) self.hourly_forecast = self._weather_data.get_forecast(time_zone, True) return self diff --git a/homeassistant/components/met_eireann/__init__.py b/homeassistant/components/met_eireann/__init__.py index 92f2ffcfac6..7d0e6401bd6 100644 --- a/homeassistant/components/met_eireann/__init__.py +++ b/homeassistant/components/met_eireann/__init__.py @@ -86,7 +86,7 @@ class MetEireannWeatherData: """Fetch data from API - (current weather and forecast).""" await self._weather_data.fetching_data() self.current_weather_data = self._weather_data.get_current_weather() - time_zone = dt_util.DEFAULT_TIME_ZONE + time_zone = dt_util.get_default_time_zone() self.daily_forecast = self._weather_data.get_forecast(time_zone, False) self.hourly_forecast = self._weather_data.get_forecast(time_zone, True) return self diff --git a/homeassistant/components/nobo_hub/__init__.py b/homeassistant/components/nobo_hub/__init__.py index f9d2ce2e3da..5b777205c8d 100644 --- a/homeassistant/components/nobo_hub/__init__.py +++ b/homeassistant/components/nobo_hub/__init__.py @@ -25,7 +25,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ip=ip_address, discover=discover, synchronous=False, - timezone=dt_util.DEFAULT_TIME_ZONE, + timezone=dt_util.get_default_time_zone(), ) await hub.connect() diff --git a/homeassistant/components/onvif/device.py b/homeassistant/components/onvif/device.py index b427cbda2f8..f51b1b74686 100644 --- a/homeassistant/components/onvif/device.py +++ b/homeassistant/components/onvif/device.py @@ -251,13 +251,13 @@ class ONVIFDevice: LOGGER.debug("%s: Device time: %s", self.name, device_time) - tzone = dt_util.DEFAULT_TIME_ZONE + tzone = dt_util.get_default_time_zone() cdate = device_time.LocalDateTime if device_time.UTCDateTime: tzone = dt_util.UTC cdate = device_time.UTCDateTime elif device_time.TimeZone: - tzone = dt_util.get_time_zone(device_time.TimeZone.TZ) or tzone + tzone = await dt_util.async_get_time_zone(device_time.TimeZone.TZ) or tzone if cdate is None: LOGGER.warning("%s: Could not retrieve date/time on this camera", self.name) diff --git a/homeassistant/components/rainbird/calendar.py b/homeassistant/components/rainbird/calendar.py index 85906fa3fe3..42c1cce69d3 100644 --- a/homeassistant/components/rainbird/calendar.py +++ b/homeassistant/components/rainbird/calendar.py @@ -73,7 +73,7 @@ class RainBirdCalendarEntity( schedule = self.coordinator.data if not schedule: return None - cursor = schedule.timeline_tz(dt_util.DEFAULT_TIME_ZONE).active_after( + cursor = schedule.timeline_tz(dt_util.get_default_time_zone()).active_after( dt_util.now() ) program_event = next(cursor, None) diff --git a/homeassistant/components/recorder/statistics.py b/homeassistant/components/recorder/statistics.py index 42aa6ec9df6..7b5c6811e29 100644 --- a/homeassistant/components/recorder/statistics.py +++ b/homeassistant/components/recorder/statistics.py @@ -952,7 +952,7 @@ def reduce_day_ts_factory() -> ( # We have to recreate _local_from_timestamp in the closure in case the timezone changes _local_from_timestamp = partial( - datetime.fromtimestamp, tz=dt_util.DEFAULT_TIME_ZONE + datetime.fromtimestamp, tz=dt_util.get_default_time_zone() ) def _same_day_ts(time1: float, time2: float) -> bool: @@ -1000,7 +1000,7 @@ def reduce_week_ts_factory() -> ( # We have to recreate _local_from_timestamp in the closure in case the timezone changes _local_from_timestamp = partial( - datetime.fromtimestamp, tz=dt_util.DEFAULT_TIME_ZONE + datetime.fromtimestamp, tz=dt_util.get_default_time_zone() ) def _same_week_ts(time1: float, time2: float) -> bool: @@ -1058,7 +1058,7 @@ def reduce_month_ts_factory() -> ( # We have to recreate _local_from_timestamp in the closure in case the timezone changes _local_from_timestamp = partial( - datetime.fromtimestamp, tz=dt_util.DEFAULT_TIME_ZONE + datetime.fromtimestamp, tz=dt_util.get_default_time_zone() ) def _same_month_ts(time1: float, time2: float) -> bool: diff --git a/homeassistant/components/risco/sensor.py b/homeassistant/components/risco/sensor.py index 50067cedccd..c1495512e62 100644 --- a/homeassistant/components/risco/sensor.py +++ b/homeassistant/components/risco/sensor.py @@ -115,7 +115,7 @@ class RiscoSensor(CoordinatorEntity[RiscoEventsDataUpdateCoordinator], SensorEnt return None if res := dt_util.parse_datetime(self._event.time): - return res.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE) + return res.replace(tzinfo=dt_util.get_default_time_zone()) return None @property diff --git a/homeassistant/components/rova/coordinator.py b/homeassistant/components/rova/coordinator.py index ef411be19e8..ecd91cad823 100644 --- a/homeassistant/components/rova/coordinator.py +++ b/homeassistant/components/rova/coordinator.py @@ -10,6 +10,8 @@ from homeassistant.util.dt import get_time_zone from .const import DOMAIN, LOGGER +EUROPE_AMSTERDAM_ZONE_INFO = get_time_zone("Europe/Amsterdam") + class RovaCoordinator(DataUpdateCoordinator[dict[str, datetime]]): """Class to manage fetching Rova data.""" @@ -33,7 +35,7 @@ class RovaCoordinator(DataUpdateCoordinator[dict[str, datetime]]): for item in items: date = datetime.strptime(item["Date"], "%Y-%m-%dT%H:%M:%S").replace( - tzinfo=get_time_zone("Europe/Amsterdam") + tzinfo=EUROPE_AMSTERDAM_ZONE_INFO ) code = item["GarbageTypeCode"].lower() if code not in data: diff --git a/homeassistant/components/srp_energy/coordinator.py b/homeassistant/components/srp_energy/coordinator.py index 60f73fc27c6..e5a72457433 100644 --- a/homeassistant/components/srp_energy/coordinator.py +++ b/homeassistant/components/srp_energy/coordinator.py @@ -15,6 +15,7 @@ from homeassistant.util import dt as dt_util from .const import DOMAIN, LOGGER, MIN_TIME_BETWEEN_UPDATES, PHOENIX_TIME_ZONE TIMEOUT = 10 +PHOENIX_ZONE_INFO = dt_util.get_time_zone(PHOENIX_TIME_ZONE) class SRPEnergyDataUpdateCoordinator(DataUpdateCoordinator[float]): @@ -43,8 +44,7 @@ class SRPEnergyDataUpdateCoordinator(DataUpdateCoordinator[float]): """ LOGGER.debug("async_update_data enter") # Fetch srp_energy data - phx_time_zone = dt_util.get_time_zone(PHOENIX_TIME_ZONE) - end_date = dt_util.now(phx_time_zone) + end_date = dt_util.now(PHOENIX_ZONE_INFO) start_date = end_date - timedelta(days=1) try: async with asyncio.timeout(TIMEOUT): diff --git a/homeassistant/components/tibber/__init__.py b/homeassistant/components/tibber/__init__.py index 1de70389114..49633707ed6 100644 --- a/homeassistant/components/tibber/__init__.py +++ b/homeassistant/components/tibber/__init__.py @@ -42,7 +42,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: tibber_connection = tibber.Tibber( access_token=entry.data[CONF_ACCESS_TOKEN], websession=async_get_clientsession(hass), - time_zone=dt_util.DEFAULT_TIME_ZONE, + time_zone=dt_util.get_default_time_zone(), ) hass.data[DOMAIN] = tibber_connection diff --git a/homeassistant/components/tod/binary_sensor.py b/homeassistant/components/tod/binary_sensor.py index 8e44c7e57d3..5b6c7077a97 100644 --- a/homeassistant/components/tod/binary_sensor.py +++ b/homeassistant/components/tod/binary_sensor.py @@ -148,7 +148,7 @@ class TodSensor(BinarySensorEntity): assert self._time_after is not None assert self._time_before is not None assert self._next_update is not None - if time_zone := dt_util.get_time_zone(self.hass.config.time_zone): + if time_zone := dt_util.get_default_time_zone(): return { ATTR_AFTER: self._time_after.astimezone(time_zone).isoformat(), ATTR_BEFORE: self._time_before.astimezone(time_zone).isoformat(), @@ -160,9 +160,7 @@ class TodSensor(BinarySensorEntity): """Convert naive time from config to utc_datetime with current day.""" # get the current local date from utc time current_local_date = ( - dt_util.utcnow() - .astimezone(dt_util.get_time_zone(self.hass.config.time_zone)) - .date() + dt_util.utcnow().astimezone(dt_util.get_default_time_zone()).date() ) # calculate utc datetime corresponding to local time return dt_util.as_utc(datetime.combine(current_local_date, naive_time)) diff --git a/homeassistant/components/trafikverket_ferry/coordinator.py b/homeassistant/components/trafikverket_ferry/coordinator.py index cb11889345a..6cfed88b79c 100644 --- a/homeassistant/components/trafikverket_ferry/coordinator.py +++ b/homeassistant/components/trafikverket_ferry/coordinator.py @@ -77,7 +77,7 @@ class TVDataUpdateCoordinator(DataUpdateCoordinator): datetime.combine( departure_day, self._time, - dt_util.get_time_zone(self.hass.config.time_zone), + dt_util.get_default_time_zone(), ) if self._time else dt_util.now() diff --git a/homeassistant/components/trafikverket_train/config_flow.py b/homeassistant/components/trafikverket_train/config_flow.py index 6795a566246..d03eeca8f65 100644 --- a/homeassistant/components/trafikverket_train/config_flow.py +++ b/homeassistant/components/trafikverket_train/config_flow.py @@ -87,7 +87,7 @@ async def validate_input( when = datetime.combine( departure_day, _time, - dt_util.get_time_zone(hass.config.time_zone), + dt_util.get_default_time_zone(), ) try: diff --git a/homeassistant/components/trafikverket_train/coordinator.py b/homeassistant/components/trafikverket_train/coordinator.py index e56f5d3a2e9..c202473da79 100644 --- a/homeassistant/components/trafikverket_train/coordinator.py +++ b/homeassistant/components/trafikverket_train/coordinator.py @@ -105,7 +105,7 @@ class TVDataUpdateCoordinator(DataUpdateCoordinator[TrainData]): when = datetime.combine( departure_day, self._time, - dt_util.get_time_zone(self.hass.config.time_zone), + dt_util.get_default_time_zone(), ) try: if self._time: diff --git a/homeassistant/components/unifiprotect/media_source.py b/homeassistant/components/unifiprotect/media_source.py index ba962891454..0ff27f562ea 100644 --- a/homeassistant/components/unifiprotect/media_source.py +++ b/homeassistant/components/unifiprotect/media_source.py @@ -670,7 +670,7 @@ class ProtectMediaSource(MediaSource): hour=0, minute=0, second=0, - tzinfo=dt_util.DEFAULT_TIME_ZONE, + tzinfo=dt_util.get_default_time_zone(), ) if is_all: if start_dt.month < 12: diff --git a/homeassistant/components/utility_meter/sensor.py b/homeassistant/components/utility_meter/sensor.py index a3b94a519ee..96cfccfd211 100644 --- a/homeassistant/components/utility_meter/sensor.py +++ b/homeassistant/components/utility_meter/sensor.py @@ -566,7 +566,7 @@ class UtilityMeterSensor(RestoreSensor): async def _program_reset(self): """Program the reset of the utility meter.""" if self._cron_pattern is not None: - tz = dt_util.get_time_zone(self.hass.config.time_zone) + tz = dt_util.get_default_time_zone() self._next_reset = croniter(self._cron_pattern, dt_util.now(tz)).get_next( datetime ) # we need timezone for DST purposes (see issue #102984) diff --git a/homeassistant/components/vallox/sensor.py b/homeassistant/components/vallox/sensor.py index 13f9f8354a7..281bc002f68 100644 --- a/homeassistant/components/vallox/sensor.py +++ b/homeassistant/components/vallox/sensor.py @@ -109,7 +109,7 @@ class ValloxFilterRemainingSensor(ValloxSensorEntity): return datetime.combine( next_filter_change_date, - time(hour=13, minute=0, second=0, tzinfo=dt_util.DEFAULT_TIME_ZONE), + time(hour=13, minute=0, second=0, tzinfo=dt_util.get_default_time_zone()), ) diff --git a/homeassistant/config.py b/homeassistant/config.py index bb7d81bb44e..bb3a8fb1cd4 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -910,7 +910,7 @@ async def async_process_ha_core_config(hass: HomeAssistant, config: dict) -> Non _raise_issue_if_no_country(hass, hass.config.country) if CONF_TIME_ZONE in config: - hac.set_time_zone(config[CONF_TIME_ZONE]) + await hac.async_set_time_zone(config[CONF_TIME_ZONE]) if CONF_MEDIA_DIRS not in config: if is_docker_env(): diff --git a/homeassistant/core.py b/homeassistant/core.py index 640e34cdedd..11a030ba8a1 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -2951,16 +2951,38 @@ class Config: "debug": self.debug, } - def set_time_zone(self, time_zone_str: str) -> None: + async def async_set_time_zone(self, time_zone_str: str) -> None: """Help to set the time zone.""" + if time_zone := await dt_util.async_get_time_zone(time_zone_str): + self.time_zone = time_zone_str + dt_util.set_default_time_zone(time_zone) + else: + raise ValueError(f"Received invalid time zone {time_zone_str}") + + def set_time_zone(self, time_zone_str: str) -> None: + """Set the time zone. + + This is a legacy method that should not be used in new code. + Use async_set_time_zone instead. + + It will be removed in Home Assistant 2025.6. + """ + # report is imported here to avoid a circular import + from .helpers.frame import report # pylint: disable=import-outside-toplevel + + report( + "set the time zone using set_time_zone instead of async_set_time_zone" + " which will stop working in Home Assistant 2025.6", + error_if_core=True, + error_if_integration=True, + ) if time_zone := dt_util.get_time_zone(time_zone_str): self.time_zone = time_zone_str dt_util.set_default_time_zone(time_zone) else: raise ValueError(f"Received invalid time zone {time_zone_str}") - @callback - def _update( + async def _async_update( self, *, source: ConfigSource, @@ -2993,7 +3015,7 @@ class Config: if location_name is not None: self.location_name = location_name if time_zone is not None: - self.set_time_zone(time_zone) + await self.async_set_time_zone(time_zone) if external_url is not _UNDEF: self.external_url = cast(str | None, external_url) if internal_url is not _UNDEF: @@ -3013,7 +3035,7 @@ class Config: _raise_issue_if_no_country, ) - self._update(source=ConfigSource.STORAGE, **kwargs) + await self._async_update(source=ConfigSource.STORAGE, **kwargs) await self._async_store() self.hass.bus.async_fire_internal(EVENT_CORE_CONFIG_UPDATE, kwargs) @@ -3039,7 +3061,7 @@ class Config: ): _LOGGER.warning("Invalid internal_url set. It's not allowed to have a path") - self._update( + await self._async_update( source=ConfigSource.STORAGE, latitude=data.get("latitude"), longitude=data.get("longitude"), diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 039651bc3d3..a69e10db2a7 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -8,6 +8,7 @@ aiohttp-fast-zlib==0.1.0 aiohttp==3.9.5 aiohttp_cors==0.7.0 aiohttp_session==2.12.0 +aiozoneinfo==0.1.0 astral==2.2 async-interrupt==1.1.1 async-upnp-client==0.38.3 diff --git a/homeassistant/util/dt.py b/homeassistant/util/dt.py index 923838a48a5..30cf7222f3a 100644 --- a/homeassistant/util/dt.py +++ b/homeassistant/util/dt.py @@ -5,11 +5,12 @@ from __future__ import annotations import bisect from contextlib import suppress import datetime as dt -from functools import partial +from functools import lru_cache, partial import re from typing import Any, Literal, overload import zoneinfo +from aiozoneinfo import async_get_time_zone as _async_get_time_zone import ciso8601 DATE_STR_FORMAT = "%Y-%m-%d" @@ -74,6 +75,12 @@ POSTGRES_INTERVAL_RE = re.compile( ) +@lru_cache(maxsize=1) +def get_default_time_zone() -> dt.tzinfo: + """Get the default time zone.""" + return DEFAULT_TIME_ZONE + + def set_default_time_zone(time_zone: dt.tzinfo) -> None: """Set a default time zone to be used when none is specified. @@ -85,12 +92,14 @@ def set_default_time_zone(time_zone: dt.tzinfo) -> None: assert isinstance(time_zone, dt.tzinfo) DEFAULT_TIME_ZONE = time_zone + get_default_time_zone.cache_clear() def get_time_zone(time_zone_str: str) -> dt.tzinfo | None: """Get time zone from string. Return None if unable to determine. - Async friendly. + Must be run in the executor if the ZoneInfo is not already + in the cache. If you are not sure, use async_get_time_zone. """ try: return zoneinfo.ZoneInfo(time_zone_str) @@ -98,6 +107,17 @@ def get_time_zone(time_zone_str: str) -> dt.tzinfo | None: return None +async def async_get_time_zone(time_zone_str: str) -> dt.tzinfo | None: + """Get time zone from string. Return None if unable to determine. + + Async friendly. + """ + try: + return await _async_get_time_zone(time_zone_str) + except zoneinfo.ZoneInfoNotFoundError: + return None + + # We use a partial here since it is implemented in native code # and avoids the global lookup of UTC utcnow = partial(dt.datetime.now, UTC) diff --git a/pyproject.toml b/pyproject.toml index cb8df2bb3c9..c54c2b97528 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ dependencies = [ "aiohttp_session==2.12.0", "aiohttp-fast-url-dispatcher==0.3.0", "aiohttp-fast-zlib==0.1.0", + "aiozoneinfo==0.1.0", "astral==2.2", "async-interrupt==1.1.1", "attrs==23.2.0", diff --git a/requirements.txt b/requirements.txt index 104e8fb796f..4453c608c4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,7 @@ aiohttp_cors==0.7.0 aiohttp_session==2.12.0 aiohttp-fast-url-dispatcher==0.3.0 aiohttp-fast-zlib==0.1.0 +aiozoneinfo==0.1.0 astral==2.2 async-interrupt==1.1.1 attrs==23.2.0 diff --git a/tests/common.py b/tests/common.py index b77ab9afc5b..33385a67d91 100644 --- a/tests/common.py +++ b/tests/common.py @@ -232,7 +232,7 @@ async def async_test_home_assistant( orig_async_add_job = hass.async_add_job orig_async_add_executor_job = hass.async_add_executor_job orig_async_create_task_internal = hass.async_create_task_internal - orig_tz = dt_util.DEFAULT_TIME_ZONE + orig_tz = dt_util.get_default_time_zone() def async_add_job(target, *args, eager_start: bool = False): """Add job.""" @@ -279,7 +279,7 @@ async def async_test_home_assistant( hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 - hass.config.set_time_zone("US/Pacific") + await hass.config.async_set_time_zone("US/Pacific") hass.config.units = METRIC_SYSTEM hass.config.media_dirs = {"local": get_test_config_dir("media")} hass.config.skip_pip = True @@ -361,7 +361,7 @@ async def async_test_home_assistant( yield hass # Restore timezone, it is set when creating the hass object - dt_util.DEFAULT_TIME_ZONE = orig_tz + dt_util.set_default_time_zone(orig_tz) def async_mock_service( diff --git a/tests/components/aemet/test_config_flow.py b/tests/components/aemet/test_config_flow.py index 45fec473396..0f3491b1c43 100644 --- a/tests/components/aemet/test_config_flow.py +++ b/tests/components/aemet/test_config_flow.py @@ -71,7 +71,7 @@ async def test_form_options( ) -> None: """Test the form options.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") with patch( "homeassistant.components.aemet.AEMET.api_call", @@ -112,7 +112,7 @@ async def test_form_duplicated_id( ) -> None: """Test setting up duplicated entry.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") with patch( "homeassistant.components.aemet.AEMET.api_call", diff --git a/tests/components/aemet/test_coordinator.py b/tests/components/aemet/test_coordinator.py index e830f50c54a..5e8938b6ba1 100644 --- a/tests/components/aemet/test_coordinator.py +++ b/tests/components/aemet/test_coordinator.py @@ -20,7 +20,7 @@ async def test_coordinator_error( ) -> None: """Test error on coordinator update.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") await async_init_integration(hass) diff --git a/tests/components/aemet/test_init.py b/tests/components/aemet/test_init.py index df69349848b..cf3204782cd 100644 --- a/tests/components/aemet/test_init.py +++ b/tests/components/aemet/test_init.py @@ -28,7 +28,7 @@ async def test_unload_entry( ) -> None: """Test (un)loading the AEMET integration.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") with patch( "homeassistant.components.aemet.AEMET.api_call", @@ -54,7 +54,7 @@ async def test_init_town_not_found( ) -> None: """Test TownNotFound when loading the AEMET integration.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") with patch( "homeassistant.components.aemet.AEMET.api_call", @@ -80,7 +80,7 @@ async def test_init_api_timeout( ) -> None: """Test API timeouts when loading the AEMET integration.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") with patch( "homeassistant.components.aemet.AEMET.api_call", diff --git a/tests/components/aemet/test_sensor.py b/tests/components/aemet/test_sensor.py index c830310b856..d0f577c8068 100644 --- a/tests/components/aemet/test_sensor.py +++ b/tests/components/aemet/test_sensor.py @@ -15,7 +15,7 @@ async def test_aemet_forecast_create_sensors( ) -> None: """Test creation of forecast sensors.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") await async_init_integration(hass) @@ -76,7 +76,7 @@ async def test_aemet_weather_create_sensors( ) -> None: """Test creation of weather sensors.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") await async_init_integration(hass) diff --git a/tests/components/aemet/test_weather.py b/tests/components/aemet/test_weather.py index ec2c088fe6d..d2f21fbec83 100644 --- a/tests/components/aemet/test_weather.py +++ b/tests/components/aemet/test_weather.py @@ -35,7 +35,7 @@ async def test_aemet_weather( ) -> None: """Test states of the weather.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") await async_init_integration(hass) @@ -69,7 +69,7 @@ async def test_forecast_service( ) -> None: """Test multiple forecast.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") await async_init_integration(hass) @@ -109,7 +109,7 @@ async def test_forecast_subscription( """Test multiple forecast.""" client = await hass_ws_client(hass) - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") await async_init_integration(hass) diff --git a/tests/components/caldav/test_calendar.py b/tests/components/caldav/test_calendar.py index 942a4913f6e..e1a681e12fe 100644 --- a/tests/components/caldav/test_calendar.py +++ b/tests/components/caldav/test_calendar.py @@ -315,10 +315,10 @@ def mock_tz() -> str | None: @pytest.fixture(autouse=True) -def set_tz(hass: HomeAssistant, tz: str | None) -> None: +async def set_tz(hass: HomeAssistant, tz: str | None) -> None: """Fixture to set the default TZ to the one requested.""" if tz is not None: - hass.config.set_time_zone(tz) + await hass.config.async_set_time_zone(tz) @pytest.fixture(autouse=True) @@ -721,7 +721,7 @@ async def test_all_day_event( target_datetime: datetime.datetime, ) -> None: """Test that the event lasting the whole day is returned, if it's early in the local day.""" - freezer.move_to(target_datetime.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE)) + freezer.move_to(target_datetime.replace(tzinfo=dt_util.get_default_time_zone())) assert await async_setup_component( hass, "calendar", @@ -895,7 +895,7 @@ async def test_event_rrule_all_day_early( target_datetime: datetime.datetime, ) -> None: """Test that the recurring all day event is returned early in the local day, and not on the first occurrence.""" - freezer.move_to(target_datetime.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE)) + freezer.move_to(target_datetime.replace(tzinfo=dt_util.get_default_time_zone())) assert await async_setup_component( hass, "calendar", diff --git a/tests/components/caldav/test_todo.py b/tests/components/caldav/test_todo.py index bea4725856e..66f6e975453 100644 --- a/tests/components/caldav/test_todo.py +++ b/tests/components/caldav/test_todo.py @@ -91,9 +91,9 @@ def platforms() -> list[Platform]: @pytest.fixture(autouse=True) -def set_tz(hass: HomeAssistant) -> None: +async def set_tz(hass: HomeAssistant) -> None: """Fixture to set timezone with fixed offset year round.""" - hass.config.set_time_zone("America/Regina") + await hass.config.async_set_time_zone("America/Regina") @pytest.fixture(name="todos") diff --git a/tests/components/calendar/conftest.py b/tests/components/calendar/conftest.py index 7a3f27c8e08..ba0064cb4e4 100644 --- a/tests/components/calendar/conftest.py +++ b/tests/components/calendar/conftest.py @@ -28,11 +28,11 @@ TEST_DOMAIN = "test" @pytest.fixture -def set_time_zone(hass: HomeAssistant) -> None: +async def set_time_zone(hass: HomeAssistant) -> None: """Set the time zone for the tests.""" # Set our timezone to CST/Regina so we can check calculations # This keeps UTC-6 all year round - hass.config.set_time_zone("America/Regina") + await hass.config.async_set_time_zone("America/Regina") class MockFlow(ConfigFlow): diff --git a/tests/components/calendar/test_trigger.py b/tests/components/calendar/test_trigger.py index 54cfd353618..9c7be2514b6 100644 --- a/tests/components/calendar/test_trigger.py +++ b/tests/components/calendar/test_trigger.py @@ -700,8 +700,8 @@ async def test_event_start_trigger_dst( freezer: FrozenDateTimeFactory, ) -> None: """Test a calendar event trigger happening at the start of daylight savings time.""" + await hass.config.async_set_time_zone("America/Los_Angeles") tzinfo = zoneinfo.ZoneInfo("America/Los_Angeles") - hass.config.set_time_zone("America/Los_Angeles") freezer.move_to("2023-03-12 01:00:00-08:00") # Before DST transition starts diff --git a/tests/components/datetime/test_init.py b/tests/components/datetime/test_init.py index da65e1bce9e..ca866ec4364 100644 --- a/tests/components/datetime/test_init.py +++ b/tests/components/datetime/test_init.py @@ -18,7 +18,7 @@ DEFAULT_VALUE = datetime(2020, 1, 1, 12, 0, 0, tzinfo=UTC) async def test_datetime(hass: HomeAssistant) -> None: """Test date/time entity.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") setup_test_component_platform( hass, DOMAIN, diff --git a/tests/components/demo/test_datetime.py b/tests/components/demo/test_datetime.py index c1f88d7686b..bd4adafd695 100644 --- a/tests/components/demo/test_datetime.py +++ b/tests/components/demo/test_datetime.py @@ -37,7 +37,7 @@ def test_setup_params(hass: HomeAssistant) -> None: async def test_set_datetime(hass: HomeAssistant) -> None: """Test set datetime service.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") await hass.services.async_call( DOMAIN, SERVICE_SET_VALUE, diff --git a/tests/components/electric_kiwi/test_sensor.py b/tests/components/electric_kiwi/test_sensor.py index a247497b263..bb3304ec66c 100644 --- a/tests/components/electric_kiwi/test_sensor.py +++ b/tests/components/electric_kiwi/test_sensor.py @@ -24,7 +24,7 @@ from .conftest import ComponentSetup, YieldFixture from tests.common import MockConfigEntry -DEFAULT_TIME_ZONE = dt_util.DEFAULT_TIME_ZONE +DEFAULT_TIME_ZONE = dt_util.get_default_time_zone() TEST_TZ_NAME = "Pacific/Auckland" TEST_TIMEZONE = zoneinfo.ZoneInfo(TEST_TZ_NAME) diff --git a/tests/components/flux/test_switch.py b/tests/components/flux/test_switch.py index 018d1c43b70..baf568b79b4 100644 --- a/tests/components/flux/test_switch.py +++ b/tests/components/flux/test_switch.py @@ -28,9 +28,9 @@ from tests.components.light.common import MockLight @pytest.fixture(autouse=True) -def set_utc(hass): +async def set_utc(hass): """Set timezone to UTC.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") async def test_valid_config(hass: HomeAssistant) -> None: diff --git a/tests/components/forecast_solar/conftest.py b/tests/components/forecast_solar/conftest.py index 06cf39b4875..bc101d81388 100644 --- a/tests/components/forecast_solar/conftest.py +++ b/tests/components/forecast_solar/conftest.py @@ -67,7 +67,7 @@ def mock_forecast_solar(hass) -> Generator[None, MagicMock, None]: autospec=True, ) as forecast_solar_mock: forecast_solar = forecast_solar_mock.return_value - now = datetime(2021, 6, 27, 6, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE) + now = datetime(2021, 6, 27, 6, 0, tzinfo=dt_util.get_default_time_zone()) estimate = MagicMock(spec=models.Estimate) estimate.now.return_value = now @@ -79,10 +79,10 @@ def mock_forecast_solar(hass) -> Generator[None, MagicMock, None]: estimate.energy_production_tomorrow = 200000 estimate.power_production_now = 300000 estimate.power_highest_peak_time_today = datetime( - 2021, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE + 2021, 6, 27, 13, 0, tzinfo=dt_util.get_default_time_zone() ) estimate.power_highest_peak_time_tomorrow = datetime( - 2021, 6, 27, 14, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE + 2021, 6, 27, 14, 0, tzinfo=dt_util.get_default_time_zone() ) estimate.energy_current_hour = 800000 @@ -96,16 +96,16 @@ def mock_forecast_solar(hass) -> Generator[None, MagicMock, None]: 1: 900000, }.get estimate.watts = { - datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 10, - datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 100, + datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.get_default_time_zone()): 10, + datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.get_default_time_zone()): 100, } estimate.wh_days = { - datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 20, - datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 200, + datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.get_default_time_zone()): 20, + datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.get_default_time_zone()): 200, } estimate.wh_period = { - datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 30, - datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 300, + datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.get_default_time_zone()): 30, + datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.get_default_time_zone()): 300, } forecast_solar.estimate.return_value = estimate diff --git a/tests/components/google/conftest.py b/tests/components/google/conftest.py index 727209620eb..037c652f400 100644 --- a/tests/components/google/conftest.py +++ b/tests/components/google/conftest.py @@ -330,11 +330,11 @@ def mock_insert_event( @pytest.fixture(autouse=True) -def set_time_zone(hass): +async def set_time_zone(hass): """Set the time zone for the tests.""" # Set our timezone to CST/Regina so we can check calculations # This keeps UTC-6 all year round - hass.config.set_time_zone("America/Regina") + await hass.config.async_set_time_zone("America/Regina") @pytest.fixture diff --git a/tests/components/google/test_calendar.py b/tests/components/google/test_calendar.py index cf138567ba9..f21531a823c 100644 --- a/tests/components/google/test_calendar.py +++ b/tests/components/google/test_calendar.py @@ -474,7 +474,7 @@ async def test_http_api_event( component_setup, ) -> None: """Test querying the API and fetching events from the server.""" - hass.config.set_time_zone("Asia/Baghdad") + await hass.config.async_set_time_zone("Asia/Baghdad") event = { **TEST_EVENT, **upcoming(), @@ -788,7 +788,7 @@ async def test_all_day_iter_order( event_order, ) -> None: """Test the sort order of an all day events depending on the time zone.""" - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) mock_events_list_items( [ { diff --git a/tests/components/history/test_init_db_schema_30.py b/tests/components/history/test_init_db_schema_30.py index 1b867cea584..bec074362ca 100644 --- a/tests/components/history/test_init_db_schema_30.py +++ b/tests/components/history/test_init_db_schema_30.py @@ -781,7 +781,7 @@ async def test_history_during_period_significant_domain( time_zone, ) -> None: """Test history_during_period with climate domain.""" - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) now = dt_util.utcnow() await async_setup_component(hass, "history", {}) diff --git a/tests/components/history/test_websocket_api.py b/tests/components/history/test_websocket_api.py index 8ff3c91a3fc..580853fb83f 100644 --- a/tests/components/history/test_websocket_api.py +++ b/tests/components/history/test_websocket_api.py @@ -241,7 +241,7 @@ async def test_history_during_period_significant_domain( time_zone, ) -> None: """Test history_during_period with climate domain.""" - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) now = dt_util.utcnow() await async_setup_component(hass, "history", {}) diff --git a/tests/components/history_stats/test_sensor.py b/tests/components/history_stats/test_sensor.py index 4b4592c2104..c18fb2ff784 100644 --- a/tests/components/history_stats/test_sensor.py +++ b/tests/components/history_stats/test_sensor.py @@ -591,7 +591,7 @@ async def test_async_start_from_history_and_switch_to_watching_state_changes_sin hass: HomeAssistant, ) -> None: """Test we startup from history and switch to watching state changes.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) @@ -692,7 +692,7 @@ async def test_async_start_from_history_and_switch_to_watching_state_changes_sin hass: HomeAssistant, ) -> None: """Test we startup from history and switch to watching state changes with an expanding end time.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) @@ -809,7 +809,7 @@ async def test_async_start_from_history_and_switch_to_watching_state_changes_mul hass: HomeAssistant, ) -> None: """Test we startup from history and switch to watching state changes.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) @@ -950,7 +950,7 @@ async def test_does_not_work_into_the_future( Verifies we do not regress https://github.com/home-assistant/core/pull/20589 """ - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) @@ -1357,7 +1357,7 @@ async def test_measure_from_end_going_backwards( async def test_measure_cet(recorder_mock: Recorder, hass: HomeAssistant) -> None: """Test the history statistics sensor measure with a non-UTC timezone.""" - hass.config.set_time_zone("Europe/Berlin") + await hass.config.async_set_time_zone("Europe/Berlin") start_time = dt_util.utcnow() - timedelta(minutes=60) t0 = start_time + timedelta(minutes=20) t1 = t0 + timedelta(minutes=10) @@ -1446,7 +1446,7 @@ async def test_end_time_with_microseconds_zeroed( hass: HomeAssistant, ) -> None: """Test the history statistics sensor that has the end time microseconds zeroed out.""" - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) start_of_today = dt_util.now().replace( day=9, month=7, year=1986, hour=0, minute=0, second=0, microsecond=0 ) @@ -1650,7 +1650,7 @@ async def test_history_stats_handles_floored_timestamps( hass: HomeAssistant, ) -> None: """Test we account for microseconds when doing the data calculation.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) last_times = None diff --git a/tests/components/input_datetime/test_init.py b/tests/components/input_datetime/test_init.py index 9d218e6d6ec..5d8ea90b8a6 100644 --- a/tests/components/input_datetime/test_init.py +++ b/tests/components/input_datetime/test_init.py @@ -688,7 +688,7 @@ async def test_setup_no_config(hass: HomeAssistant, hass_admin_user: MockUser) - async def test_timestamp(hass: HomeAssistant) -> None: """Test timestamp.""" - hass.config.set_time_zone("America/Los_Angeles") + await hass.config.async_set_time_zone("America/Los_Angeles") assert await async_setup_component( hass, diff --git a/tests/components/islamic_prayer_times/test_init.py b/tests/components/islamic_prayer_times/test_init.py index 2a2597ef0ce..025a202e6da 100644 --- a/tests/components/islamic_prayer_times/test_init.py +++ b/tests/components/islamic_prayer_times/test_init.py @@ -21,9 +21,9 @@ from tests.common import MockConfigEntry, async_fire_time_changed @pytest.fixture(autouse=True) -def set_utc(hass: HomeAssistant) -> None: +async def set_utc(hass: HomeAssistant) -> None: """Set timezone to UTC.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") async def test_successful_config_entry(hass: HomeAssistant) -> None: diff --git a/tests/components/islamic_prayer_times/test_sensor.py b/tests/components/islamic_prayer_times/test_sensor.py index 7bd1a1192ad..153f0012a2c 100644 --- a/tests/components/islamic_prayer_times/test_sensor.py +++ b/tests/components/islamic_prayer_times/test_sensor.py @@ -15,9 +15,9 @@ from tests.common import MockConfigEntry @pytest.fixture(autouse=True) -def set_utc(hass: HomeAssistant) -> None: +async def set_utc(hass: HomeAssistant) -> None: """Set timezone to UTC.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") @pytest.mark.parametrize( diff --git a/tests/components/jewish_calendar/test_binary_sensor.py b/tests/components/jewish_calendar/test_binary_sensor.py index bced831462a..ce59c7fe189 100644 --- a/tests/components/jewish_calendar/test_binary_sensor.py +++ b/tests/components/jewish_calendar/test_binary_sensor.py @@ -184,7 +184,7 @@ async def test_issur_melacha_sensor( time_zone = dt_util.get_time_zone(tzname) test_time = now.replace(tzinfo=time_zone) - hass.config.set_time_zone(tzname) + await hass.config.async_set_time_zone(tzname) hass.config.latitude = latitude hass.config.longitude = longitude @@ -272,7 +272,7 @@ async def test_issur_melacha_sensor_update( time_zone = dt_util.get_time_zone(tzname) test_time = now.replace(tzinfo=time_zone) - hass.config.set_time_zone(tzname) + await hass.config.async_set_time_zone(tzname) hass.config.latitude = latitude hass.config.longitude = longitude diff --git a/tests/components/jewish_calendar/test_sensor.py b/tests/components/jewish_calendar/test_sensor.py index d9f43236965..91883ce0d19 100644 --- a/tests/components/jewish_calendar/test_sensor.py +++ b/tests/components/jewish_calendar/test_sensor.py @@ -167,7 +167,7 @@ async def test_jewish_calendar_sensor( time_zone = dt_util.get_time_zone(tzname) test_time = now.replace(tzinfo=time_zone) - hass.config.set_time_zone(tzname) + await hass.config.async_set_time_zone(tzname) hass.config.latitude = latitude hass.config.longitude = longitude @@ -512,7 +512,7 @@ async def test_shabbat_times_sensor( time_zone = dt_util.get_time_zone(tzname) test_time = now.replace(tzinfo=time_zone) - hass.config.set_time_zone(tzname) + await hass.config.async_set_time_zone(tzname) hass.config.latitude = latitude hass.config.longitude = longitude diff --git a/tests/components/knx/test_datetime.py b/tests/components/knx/test_datetime.py index e2dcfc8d112..c8c6bd4f346 100644 --- a/tests/components/knx/test_datetime.py +++ b/tests/components/knx/test_datetime.py @@ -50,7 +50,7 @@ async def test_datetime(hass: HomeAssistant, knx: KNXTestKit) -> None: async def test_date_restore_and_respond(hass: HomeAssistant, knx: KNXTestKit) -> None: """Test KNX datetime with passive_address, restoring state and respond_to_read.""" - hass.config.set_time_zone("Europe/Vienna") + await hass.config.async_set_time_zone("Europe/Vienna") test_address = "1/1/1" test_passive_address = "3/3/3" fake_state = State("datetime.test", "2022-03-03T03:04:05+00:00") diff --git a/tests/components/lamarzocco/test_calendar.py b/tests/components/lamarzocco/test_calendar.py index 8cc529c226f..d26faa615e6 100644 --- a/tests/components/lamarzocco/test_calendar.py +++ b/tests/components/lamarzocco/test_calendar.py @@ -33,7 +33,7 @@ async def test_calendar_events( ) -> None: """Test the calendar.""" - test_time = datetime(2024, 1, 12, 11, tzinfo=dt_util.DEFAULT_TIME_ZONE) + test_time = datetime(2024, 1, 12, 11, tzinfo=dt_util.get_default_time_zone()) freezer.move_to(test_time) await async_init_integration(hass, mock_config_entry) @@ -86,8 +86,8 @@ async def test_calendar_edge_cases( end_date: datetime, ) -> None: """Test edge cases.""" - start_date = start_date.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE) - end_date = end_date.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE) + start_date = start_date.replace(tzinfo=dt_util.get_default_time_zone()) + end_date = end_date.replace(tzinfo=dt_util.get_default_time_zone()) # set schedule to be only on Sunday, 07:00 - 07:30 mock_lamarzocco.schedule[2]["enable"] = "Disabled" @@ -124,7 +124,7 @@ async def test_no_calendar_events_global_disable( """Assert no events when global auto on/off is disabled.""" mock_lamarzocco.current_status["global_auto"] = "Disabled" - test_time = datetime(2024, 1, 12, 11, tzinfo=dt_util.DEFAULT_TIME_ZONE) + test_time = datetime(2024, 1, 12, 11, tzinfo=dt_util.get_default_time_zone()) freezer.move_to(test_time) await async_init_integration(hass, mock_config_entry) diff --git a/tests/components/local_calendar/conftest.py b/tests/components/local_calendar/conftest.py index 82f69be5fd1..228a7783d73 100644 --- a/tests/components/local_calendar/conftest.py +++ b/tests/components/local_calendar/conftest.py @@ -87,11 +87,11 @@ def mock_time_zone() -> str: @pytest.fixture(autouse=True) -def set_time_zone(hass: HomeAssistant, time_zone: str): +async def set_time_zone(hass: HomeAssistant, time_zone: str): """Set the time zone for the tests.""" # Set our timezone to CST/Regina so we can check calculations # This keeps UTC-6 all year round - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) @pytest.fixture(name="config_entry") diff --git a/tests/components/local_todo/test_todo.py b/tests/components/local_todo/test_todo.py index 3074cdcf88f..e54ee925437 100644 --- a/tests/components/local_todo/test_todo.py +++ b/tests/components/local_todo/test_todo.py @@ -61,9 +61,9 @@ async def ws_move_item( @pytest.fixture(autouse=True) -def set_time_zone(hass: HomeAssistant) -> None: +async def set_time_zone(hass: HomeAssistant) -> None: """Set the time zone for the tests that keesp UTC-6 all year round.""" - hass.config.set_time_zone("America/Regina") + await hass.config.async_set_time_zone("America/Regina") EXPECTED_ADD_ITEM = { diff --git a/tests/components/logbook/test_init.py b/tests/components/logbook/test_init.py index d752b896401..0ba96a8ca6a 100644 --- a/tests/components/logbook/test_init.py +++ b/tests/components/logbook/test_init.py @@ -68,9 +68,9 @@ async def hass_(recorder_mock, hass): @pytest.fixture -def set_utc(hass): +async def set_utc(hass): """Set timezone to UTC.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") async def test_service_call_create_logbook_entry(hass_) -> None: diff --git a/tests/components/logbook/test_websocket_api.py b/tests/components/logbook/test_websocket_api.py index 1be0e5bd9af..1fb0e6eb24b 100644 --- a/tests/components/logbook/test_websocket_api.py +++ b/tests/components/logbook/test_websocket_api.py @@ -47,9 +47,9 @@ from tests.typing import RecorderInstanceGenerator, WebSocketGenerator @pytest.fixture -def set_utc(hass): +async def set_utc(hass): """Set timezone to UTC.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") def listeners_without_writes(listeners: dict[str, int]) -> dict[str, int]: diff --git a/tests/components/nam/test_sensor.py b/tests/components/nam/test_sensor.py index 2b307b4b02a..b9d6c20939e 100644 --- a/tests/components/nam/test_sensor.py +++ b/tests/components/nam/test_sensor.py @@ -39,7 +39,7 @@ async def test_sensor( freezer: FrozenDateTimeFactory, ) -> None: """Test states of the air_quality.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2024-04-20 12:00:00+00:00") with patch("homeassistant.components.nam.PLATFORMS", [Platform.SENSOR]): diff --git a/tests/components/pvpc_hourly_pricing/test_config_flow.py b/tests/components/pvpc_hourly_pricing/test_config_flow.py index 70e25392bb6..cc15944b212 100644 --- a/tests/components/pvpc_hourly_pricing/test_config_flow.py +++ b/tests/components/pvpc_hourly_pricing/test_config_flow.py @@ -42,7 +42,7 @@ async def test_config_flow( - Configure options to introduce API Token, with bad auth and good one """ freezer.move_to(_MOCK_TIME_VALID_RESPONSES) - hass.config.set_time_zone("Europe/Madrid") + await hass.config.async_set_time_zone("Europe/Madrid") tst_config = { CONF_NAME: "test", ATTR_TARIFF: TARIFFS[1], @@ -184,7 +184,7 @@ async def test_reauth( ) -> None: """Test reauth flow for API-token mode.""" freezer.move_to(_MOCK_TIME_BAD_AUTH_RESPONSES) - hass.config.set_time_zone("Europe/Madrid") + await hass.config.async_set_time_zone("Europe/Madrid") tst_config = { CONF_NAME: "test", ATTR_TARIFF: TARIFFS[1], diff --git a/tests/components/rainbird/test_calendar.py b/tests/components/rainbird/test_calendar.py index 1af6ca7ba7f..1bc692e3930 100644 --- a/tests/components/rainbird/test_calendar.py +++ b/tests/components/rainbird/test_calendar.py @@ -91,9 +91,9 @@ async def setup_config_entry( @pytest.fixture(autouse=True) -def set_time_zone(hass: HomeAssistant): +async def set_time_zone(hass: HomeAssistant): """Set the time zone for the tests.""" - hass.config.set_time_zone("America/Regina") + await hass.config.async_set_time_zone("America/Regina") @pytest.fixture(autouse=True) diff --git a/tests/components/recorder/test_history.py b/tests/components/recorder/test_history.py index af32edbca6b..05542cbecb5 100644 --- a/tests/components/recorder/test_history.py +++ b/tests/components/recorder/test_history.py @@ -602,7 +602,7 @@ async def test_get_significant_states_with_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) zero, four, states = record_states(hass) await async_wait_recording_done(hass) diff --git a/tests/components/recorder/test_history_db_schema_32.py b/tests/components/recorder/test_history_db_schema_32.py index 821dbf5e955..b778a3ff6a3 100644 --- a/tests/components/recorder/test_history_db_schema_32.py +++ b/tests/components/recorder/test_history_db_schema_32.py @@ -382,7 +382,7 @@ async def test_get_significant_states_with_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) zero, four, states = record_states(hass) await async_wait_recording_done(hass) diff --git a/tests/components/recorder/test_history_db_schema_42.py b/tests/components/recorder/test_history_db_schema_42.py index 6ed2a683552..04490b88a28 100644 --- a/tests/components/recorder/test_history_db_schema_42.py +++ b/tests/components/recorder/test_history_db_schema_42.py @@ -604,7 +604,7 @@ async def test_get_significant_states_with_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) zero, four, states = record_states(hass) await async_wait_recording_done(hass) diff --git a/tests/components/recorder/test_init.py b/tests/components/recorder/test_init.py index 88fbf8f388a..d5874cefd59 100644 --- a/tests/components/recorder/test_init.py +++ b/tests/components/recorder/test_init.py @@ -1027,7 +1027,7 @@ async def run_tasks_at_time(hass: HomeAssistant, test_time: datetime) -> None: async def test_auto_purge(hass: HomeAssistant, setup_recorder: None) -> None: """Test periodic purge scheduling.""" timezone = "Europe/Copenhagen" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) tz = dt_util.get_time_zone(timezone) # Purging is scheduled to happen at 4:12am every day. Exercise this behavior by @@ -1089,7 +1089,7 @@ async def test_auto_purge_auto_repack_on_second_sunday( ) -> None: """Test periodic purge scheduling does a repack on the 2nd sunday.""" timezone = "Europe/Copenhagen" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) tz = dt_util.get_time_zone(timezone) # Purging is scheduled to happen at 4:12am every day. Exercise this behavior by @@ -1132,7 +1132,7 @@ async def test_auto_purge_auto_repack_disabled_on_second_sunday( ) -> None: """Test periodic purge scheduling does not auto repack on the 2nd sunday if disabled.""" timezone = "Europe/Copenhagen" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) await async_setup_recorder_instance(hass, {CONF_AUTO_REPACK: False}) tz = dt_util.get_time_zone(timezone) @@ -1176,7 +1176,7 @@ async def test_auto_purge_no_auto_repack_on_not_second_sunday( ) -> None: """Test periodic purge scheduling does not do a repack unless its the 2nd sunday.""" timezone = "Europe/Copenhagen" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) tz = dt_util.get_time_zone(timezone) # Purging is scheduled to happen at 4:12am every day. Exercise this behavior by @@ -1220,7 +1220,7 @@ async def test_auto_purge_disabled( ) -> None: """Test periodic db cleanup still run when auto purge is disabled.""" timezone = "Europe/Copenhagen" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) await async_setup_recorder_instance(hass, {CONF_AUTO_PURGE: False}) tz = dt_util.get_time_zone(timezone) @@ -1262,7 +1262,7 @@ async def test_auto_statistics( ) -> None: """Test periodic statistics scheduling.""" timezone = "Europe/Copenhagen" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) tz = dt_util.get_time_zone(timezone) stats_5min = [] diff --git a/tests/components/recorder/test_models.py b/tests/components/recorder/test_models.py index 262fb48af4d..d06c4a629d7 100644 --- a/tests/components/recorder/test_models.py +++ b/tests/components/recorder/test_models.py @@ -361,9 +361,9 @@ async def test_lazy_state_handles_same_last_updated_and_last_changed( @pytest.mark.parametrize( "time_zone", ["Europe/Berlin", "America/Chicago", "US/Hawaii", "UTC"] ) -def test_process_datetime_to_timestamp(time_zone, hass: HomeAssistant) -> None: +async def test_process_datetime_to_timestamp(time_zone, hass: HomeAssistant) -> None: """Test we can handle processing database datatimes to timestamps.""" - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) utc_now = dt_util.utcnow() assert process_datetime_to_timestamp(utc_now) == utc_now.timestamp() now = dt_util.now() @@ -373,14 +373,14 @@ def test_process_datetime_to_timestamp(time_zone, hass: HomeAssistant) -> None: @pytest.mark.parametrize( "time_zone", ["Europe/Berlin", "America/Chicago", "US/Hawaii", "UTC"] ) -def test_process_datetime_to_timestamp_freeze_time( +async def test_process_datetime_to_timestamp_freeze_time( time_zone, hass: HomeAssistant ) -> None: """Test we can handle processing database datatimes to timestamps. This test freezes time to make sure everything matches. """ - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) utc_now = dt_util.utcnow() with freeze_time(utc_now): epoch = utc_now.timestamp() @@ -396,7 +396,7 @@ async def test_process_datetime_to_timestamp_mirrors_utc_isoformat_behavior( time_zone, hass: HomeAssistant ) -> None: """Test process_datetime_to_timestamp mirrors process_timestamp_to_utc_isoformat.""" - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) datetime_with_tzinfo = datetime(2016, 7, 9, 11, 0, 0, tzinfo=dt_util.UTC) datetime_without_tzinfo = datetime(2016, 7, 9, 11, 0, 0) est = dt_util.get_time_zone("US/Eastern") diff --git a/tests/components/recorder/test_statistics.py b/tests/components/recorder/test_statistics.py index ca232c49db6..7d8bc6e3415 100644 --- a/tests/components/recorder/test_statistics.py +++ b/tests/components/recorder/test_statistics.py @@ -1102,7 +1102,7 @@ async def test_daily_statistics_sum( timezone, ) -> None: """Test daily statistics.""" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) await async_wait_recording_done(hass) assert "Compiling statistics for" not in caplog.text assert "Statistics already compiled" not in caplog.text @@ -1282,7 +1282,7 @@ async def test_weekly_statistics_mean( timezone, ) -> None: """Test weekly statistics.""" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) await async_wait_recording_done(hass) assert "Compiling statistics for" not in caplog.text assert "Statistics already compiled" not in caplog.text @@ -1417,7 +1417,7 @@ async def test_weekly_statistics_sum( timezone, ) -> None: """Test weekly statistics.""" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) await async_wait_recording_done(hass) assert "Compiling statistics for" not in caplog.text assert "Statistics already compiled" not in caplog.text @@ -1597,7 +1597,7 @@ async def test_monthly_statistics_sum( timezone, ) -> None: """Test monthly statistics.""" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) await async_wait_recording_done(hass) assert "Compiling statistics for" not in caplog.text assert "Statistics already compiled" not in caplog.text @@ -1917,7 +1917,7 @@ async def test_change( timezone, ) -> None: """Test deriving change from sum statistic.""" - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) await async_wait_recording_done(hass) assert "Compiling statistics for" not in caplog.text assert "Statistics already compiled" not in caplog.text @@ -2256,7 +2256,7 @@ async def test_change_with_none( This tests the behavior when some record has None sum. The calculated change is not expected to be correct, but we should not raise on this error. """ - hass.config.set_time_zone(timezone) + await hass.config.async_set_time_zone(timezone) await async_wait_recording_done(hass) assert "Compiling statistics for" not in caplog.text assert "Statistics already compiled" not in caplog.text diff --git a/tests/components/recorder/test_websocket_api.py b/tests/components/recorder/test_websocket_api.py index f97c5b835b5..9cb06003415 100644 --- a/tests/components/recorder/test_websocket_api.py +++ b/tests/components/recorder/test_websocket_api.py @@ -1127,7 +1127,7 @@ async def test_statistics_during_period_in_the_past( recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator ) -> None: """Test statistics_during_period in the past.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") now = dt_util.utcnow().replace() hass.config.units = US_CUSTOMARY_SYSTEM diff --git a/tests/components/rfxtrx/test_event.py b/tests/components/rfxtrx/test_event.py index 035949efe3b..5e5f7d246c5 100644 --- a/tests/components/rfxtrx/test_event.py +++ b/tests/components/rfxtrx/test_event.py @@ -32,7 +32,7 @@ async def test_control_event( snapshot: SnapshotAssertion, ) -> None: """Test event update updates correct event object.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") await setup_rfx_test_cfg( @@ -60,7 +60,7 @@ async def test_status_event( snapshot: SnapshotAssertion, ) -> None: """Test event update updates correct event object.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") await setup_rfx_test_cfg( diff --git a/tests/components/ring/test_sensor.py b/tests/components/ring/test_sensor.py index 2c866586c6c..e812b6bcb33 100644 --- a/tests/components/ring/test_sensor.py +++ b/tests/components/ring/test_sensor.py @@ -97,7 +97,7 @@ async def test_only_chime_devices( caplog, ) -> None: """Tests the update service works correctly if only chimes are returned.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to("2021-01-09 12:00:00+00:00") requests_mock.get( "https://api.ring.com/clients_api/ring_devices", diff --git a/tests/components/risco/test_sensor.py b/tests/components/risco/test_sensor.py index ec3f2d14026..02314983acf 100644 --- a/tests/components/risco/test_sensor.py +++ b/tests/components/risco/test_sensor.py @@ -158,8 +158,8 @@ def _check_state(hass, category, entity_id): @pytest.fixture -def _set_utc_time_zone(hass): - hass.config.set_time_zone("UTC") +async def _set_utc_time_zone(hass): + await hass.config.async_set_time_zone("UTC") @pytest.fixture diff --git a/tests/components/srp_energy/conftest.py b/tests/components/srp_energy/conftest.py index 12fa7ffd6d6..b83fff778ac 100644 --- a/tests/components/srp_energy/conftest.py +++ b/tests/components/srp_energy/conftest.py @@ -20,11 +20,11 @@ from tests.common import MockConfigEntry @pytest.fixture(name="setup_hass_config", autouse=True) -def fixture_setup_hass_config(hass: HomeAssistant) -> None: +async def fixture_setup_hass_config(hass: HomeAssistant) -> None: """Set up things to be run when tests are started.""" hass.config.latitude = 33.27 hass.config.longitude = 112 - hass.config.set_time_zone(PHOENIX_TIME_ZONE) + await hass.config.async_set_time_zone(PHOENIX_TIME_ZONE) @pytest.fixture(name="hass_tz_info") diff --git a/tests/components/time_date/test_sensor.py b/tests/components/time_date/test_sensor.py index d7e87b3a471..bbdb770c868 100644 --- a/tests/components/time_date/test_sensor.py +++ b/tests/components/time_date/test_sensor.py @@ -51,7 +51,7 @@ async def test_intervals( tracked_time, ) -> None: """Test timing intervals of sensors when time zone is UTC.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") freezer.move_to(start_time) await load_int(hass, display_option) @@ -61,7 +61,7 @@ async def test_intervals( async def test_states(hass: HomeAssistant, freezer: FrozenDateTimeFactory) -> None: """Test states of sensors.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") now = dt_util.utc_from_timestamp(1495068856) freezer.move_to(now) @@ -121,7 +121,7 @@ async def test_states_non_default_timezone( hass: HomeAssistant, freezer: FrozenDateTimeFactory ) -> None: """Test states of sensors in a timezone other than UTC.""" - hass.config.set_time_zone("America/New_York") + await hass.config.async_set_time_zone("America/New_York") now = dt_util.utc_from_timestamp(1495068856) freezer.move_to(now) @@ -254,7 +254,7 @@ async def test_timezone_intervals( tracked_time, ) -> None: """Test timing intervals of sensors in timezone other than UTC.""" - hass.config.set_time_zone(time_zone) + await hass.config.async_set_time_zone(time_zone) freezer.move_to(start_time) await load_int(hass, "date") diff --git a/tests/components/tod/test_binary_sensor.py b/tests/components/tod/test_binary_sensor.py index 1a2e1ad9849..91af702e093 100644 --- a/tests/components/tod/test_binary_sensor.py +++ b/tests/components/tod/test_binary_sensor.py @@ -22,11 +22,11 @@ def hass_time_zone(): @pytest.fixture(autouse=True) -def setup_fixture(hass, hass_time_zone): +async def setup_fixture(hass, hass_time_zone): """Set up things to be run when tests are started.""" hass.config.latitude = 50.27583 hass.config.longitude = 18.98583 - hass.config.set_time_zone(hass_time_zone) + await hass.config.async_set_time_zone(hass_time_zone) @pytest.fixture diff --git a/tests/components/todo/test_init.py b/tests/components/todo/test_init.py index 95024b71757..4b8e35c9061 100644 --- a/tests/components/todo/test_init.py +++ b/tests/components/todo/test_init.py @@ -113,9 +113,9 @@ def mock_setup_integration(hass: HomeAssistant) -> None: @pytest.fixture(autouse=True) -def set_time_zone(hass: HomeAssistant) -> None: +async def set_time_zone(hass: HomeAssistant) -> None: """Set the time zone for the tests that keesp UTC-6 all year round.""" - hass.config.set_time_zone("America/Regina") + await hass.config.async_set_time_zone("America/Regina") async def create_mock_platform( diff --git a/tests/components/todoist/test_calendar.py b/tests/components/todoist/test_calendar.py index ddffd879d46..dae5f0a8ee5 100644 --- a/tests/components/todoist/test_calendar.py +++ b/tests/components/todoist/test_calendar.py @@ -42,9 +42,9 @@ def platforms() -> list[Platform]: @pytest.fixture(autouse=True) -def set_time_zone(hass: HomeAssistant): +async def set_time_zone(hass: HomeAssistant): """Set the time zone for the tests.""" - hass.config.set_time_zone(TZ_NAME) + await hass.config.async_set_time_zone(TZ_NAME) def get_events_url(entity: str, start: str, end: str) -> str: diff --git a/tests/components/todoist/test_todo.py b/tests/components/todoist/test_todo.py index 373eb0158ea..2aabfcc5755 100644 --- a/tests/components/todoist/test_todo.py +++ b/tests/components/todoist/test_todo.py @@ -23,9 +23,9 @@ def platforms() -> list[Platform]: @pytest.fixture(autouse=True) -def set_time_zone(hass: HomeAssistant) -> None: +async def set_time_zone(hass: HomeAssistant) -> None: """Set the time zone for the tests that keesp UTC-6 all year round.""" - hass.config.set_time_zone("America/Regina") + await hass.config.async_set_time_zone("America/Regina") @pytest.mark.parametrize( diff --git a/tests/components/utility_meter/test_sensor.py b/tests/components/utility_meter/test_sensor.py index cd0a8082578..ad118d424eb 100644 --- a/tests/components/utility_meter/test_sensor.py +++ b/tests/components/utility_meter/test_sensor.py @@ -55,9 +55,9 @@ from tests.common import ( @pytest.fixture(autouse=True) -def set_utc(hass: HomeAssistant): +async def set_utc(hass: HomeAssistant): """Set timezone to UTC.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") @pytest.mark.parametrize( diff --git a/tests/components/vallox/test_sensor.py b/tests/components/vallox/test_sensor.py index d35c33a0305..8d8389fba80 100644 --- a/tests/components/vallox/test_sensor.py +++ b/tests/components/vallox/test_sensor.py @@ -18,21 +18,21 @@ def set_tz(request): @pytest.fixture -def utc(hass: HomeAssistant) -> None: +async def utc(hass: HomeAssistant) -> None: """Set the default TZ to UTC.""" - hass.config.set_time_zone("UTC") + hass.config.async_set_time_zone("UTC") @pytest.fixture -def helsinki(hass: HomeAssistant) -> None: +async def helsinki(hass: HomeAssistant) -> None: """Set the default TZ to Europe/Helsinki.""" - hass.config.set_time_zone("Europe/Helsinki") + hass.config.async_set_time_zone("Europe/Helsinki") @pytest.fixture -def new_york(hass: HomeAssistant) -> None: +async def new_york(hass: HomeAssistant) -> None: """Set the default TZ to America/New_York.""" - hass.config.set_time_zone("America/New_York") + hass.config.async_set_time_zone("America/New_York") def _sensor_to_datetime(sensor): diff --git a/tests/components/zodiac/test_sensor.py b/tests/components/zodiac/test_sensor.py index 3d43fe60a5a..723dc5b8f0e 100644 --- a/tests/components/zodiac/test_sensor.py +++ b/tests/components/zodiac/test_sensor.py @@ -44,7 +44,7 @@ async def test_zodiac_day( hass: HomeAssistant, now: datetime, sign: str, element: str, modality: str ) -> None: """Test the zodiac sensor.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") MockConfigEntry( domain=DOMAIN, ).add_to_hass(hass) diff --git a/tests/conftest.py b/tests/conftest.py index 4de97bd5094..3bcfcfa40f6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1455,7 +1455,9 @@ def hass_recorder( ) -> HomeAssistant: """Set up with params.""" if timezone is not None: - hass.config.set_time_zone(timezone) + asyncio.run_coroutine_threadsafe( + hass.config.async_set_time_zone(timezone), hass.loop + ).result() init_recorder_component(hass, config, recorder_db_url) hass.start() hass.block_till_done() diff --git a/tests/helpers/test_condition.py b/tests/helpers/test_condition.py index 7b98ccb3749..7f090f5e63b 100644 --- a/tests/helpers/test_condition.py +++ b/tests/helpers/test_condition.py @@ -3059,7 +3059,7 @@ async def test_if_action_before_sunrise_no_offset_kotzebue( at 7 AM and sunset at 3AM during summer After sunrise is true from sunrise until midnight, local time. """ - hass.config.set_time_zone("America/Anchorage") + await hass.config.async_set_time_zone("America/Anchorage") hass.config.latitude = 66.5 hass.config.longitude = 162.4 await async_setup_component( @@ -3136,7 +3136,7 @@ async def test_if_action_after_sunrise_no_offset_kotzebue( at 7 AM and sunset at 3AM during summer Before sunrise is true from midnight until sunrise, local time. """ - hass.config.set_time_zone("America/Anchorage") + await hass.config.async_set_time_zone("America/Anchorage") hass.config.latitude = 66.5 hass.config.longitude = 162.4 await async_setup_component( @@ -3213,7 +3213,7 @@ async def test_if_action_before_sunset_no_offset_kotzebue( at 7 AM and sunset at 3AM during summer Before sunset is true from midnight until sunset, local time. """ - hass.config.set_time_zone("America/Anchorage") + await hass.config.async_set_time_zone("America/Anchorage") hass.config.latitude = 66.5 hass.config.longitude = 162.4 await async_setup_component( @@ -3290,7 +3290,7 @@ async def test_if_action_after_sunset_no_offset_kotzebue( at 7 AM and sunset at 3AM during summer After sunset is true from sunset until midnight, local time. """ - hass.config.set_time_zone("America/Anchorage") + await hass.config.async_set_time_zone("America/Anchorage") hass.config.latitude = 66.5 hass.config.longitude = 162.4 await async_setup_component( diff --git a/tests/helpers/test_event.py b/tests/helpers/test_event.py index a6fad968eac..f45433afde0 100644 --- a/tests/helpers/test_event.py +++ b/tests/helpers/test_event.py @@ -49,7 +49,7 @@ import homeassistant.util.dt as dt_util from tests.common import async_fire_time_changed, async_fire_time_changed_exact -DEFAULT_TIME_ZONE = dt_util.DEFAULT_TIME_ZONE +DEFAULT_TIME_ZONE = dt_util.get_default_time_zone() async def test_track_point_in_time(hass: HomeAssistant) -> None: @@ -4097,7 +4097,7 @@ async def test_periodic_task_entering_dst( hass: HomeAssistant, freezer: FrozenDateTimeFactory ) -> None: """Test periodic task behavior when entering dst.""" - hass.config.set_time_zone("Europe/Vienna") + await hass.config.async_set_time_zone("Europe/Vienna") specific_runs = [] today = date.today().isoformat() @@ -4148,7 +4148,7 @@ async def test_periodic_task_entering_dst_2( This tests a task firing every second in the range 0..58 (not *:*:59) """ - hass.config.set_time_zone("Europe/Vienna") + await hass.config.async_set_time_zone("Europe/Vienna") specific_runs = [] today = date.today().isoformat() @@ -4198,7 +4198,7 @@ async def test_periodic_task_leaving_dst( hass: HomeAssistant, freezer: FrozenDateTimeFactory ) -> None: """Test periodic task behavior when leaving dst.""" - hass.config.set_time_zone("Europe/Vienna") + await hass.config.async_set_time_zone("Europe/Vienna") specific_runs = [] today = date.today().isoformat() @@ -4274,7 +4274,7 @@ async def test_periodic_task_leaving_dst_2( hass: HomeAssistant, freezer: FrozenDateTimeFactory ) -> None: """Test periodic task behavior when leaving dst.""" - hass.config.set_time_zone("Europe/Vienna") + await hass.config.async_set_time_zone("Europe/Vienna") specific_runs = [] today = date.today().isoformat() @@ -4565,7 +4565,7 @@ async def test_async_track_point_in_time_cancel(hass: HomeAssistant) -> None: """Test cancel of async track point in time.""" times = [] - hass.config.set_time_zone("US/Hawaii") + await hass.config.async_set_time_zone("US/Hawaii") hst_tz = dt_util.get_time_zone("US/Hawaii") @ha.callback diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 241a59f9b68..2561396d387 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -1108,9 +1108,9 @@ def test_strptime(hass: HomeAssistant) -> None: assert render(hass, "{{ strptime('invalid', '%Y', default=1) }}") == 1 -def test_timestamp_custom(hass: HomeAssistant) -> None: +async def test_timestamp_custom(hass: HomeAssistant) -> None: """Test the timestamps to custom filter.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") now = dt_util.utcnow() tests = [ (1469119144, None, True, "2016-07-21 16:39:04"), @@ -1150,9 +1150,9 @@ def test_timestamp_custom(hass: HomeAssistant) -> None: assert render(hass, "{{ None | timestamp_custom(default=1) }}") == 1 -def test_timestamp_local(hass: HomeAssistant) -> None: +async def test_timestamp_local(hass: HomeAssistant) -> None: """Test the timestamps to local filter.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") tests = [ (1469119144, "2016-07-21T16:39:04+00:00"), ] @@ -2225,14 +2225,14 @@ def test_utcnow(mock_is_safe, hass: HomeAssistant) -> None: "homeassistant.helpers.template.TemplateEnvironment.is_safe_callable", return_value=True, ) -def test_today_at( +async def test_today_at( mock_is_safe, hass: HomeAssistant, now, expected, expected_midnight, timezone_str ) -> None: """Test today_at method.""" freezer = freeze_time(now) freezer.start() - hass.config.set_time_zone(timezone_str) + await hass.config.async_set_time_zone(timezone_str) result = template.Template( "{{ today_at('10:00').isoformat() }}", @@ -2273,9 +2273,9 @@ def test_today_at( "homeassistant.helpers.template.TemplateEnvironment.is_safe_callable", return_value=True, ) -def test_relative_time(mock_is_safe, hass: HomeAssistant) -> None: +async def test_relative_time(mock_is_safe, hass: HomeAssistant) -> None: """Test relative_time method.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") now = datetime.strptime("2000-01-01 10:00:00 +00:00", "%Y-%m-%d %H:%M:%S %z") relative_time_template = ( '{{relative_time(strptime("2000-01-01 09:00:00", "%Y-%m-%d %H:%M:%S"))}}' @@ -2380,9 +2380,9 @@ def test_relative_time(mock_is_safe, hass: HomeAssistant) -> None: "homeassistant.helpers.template.TemplateEnvironment.is_safe_callable", return_value=True, ) -def test_time_since(mock_is_safe, hass: HomeAssistant) -> None: +async def test_time_since(mock_is_safe, hass: HomeAssistant) -> None: """Test time_since method.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") now = datetime.strptime("2000-01-01 10:00:00 +00:00", "%Y-%m-%d %H:%M:%S %z") time_since_template = ( '{{time_since(strptime("2000-01-01 09:00:00", "%Y-%m-%d %H:%M:%S"))}}' @@ -2543,9 +2543,9 @@ def test_time_since(mock_is_safe, hass: HomeAssistant) -> None: "homeassistant.helpers.template.TemplateEnvironment.is_safe_callable", return_value=True, ) -def test_time_until(mock_is_safe, hass: HomeAssistant) -> None: +async def test_time_until(mock_is_safe, hass: HomeAssistant) -> None: """Test time_until method.""" - hass.config.set_time_zone("UTC") + await hass.config.async_set_time_zone("UTC") now = datetime.strptime("2000-01-01 10:00:00 +00:00", "%Y-%m-%d %H:%M:%S %z") time_until_template = ( '{{time_until(strptime("2000-01-01 11:00:00", "%Y-%m-%d %H:%M:%S"))}}' diff --git a/tests/test_core.py b/tests/test_core.py index dc74697dcfb..b7cdae1c6e5 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -3502,3 +3502,16 @@ async def test_thread_safety_message(hass: HomeAssistant) -> None: ), ): await hass.async_add_executor_job(hass.verify_event_loop_thread, "test") + + +async def test_set_time_zone_deprecated(hass: HomeAssistant) -> None: + """Test set_time_zone is deprecated.""" + with pytest.raises( + RuntimeError, + match=re.escape( + "Detected code that set the time zone using set_time_zone instead of " + "async_set_time_zone which will stop working in Home Assistant 2025.6. " + "Please report this issue.", + ), + ): + await hass.config.set_time_zone("America/New_York") diff --git a/tests/util/test_dt.py b/tests/util/test_dt.py index 215524c426b..6caca092517 100644 --- a/tests/util/test_dt.py +++ b/tests/util/test_dt.py @@ -8,7 +8,7 @@ import pytest import homeassistant.util.dt as dt_util -DEFAULT_TIME_ZONE = dt_util.DEFAULT_TIME_ZONE +DEFAULT_TIME_ZONE = dt_util.get_default_time_zone() TEST_TIME_ZONE = "America/Los_Angeles" @@ -25,11 +25,21 @@ def test_get_time_zone_retrieves_valid_time_zone() -> None: assert dt_util.get_time_zone(TEST_TIME_ZONE) is not None +async def test_async_get_time_zone_retrieves_valid_time_zone() -> None: + """Test getting a time zone.""" + assert await dt_util.async_get_time_zone(TEST_TIME_ZONE) is not None + + def test_get_time_zone_returns_none_for_garbage_time_zone() -> None: """Test getting a non existing time zone.""" assert dt_util.get_time_zone("Non existing time zone") is None +async def test_async_get_time_zone_returns_none_for_garbage_time_zone() -> None: + """Test getting a non existing time zone.""" + assert await dt_util.async_get_time_zone("Non existing time zone") is None + + def test_set_default_time_zone() -> None: """Test setting default time zone.""" time_zone = dt_util.get_time_zone(TEST_TIME_ZONE)