Skip to content

Commit

Permalink
Fix due date calculation for future dailies in Habitica integration (h…
Browse files Browse the repository at this point in the history
…ome-assistant#126403)

Calculate next due date for dailies with startdate in the future
  • Loading branch information
tr4nt0r authored Sep 22, 2024
1 parent 06cd864 commit 79872b3
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions homeassistant/components/habitica/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from __future__ import annotations

import datetime
from typing import Any
from typing import TYPE_CHECKING, Any

from homeassistant.components.automation import automations_with_entity
from homeassistant.components.script import scripts_with_entity
Expand All @@ -14,25 +14,44 @@
def next_due_date(task: dict[str, Any], last_cron: str) -> datetime.date | None:
"""Calculate due date for dailies and yesterdailies."""

today = to_date(last_cron)
startdate = to_date(task["startDate"])
if TYPE_CHECKING:
assert today
assert startdate

if task["isDue"] and not task["completed"]:
return dt_util.as_local(datetime.datetime.fromisoformat(last_cron)).date()
return to_date(last_cron)

if startdate > today:
if task["frequency"] == "daily" or (
task["frequency"] in ("monthly", "yearly") and task["daysOfMonth"]
):
return startdate

if (
task["frequency"] in ("weekly", "monthly")
and (nextdue := to_date(task["nextDue"][0]))
and startdate > nextdue
):
return to_date(task["nextDue"][1])

return to_date(task["nextDue"][0])


def to_date(date: str) -> datetime.date | None:
"""Convert an iso date to a datetime.date object."""
try:
return dt_util.as_local(
datetime.datetime.fromisoformat(task["nextDue"][0])
).date()
return dt_util.as_local(datetime.datetime.fromisoformat(date)).date()
except ValueError:
# sometimes nextDue dates are in this format instead of iso:
# sometimes nextDue dates are JavaScript datetime strings instead of iso:
# "Mon May 06 2024 00:00:00 GMT+0200"
try:
return dt_util.as_local(
datetime.datetime.strptime(
task["nextDue"][0], "%a %b %d %Y %H:%M:%S %Z%z"
)
datetime.datetime.strptime(date, "%a %b %d %Y %H:%M:%S %Z%z")
).date()
except ValueError:
return None
except IndexError:
return None


def entity_used_in(hass: HomeAssistant, entity_id: str) -> list[str]:
Expand Down

0 comments on commit 79872b3

Please sign in to comment.