I am trying to run a daily task as part of my Django web application using celery beat, which calls a function with a date string argument. The beat schedule works fine and calls the function at the right time each day, but the date string inputted to the function is always one day behind. I assume this is because the timezone setting is wrong, but I think I have configured Django and celery correctly so I can't see where the problem is.
Relevant settings in ./settings.py
:
TIME_ZONE = 'Europe/London'
USE_TZ = True
CELERY_ENABLE_UTC = False
CELERY_TIMEZONE = TIME_ZONE
My celery config in ./my_project/celery.py
:
from django.utils import timezone
from celery import Celery
from celery.schedules import crontab
app = Celery('my_project')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
# Configure daily tasks
app.conf.beat_schedule = {
# Executes `my_task` every day at 10:00am
'do-my-task': {
'task': 'tasks.tasks.my_task',
'schedule': crontab(minute=0, hour=10),
'args': (timezone.now().strftime('%d/%m/%Y'), ),
},
}
Any ideas why this should be inputting the wrong date string as the argument to my_task
?
django.utils.timezone.now
does not do what you think it does. According to the docs it will return the time in UTC with the timezone set to UTC. It will not return the time in Europe/London
as you want:
If
USE_TZ
isTrue
, this will be an awaredatetime
representing the current time in UTC. Note thatnow()
will always return times in UTC regardless of the value ofTIME_ZONE
; you can uselocaltime()
to get the time in the current time zone.
As the docs suggest, use localtime
instead of now
.