3

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
                   )
reptilicus
  • 10,290
  • 6
  • 55
  • 79

2 Answers2

3

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'))
daniula
  • 6,898
  • 4
  • 32
  • 49
  • Yeah this is kind of what I'm doing. The problem is that anytime there is a damn daylight savings time change, it gets out of sync. It will be off by an hour. – reptilicus Apr 28 '14 at 20:52
  • So maybe you could use `timezone.localize()` method with `is_dst` argument. The only problem is that you have to determine by yourself in what dates is_dst is True or False. – daniula Apr 28 '14 at 20:56
  • yeah I have no idea how to figure out if the date is in dst or not. I think I may just have another celery job that runs every hour and sets the times – reptilicus Apr 29 '14 at 04:19
0

Try the nowfun argument in crontab which takes the datetime object

Celery beat - different time zone per task

Akhilraj N S
  • 9,049
  • 5
  • 36
  • 42