Skip to content

Commit 6bef390

Browse files
committed
use a consistent 'now' reference for get_next_period
1 parent d47045d commit 6bef390

1 file changed

Lines changed: 17 additions & 10 deletions

File tree

appdaemon/scheduler.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -481,18 +481,20 @@ async def get_next_period(
481481
self,
482482
interval: TimeDeltaLike,
483483
start: time | datetime | str | None = None,
484-
buffer: TimeDeltaLike = 0.01,
485484
) -> datetime:
486485
interval = utils.parse_timedelta(interval)
487486
start = "now" if start is None else start
488-
aware_start = await self.parse_datetime(start, aware=True)
487+
488+
# Get "now" once and use it consistently to avoid timing races
489+
now = await self.get_now()
490+
aware_start = await self.parse_datetime(start, aware=True, now=now)
489491
assert isinstance(aware_start, datetime) and aware_start.tzinfo is not None
490-
buffer = utils.parse_timedelta(buffer)
491-
while True:
492-
if aware_start >= (await self.get_now() - buffer):
493-
return aware_start
494-
else:
495-
aware_start += interval
492+
493+
# Skip forward to the next period if start is in the past
494+
while aware_start < now:
495+
aware_start += interval
496+
497+
return aware_start
496498

497499
async def terminate_app(self, name: str):
498500
if app_sched := self.schedule.pop(name, False):
@@ -875,7 +877,9 @@ async def parse_datetime(
875877
input_: str | time | datetime,
876878
aware: bool = False,
877879
today: bool | None = None,
878-
days_offset: int = 0
880+
days_offset: int = 0,
881+
*,
882+
now: datetime | None = None,
879883
) -> datetime: # fmt: skip
880884
"""Parse a variety of inputs into a datetime object.
881885
@@ -890,9 +894,12 @@ async def parse_datetime(
890894
of the next one.
891895
days_offset (int, optional): Number of days to offset from the current date for sunrise/sunset parsing. If
892896
this is negative, this will unset the `today` argument, which allows the result to be in the past.
897+
now (datetime, optional): The current time to use as reference. If not provided, will call get_now().
893898
"""
894899
# Need to force timezone during time-travel mode
895-
now = (await self.get_now()).astimezone(self.AD.tz)
900+
if now is None:
901+
now = await self.get_now()
902+
now = now.astimezone(self.AD.tz)
896903
return parse.parse_datetime(
897904
input_=input_,
898905
now=now,

0 commit comments

Comments
 (0)