A systemd OnCalendar expression parser and evaluator. Requires Python 3.10+.
oncalendar is written for and being used in Healthchecks (a scheduled task monitoring service).
This package provides three iterators:
-
oncalendar.BaseIterator(expression: str, start: datime): supports expressions without timezone (example: "Mon, 12:34"). Accepts both naive and timezone-aware datetimes as the start time.
-
oncalendar.TzIterator(expression: str, start: datetime): supports expressions with and without timezone. (example: "Mon, 12:34 Europe/Riga"). Requires the start datetime to be timezone-aware.
-
oncalendar.OnCalendar(expressions:str, start: datetime): supports multiple expressions with or without timezones, separated by newlines. Requires the start datetime to be timezone-aware. Example:
2020-01-01 12:34 Europe/Riga
pip install oncalendar
from datetime import datetime
from oncalendar import BaseIterator
it = BaseIterator("Mon, 12:34", datetime.now())
for x in range(0, 10):
print(next(it))
Produces:
2023-12-11 12:34:00
2023-12-18 12:34:00
2023-12-25 12:34:00
2024-01-01 12:34:00
2024-01-08 12:34:00
2024-01-15 12:34:00
2024-01-22 12:34:00
2024-01-29 12:34:00
2024-02-05 12:34:00
2024-02-12 12:34:00
If oncalendar receives an invalid expression, it raises oncalendar.OnCalendarError
exception:
from datetime import datetime
from oncalendar import BaseIterator
BaseIterator("Mon, 123:456", datetime.now())
Produces:
oncalendar.OnCalendarError: Bad hour
If oncalendar hits year 2200 while iterating, it stops iteration by raising
StopIteration
:
from datetime import datetime
from oncalendar import BaseIterator
# 2199 is not leap year, and we stop at 2200
print(next(BaseIterator("2199-2-29", datetime.now())))
Produces:
StopIteration
- Does not support decimals in the second field.