apscheduler.triggers.calendarinterval

class apscheduler.triggers.calendarinterval.CalendarIntervalTrigger(*, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0, hour: int = 0, minute: int = 0, second: int = 0, start_date: date | str | None = None, end_date: date | str | None = None, timezone: str | tzinfo | None = None, jitter: int | None = None)

Bases: BaseTrigger

Runs the task on specified calendar-based intervals always at the same exact time of day.

When calculating the next date, the years and months parameters are first added to the previous date while keeping the day of the month constant. This is repeated until the resulting date is valid. After that, the weeks and days parameters are added to that date. Finally, the date is combined with the given time (hour, minute, second) to form the final datetime.

This means that if the days or weeks parameters are not used, the task will always be executed on the same day of the month at the same wall clock time, assuming the date and time are valid.

If the resulting datetime is invalid due to a daylight saving forward shift, the date is discarded and the process moves on to the next date. If instead the datetime is ambiguous due to a backward DST shift, the earlier of the two resulting datetimes is used.

If no previous run time is specified when requesting a new run time (like when starting for the first time or resuming after being paused), start_date is used as a reference and the next valid datetime equal to or later than the current time will be returned. Otherwise, the next valid datetime starting from the previous run time is returned, even if it’s in the past.

Warning

Be wary of setting a start date near the end of the month (29. – 31.) if you have months specified in your interval, as this will skip the months when those days do not exist. Likewise, setting the start date on the leap day (February 29th) and having years defined may cause some years to be skipped.

Users are also discouraged from using a time inside the target timezone’s DST switching period (typically around 2 am) since a date could either be skipped or repeated due to the specified wall clock time either occurring twice or not at all.

Parameters:
  • years – number of years to wait

  • months – number of months to wait

  • weeks – number of weeks to wait

  • days – number of days to wait

  • hour – hour to run the task at

  • minute – minute to run the task at

  • second – second to run the task at

  • start_date – first date to trigger on (defaults to current date if omitted)

  • end_date – latest possible date to trigger on

  • timezone – time zone to use for calculating the next fire time (defaults to scheduler timezone if created via the scheduler, otherwise the local time zone)

  • jitter – delay the job execution by jitter seconds at most

get_next_fire_time(previous_fire_time: datetime | None, now: datetime) datetime | None

Returns the next datetime to fire on, If no such datetime can be calculated, returns None.

Parameters:

API

Trigger alias for add_job(): calendarinterval

class apscheduler.triggers.calendarinterval.CalendarIntervalTrigger(*, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0, hour: int = 0, minute: int = 0, second: int = 0, start_date: date | str | None = None, end_date: date | str | None = None, timezone: str | tzinfo | None = None, jitter: int | None = None)

Bases: BaseTrigger

Runs the task on specified calendar-based intervals always at the same exact time of day.

When calculating the next date, the years and months parameters are first added to the previous date while keeping the day of the month constant. This is repeated until the resulting date is valid. After that, the weeks and days parameters are added to that date. Finally, the date is combined with the given time (hour, minute, second) to form the final datetime.

This means that if the days or weeks parameters are not used, the task will always be executed on the same day of the month at the same wall clock time, assuming the date and time are valid.

If the resulting datetime is invalid due to a daylight saving forward shift, the date is discarded and the process moves on to the next date. If instead the datetime is ambiguous due to a backward DST shift, the earlier of the two resulting datetimes is used.

If no previous run time is specified when requesting a new run time (like when starting for the first time or resuming after being paused), start_date is used as a reference and the next valid datetime equal to or later than the current time will be returned. Otherwise, the next valid datetime starting from the previous run time is returned, even if it’s in the past.

Warning

Be wary of setting a start date near the end of the month (29. – 31.) if you have months specified in your interval, as this will skip the months when those days do not exist. Likewise, setting the start date on the leap day (February 29th) and having years defined may cause some years to be skipped.

Users are also discouraged from using a time inside the target timezone’s DST switching period (typically around 2 am) since a date could either be skipped or repeated due to the specified wall clock time either occurring twice or not at all.

Parameters:
  • years – number of years to wait

  • months – number of months to wait

  • weeks – number of weeks to wait

  • days – number of days to wait

  • hour – hour to run the task at

  • minute – minute to run the task at

  • second – second to run the task at

  • start_date – first date to trigger on (defaults to current date if omitted)

  • end_date – latest possible date to trigger on

  • timezone – time zone to use for calculating the next fire time (defaults to scheduler timezone if created via the scheduler, otherwise the local time zone)

  • jitter – delay the job execution by jitter seconds at most

get_next_fire_time(previous_fire_time: datetime | None, now: datetime) datetime | None

Returns the next datetime to fire on, If no such datetime can be calculated, returns None.

Parameters:

Examples

from datetime import datetime

from apscheduler.schedulers.blocking import BlockingScheduler


def job_function():
    print("Hello World")

sched = BlockingScheduler()

# Schedule job_function to be called every two months at 16:49:00
sched.add_job(job_function, 'calendarinterval', months=2, hour=16, minute=49)

sched.start()

You can use start_date and end_date to limit the total time in which the schedule runs:

# The same as before, but starts on 2010-10-10 and stops on 2014-06-15
sched.add_job(
    job_function,
    'calendarinterval',
    months=2,
    hour=16,
    minute=49,
    start_date='2010-10-10',
    end_date='2014-06-15'
)

The jitter option enables you to add a random component to the execution time. This might be useful if you have multiple servers and don’t want them to run a job at the exact same moment or if you want to prevent multiple jobs with similar options from always running concurrently:

# Run `job_function` every two months with an extra delay picked randomly between 0
# and 120 seconds
sched.add_job(job_function, 'calendarinterval', months=2, jitter=120)