Skip to content

Commit

Permalink
fix issue with daylight saving time change (#71)
Browse files Browse the repository at this point in the history
* Improve setting the datetime for energy request

* Improve setting the datetime for gas request

* Add test for midnight value in CEST

* Change freeze_time from UTC to CET

* Change timezone notation for freeze_time
  • Loading branch information
klaasnicolaas authored Mar 28, 2023
1 parent cd2f4d3 commit 20df51c
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 45 deletions.
72 changes: 37 additions & 35 deletions energyzero/energyzero.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,55 +125,56 @@ async def gas_prices(
------
EnergyZeroNoDataError: No gas prices found for this period.
"""
start_date_utc: datetime
end_date_utc: datetime
utcnow: datetime = datetime.now(timezone.utc)
if utcnow.hour >= 5 and utcnow.hour <= 22:
# Set start_date to 05:00:00 and the end_date to 04:59:59 UTC next day
start_date_utc = datetime(
local_tz = datetime.now(timezone.utc).astimezone().tzinfo
now: datetime = datetime.now(tz=local_tz)

if now.hour >= 6 and now.hour <= 23:
# Set start_date to 06:00:00 and the end_date to 05:59:59 next day
# Convert to UTC time 04:00:00 and 03:59:59 next day
utc_start_date = datetime(
start_date.year,
start_date.month,
start_date.day,
5,
6,
0,
0,
tzinfo=timezone.utc,
)
end_date_utc = datetime(
tzinfo=local_tz,
).astimezone(timezone.utc)
utc_end_date = datetime(
end_date.year,
end_date.month,
end_date.day,
4,
5,
59,
59,
tzinfo=timezone.utc,
) + timedelta(days=1)
tzinfo=local_tz,
).astimezone(timezone.utc) + timedelta(days=1)
else:
# Set start_date to 05:00:00 prev day and the end_date to 04:59:59 UTC
start_date_utc = datetime(
# Set start_date to 06:00:00 prev day and the end_date to 05:59:59
# Convert to UTC time 04:00:00 prev day and 03:59:59 current day
utc_start_date = datetime(
start_date.year,
start_date.month,
start_date.day,
5,
6,
0,
0,
tzinfo=timezone.utc,
) - timedelta(days=1)
end_date_utc = datetime(
tzinfo=local_tz,
).astimezone(timezone.utc) - timedelta(days=1)
utc_end_date = datetime(
end_date.year,
end_date.month,
end_date.day,
4,
5,
59,
59,
tzinfo=timezone.utc,
)

tzinfo=local_tz,
).astimezone(timezone.utc)
data = await self._request(
"energyprices",
params={
"fromDate": start_date_utc.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"tillDate": end_date_utc.strftime("%Y-%m-%dT%H:%M:%S.999Z"),
"fromDate": utc_start_date.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"tillDate": utc_end_date.strftime("%Y-%m-%dT%H:%M:%S.999Z"),
"interval": interval,
"usageType": 3,
"inclBtw": self.incl_btw.lower(),
Expand Down Expand Up @@ -207,30 +208,31 @@ async def energy_prices(
------
EnergyZeroNoDataError: No energy prices found for this period.
"""
# Set the start date to 23:00:00 previous day and the end date to 22:59:59 UTC
start_date_utc: datetime = datetime(
local_tz = datetime.now(timezone.utc).astimezone().tzinfo
# Set start_date to 00:00:00 and the end_date to 23:59:59 and convert to UTC
utc_start_date = datetime(
start_date.year,
start_date.month,
start_date.day,
0,
0,
0,
tzinfo=timezone.utc,
) - timedelta(hours=1)
end_date_utc: datetime = datetime(
tzinfo=local_tz,
).astimezone(timezone.utc)
utc_end_date = datetime(
end_date.year,
end_date.month,
end_date.day,
22,
23,
59,
59,
tzinfo=timezone.utc,
)
tzinfo=local_tz,
).astimezone(timezone.utc)
data = await self._request(
"energyprices",
params={
"fromDate": start_date_utc.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"tillDate": end_date_utc.strftime("%Y-%m-%dT%H:%M:%S.999Z"),
"fromDate": utc_start_date.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"tillDate": utc_end_date.strftime("%Y-%m-%dT%H:%M:%S.999Z"),
"interval": interval,
"usageType": 1,
"inclBtw": self.incl_btw.lower(),
Expand Down
3 changes: 2 additions & 1 deletion energyzero/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def _timed_value(moment: datetime, prices: dict[datetime, float]) -> float | Non
"""
value = None
for timestamp, price in prices.items():
if timestamp <= moment < (timestamp + timedelta(hours=1)):
future_ts = timestamp + timedelta(hours=1)
if timestamp <= moment < future_ts:
value = price
return value

Expand Down
4 changes: 2 additions & 2 deletions examples/energy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ async def main() -> None:
"""Show example on fetching the energy prices from EnergyZero."""
async with EnergyZero() as client:
local = pytz.timezone("CET")
today = date(2023, 2, 8)
tomorrow = date(2023, 2, 9)
today = date(2023, 3, 29)
tomorrow = date(2023, 3, 29)

energy_today = await client.energy_prices(start_date=today, end_date=today)
energy_tomorrow = await client.energy_prices(
Expand Down
2 changes: 1 addition & 1 deletion examples/gas.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
async def main() -> None:
"""Show example on fetching the gas prices from EnergyZero."""
async with EnergyZero() as client:
today = date(2023, 2, 8)
today = date(2023, 3, 28)

gas_today = await client.gas_prices(start_date=today, end_date=today)
print()
Expand Down
4 changes: 4 additions & 0 deletions tests/fixtures/energy.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"Prices": [
{
"price": 0.31,
"readingDate": "2022-12-06T22:00:00Z"
},
{
"price": 0.35,
"readingDate": "2022-12-06T23:00:00Z"
Expand Down
38 changes: 32 additions & 6 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from . import load_fixtures


@pytest.mark.freeze_time("2022-12-07 14:00:00 UTC")
@pytest.mark.freeze_time("2022-12-07 15:00:00+01:00")
async def test_electricity_model(aresponses: ResponsesMockServer) -> None:
"""Test the electricity model at 14:00:00 UTC."""
"""Test the electricity model at 15:00:00 CET."""
aresponses.add(
"api.energyzero.nl",
"/v1/energyprices",
Expand Down Expand Up @@ -76,6 +76,32 @@ async def test_electricity_none_date(aresponses: ResponsesMockServer) -> None:
assert energy.average_price == 0.37


@pytest.mark.freeze_time("2022-12-07 00:30:00+02:00")
async def test_electricity_midnight_cest(aresponses: ResponsesMockServer) -> None:
"""Test the electricity model between 00:00 and 01:00 with in CEST."""
aresponses.add(
"api.energyzero.nl",
"/v1/energyprices",
"GET",
aresponses.Response(
status=200,
headers={"Content-Type": "application/json"},
text=load_fixtures("energy.json"),
),
)
async with ClientSession() as session:
today = date(2022, 12, 7)
client = EnergyZero(session=session)
energy: Electricity = await client.energy_prices(
start_date=today,
end_date=today,
)
assert energy is not None
assert isinstance(energy, Electricity)
# Price at 22:30:00 UTC
assert energy.current_price == 0.31


async def test_no_electricity_data(aresponses: ResponsesMockServer) -> None:
"""Raise exception when there is no data."""
aresponses.add(
Expand All @@ -95,9 +121,9 @@ async def test_no_electricity_data(aresponses: ResponsesMockServer) -> None:
await client.energy_prices(start_date=today, end_date=today)


@pytest.mark.freeze_time("2022-12-07 14:00:00 UTC")
@pytest.mark.freeze_time("2022-12-07 15:00:00+01:00")
async def test_gas_model(aresponses: ResponsesMockServer) -> None:
"""Test the gas model at 14:00:00 UTC."""
"""Test the gas model at 15:00:00 CET."""
aresponses.add(
"api.energyzero.nl",
"/v1/energyprices",
Expand All @@ -123,9 +149,9 @@ async def test_gas_model(aresponses: ResponsesMockServer) -> None:
assert gas.price_at_time(next_hour) == 1.47


@pytest.mark.freeze_time("2022-12-07 03:00:00 UTC")
@pytest.mark.freeze_time("2022-12-07 04:00:00+01:00")
async def test_gas_morning_model(aresponses: ResponsesMockServer) -> None:
"""Test the gas model in the morning at 03:00:00 UTC."""
"""Test the gas model in the morning at 04:00:00 CET."""
aresponses.add(
"api.energyzero.nl",
"/v1/energyprices",
Expand Down

0 comments on commit 20df51c

Please sign in to comment.