reptilicus
reptilicus

Reputation: 10407

Celery periodic tasks timezones

I've got some periodic tasks that need to run at midnight, on the first day of every month, but on the specific timezone of the client. I'm trying to keep everything in UTC, so I have

CELERY_ENABLE_UTC = True

So if I have multiple tasks, that each need to be run at midnight in a specific timezone, what is the cleanest way to do this with Celery? For instance, run these 2 tasks at midnight in their respective timezones?

#for Client 1, this needs to run at Midnight EST (US/Eastern)
schedule1 = crontab(day_of_month=1, 
                     hour = 0, 
                     minute = 0
                   )
#for Client 2, this needs to run at Midnight PST (US/Pacific)
schedule1 = crontab(day_of_month=1, 
                     hour = 0, 
                     minute = 0
                   )

Upvotes: 3

Views: 3770

Answers (2)

Akhilraj N S
Akhilraj N S

Reputation: 9507

Try the nowfun argument in crontab which takes the datetime object

Celery beat - different time zone per task

Upvotes: 0

daniula
daniula

Reputation: 7028

crontab() function accepts only minute, hour, day_of_week, day_of_month, day_of_year and month_of_year as parameters. If you want to run a task at midnight for different timezones you have to calculate time for them according to UTC (or any other default timezone set in Celery config).

from datetime import datetime
from pytz import timezone

def get_utc_for_midnight_in_timezone(tzstring):
    local_midnight = datetime(2000, 1, 1, 0, 0, 0, tzinfo=timezone(tzstring))
    utc = local_midnight.astimezone(timezone('UTC'))
    return {
        'day_of_month': utc.day,
        'hour': utc.hour,
        'minute': utc.minute
    }

You can use above function in this way:

client1_schedule = crontab(**get_utc_for_midnight_in_timezone('US/Pacific'))
client2_schedule = crontab(**get_utc_for_midnight_in_timezone('US/Eastern'))

Upvotes: 3

Related Questions