Adding a job with CronTrigger.from_crontab() does not default to scheduler timezone
See original GitHub issueIn some situations, the job time zone is not defaulted to the scheduler time zone, as is specified in the docs.
Expected Behavior
From the docs: https://apscheduler.readthedocs.io/en/latest/modules/triggers/cron.html?highlight=add_job
timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations (defaults to scheduler timezone)
The time zone used for the scheduled job should be defaulted to the scheduler’s time zone.
Current Behavior
The time zone used for the scheduled job is the system time zone.
Steps to Reproduce
Here is a snippet of code that I used to reproduce the issue:
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
from pytz import utc
import logging
def job_function():
print('hello world!')
scheduler = BlockingScheduler(timezone=utc)
scheduler.add_job(job_function, CronTrigger.from_crontab('46 19 * * *'))
scheduler.print_jobs()
scheduler.start()
For reference, I am in the US/Eastern time zone. I would expect this job to default to using the time zone of the scheduler (UTC), and to be scheduled at 19:46 UTC every day. Instead, the job is running at 19:46 US/Eastern time every day.
Context (Environment)
I am working on a home automation system project, and I use apscheduler to schedule things like alarms, etc. It runs on the Raspbian linux distro, but I do most of my development on Fedora 29 or in alpine linux based docker containers. Python version is 3.7.1
Detailed Description
I took a quick look at the code, and the root cause seemed to be that the “default to scheduler time zone” logic was only applied when the trigger argument passed to .add_job()
was the alias name of the trigger.
Relevant code from apscheduler/base.py
:
def _create_trigger(self, trigger, trigger_args):
if isinstance(trigger, BaseTrigger):
return trigger # <---- time zone logic below is not applied
elif trigger is None:
trigger = 'date'
elif not isinstance(trigger, six.string_types):
raise TypeError('Expected a trigger instance or string, got %s instead' %
trigger.__class__.__name__)
# Use the scheduler's time zone if nothing else is specified
trigger_args.setdefault('timezone', self.timezone)
# Instantiate the trigger class
return self._create_plugin_instance('trigger', trigger, trigger_args)
Issue Analytics
- State:
- Created 5 years ago
- Reactions:4
- Comments:5 (3 by maintainers)
Top GitHub Comments
For anyone else running into this, the workaround looks to be the following:
More precise for CRONTrigger --> CronTrigger.from_crontab(‘0 21 * * THU’, timezone=‘UTC’)