Migrate from pytz to python-dateutil (#49643)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
13fe837fd2
commit
bf2d40adfe
37 changed files with 325 additions and 361 deletions
|
@ -95,8 +95,14 @@ async def async_attach_trigger(hass, config, action, automation_info):
|
|||
|
||||
if has_date:
|
||||
# If input_datetime has date, then track point in time.
|
||||
trigger_dt = dt_util.DEFAULT_TIME_ZONE.localize(
|
||||
datetime(year, month, day, hour, minute, second)
|
||||
trigger_dt = datetime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
tzinfo=dt_util.DEFAULT_TIME_ZONE,
|
||||
)
|
||||
# Only set up listener if time is now or in the future.
|
||||
if trigger_dt >= dt_util.now():
|
||||
|
|
|
@ -4,13 +4,12 @@ import logging
|
|||
|
||||
from aiohttp import ClientConnectorError
|
||||
from pygti.exceptions import InvalidAuth
|
||||
from pytz import timezone
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.const import ATTR_ATTRIBUTION, ATTR_ID, DEVICE_CLASS_TIMESTAMP
|
||||
from homeassistant.helpers import aiohttp_client
|
||||
from homeassistant.util import Throttle
|
||||
from homeassistant.util.dt import utcnow
|
||||
from homeassistant.util.dt import get_time_zone, utcnow
|
||||
|
||||
from .const import ATTRIBUTION, CONF_STATION, DOMAIN, MANUFACTURER
|
||||
|
||||
|
@ -28,6 +27,7 @@ ATTR_DELAY = "delay"
|
|||
ATTR_NEXT = "next"
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
BERLIN_TIME_ZONE = get_time_zone("Europe/Berlin")
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -60,12 +60,11 @@ class HVVDepartureSensor(SensorEntity):
|
|||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
async def async_update(self, **kwargs):
|
||||
"""Update the sensor."""
|
||||
|
||||
departure_time = utcnow() + timedelta(
|
||||
minutes=self.config_entry.options.get("offset", 0)
|
||||
)
|
||||
|
||||
departure_time_tz_berlin = departure_time.astimezone(timezone("Europe/Berlin"))
|
||||
departure_time_tz_berlin = departure_time.astimezone(BERLIN_TIME_ZONE)
|
||||
|
||||
payload = {
|
||||
"station": self.config_entry.data[CONF_STATION],
|
||||
|
|
|
@ -224,8 +224,8 @@ class InputDatetime(RestoreEntity):
|
|||
dt_util.DEFAULT_TIME_ZONE
|
||||
)
|
||||
else:
|
||||
self._current_datetime = dt_util.DEFAULT_TIME_ZONE.localize(
|
||||
current_datetime
|
||||
self._current_datetime = current_datetime.replace(
|
||||
tzinfo=dt_util.DEFAULT_TIME_ZONE
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
@ -388,8 +388,8 @@ class InputDatetime(RestoreEntity):
|
|||
if not time:
|
||||
time = self._current_datetime.time()
|
||||
|
||||
self._current_datetime = dt_util.DEFAULT_TIME_ZONE.localize(
|
||||
py_datetime.datetime.combine(date, time)
|
||||
self._current_datetime = py_datetime.datetime.combine(
|
||||
date, time, dt_util.DEFAULT_TIME_ZONE
|
||||
)
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ from datetime import datetime, timedelta
|
|||
import logging
|
||||
import time
|
||||
|
||||
from pytz import timezone
|
||||
import requests
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -26,6 +25,7 @@ from homeassistant.const import (
|
|||
HTTP_OK,
|
||||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -112,7 +112,6 @@ class RadarrSensor(SensorEntity):
|
|||
self.ssl = "https" if conf.get(CONF_SSL) else "http"
|
||||
self._state = None
|
||||
self.data = []
|
||||
self._tz = timezone(str(hass.config.time_zone))
|
||||
self.type = sensor_type
|
||||
self._name = SENSOR_TYPES[self.type][0]
|
||||
if self.type == "diskspace":
|
||||
|
@ -177,8 +176,9 @@ class RadarrSensor(SensorEntity):
|
|||
|
||||
def update(self):
|
||||
"""Update the data for the sensor."""
|
||||
start = get_date(self._tz)
|
||||
end = get_date(self._tz, self.days)
|
||||
time_zone = dt_util.get_time_zone(self.hass.config.time_zone)
|
||||
start = get_date(time_zone)
|
||||
end = get_date(time_zone, self.days)
|
||||
try:
|
||||
res = requests.get(
|
||||
ENDPOINTS[self.type].format(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
"""Support for representing current time of the day as binary sensors."""
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
from typing import Callable
|
||||
|
||||
import pytz
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorEntity
|
||||
|
@ -70,6 +70,7 @@ class TodSensor(BinarySensorEntity):
|
|||
self._before_offset = before_offset
|
||||
self._before = before
|
||||
self._after = after
|
||||
self._unsub_update: Callable[[], None] = None
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
|
@ -81,59 +82,37 @@ class TodSensor(BinarySensorEntity):
|
|||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def after(self):
|
||||
"""Return the timestamp for the beginning of the period."""
|
||||
return self._time_after
|
||||
|
||||
@property
|
||||
def before(self):
|
||||
"""Return the timestamp for the end of the period."""
|
||||
return self._time_before
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True is sensor is on."""
|
||||
if self.after < self.before:
|
||||
return self.after <= self.current_datetime < self.before
|
||||
if self._time_after < self._time_before:
|
||||
return self._time_after <= dt_util.utcnow() < self._time_before
|
||||
return False
|
||||
|
||||
@property
|
||||
def current_datetime(self):
|
||||
"""Return local current datetime according to hass configuration."""
|
||||
return dt_util.utcnow()
|
||||
|
||||
@property
|
||||
def next_update(self):
|
||||
"""Return the next update point in the UTC time."""
|
||||
return self._next_update
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the state attributes of the sensor."""
|
||||
time_zone = dt_util.get_time_zone(self.hass.config.time_zone)
|
||||
return {
|
||||
ATTR_AFTER: self.after.astimezone(self.hass.config.time_zone).isoformat(),
|
||||
ATTR_BEFORE: self.before.astimezone(self.hass.config.time_zone).isoformat(),
|
||||
ATTR_NEXT_UPDATE: self.next_update.astimezone(
|
||||
self.hass.config.time_zone
|
||||
).isoformat(),
|
||||
ATTR_AFTER: self._time_after.astimezone(time_zone).isoformat(),
|
||||
ATTR_BEFORE: self._time_before.astimezone(time_zone).isoformat(),
|
||||
ATTR_NEXT_UPDATE: self._next_update.astimezone(time_zone).isoformat(),
|
||||
}
|
||||
|
||||
def _naive_time_to_utc_datetime(self, naive_time):
|
||||
"""Convert naive time from config to utc_datetime with current day."""
|
||||
# get the current local date from utc time
|
||||
current_local_date = self.current_datetime.astimezone(
|
||||
self.hass.config.time_zone
|
||||
).date()
|
||||
# calculate utc datetime corecponding to local time
|
||||
utc_datetime = self.hass.config.time_zone.localize(
|
||||
datetime.combine(current_local_date, naive_time)
|
||||
).astimezone(tz=pytz.UTC)
|
||||
return utc_datetime
|
||||
current_local_date = (
|
||||
dt_util.utcnow()
|
||||
.astimezone(dt_util.get_time_zone(self.hass.config.time_zone))
|
||||
.date()
|
||||
)
|
||||
# calculate utc datetime corresponding to local time
|
||||
return dt_util.as_utc(datetime.combine(current_local_date, naive_time))
|
||||
|
||||
def _calculate_initial_boudary_time(self):
|
||||
def _calculate_boudary_time(self):
|
||||
"""Calculate internal absolute time boundaries."""
|
||||
nowutc = self.current_datetime
|
||||
nowutc = dt_util.utcnow()
|
||||
# If after value is a sun event instead of absolute time
|
||||
if is_sun_event(self._after):
|
||||
# Calculate the today's event utc time or
|
||||
|
@ -177,43 +156,34 @@ class TodSensor(BinarySensorEntity):
|
|||
self._time_after += self._after_offset
|
||||
self._time_before += self._before_offset
|
||||
|
||||
def _turn_to_next_day(self):
|
||||
"""Turn to to the next day."""
|
||||
if is_sun_event(self._after):
|
||||
self._time_after = get_astral_event_next(
|
||||
self.hass, self._after, self._time_after - self._after_offset
|
||||
)
|
||||
self._time_after += self._after_offset
|
||||
else:
|
||||
# Offset is already there
|
||||
self._time_after += timedelta(days=1)
|
||||
|
||||
if is_sun_event(self._before):
|
||||
self._time_before = get_astral_event_next(
|
||||
self.hass, self._before, self._time_before - self._before_offset
|
||||
)
|
||||
self._time_before += self._before_offset
|
||||
else:
|
||||
# Offset is already there
|
||||
self._time_before += timedelta(days=1)
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Call when entity about to be added to Home Assistant."""
|
||||
self._calculate_initial_boudary_time()
|
||||
self._calculate_boudary_time()
|
||||
self._calculate_next_update()
|
||||
self._point_in_time_listener(dt_util.now())
|
||||
|
||||
@callback
|
||||
def _clean_up_listener():
|
||||
if self._unsub_update is not None:
|
||||
self._unsub_update()
|
||||
self._unsub_update = None
|
||||
|
||||
self.async_on_remove(_clean_up_listener)
|
||||
|
||||
self._unsub_update = event.async_track_point_in_utc_time(
|
||||
self.hass, self._point_in_time_listener, self._next_update
|
||||
)
|
||||
|
||||
def _calculate_next_update(self):
|
||||
"""Datetime when the next update to the state."""
|
||||
now = self.current_datetime
|
||||
if now < self.after:
|
||||
self._next_update = self.after
|
||||
now = dt_util.utcnow()
|
||||
if now < self._time_after:
|
||||
self._next_update = self._time_after
|
||||
return
|
||||
if now < self.before:
|
||||
self._next_update = self.before
|
||||
if now < self._time_before:
|
||||
self._next_update = self._time_before
|
||||
return
|
||||
self._turn_to_next_day()
|
||||
self._next_update = self.after
|
||||
self._calculate_boudary_time()
|
||||
self._next_update = self._time_after
|
||||
|
||||
@callback
|
||||
def _point_in_time_listener(self, now):
|
||||
|
@ -221,6 +191,6 @@ class TodSensor(BinarySensorEntity):
|
|||
self._calculate_next_update()
|
||||
self.async_write_ha_state()
|
||||
|
||||
event.async_track_point_in_utc_time(
|
||||
self.hass, self._point_in_time_listener, self.next_update
|
||||
self._unsub_update = event.async_track_point_in_utc_time(
|
||||
self.hass, self._point_in_time_listener, self._next_update
|
||||
)
|
||||
|
|
|
@ -7,7 +7,6 @@ import logging
|
|||
import os
|
||||
|
||||
from aiohttp.hdrs import USER_AGENT
|
||||
import pytz
|
||||
import requests
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -28,7 +27,7 @@ from homeassistant.const import (
|
|||
__version__,
|
||||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util import Throttle
|
||||
from homeassistant.util import Throttle, dt as dt_util
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -41,6 +40,7 @@ CONF_STATION_ID = "station_id"
|
|||
DEFAULT_NAME = "zamg"
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10)
|
||||
VIENNA_TIME_ZONE = dt_util.get_time_zone("Europe/Vienna")
|
||||
|
||||
SENSOR_TYPES = {
|
||||
"pressure": ("Pressure", PRESSURE_HPA, "LDstat hPa", float),
|
||||
|
@ -187,7 +187,7 @@ class ZamgData:
|
|||
date, time = self.data.get("update_date"), self.data.get("update_time")
|
||||
if date is not None and time is not None:
|
||||
return datetime.strptime(date + time, "%d-%m-%Y%H:%M").replace(
|
||||
tzinfo=pytz.timezone("Europe/Vienna")
|
||||
tzinfo=VIENNA_TIME_ZONE
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
@ -208,7 +208,7 @@ class ZamgData:
|
|||
"""Get the latest data from ZAMG."""
|
||||
if self.last_update and (
|
||||
self.last_update + timedelta(hours=1)
|
||||
> datetime.utcnow().replace(tzinfo=pytz.utc)
|
||||
> datetime.utcnow().replace(tzinfo=dt_util.UTC)
|
||||
):
|
||||
return # Not time to update yet; data is only hourly
|
||||
|
||||
|
|
|
@ -1531,7 +1531,7 @@ class Config:
|
|||
self.longitude: float = 0
|
||||
self.elevation: int = 0
|
||||
self.location_name: str = "Home"
|
||||
self.time_zone: datetime.tzinfo = dt_util.UTC
|
||||
self.time_zone: str = "UTC"
|
||||
self.units: UnitSystem = METRIC_SYSTEM
|
||||
self.internal_url: str | None = None
|
||||
self.external_url: str | None = None
|
||||
|
@ -1621,17 +1621,13 @@ class Config:
|
|||
|
||||
Async friendly.
|
||||
"""
|
||||
time_zone = dt_util.UTC.zone
|
||||
if self.time_zone and getattr(self.time_zone, "zone"):
|
||||
time_zone = getattr(self.time_zone, "zone")
|
||||
|
||||
return {
|
||||
"latitude": self.latitude,
|
||||
"longitude": self.longitude,
|
||||
"elevation": self.elevation,
|
||||
"unit_system": self.units.as_dict(),
|
||||
"location_name": self.location_name,
|
||||
"time_zone": time_zone,
|
||||
"time_zone": self.time_zone,
|
||||
"components": self.components,
|
||||
"config_dir": self.config_dir,
|
||||
# legacy, backwards compat
|
||||
|
@ -1651,7 +1647,7 @@ class Config:
|
|||
time_zone = dt_util.get_time_zone(time_zone_str)
|
||||
|
||||
if time_zone:
|
||||
self.time_zone = time_zone
|
||||
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}")
|
||||
|
@ -1721,17 +1717,13 @@ class Config:
|
|||
|
||||
async def async_store(self) -> None:
|
||||
"""Store [homeassistant] core config."""
|
||||
time_zone = dt_util.UTC.zone
|
||||
if self.time_zone and getattr(self.time_zone, "zone"):
|
||||
time_zone = getattr(self.time_zone, "zone")
|
||||
|
||||
data = {
|
||||
"latitude": self.latitude,
|
||||
"longitude": self.longitude,
|
||||
"elevation": self.elevation,
|
||||
"unit_system": self.units.name,
|
||||
"location_name": self.location_name,
|
||||
"time_zone": time_zone,
|
||||
"time_zone": self.time_zone,
|
||||
"external_url": self.external_url,
|
||||
"internal_url": self.internal_url,
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ paho-mqtt==1.5.1
|
|||
pillow==8.1.2
|
||||
pip>=8.0.3,<20.3
|
||||
pyroute2==0.5.18
|
||||
python-dateutil==2.8.1
|
||||
python-slugify==4.0.1
|
||||
pytz>=2021.1
|
||||
pyyaml==5.4.1
|
||||
requests==2.25.1
|
||||
ruamel.yaml==0.15.100
|
||||
|
|
|
@ -4,20 +4,16 @@ from __future__ import annotations
|
|||
from contextlib import suppress
|
||||
import datetime as dt
|
||||
import re
|
||||
from typing import Any, cast
|
||||
from typing import Any
|
||||
|
||||
import ciso8601
|
||||
import pytz
|
||||
import pytz.exceptions as pytzexceptions
|
||||
import pytz.tzinfo as pytzinfo
|
||||
from dateutil import tz
|
||||
|
||||
from homeassistant.const import MATCH_ALL
|
||||
|
||||
DATE_STR_FORMAT = "%Y-%m-%d"
|
||||
NATIVE_UTC = dt.timezone.utc
|
||||
UTC = pytz.utc
|
||||
DEFAULT_TIME_ZONE: dt.tzinfo = pytz.utc
|
||||
|
||||
UTC = dt.timezone.utc
|
||||
DEFAULT_TIME_ZONE: dt.tzinfo = dt.timezone.utc
|
||||
|
||||
# Copyright (c) Django Software Foundation and individual contributors.
|
||||
# All rights reserved.
|
||||
|
@ -37,7 +33,6 @@ def set_default_time_zone(time_zone: dt.tzinfo) -> None:
|
|||
"""
|
||||
global DEFAULT_TIME_ZONE # pylint: disable=global-statement
|
||||
|
||||
# NOTE: Remove in the future in favour of typing
|
||||
assert isinstance(time_zone, dt.tzinfo)
|
||||
|
||||
DEFAULT_TIME_ZONE = time_zone
|
||||
|
@ -48,15 +43,12 @@ def get_time_zone(time_zone_str: str) -> dt.tzinfo | None:
|
|||
|
||||
Async friendly.
|
||||
"""
|
||||
try:
|
||||
return pytz.timezone(time_zone_str)
|
||||
except pytzexceptions.UnknownTimeZoneError:
|
||||
return None
|
||||
return tz.gettz(time_zone_str)
|
||||
|
||||
|
||||
def utcnow() -> dt.datetime:
|
||||
"""Get now in UTC time."""
|
||||
return dt.datetime.now(NATIVE_UTC)
|
||||
return dt.datetime.now(UTC)
|
||||
|
||||
|
||||
def now(time_zone: dt.tzinfo | None = None) -> dt.datetime:
|
||||
|
@ -72,7 +64,7 @@ def as_utc(dattim: dt.datetime) -> dt.datetime:
|
|||
if dattim.tzinfo == UTC:
|
||||
return dattim
|
||||
if dattim.tzinfo is None:
|
||||
dattim = DEFAULT_TIME_ZONE.localize(dattim) # type: ignore
|
||||
dattim = dattim.replace(tzinfo=DEFAULT_TIME_ZONE)
|
||||
|
||||
return dattim.astimezone(UTC)
|
||||
|
||||
|
@ -93,14 +85,14 @@ def as_local(dattim: dt.datetime) -> dt.datetime:
|
|||
if dattim.tzinfo == DEFAULT_TIME_ZONE:
|
||||
return dattim
|
||||
if dattim.tzinfo is None:
|
||||
dattim = UTC.localize(dattim)
|
||||
dattim = dattim.replace(tzinfo=DEFAULT_TIME_ZONE)
|
||||
|
||||
return dattim.astimezone(DEFAULT_TIME_ZONE)
|
||||
|
||||
|
||||
def utc_from_timestamp(timestamp: float) -> dt.datetime:
|
||||
"""Return a UTC time from a timestamp."""
|
||||
return UTC.localize(dt.datetime.utcfromtimestamp(timestamp))
|
||||
return dt.datetime.utcfromtimestamp(timestamp).replace(tzinfo=UTC)
|
||||
|
||||
|
||||
def start_of_local_day(dt_or_d: dt.date | dt.datetime | None = None) -> dt.datetime:
|
||||
|
@ -112,9 +104,7 @@ def start_of_local_day(dt_or_d: dt.date | dt.datetime | None = None) -> dt.datet
|
|||
else:
|
||||
date = dt_or_d
|
||||
|
||||
return DEFAULT_TIME_ZONE.localize( # type: ignore
|
||||
dt.datetime.combine(date, dt.time())
|
||||
)
|
||||
return dt.datetime.combine(date, dt.time(), tzinfo=DEFAULT_TIME_ZONE)
|
||||
|
||||
|
||||
# Copyright (c) Django Software Foundation and individual contributors.
|
||||
|
@ -239,6 +229,12 @@ def parse_time_expression(parameter: Any, min_value: int, max_value: int) -> lis
|
|||
return res
|
||||
|
||||
|
||||
def _dst_offset_diff(dattim: dt.datetime) -> dt.timedelta:
|
||||
"""Return the offset when crossing the DST barrier."""
|
||||
delta = dt.timedelta(hours=24)
|
||||
return (dattim + delta).utcoffset() - (dattim - delta).utcoffset() # type: ignore[operator]
|
||||
|
||||
|
||||
def find_next_time_expression_time(
|
||||
now: dt.datetime, # pylint: disable=redefined-outer-name
|
||||
seconds: list[int],
|
||||
|
@ -312,38 +308,28 @@ def find_next_time_expression_time(
|
|||
|
||||
result = result.replace(hour=next_hour)
|
||||
|
||||
if result.tzinfo is None:
|
||||
if result.tzinfo in (None, UTC):
|
||||
return result
|
||||
|
||||
# Now we need to handle timezones. We will make this datetime object
|
||||
# "naive" first and then re-convert it to the target timezone.
|
||||
# This is so that we can call pytz's localize and handle DST changes.
|
||||
tzinfo: pytzinfo.DstTzInfo = UTC if result.tzinfo == NATIVE_UTC else result.tzinfo
|
||||
result = result.replace(tzinfo=None)
|
||||
|
||||
try:
|
||||
result = tzinfo.localize(result, is_dst=None)
|
||||
except pytzexceptions.AmbiguousTimeError:
|
||||
if tz.datetime_ambiguous(result):
|
||||
# This happens when we're leaving daylight saving time and local
|
||||
# clocks are rolled back. In this case, we want to trigger
|
||||
# on both the DST and non-DST time. So when "now" is in the DST
|
||||
# use the DST-on time, and if not, use the DST-off time.
|
||||
use_dst = bool(now.dst())
|
||||
result = tzinfo.localize(result, is_dst=use_dst)
|
||||
except pytzexceptions.NonExistentTimeError:
|
||||
fold = 1 if now.dst() else 0
|
||||
if result.fold != fold:
|
||||
result = result.replace(fold=fold)
|
||||
|
||||
if not tz.datetime_exists(result):
|
||||
# This happens when we're entering daylight saving time and local
|
||||
# clocks are rolled forward, thus there are local times that do
|
||||
# not exist. In this case, we want to trigger on the next time
|
||||
# that *does* exist.
|
||||
# In the worst case, this will run through all the seconds in the
|
||||
# time shift, but that's max 3600 operations for once per year
|
||||
result = result.replace(tzinfo=tzinfo) + dt.timedelta(seconds=1)
|
||||
return find_next_time_expression_time(result, seconds, minutes, hours)
|
||||
|
||||
result_dst = cast(dt.timedelta, result.dst())
|
||||
now_dst = cast(dt.timedelta, now.dst()) or dt.timedelta(0)
|
||||
if result_dst >= now_dst:
|
||||
return result
|
||||
return find_next_time_expression_time(
|
||||
result + dt.timedelta(seconds=1), seconds, minutes, hours
|
||||
)
|
||||
|
||||
# Another edge-case when leaving DST:
|
||||
# When now is in DST and ambiguous *and* the next trigger time we *should*
|
||||
|
@ -351,23 +337,11 @@ def find_next_time_expression_time(
|
|||
# For example: if triggering on 2:30 and now is 28.10.2018 2:30 (in DST)
|
||||
# we should trigger next on 28.10.2018 2:30 (out of DST), but our
|
||||
# algorithm above would produce 29.10.2018 2:30 (out of DST)
|
||||
if tz.datetime_ambiguous(now):
|
||||
check_result = find_next_time_expression_time(
|
||||
now + _dst_offset_diff(now), seconds, minutes, hours
|
||||
)
|
||||
if tz.datetime_ambiguous(check_result):
|
||||
return check_result
|
||||
|
||||
# Step 1: Check if now is ambiguous
|
||||
try:
|
||||
tzinfo.localize(now.replace(tzinfo=None), is_dst=None)
|
||||
return result
|
||||
except pytzexceptions.AmbiguousTimeError:
|
||||
pass
|
||||
|
||||
# Step 2: Check if result of (now - DST) is ambiguous.
|
||||
check = now - now_dst
|
||||
check_result = find_next_time_expression_time(check, seconds, minutes, hours)
|
||||
try:
|
||||
tzinfo.localize(check_result.replace(tzinfo=None), is_dst=None)
|
||||
return result
|
||||
except pytzexceptions.AmbiguousTimeError:
|
||||
pass
|
||||
|
||||
# OK, edge case does apply. We must override the DST to DST-off
|
||||
check_result = tzinfo.localize(check_result.replace(tzinfo=None), is_dst=False)
|
||||
return check_result
|
||||
return result
|
||||
|
|
|
@ -15,7 +15,7 @@ PyJWT==1.7.1
|
|||
cryptography==3.3.2
|
||||
pip>=8.0.3,<20.3
|
||||
python-slugify==4.0.1
|
||||
pytz>=2021.1
|
||||
python-dateutil==2.8.1
|
||||
pyyaml==5.4.1
|
||||
requests==2.25.1
|
||||
ruamel.yaml==0.15.100
|
||||
|
|
2
setup.py
2
setup.py
|
@ -47,7 +47,7 @@ REQUIRES = [
|
|||
"cryptography==3.3.2",
|
||||
"pip>=8.0.3,<20.3",
|
||||
"python-slugify==4.0.1",
|
||||
"pytz>=2021.1",
|
||||
"python-dateutil==2.8.1",
|
||||
"pyyaml==5.4.1",
|
||||
"requests==2.25.1",
|
||||
"ruamel.yaml==0.15.100",
|
||||
|
|
|
@ -270,7 +270,7 @@ async def async_test_home_assistant(loop, load_registries=True):
|
|||
hass.config.latitude = 32.87336
|
||||
hass.config.longitude = -117.22743
|
||||
hass.config.elevation = 0
|
||||
hass.config.time_zone = date_util.get_time_zone("US/Pacific")
|
||||
hass.config.time_zone = "US/Pacific"
|
||||
hass.config.units = METRIC_SYSTEM
|
||||
hass.config.media_dirs = {"local": get_test_config_dir("media")}
|
||||
hass.config.skip_pip = True
|
||||
|
|
|
@ -7,7 +7,6 @@ from typing import Any
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from homeassistant.components.climacell.config_flow import (
|
||||
_get_config_schema,
|
||||
|
@ -18,6 +17,7 @@ from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
|||
from homeassistant.const import ATTR_ATTRIBUTION
|
||||
from homeassistant.core import HomeAssistant, State, callback
|
||||
from homeassistant.helpers.entity_registry import async_get
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import API_V3_ENTRY_DATA, API_V4_ENTRY_DATA
|
||||
|
||||
|
@ -59,7 +59,7 @@ async def _setup(hass: HomeAssistant, config: dict[str, Any]) -> State:
|
|||
"""Set up entry and return entity state."""
|
||||
with patch(
|
||||
"homeassistant.util.dt.utcnow",
|
||||
return_value=datetime(2021, 3, 6, 23, 59, 59, tzinfo=pytz.UTC),
|
||||
return_value=datetime(2021, 3, 6, 23, 59, 59, tzinfo=dt_util.UTC),
|
||||
):
|
||||
data = _get_config_schema(hass)(config)
|
||||
config_entry = MockConfigEntry(
|
||||
|
|
|
@ -7,7 +7,6 @@ from typing import Any
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from homeassistant.components.climacell.config_flow import (
|
||||
_get_config_schema,
|
||||
|
@ -46,6 +45,7 @@ from homeassistant.components.weather import (
|
|||
from homeassistant.const import ATTR_ATTRIBUTION, ATTR_FRIENDLY_NAME
|
||||
from homeassistant.core import HomeAssistant, State, callback
|
||||
from homeassistant.helpers.entity_registry import async_get
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import API_V3_ENTRY_DATA, API_V4_ENTRY_DATA
|
||||
|
||||
|
@ -70,7 +70,7 @@ async def _setup(hass: HomeAssistant, config: dict[str, Any]) -> State:
|
|||
"""Set up entry and return entity state."""
|
||||
with patch(
|
||||
"homeassistant.util.dt.utcnow",
|
||||
return_value=datetime(2021, 3, 6, 23, 59, 59, tzinfo=pytz.UTC),
|
||||
return_value=datetime(2021, 3, 6, 23, 59, 59, tzinfo=dt_util.UTC),
|
||||
):
|
||||
data = _get_config_schema(hass)(config)
|
||||
config_entry = MockConfigEntry(
|
||||
|
|
|
@ -57,7 +57,7 @@ async def test_websocket_core_update(hass, client):
|
|||
assert hass.config.elevation != 25
|
||||
assert hass.config.location_name != "Huis"
|
||||
assert hass.config.units.name != CONF_UNIT_SYSTEM_IMPERIAL
|
||||
assert hass.config.time_zone.zone != "America/New_York"
|
||||
assert hass.config.time_zone != "America/New_York"
|
||||
assert hass.config.external_url != "https://www.example.com"
|
||||
assert hass.config.internal_url != "http://example.com"
|
||||
|
||||
|
@ -91,7 +91,7 @@ async def test_websocket_core_update(hass, client):
|
|||
assert hass.config.internal_url == "http://example.local"
|
||||
|
||||
assert len(mock_set_tz.mock_calls) == 1
|
||||
assert mock_set_tz.mock_calls[0][1][0].zone == "America/New_York"
|
||||
assert mock_set_tz.mock_calls[0][1][0] == dt_util.get_time_zone("America/New_York")
|
||||
|
||||
|
||||
async def test_websocket_core_update_not_admin(hass, hass_ws_client, hass_admin_user):
|
||||
|
|
|
@ -4,7 +4,6 @@ from os import path
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config as hass_config
|
||||
|
@ -37,6 +36,7 @@ import homeassistant.core as ha
|
|||
from homeassistant.core import DOMAIN as HASS_DOMAIN, CoreState, State, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
from homeassistant.util.unit_system import METRIC_SYSTEM
|
||||
|
||||
from tests.common import (
|
||||
|
@ -691,9 +691,7 @@ async def test_temp_change_ac_trigger_on_not_long_enough(hass, setup_comp_4):
|
|||
|
||||
async def test_temp_change_ac_trigger_on_long_enough(hass, setup_comp_4):
|
||||
"""Test if temperature change turn ac on."""
|
||||
fake_changed = datetime.datetime(
|
||||
1918, 11, 11, 11, 11, 11, tzinfo=datetime.timezone.utc
|
||||
)
|
||||
fake_changed = datetime.datetime(1918, 11, 11, 11, 11, 11, tzinfo=dt_util.UTC)
|
||||
with patch(
|
||||
"homeassistant.helpers.condition.dt_util.utcnow", return_value=fake_changed
|
||||
):
|
||||
|
@ -719,9 +717,7 @@ async def test_temp_change_ac_trigger_off_not_long_enough(hass, setup_comp_4):
|
|||
|
||||
async def test_temp_change_ac_trigger_off_long_enough(hass, setup_comp_4):
|
||||
"""Test if temperature change turn ac on."""
|
||||
fake_changed = datetime.datetime(
|
||||
1918, 11, 11, 11, 11, 11, tzinfo=datetime.timezone.utc
|
||||
)
|
||||
fake_changed = datetime.datetime(1918, 11, 11, 11, 11, 11, tzinfo=dt_util.UTC)
|
||||
with patch(
|
||||
"homeassistant.helpers.condition.dt_util.utcnow", return_value=fake_changed
|
||||
):
|
||||
|
@ -801,9 +797,7 @@ async def test_temp_change_ac_trigger_on_not_long_enough_2(hass, setup_comp_5):
|
|||
|
||||
async def test_temp_change_ac_trigger_on_long_enough_2(hass, setup_comp_5):
|
||||
"""Test if temperature change turn ac on."""
|
||||
fake_changed = datetime.datetime(
|
||||
1918, 11, 11, 11, 11, 11, tzinfo=datetime.timezone.utc
|
||||
)
|
||||
fake_changed = datetime.datetime(1918, 11, 11, 11, 11, 11, tzinfo=dt_util.UTC)
|
||||
with patch(
|
||||
"homeassistant.helpers.condition.dt_util.utcnow", return_value=fake_changed
|
||||
):
|
||||
|
@ -829,9 +823,7 @@ async def test_temp_change_ac_trigger_off_not_long_enough_2(hass, setup_comp_5):
|
|||
|
||||
async def test_temp_change_ac_trigger_off_long_enough_2(hass, setup_comp_5):
|
||||
"""Test if temperature change turn ac on."""
|
||||
fake_changed = datetime.datetime(
|
||||
1918, 11, 11, 11, 11, 11, tzinfo=datetime.timezone.utc
|
||||
)
|
||||
fake_changed = datetime.datetime(1918, 11, 11, 11, 11, 11, tzinfo=dt_util.UTC)
|
||||
with patch(
|
||||
"homeassistant.helpers.condition.dt_util.utcnow", return_value=fake_changed
|
||||
):
|
||||
|
@ -919,9 +911,7 @@ async def test_temp_change_heater_trigger_on_not_long_enough(hass, setup_comp_6)
|
|||
|
||||
async def test_temp_change_heater_trigger_on_long_enough(hass, setup_comp_6):
|
||||
"""Test if temperature change turn heater on after min cycle."""
|
||||
fake_changed = datetime.datetime(
|
||||
1918, 11, 11, 11, 11, 11, tzinfo=datetime.timezone.utc
|
||||
)
|
||||
fake_changed = datetime.datetime(1918, 11, 11, 11, 11, 11, tzinfo=dt_util.UTC)
|
||||
with patch(
|
||||
"homeassistant.helpers.condition.dt_util.utcnow", return_value=fake_changed
|
||||
):
|
||||
|
@ -938,9 +928,7 @@ async def test_temp_change_heater_trigger_on_long_enough(hass, setup_comp_6):
|
|||
|
||||
async def test_temp_change_heater_trigger_off_long_enough(hass, setup_comp_6):
|
||||
"""Test if temperature change turn heater off after min cycle."""
|
||||
fake_changed = datetime.datetime(
|
||||
1918, 11, 11, 11, 11, 11, tzinfo=datetime.timezone.utc
|
||||
)
|
||||
fake_changed = datetime.datetime(1918, 11, 11, 11, 11, 11, tzinfo=dt_util.UTC)
|
||||
with patch(
|
||||
"homeassistant.helpers.condition.dt_util.utcnow", return_value=fake_changed
|
||||
):
|
||||
|
@ -1019,7 +1007,7 @@ async def test_temp_change_ac_trigger_on_long_enough_3(hass, setup_comp_7):
|
|||
_setup_sensor(hass, 30)
|
||||
await hass.async_block_till_done()
|
||||
await common.async_set_temperature(hass, 25)
|
||||
test_time = datetime.datetime.now(pytz.UTC)
|
||||
test_time = datetime.datetime.now(dt_util.UTC)
|
||||
async_fire_time_changed(hass, test_time)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 0
|
||||
|
@ -1042,7 +1030,7 @@ async def test_temp_change_ac_trigger_off_long_enough_3(hass, setup_comp_7):
|
|||
_setup_sensor(hass, 20)
|
||||
await hass.async_block_till_done()
|
||||
await common.async_set_temperature(hass, 25)
|
||||
test_time = datetime.datetime.now(pytz.UTC)
|
||||
test_time = datetime.datetime.now(dt_util.UTC)
|
||||
async_fire_time_changed(hass, test_time)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 0
|
||||
|
@ -1090,7 +1078,7 @@ async def test_temp_change_heater_trigger_on_long_enough_2(hass, setup_comp_8):
|
|||
_setup_sensor(hass, 20)
|
||||
await hass.async_block_till_done()
|
||||
await common.async_set_temperature(hass, 25)
|
||||
test_time = datetime.datetime.now(pytz.UTC)
|
||||
test_time = datetime.datetime.now(dt_util.UTC)
|
||||
async_fire_time_changed(hass, test_time)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 0
|
||||
|
@ -1113,7 +1101,7 @@ async def test_temp_change_heater_trigger_off_long_enough_2(hass, setup_comp_8):
|
|||
_setup_sensor(hass, 30)
|
||||
await hass.async_block_till_done()
|
||||
await common.async_set_temperature(hass, 25)
|
||||
test_time = datetime.datetime.now(pytz.UTC)
|
||||
test_time = datetime.datetime.now(dt_util.UTC)
|
||||
async_fire_time_changed(hass, test_time)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 0
|
||||
|
|
|
@ -6,7 +6,6 @@ import unittest
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from homeassistant import config as hass_config
|
||||
from homeassistant.components.history_stats import DOMAIN
|
||||
|
@ -82,7 +81,7 @@ class TestHistoryStatsSensor(unittest.TestCase):
|
|||
)
|
||||
def test_period_parsing(self, mock):
|
||||
"""Test the conversion from templates to period."""
|
||||
now = datetime(2019, 1, 1, 23, 30, 0, tzinfo=pytz.utc)
|
||||
now = datetime(2019, 1, 1, 23, 30, 0, tzinfo=dt_util.UTC)
|
||||
with patch("homeassistant.util.dt.now", return_value=now):
|
||||
today = Template(
|
||||
"{{ now().replace(hour=0).replace(minute=0).replace(second=0) }}",
|
||||
|
|
|
@ -26,7 +26,9 @@ def make_nyc_test_params(dtime, results, havdalah_offset=0):
|
|||
if isinstance(results, dict):
|
||||
time_zone = dt_util.get_time_zone("America/New_York")
|
||||
results = {
|
||||
key: time_zone.localize(value) if isinstance(value, datetime) else value
|
||||
key: value.replace(tzinfo=time_zone)
|
||||
if isinstance(value, datetime)
|
||||
else value
|
||||
for key, value in results.items()
|
||||
}
|
||||
return (
|
||||
|
@ -46,7 +48,9 @@ def make_jerusalem_test_params(dtime, results, havdalah_offset=0):
|
|||
if isinstance(results, dict):
|
||||
time_zone = dt_util.get_time_zone("Asia/Jerusalem")
|
||||
results = {
|
||||
key: time_zone.localize(value) if isinstance(value, datetime) else value
|
||||
key: value.replace(tzinfo=time_zone)
|
||||
if isinstance(value, datetime)
|
||||
else value
|
||||
for key, value in results.items()
|
||||
}
|
||||
return (
|
||||
|
|
|
@ -179,9 +179,9 @@ async def test_issur_melacha_sensor(
|
|||
):
|
||||
"""Test Issur Melacha sensor output."""
|
||||
time_zone = dt_util.get_time_zone(tzname)
|
||||
test_time = time_zone.localize(now)
|
||||
test_time = now.replace(tzinfo=time_zone)
|
||||
|
||||
hass.config.time_zone = time_zone
|
||||
hass.config.time_zone = tzname
|
||||
hass.config.latitude = latitude
|
||||
hass.config.longitude = longitude
|
||||
|
||||
|
@ -214,7 +214,7 @@ async def test_issur_melacha_sensor(
|
|||
[
|
||||
latitude,
|
||||
longitude,
|
||||
time_zone,
|
||||
tzname,
|
||||
HDATE_DEFAULT_ALTITUDE,
|
||||
diaspora,
|
||||
"english",
|
||||
|
@ -270,9 +270,9 @@ async def test_issur_melacha_sensor_update(
|
|||
):
|
||||
"""Test Issur Melacha sensor output."""
|
||||
time_zone = dt_util.get_time_zone(tzname)
|
||||
test_time = time_zone.localize(now)
|
||||
test_time = now.replace(tzinfo=time_zone)
|
||||
|
||||
hass.config.time_zone = time_zone
|
||||
hass.config.time_zone = tzname
|
||||
hass.config.latitude = latitude
|
||||
hass.config.longitude = longitude
|
||||
|
||||
|
|
|
@ -163,9 +163,9 @@ async def test_jewish_calendar_sensor(
|
|||
):
|
||||
"""Test Jewish calendar sensor output."""
|
||||
time_zone = dt_util.get_time_zone(tzname)
|
||||
test_time = time_zone.localize(now)
|
||||
test_time = now.replace(tzinfo=time_zone)
|
||||
|
||||
hass.config.time_zone = time_zone
|
||||
hass.config.time_zone = tzname
|
||||
hass.config.latitude = latitude
|
||||
hass.config.longitude = longitude
|
||||
|
||||
|
@ -188,7 +188,9 @@ async def test_jewish_calendar_sensor(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
result = (
|
||||
dt_util.as_utc(time_zone.localize(result)) if isinstance(result, dt) else result
|
||||
dt_util.as_utc(result.replace(tzinfo=time_zone))
|
||||
if isinstance(result, dt)
|
||||
else result
|
||||
)
|
||||
|
||||
sensor_object = hass.states.get(f"sensor.test_{sensor}")
|
||||
|
@ -506,9 +508,9 @@ async def test_shabbat_times_sensor(
|
|||
):
|
||||
"""Test sensor output for upcoming shabbat/yomtov times."""
|
||||
time_zone = dt_util.get_time_zone(tzname)
|
||||
test_time = time_zone.localize(now)
|
||||
test_time = now.replace(tzinfo=time_zone)
|
||||
|
||||
hass.config.time_zone = time_zone
|
||||
hass.config.time_zone = tzname
|
||||
hass.config.latitude = latitude
|
||||
hass.config.longitude = longitude
|
||||
|
||||
|
@ -559,7 +561,7 @@ async def test_shabbat_times_sensor(
|
|||
[
|
||||
latitude,
|
||||
longitude,
|
||||
time_zone,
|
||||
tzname,
|
||||
HDATE_DEFAULT_ALTITUDE,
|
||||
diaspora,
|
||||
language,
|
||||
|
@ -593,7 +595,7 @@ OMER_TEST_IDS = [
|
|||
@pytest.mark.parametrize(["test_time", "result"], OMER_PARAMS, ids=OMER_TEST_IDS)
|
||||
async def test_omer_sensor(hass, legacy_patchable_time, test_time, result):
|
||||
"""Test Omer Count sensor output."""
|
||||
test_time = hass.config.time_zone.localize(test_time)
|
||||
test_time = test_time.replace(tzinfo=dt_util.get_time_zone(hass.config.time_zone))
|
||||
|
||||
with alter_time(test_time):
|
||||
assert await async_setup_component(
|
||||
|
@ -627,7 +629,7 @@ DAFYOMI_TEST_IDS = [
|
|||
@pytest.mark.parametrize(["test_time", "result"], DAFYOMI_PARAMS, ids=DAFYOMI_TEST_IDS)
|
||||
async def test_dafyomi_sensor(hass, legacy_patchable_time, test_time, result):
|
||||
"""Test Daf Yomi sensor output."""
|
||||
test_time = hass.config.time_zone.localize(test_time)
|
||||
test_time = test_time.replace(tzinfo=dt_util.get_time_zone(hass.config.time_zone))
|
||||
|
||||
with alter_time(test_time):
|
||||
assert await async_setup_component(
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from pytz import timezone
|
||||
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components.pvpc_hourly_pricing import ATTR_TARIFF, DOMAIN
|
||||
from homeassistant.const import CONF_NAME
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .conftest import check_valid_state
|
||||
|
||||
|
@ -26,7 +25,7 @@ async def test_config_flow(
|
|||
- Check abort when trying to config another with same tariff
|
||||
- Check removal and add again to check state restoration
|
||||
"""
|
||||
hass.config.time_zone = timezone("Europe/Madrid")
|
||||
hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid")
|
||||
mock_data = {"return_time": datetime(2019, 10, 26, 14, 0, tzinfo=date_util.UTC)}
|
||||
|
||||
def mock_now():
|
||||
|
|
|
@ -3,12 +3,11 @@ from datetime import datetime, timedelta
|
|||
import logging
|
||||
from unittest.mock import patch
|
||||
|
||||
from pytz import timezone
|
||||
|
||||
from homeassistant.components.pvpc_hourly_pricing import ATTR_TARIFF, DOMAIN
|
||||
from homeassistant.const import CONF_NAME
|
||||
from homeassistant.core import ATTR_NOW, EVENT_TIME_CHANGED
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .conftest import check_valid_state
|
||||
|
||||
|
@ -32,7 +31,7 @@ async def test_sensor_availability(
|
|||
hass, caplog, legacy_patchable_time, pvpc_aioclient_mock: AiohttpClientMocker
|
||||
):
|
||||
"""Test sensor availability and handling of cloud access."""
|
||||
hass.config.time_zone = timezone("Europe/Madrid")
|
||||
hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid")
|
||||
config = {DOMAIN: [{CONF_NAME: "test_dst", ATTR_TARIFF: "discrimination"}]}
|
||||
mock_data = {"return_time": datetime(2019, 10, 27, 20, 0, 0, tzinfo=date_util.UTC)}
|
||||
|
||||
|
|
|
@ -170,5 +170,5 @@ def _process_timestamp(ts):
|
|||
if ts is None:
|
||||
return None
|
||||
if ts.tzinfo is None:
|
||||
return dt_util.UTC.localize(ts)
|
||||
return ts.replace(tzinfo=dt_util.UTC)
|
||||
return dt_util.as_utc(ts)
|
||||
|
|
|
@ -604,7 +604,7 @@ def test_auto_purge(hass_recorder):
|
|||
#
|
||||
# The clock is started at 4:15am then advanced forward below
|
||||
now = dt_util.utcnow()
|
||||
test_time = tz.localize(datetime(now.year + 2, 1, 1, 4, 15, 0))
|
||||
test_time = datetime(now.year + 2, 1, 1, 4, 15, 0, tzinfo=tz)
|
||||
run_tasks_at_time(hass, test_time)
|
||||
|
||||
with patch(
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||
|
||||
|
@ -144,11 +143,11 @@ async def test_process_timestamp():
|
|||
"""Test processing time stamp to UTC."""
|
||||
datetime_with_tzinfo = datetime(2016, 7, 9, 11, 0, 0, tzinfo=dt.UTC)
|
||||
datetime_without_tzinfo = datetime(2016, 7, 9, 11, 0, 0)
|
||||
est = pytz.timezone("US/Eastern")
|
||||
est = dt_util.get_time_zone("US/Eastern")
|
||||
datetime_est_timezone = datetime(2016, 7, 9, 11, 0, 0, tzinfo=est)
|
||||
nst = pytz.timezone("Canada/Newfoundland")
|
||||
nst = dt_util.get_time_zone("Canada/Newfoundland")
|
||||
datetime_nst_timezone = datetime(2016, 7, 9, 11, 0, 0, tzinfo=nst)
|
||||
hst = pytz.timezone("US/Hawaii")
|
||||
hst = dt_util.get_time_zone("US/Hawaii")
|
||||
datetime_hst_timezone = datetime(2016, 7, 9, 11, 0, 0, tzinfo=hst)
|
||||
|
||||
assert process_timestamp(datetime_with_tzinfo) == datetime(
|
||||
|
@ -158,13 +157,13 @@ async def test_process_timestamp():
|
|||
2016, 7, 9, 11, 0, 0, tzinfo=dt.UTC
|
||||
)
|
||||
assert process_timestamp(datetime_est_timezone) == datetime(
|
||||
2016, 7, 9, 15, 56, tzinfo=dt.UTC
|
||||
2016, 7, 9, 15, 0, tzinfo=dt.UTC
|
||||
)
|
||||
assert process_timestamp(datetime_nst_timezone) == datetime(
|
||||
2016, 7, 9, 14, 31, tzinfo=dt.UTC
|
||||
2016, 7, 9, 13, 30, tzinfo=dt.UTC
|
||||
)
|
||||
assert process_timestamp(datetime_hst_timezone) == datetime(
|
||||
2016, 7, 9, 21, 31, tzinfo=dt.UTC
|
||||
2016, 7, 9, 21, 0, tzinfo=dt.UTC
|
||||
)
|
||||
assert process_timestamp(None) is None
|
||||
|
||||
|
@ -173,13 +172,13 @@ async def test_process_timestamp_to_utc_isoformat():
|
|||
"""Test processing time stamp to UTC isoformat."""
|
||||
datetime_with_tzinfo = datetime(2016, 7, 9, 11, 0, 0, tzinfo=dt.UTC)
|
||||
datetime_without_tzinfo = datetime(2016, 7, 9, 11, 0, 0)
|
||||
est = pytz.timezone("US/Eastern")
|
||||
est = dt_util.get_time_zone("US/Eastern")
|
||||
datetime_est_timezone = datetime(2016, 7, 9, 11, 0, 0, tzinfo=est)
|
||||
est = pytz.timezone("US/Eastern")
|
||||
est = dt_util.get_time_zone("US/Eastern")
|
||||
datetime_est_timezone = datetime(2016, 7, 9, 11, 0, 0, tzinfo=est)
|
||||
nst = pytz.timezone("Canada/Newfoundland")
|
||||
nst = dt_util.get_time_zone("Canada/Newfoundland")
|
||||
datetime_nst_timezone = datetime(2016, 7, 9, 11, 0, 0, tzinfo=nst)
|
||||
hst = pytz.timezone("US/Hawaii")
|
||||
hst = dt_util.get_time_zone("US/Hawaii")
|
||||
datetime_hst_timezone = datetime(2016, 7, 9, 11, 0, 0, tzinfo=hst)
|
||||
|
||||
assert (
|
||||
|
@ -192,15 +191,15 @@ async def test_process_timestamp_to_utc_isoformat():
|
|||
)
|
||||
assert (
|
||||
process_timestamp_to_utc_isoformat(datetime_est_timezone)
|
||||
== "2016-07-09T15:56:00+00:00"
|
||||
== "2016-07-09T15:00:00+00:00"
|
||||
)
|
||||
assert (
|
||||
process_timestamp_to_utc_isoformat(datetime_nst_timezone)
|
||||
== "2016-07-09T14:31:00+00:00"
|
||||
== "2016-07-09T13:30:00+00:00"
|
||||
)
|
||||
assert (
|
||||
process_timestamp_to_utc_isoformat(datetime_hst_timezone)
|
||||
== "2016-07-09T21:31:00+00:00"
|
||||
== "2016-07-09T21:00:00+00:00"
|
||||
)
|
||||
assert process_timestamp_to_utc_isoformat(None) is None
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ def calls(hass):
|
|||
def setup_comp(hass):
|
||||
"""Initialize components."""
|
||||
mock_component(hass, "group")
|
||||
dt_util.set_default_time_zone(hass.config.time_zone)
|
||||
hass.config.set_time_zone(hass.config.time_zone)
|
||||
hass.loop.run_until_complete(
|
||||
async_setup_component(hass, sun.DOMAIN, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
|
||||
)
|
||||
|
|
|
@ -3,7 +3,6 @@ from datetime import datetime, timedelta
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from homeassistant.const import STATE_OFF, STATE_ON
|
||||
import homeassistant.core as ha
|
||||
|
@ -61,7 +60,7 @@ async def test_setup_no_sensors(hass):
|
|||
|
||||
async def test_in_period_on_start(hass):
|
||||
"""Test simple setting."""
|
||||
test_time = datetime(2019, 1, 10, 18, 43, 0, tzinfo=hass.config.time_zone)
|
||||
test_time = datetime(2019, 1, 10, 18, 43, 0, tzinfo=dt_util.UTC)
|
||||
config = {
|
||||
"binary_sensor": [
|
||||
{
|
||||
|
@ -85,7 +84,7 @@ async def test_in_period_on_start(hass):
|
|||
|
||||
async def test_midnight_turnover_before_midnight_inside_period(hass):
|
||||
"""Test midnight turnover setting before midnight inside period ."""
|
||||
test_time = datetime(2019, 1, 10, 22, 30, 0, tzinfo=hass.config.time_zone)
|
||||
test_time = datetime(2019, 1, 10, 22, 30, 0, tzinfo=dt_util.UTC)
|
||||
config = {
|
||||
"binary_sensor": [
|
||||
{"platform": "tod", "name": "Night", "after": "22:00", "before": "5:00"}
|
||||
|
@ -104,9 +103,7 @@ async def test_midnight_turnover_before_midnight_inside_period(hass):
|
|||
|
||||
async def test_midnight_turnover_after_midnight_inside_period(hass):
|
||||
"""Test midnight turnover setting before midnight inside period ."""
|
||||
test_time = hass.config.time_zone.localize(
|
||||
datetime(2019, 1, 10, 21, 0, 0)
|
||||
).astimezone(pytz.UTC)
|
||||
test_time = datetime(2019, 1, 10, 21, 0, 0, tzinfo=dt_util.UTC)
|
||||
config = {
|
||||
"binary_sensor": [
|
||||
{"platform": "tod", "name": "Night", "after": "22:00", "before": "5:00"}
|
||||
|
@ -140,9 +137,7 @@ async def test_midnight_turnover_after_midnight_inside_period(hass):
|
|||
|
||||
async def test_midnight_turnover_before_midnight_outside_period(hass):
|
||||
"""Test midnight turnover setting before midnight outside period."""
|
||||
test_time = hass.config.time_zone.localize(
|
||||
datetime(2019, 1, 10, 20, 30, 0)
|
||||
).astimezone(pytz.UTC)
|
||||
test_time = datetime(2019, 1, 10, 20, 30, 0, tzinfo=dt_util.UTC)
|
||||
config = {
|
||||
"binary_sensor": [
|
||||
{"platform": "tod", "name": "Night", "after": "22:00", "before": "5:00"}
|
||||
|
@ -161,9 +156,7 @@ async def test_midnight_turnover_before_midnight_outside_period(hass):
|
|||
|
||||
async def test_midnight_turnover_after_midnight_outside_period(hass):
|
||||
"""Test midnight turnover setting before midnight inside period ."""
|
||||
test_time = hass.config.time_zone.localize(
|
||||
datetime(2019, 1, 10, 20, 0, 0)
|
||||
).astimezone(pytz.UTC)
|
||||
test_time = datetime(2019, 1, 10, 20, 0, 0, tzinfo=dt_util.UTC)
|
||||
|
||||
config = {
|
||||
"binary_sensor": [
|
||||
|
@ -180,9 +173,7 @@ async def test_midnight_turnover_after_midnight_outside_period(hass):
|
|||
state = hass.states.get("binary_sensor.night")
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
switchover_time = hass.config.time_zone.localize(
|
||||
datetime(2019, 1, 11, 4, 59, 0)
|
||||
).astimezone(pytz.UTC)
|
||||
switchover_time = datetime(2019, 1, 11, 4, 59, 0, tzinfo=dt_util.UTC)
|
||||
with patch(
|
||||
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||
return_value=switchover_time,
|
||||
|
@ -210,9 +201,7 @@ async def test_midnight_turnover_after_midnight_outside_period(hass):
|
|||
|
||||
async def test_from_sunrise_to_sunset(hass):
|
||||
"""Test period from sunrise to sunset."""
|
||||
test_time = hass.config.time_zone.localize(datetime(2019, 1, 12)).astimezone(
|
||||
pytz.UTC
|
||||
)
|
||||
test_time = datetime(2019, 1, 12, tzinfo=dt_util.UTC)
|
||||
sunrise = dt_util.as_local(
|
||||
get_astral_event_date(hass, "sunrise", dt_util.as_utc(test_time))
|
||||
)
|
||||
|
@ -311,9 +300,7 @@ async def test_from_sunrise_to_sunset(hass):
|
|||
|
||||
async def test_from_sunset_to_sunrise(hass):
|
||||
"""Test period from sunset to sunrise."""
|
||||
test_time = hass.config.time_zone.localize(datetime(2019, 1, 12)).astimezone(
|
||||
pytz.UTC
|
||||
)
|
||||
test_time = datetime(2019, 1, 12, tzinfo=dt_util.UTC)
|
||||
sunset = dt_util.as_local(get_astral_event_date(hass, "sunset", test_time))
|
||||
sunrise = dt_util.as_local(get_astral_event_next(hass, "sunrise", sunset))
|
||||
# assert sunset == sunrise
|
||||
|
@ -405,13 +392,13 @@ async def test_from_sunset_to_sunrise(hass):
|
|||
|
||||
async def test_offset(hass):
|
||||
"""Test offset."""
|
||||
after = hass.config.time_zone.localize(datetime(2019, 1, 10, 18, 0, 0)).astimezone(
|
||||
pytz.UTC
|
||||
) + timedelta(hours=1, minutes=34)
|
||||
after = datetime(2019, 1, 10, 18, 0, 0, tzinfo=dt_util.UTC) + timedelta(
|
||||
hours=1, minutes=34
|
||||
)
|
||||
|
||||
before = hass.config.time_zone.localize(datetime(2019, 1, 10, 22, 0, 0)).astimezone(
|
||||
pytz.UTC
|
||||
) + timedelta(hours=1, minutes=45)
|
||||
before = datetime(2019, 1, 10, 22, 0, 0, tzinfo=dt_util.UTC) + timedelta(
|
||||
hours=1, minutes=45
|
||||
)
|
||||
|
||||
entity_id = "binary_sensor.evening"
|
||||
config = {
|
||||
|
@ -484,9 +471,9 @@ async def test_offset(hass):
|
|||
|
||||
async def test_offset_overnight(hass):
|
||||
"""Test offset overnight."""
|
||||
after = hass.config.time_zone.localize(datetime(2019, 1, 10, 18, 0, 0)).astimezone(
|
||||
pytz.UTC
|
||||
) + timedelta(hours=1, minutes=34)
|
||||
after = datetime(2019, 1, 10, 18, 0, 0, tzinfo=dt_util.UTC) + timedelta(
|
||||
hours=1, minutes=34
|
||||
)
|
||||
entity_id = "binary_sensor.evening"
|
||||
config = {
|
||||
"binary_sensor": [
|
||||
|
@ -528,9 +515,7 @@ async def test_norwegian_case_winter(hass):
|
|||
hass.config.latitude = 69.6
|
||||
hass.config.longitude = 18.8
|
||||
|
||||
test_time = hass.config.time_zone.localize(datetime(2010, 1, 1)).astimezone(
|
||||
pytz.UTC
|
||||
)
|
||||
test_time = datetime(2010, 1, 1, tzinfo=dt_util.UTC)
|
||||
sunrise = dt_util.as_local(
|
||||
get_astral_event_next(hass, "sunrise", dt_util.as_utc(test_time))
|
||||
)
|
||||
|
@ -645,9 +630,7 @@ async def test_norwegian_case_summer(hass):
|
|||
hass.config.longitude = 18.8
|
||||
hass.config.elevation = 10.0
|
||||
|
||||
test_time = hass.config.time_zone.localize(datetime(2010, 6, 1)).astimezone(
|
||||
pytz.UTC
|
||||
)
|
||||
test_time = datetime(2010, 6, 1, tzinfo=dt_util.UTC)
|
||||
|
||||
sunrise = dt_util.as_local(
|
||||
get_astral_event_next(hass, "sunrise", dt_util.as_utc(test_time))
|
||||
|
@ -759,9 +742,7 @@ async def test_norwegian_case_summer(hass):
|
|||
|
||||
async def test_sun_offset(hass):
|
||||
"""Test sun event with offset."""
|
||||
test_time = hass.config.time_zone.localize(datetime(2019, 1, 12)).astimezone(
|
||||
pytz.UTC
|
||||
)
|
||||
test_time = datetime(2019, 1, 12, tzinfo=dt_util.UTC)
|
||||
sunrise = dt_util.as_local(
|
||||
get_astral_event_date(hass, "sunrise", dt_util.as_utc(test_time))
|
||||
+ timedelta(hours=-1, minutes=-30)
|
||||
|
@ -881,30 +862,27 @@ async def test_sun_offset(hass):
|
|||
|
||||
async def test_dst(hass):
|
||||
"""Test sun event with offset."""
|
||||
hass.config.time_zone = pytz.timezone("CET")
|
||||
test_time = hass.config.time_zone.localize(
|
||||
datetime(2019, 3, 30, 3, 0, 0)
|
||||
).astimezone(pytz.UTC)
|
||||
hass.config.time_zone = "CET"
|
||||
test_time = datetime(2019, 3, 30, 3, 0, 0, tzinfo=dt_util.UTC)
|
||||
config = {
|
||||
"binary_sensor": [
|
||||
{"platform": "tod", "name": "Day", "after": "2:30", "before": "2:40"}
|
||||
]
|
||||
}
|
||||
# Test DST:
|
||||
# after 2019-03-30 03:00 CET the next update should ge scheduled
|
||||
# at 3:30 not 2:30 local time
|
||||
# Internally the
|
||||
entity_id = "binary_sensor.day"
|
||||
testtime = test_time
|
||||
with patch(
|
||||
"homeassistant.components.tod.binary_sensor.dt_util.utcnow",
|
||||
return_value=testtime,
|
||||
return_value=test_time,
|
||||
):
|
||||
await async_setup_component(hass, "binary_sensor", config)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.attributes["after"] == "2019-03-31T03:30:00+02:00"
|
||||
assert state.attributes["before"] == "2019-03-31T03:40:00+02:00"
|
||||
assert state.attributes["next_update"] == "2019-03-31T03:30:00+02:00"
|
||||
assert state.attributes["after"] == "2019-03-30T03:30:00+01:00"
|
||||
assert state.attributes["before"] == "2019-03-30T03:40:00+01:00"
|
||||
assert state.attributes["next_update"] == "2019-03-30T03:30:00+01:00"
|
||||
assert state.state == STATE_OFF
|
||||
|
|
|
@ -7,7 +7,6 @@ from urllib.parse import urlparse
|
|||
|
||||
from aiohttp.test_utils import TestClient
|
||||
import arrow
|
||||
import pytz
|
||||
from withings_api.common import (
|
||||
MeasureGetMeasResponse,
|
||||
NotifyAppli,
|
||||
|
@ -40,6 +39,7 @@ from homeassistant.core import HomeAssistant
|
|||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
from homeassistant.helpers.config_entry_oauth2_flow import AUTH_CALLBACK_PATH
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||
|
||||
|
@ -77,7 +77,7 @@ def new_profile_config(
|
|||
measuregrps=[],
|
||||
more=False,
|
||||
offset=0,
|
||||
timezone=pytz.UTC,
|
||||
timezone=dt_util.UTC,
|
||||
updatetime=arrow.get(12345),
|
||||
),
|
||||
api_response_sleep_get_summary=api_response_sleep_get_summary
|
||||
|
|
|
@ -3,7 +3,6 @@ from typing import Any
|
|||
from unittest.mock import patch
|
||||
|
||||
import arrow
|
||||
import pytz
|
||||
from withings_api.common import (
|
||||
GetSleepSummaryData,
|
||||
GetSleepSummarySerie,
|
||||
|
@ -29,6 +28,7 @@ from homeassistant.components.withings.const import Measurement
|
|||
from homeassistant.core import HomeAssistant, State
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity_registry import EntityRegistry
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .common import ComponentFactory, new_profile_config
|
||||
|
||||
|
@ -189,7 +189,7 @@ PERSON0 = new_profile_config(
|
|||
),
|
||||
),
|
||||
more=False,
|
||||
timezone=pytz.UTC,
|
||||
timezone=dt_util.UTC,
|
||||
updatetime=arrow.get("2019-08-01"),
|
||||
offset=0,
|
||||
),
|
||||
|
@ -198,7 +198,7 @@ PERSON0 = new_profile_config(
|
|||
offset=0,
|
||||
series=(
|
||||
GetSleepSummarySerie(
|
||||
timezone=pytz.UTC,
|
||||
timezone=dt_util.UTC,
|
||||
model=SleepModel.SLEEP_MONITOR,
|
||||
startdate=arrow.get("2019-02-01"),
|
||||
enddate=arrow.get("2019-02-01"),
|
||||
|
@ -225,7 +225,7 @@ PERSON0 = new_profile_config(
|
|||
),
|
||||
),
|
||||
GetSleepSummarySerie(
|
||||
timezone=pytz.UTC,
|
||||
timezone=dt_util.UTC,
|
||||
model=SleepModel.SLEEP_MONITOR,
|
||||
startdate=arrow.get("2019-02-01"),
|
||||
enddate=arrow.get("2019-02-01"),
|
||||
|
|
|
@ -5,7 +5,6 @@ from unittest.mock import MagicMock, patch
|
|||
|
||||
from miio import DeviceException
|
||||
import pytest
|
||||
from pytz import utc
|
||||
|
||||
from homeassistant.components.vacuum import (
|
||||
ATTR_BATTERY_ICON,
|
||||
|
@ -55,6 +54,7 @@ from homeassistant.const import (
|
|||
STATE_ON,
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .test_config_flow import TEST_MAC
|
||||
|
||||
|
@ -106,12 +106,12 @@ def mirobo_is_got_error_fixture():
|
|||
mock_timer_1 = MagicMock()
|
||||
mock_timer_1.enabled = True
|
||||
mock_timer_1.cron = "5 5 1 8 1"
|
||||
mock_timer_1.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc)
|
||||
mock_timer_1.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=dt_util.UTC)
|
||||
|
||||
mock_timer_2 = MagicMock()
|
||||
mock_timer_2.enabled = False
|
||||
mock_timer_2.cron = "5 5 1 8 2"
|
||||
mock_timer_2.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc)
|
||||
mock_timer_2.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=dt_util.UTC)
|
||||
|
||||
mock_vacuum.timer.return_value = [mock_timer_1, mock_timer_2]
|
||||
|
||||
|
@ -180,12 +180,12 @@ def mirobo_is_on_fixture():
|
|||
mock_timer_1 = MagicMock()
|
||||
mock_timer_1.enabled = True
|
||||
mock_timer_1.cron = "5 5 1 8 1"
|
||||
mock_timer_1.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc)
|
||||
mock_timer_1.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=dt_util.UTC)
|
||||
|
||||
mock_timer_2 = MagicMock()
|
||||
mock_timer_2.enabled = False
|
||||
mock_timer_2.cron = "5 5 1 8 2"
|
||||
mock_timer_2.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc)
|
||||
mock_timer_2.next_schedule = datetime(2020, 5, 23, 13, 21, 10, tzinfo=dt_util.UTC)
|
||||
|
||||
mock_vacuum.timer.return_value = [mock_timer_1, mock_timer_2]
|
||||
|
||||
|
@ -255,12 +255,12 @@ async def test_xiaomi_vacuum_services(hass, caplog, mock_mirobo_is_got_error):
|
|||
{
|
||||
"enabled": True,
|
||||
"cron": "5 5 1 8 1",
|
||||
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc),
|
||||
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=dt_util.UTC),
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"cron": "5 5 1 8 2",
|
||||
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc),
|
||||
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=dt_util.UTC),
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -353,12 +353,12 @@ async def test_xiaomi_specific_services(hass, caplog, mock_mirobo_is_on):
|
|||
{
|
||||
"enabled": True,
|
||||
"cron": "5 5 1 8 1",
|
||||
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc),
|
||||
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=dt_util.UTC),
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"cron": "5 5 1 8 2",
|
||||
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=utc),
|
||||
"next_schedule": datetime(2020, 5, 23, 13, 21, 10, tzinfo=dt_util.UTC),
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ from datetime import datetime
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from pytz import utc
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.bootstrap import async_setup_component
|
||||
|
@ -19,6 +18,7 @@ from homeassistant.components.zwave import (
|
|||
from homeassistant.components.zwave.binary_sensor import get_device
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_NAME
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.common import async_fire_time_changed, mock_registry
|
||||
from tests.mock.zwave import MockEntityValues, MockNetwork, MockNode, MockValue
|
||||
|
@ -140,7 +140,7 @@ async def test_auto_heal_midnight(hass, mock_openzwave, legacy_patchable_time):
|
|||
network = hass.data[zwave.DATA_NETWORK]
|
||||
assert not network.heal.called
|
||||
|
||||
time = utc.localize(datetime(2017, 5, 6, 0, 0, 0))
|
||||
time = datetime(2017, 5, 6, 0, 0, 0, tzinfo=dt_util.UTC)
|
||||
async_fire_time_changed(hass, time)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done()
|
||||
|
@ -156,7 +156,7 @@ async def test_auto_heal_disabled(hass, mock_openzwave):
|
|||
network = hass.data[zwave.DATA_NETWORK]
|
||||
assert not network.heal.called
|
||||
|
||||
time = utc.localize(datetime(2017, 5, 6, 0, 0, 0))
|
||||
time = datetime(2017, 5, 6, 0, 0, 0, tzinfo=dt_util.UTC)
|
||||
async_fire_time_changed(hass, time)
|
||||
await hass.async_block_till_done()
|
||||
assert not network.heal.called
|
||||
|
|
|
@ -27,7 +27,7 @@ def calls(hass):
|
|||
@pytest.fixture(autouse=True)
|
||||
def setup_comp(hass):
|
||||
"""Initialize components."""
|
||||
dt_util.set_default_time_zone(hass.config.time_zone)
|
||||
hass.config.set_time_zone(hass.config.time_zone)
|
||||
hass.loop.run_until_complete(
|
||||
async_setup_component(hass, sun.DOMAIN, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
|
||||
)
|
||||
|
|
|
@ -2908,8 +2908,8 @@ async def test_periodic_task_entering_dst(hass):
|
|||
specific_runs = []
|
||||
|
||||
now = dt_util.utcnow()
|
||||
time_that_will_not_match_right_away = timezone.localize(
|
||||
datetime(now.year + 1, 3, 25, 2, 31, 0)
|
||||
time_that_will_not_match_right_away = datetime(
|
||||
now.year + 1, 3, 25, 2, 31, 0, tzinfo=timezone
|
||||
)
|
||||
|
||||
with patch(
|
||||
|
@ -2924,25 +2924,25 @@ async def test_periodic_task_entering_dst(hass):
|
|||
)
|
||||
|
||||
async_fire_time_changed(
|
||||
hass, timezone.localize(datetime(now.year + 1, 3, 25, 1, 50, 0, 999999))
|
||||
hass, datetime(now.year + 1, 3, 25, 1, 50, 0, 999999, tzinfo=timezone)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 0
|
||||
|
||||
async_fire_time_changed(
|
||||
hass, timezone.localize(datetime(now.year + 1, 3, 25, 3, 50, 0, 999999))
|
||||
hass, datetime(now.year + 1, 3, 25, 3, 50, 0, 999999, tzinfo=timezone)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 0
|
||||
|
||||
async_fire_time_changed(
|
||||
hass, timezone.localize(datetime(now.year + 1, 3, 26, 1, 50, 0, 999999))
|
||||
hass, datetime(now.year + 1, 3, 26, 1, 50, 0, 999999, tzinfo=timezone)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 0
|
||||
|
||||
async_fire_time_changed(
|
||||
hass, timezone.localize(datetime(now.year + 1, 3, 26, 2, 50, 0, 999999))
|
||||
hass, datetime(now.year + 1, 3, 26, 2, 50, 0, 999999, tzinfo=timezone)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 1
|
||||
|
@ -2958,8 +2958,8 @@ async def test_periodic_task_leaving_dst(hass):
|
|||
|
||||
now = dt_util.utcnow()
|
||||
|
||||
time_that_will_not_match_right_away = timezone.localize(
|
||||
datetime(now.year + 1, 10, 28, 2, 28, 0), is_dst=True
|
||||
time_that_will_not_match_right_away = datetime(
|
||||
now.year + 1, 10, 28, 2, 28, 0, tzinfo=timezone, fold=1
|
||||
)
|
||||
|
||||
with patch(
|
||||
|
@ -2974,46 +2974,33 @@ async def test_periodic_task_leaving_dst(hass):
|
|||
)
|
||||
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
timezone.localize(
|
||||
datetime(now.year + 1, 10, 28, 2, 5, 0, 999999), is_dst=False
|
||||
),
|
||||
hass, datetime(now.year + 1, 10, 28, 2, 5, 0, 999999, tzinfo=timezone, fold=0)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 0
|
||||
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
timezone.localize(
|
||||
datetime(now.year + 1, 10, 28, 2, 55, 0, 999999), is_dst=False
|
||||
),
|
||||
hass, datetime(now.year + 1, 10, 28, 2, 55, 0, 999999, tzinfo=timezone, fold=0)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 1
|
||||
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
timezone.localize(
|
||||
datetime(now.year + 2, 10, 28, 2, 45, 0, 999999), is_dst=True
|
||||
),
|
||||
datetime(now.year + 2, 10, 28, 2, 45, 0, 999999, tzinfo=timezone, fold=1),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 2
|
||||
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
timezone.localize(
|
||||
datetime(now.year + 2, 10, 28, 2, 55, 0, 999999), is_dst=True
|
||||
),
|
||||
datetime(now.year + 2, 10, 28, 2, 55, 0, 999999, tzinfo=timezone, fold=1),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 2
|
||||
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
timezone.localize(
|
||||
datetime(now.year + 2, 10, 28, 2, 55, 0, 999999), is_dst=True
|
||||
),
|
||||
hass, datetime(now.year + 2, 10, 28, 2, 55, 0, 999999, tzinfo=timezone, fold=1)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(specific_runs) == 2
|
||||
|
@ -3224,7 +3211,7 @@ async def test_async_track_point_in_time_cancel(hass):
|
|||
await asyncio.sleep(0.2)
|
||||
|
||||
assert len(times) == 1
|
||||
assert times[0].tzinfo.zone == "US/Hawaii"
|
||||
assert "US/Hawaii" in str(times[0].tzinfo)
|
||||
|
||||
|
||||
async def test_async_track_entity_registry_updated_event(hass):
|
||||
|
|
|
@ -5,7 +5,6 @@ import random
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import group
|
||||
|
@ -763,7 +762,7 @@ def test_render_with_possible_json_value_non_string_value(hass):
|
|||
hass,
|
||||
)
|
||||
value = datetime(2019, 1, 18, 12, 13, 14)
|
||||
expected = str(pytz.utc.localize(value))
|
||||
expected = str(value.replace(tzinfo=dt_util.UTC))
|
||||
assert tpl.async_render_with_possible_json_value(value) == expected
|
||||
|
||||
|
||||
|
|
|
@ -374,7 +374,7 @@ async def test_loading_configuration_from_storage(hass, hass_storage):
|
|||
assert hass.config.elevation == 10
|
||||
assert hass.config.location_name == "Home"
|
||||
assert hass.config.units.name == CONF_UNIT_SYSTEM_METRIC
|
||||
assert hass.config.time_zone.zone == "Europe/Copenhagen"
|
||||
assert hass.config.time_zone == "Europe/Copenhagen"
|
||||
assert hass.config.external_url == "https://www.example.com"
|
||||
assert hass.config.internal_url == "http://example.local"
|
||||
assert len(hass.config.allowlist_external_dirs) == 3
|
||||
|
@ -405,7 +405,7 @@ async def test_loading_configuration_from_storage_with_yaml_only(hass, hass_stor
|
|||
assert hass.config.elevation == 10
|
||||
assert hass.config.location_name == "Home"
|
||||
assert hass.config.units.name == CONF_UNIT_SYSTEM_METRIC
|
||||
assert hass.config.time_zone.zone == "Europe/Copenhagen"
|
||||
assert hass.config.time_zone == "Europe/Copenhagen"
|
||||
assert len(hass.config.allowlist_external_dirs) == 3
|
||||
assert "/etc" in hass.config.allowlist_external_dirs
|
||||
assert hass.config.media_dirs == {"mymedia": "/usr"}
|
||||
|
@ -463,7 +463,7 @@ async def test_override_stored_configuration(hass, hass_storage):
|
|||
assert hass.config.elevation == 10
|
||||
assert hass.config.location_name == "Home"
|
||||
assert hass.config.units.name == CONF_UNIT_SYSTEM_METRIC
|
||||
assert hass.config.time_zone.zone == "Europe/Copenhagen"
|
||||
assert hass.config.time_zone == "Europe/Copenhagen"
|
||||
assert len(hass.config.allowlist_external_dirs) == 3
|
||||
assert "/etc" in hass.config.allowlist_external_dirs
|
||||
assert hass.config.config_source == config_util.SOURCE_YAML
|
||||
|
@ -493,7 +493,7 @@ async def test_loading_configuration(hass):
|
|||
assert hass.config.elevation == 25
|
||||
assert hass.config.location_name == "Huis"
|
||||
assert hass.config.units.name == CONF_UNIT_SYSTEM_IMPERIAL
|
||||
assert hass.config.time_zone.zone == "America/New_York"
|
||||
assert hass.config.time_zone == "America/New_York"
|
||||
assert hass.config.external_url == "https://www.example.com"
|
||||
assert hass.config.internal_url == "http://example.local"
|
||||
assert len(hass.config.allowlist_external_dirs) == 3
|
||||
|
@ -525,7 +525,7 @@ async def test_loading_configuration_temperature_unit(hass):
|
|||
assert hass.config.elevation == 25
|
||||
assert hass.config.location_name == "Huis"
|
||||
assert hass.config.units.name == CONF_UNIT_SYSTEM_METRIC
|
||||
assert hass.config.time_zone.zone == "America/New_York"
|
||||
assert hass.config.time_zone == "America/New_York"
|
||||
assert hass.config.external_url == "https://www.example.com"
|
||||
assert hass.config.internal_url == "http://example.local"
|
||||
assert hass.config.config_source == config_util.SOURCE_YAML
|
||||
|
|
|
@ -9,7 +9,6 @@ from tempfile import TemporaryDirectory
|
|||
from unittest.mock import MagicMock, Mock, PropertyMock, patch
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
|
@ -44,7 +43,7 @@ from homeassistant.util.unit_system import METRIC_SYSTEM
|
|||
|
||||
from tests.common import async_capture_events, async_mock_service
|
||||
|
||||
PST = pytz.timezone("America/Los_Angeles")
|
||||
PST = dt_util.get_time_zone("America/Los_Angeles")
|
||||
|
||||
|
||||
def test_split_entity_id():
|
||||
|
@ -877,7 +876,7 @@ def test_config_defaults():
|
|||
assert config.longitude == 0
|
||||
assert config.elevation == 0
|
||||
assert config.location_name == "Home"
|
||||
assert config.time_zone == dt_util.UTC
|
||||
assert config.time_zone == "UTC"
|
||||
assert config.internal_url is None
|
||||
assert config.external_url is None
|
||||
assert config.config_source == "default"
|
||||
|
|
|
@ -16,17 +16,12 @@ def teardown():
|
|||
|
||||
def test_get_time_zone_retrieves_valid_time_zone():
|
||||
"""Test getting a time zone."""
|
||||
time_zone = dt_util.get_time_zone(TEST_TIME_ZONE)
|
||||
|
||||
assert time_zone is not None
|
||||
assert time_zone.zone == TEST_TIME_ZONE
|
||||
assert dt_util.get_time_zone(TEST_TIME_ZONE) is not None
|
||||
|
||||
|
||||
def test_get_time_zone_returns_none_for_garbage_time_zone():
|
||||
"""Test getting a non existing time zone."""
|
||||
time_zone = dt_util.get_time_zone("Non existing time zone")
|
||||
|
||||
assert time_zone is None
|
||||
assert dt_util.get_time_zone("Non existing time zone") is None
|
||||
|
||||
|
||||
def test_set_default_time_zone():
|
||||
|
@ -35,8 +30,7 @@ def test_set_default_time_zone():
|
|||
|
||||
dt_util.set_default_time_zone(time_zone)
|
||||
|
||||
# We cannot compare the timezones directly because of DST
|
||||
assert time_zone.zone == dt_util.now().tzinfo.zone
|
||||
assert dt_util.now().tzinfo is time_zone
|
||||
|
||||
|
||||
def test_utcnow():
|
||||
|
@ -239,35 +233,111 @@ def test_find_next_time_expression_time_dst():
|
|||
return dt_util.find_next_time_expression_time(dt, seconds, minutes, hours)
|
||||
|
||||
# Entering DST, clocks are rolled forward
|
||||
assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == find(
|
||||
tz.localize(datetime(2018, 3, 25, 1, 50, 0)), 2, 30, 0
|
||||
assert datetime(2018, 3, 26, 2, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2018, 3, 25, 1, 50, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == find(
|
||||
tz.localize(datetime(2018, 3, 25, 3, 50, 0)), 2, 30, 0
|
||||
assert datetime(2018, 3, 26, 2, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2018, 3, 25, 3, 50, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == find(
|
||||
tz.localize(datetime(2018, 3, 26, 1, 50, 0)), 2, 30, 0
|
||||
assert datetime(2018, 3, 26, 2, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2018, 3, 26, 1, 50, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
# Leaving DST, clocks are rolled back
|
||||
assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=False) == find(
|
||||
tz.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=False), 2, 30, 0
|
||||
assert datetime(2018, 10, 28, 2, 30, 0, tzinfo=tz, fold=0) == find(
|
||||
datetime(2018, 10, 28, 2, 5, 0, tzinfo=tz, fold=0), 2, 30, 0
|
||||
)
|
||||
|
||||
assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=False) == find(
|
||||
tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True), 2, 30, 0
|
||||
assert datetime(2018, 10, 28, 2, 30, 0, tzinfo=tz, fold=0) == find(
|
||||
datetime(2018, 10, 28, 2, 5, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert tz.localize(datetime(2018, 10, 28, 4, 30, 0), is_dst=False) == find(
|
||||
tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True), 4, 30, 0
|
||||
assert datetime(2018, 10, 28, 2, 30, 0, tzinfo=tz, fold=1) == find(
|
||||
datetime(2018, 10, 28, 2, 55, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=True) == find(
|
||||
tz.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=True), 2, 30, 0
|
||||
assert datetime(2018, 10, 28, 2, 30, 0, tzinfo=tz, fold=1) == find(
|
||||
datetime(2018, 10, 28, 2, 55, 0, tzinfo=tz, fold=0), 2, 30, 0
|
||||
)
|
||||
|
||||
assert tz.localize(datetime(2018, 10, 29, 2, 30, 0)) == find(
|
||||
tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=False), 2, 30, 0
|
||||
assert datetime(2018, 10, 28, 4, 30, 0, tzinfo=tz, fold=0) == find(
|
||||
datetime(2018, 10, 28, 2, 55, 0, tzinfo=tz, fold=1), 4, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2018, 10, 28, 2, 30, 0, tzinfo=tz, fold=1) == find(
|
||||
datetime(2018, 10, 28, 2, 5, 0, tzinfo=tz, fold=1), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2018, 10, 28, 2, 30, 0, tzinfo=tz, fold=1) == find(
|
||||
datetime(2018, 10, 28, 2, 55, 0, tzinfo=tz, fold=0), 2, 30, 0
|
||||
)
|
||||
|
||||
|
||||
def test_find_next_time_expression_time_dst_chicago():
|
||||
"""Test daylight saving time for find_next_time_expression_time."""
|
||||
tz = dt_util.get_time_zone("America/Chicago")
|
||||
dt_util.set_default_time_zone(tz)
|
||||
|
||||
def find(dt, hour, minute, second):
|
||||
"""Call test_find_next_time_expression_time."""
|
||||
seconds = dt_util.parse_time_expression(second, 0, 59)
|
||||
minutes = dt_util.parse_time_expression(minute, 0, 59)
|
||||
hours = dt_util.parse_time_expression(hour, 0, 23)
|
||||
|
||||
return dt_util.find_next_time_expression_time(dt, seconds, minutes, hours)
|
||||
|
||||
# Entering DST, clocks are rolled forward
|
||||
assert datetime(2021, 3, 15, 2, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2021, 3, 14, 1, 50, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 3, 15, 2, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2021, 3, 14, 3, 50, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 3, 15, 2, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2021, 3, 14, 1, 50, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 3, 14, 3, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2021, 3, 14, 1, 50, 0, tzinfo=tz), 3, 30, 0
|
||||
)
|
||||
|
||||
# Leaving DST, clocks are rolled back
|
||||
assert datetime(2021, 11, 7, 2, 30, 0, tzinfo=tz, fold=0) == find(
|
||||
datetime(2021, 11, 7, 2, 5, 0, tzinfo=tz, fold=0), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 11, 7, 2, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2021, 11, 7, 2, 5, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 11, 7, 2, 30, 0, tzinfo=tz, fold=0) == find(
|
||||
datetime(2021, 11, 7, 2, 5, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 11, 7, 2, 30, 0, tzinfo=tz, fold=1) == find(
|
||||
datetime(2021, 11, 7, 2, 10, 0, tzinfo=tz), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 11, 7, 2, 30, 0, tzinfo=tz, fold=1) == find(
|
||||
datetime(2021, 11, 7, 2, 30, 0, tzinfo=tz, fold=0), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 11, 8, 2, 30, 0, tzinfo=tz, fold=1) == find(
|
||||
datetime(2021, 11, 7, 2, 55, 0, tzinfo=tz, fold=0), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 11, 7, 4, 30, 0, tzinfo=tz, fold=0) == find(
|
||||
datetime(2021, 11, 7, 2, 55, 0, tzinfo=tz, fold=1), 4, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 11, 7, 2, 30, 0, tzinfo=tz, fold=1) == find(
|
||||
datetime(2021, 11, 7, 2, 5, 0, tzinfo=tz, fold=1), 2, 30, 0
|
||||
)
|
||||
|
||||
assert datetime(2021, 11, 8, 2, 30, 0, tzinfo=tz) == find(
|
||||
datetime(2021, 11, 7, 2, 55, 0, tzinfo=tz, fold=0), 2, 30, 0
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue