安排在不同的时区

问题描述 投票:2回答:1

我正在开发一个Django项目。

我想自动同步类。

我的代码:

from datetime import timedelta
from celery.schedules import crontab

CELERYBEAT_SCHEDULE = {
'sync-classes': {
    'task': 'scheduler.tasks.sync_classes',
    'schedule': crontab(hour='0', minute=0),
}

CELERY_ENABLE_UTC = False
CELERY_TIMEZONE = 'Europe/London'

它适用于伦敦时区。

每个班级都有不同的时区。我希望计划根据类的相关时区自动运行。

sync_classes()方法中,我得到所有课程并在伦敦时区同步。

问题:如何根据时区同步每个班级?

python django timezone celerybeat
1个回答
2
投票

这个代码在Django / Celery部分没有经过测试,但这里的想法是:

  1. 将Celery-Beat的计划更改为每15分钟运行一次。这应该几乎覆盖all the TZ offsets in existence,因为大多数是小时的倍数,或半小时的倍数,只有少数情况是四分之一小时的倍数(因此这15分钟的分辨率应涵盖世界的所有时区偏移): CELERYBEAT_SCHEDULE = { 'sync-classes': { 'task': 'scheduler.tasks.sync_classes', 'schedule': crontab(minute='*/15'), } CELERY_ENABLE_UTC = False CELERY_TIMEZONE = 'Europe/London' 在这一点上,Celery的时区并不重要,因为我们将使用唯一合适的时区作为参考:UTC。
  2. 创建一个辅助函数,它将为您提供时区的名称(“now”表示“当您的任务运行时”)是“几乎”午夜。你的任务将每15分钟运行一次......也许在15分钟后几毫秒...所以让我们给它10分钟的缓冲区(这应该是方式,方式绰绰有余)。只要缓冲区少于15分钟,你应该没问题(很好意味着你不会有一个任务,下一步认为“现在”是午夜,因此两次运行同步) 这应该有所帮助: import pytz import datetime utc_now = pytz.utc.localize(datetime.datetime.utcnow()) collected_tz_names = [] for tz in pytz.all_timezones_set: test_dt = utc_now.astimezone(pytz.timezone(tz)) print("tz: %s, test_dt.time() %s" % (tz, test_dt.time())) is_midnight = ( datetime.time(hour=0, minute=0, second=0) <= test_dt.time() <= datetime.time(hour=0, minute=10, second=0) ) if is_midnight: collected_tz_names.append(tz) print("collected %s" % collected_tz_names) 如果要测试它,请将utc_now = pytz.utc.localize(datetime.datetime.utcnow())“探测器”(或参考)更改为一些手动值,例如utc_now = pytz.utc.localize(datetime.datetime(year=2018, month=1, day=4, hour=4, minute=1, second=0)
  3. 一旦你在now列表中收集了collected_tz_names午夜的时区,就运行你的同步方法。假设您需要同步的对象是User(s),对吧?而且你的User模型有一个属性tz_name,它指示每个用户的时区。在这种情况下,这应该做: for user in User.objects.filter(tz_name__in=collected_tz_names): user.synchronize()

请记住,在夏令时切换中,您可能最终会同步两次。

© www.soinside.com 2019 - 2024. All rights reserved.