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