微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

具有 UTC 支持/时区问题的 Django 开放时间

如何解决具有 UTC 支持/时区问题的 Django 开放时间

我有一个 Django 应用程序,用户可以在其中设置商店。我最近根据此线程的建议添加支持开放时间的功能 - Business Opening hours in Django。我的模型看起来像这样:

class LocationHours(SafeDeleteModel):
    location = models.ForeignKey(Location,related_name="hours",on_delete=models.CASCADE)

    weekday = models.IntegerField(choices=WEEKDAYS,blank=False,null=False)
    start_time = models.TimeField(blank=False,null=False,help_text="opening time (00:00 format)")
    end_time = models.TimeField(blank=False,help_text="Closing time (00:00 format)")

    class Meta:
        ordering = ('weekday','start_time')
        unique_together = ('location','weekday','start_time','end_time')
        verbose_name_plural = "Location hours"

过程是这样的 - 这些时间由最终用户以表格形式输入,因此假定为本地时间,我的应用程序中使用的大多数日期时间/时间都是 UTC。我最初需要经常比较这两者,我想我可以找出每个位置对象的时区,然后每当我将某些内容与这些 openingHours 进行比较时,我就可以使用给定的时间和 tz(在关联的 Location 对象上)来以 UTC 计算时间,然后它只是一个常规的日期时间比较。

我编写了以下函数来尝试解决此问题:

def is_dt_within_location_hours(location,dt):
    # see if time falls within hours
    hours = location.hours
    if hours.count() > 0:
        for hour in hours.all():
            dt = dt.astimezone(hour.location.timezone)
            if dt.weekday() == hour.weekday:
                if hour.start_time < dt.time() < hour.end_time:
                    return True
        return False
    else:  # this location has no hours
        return True

我认为这可行,但有一些问题。

主要问题是 - 当 Location 对象最初被制作或编辑时,我查找它所在的时区(使用 timezonefinder 包)并将其存储在 Location 对象中(使用 { {3}}) 当时。也就是说,据我所知,它不会自动更新 DST 或类似的东西。每次调用上述函数时,我都可以找出时区,但是我经常调用上述函数,因此在资源方面我想说这不是一种选择。

我想我可以找到一种方法来计算本地时间在他们创建 openingHours 对象的那一刻,这样我就可以转换为 UTC 并保存它,但我不知道这样做的好方法

我现在想我可能需要放弃我的整个解决方案并从头开始,但任何建议都非常有帮助我已经为此苦苦挣扎了一段时间。

解决方法

你做对了。

您担心在记录 PS > .\Code.exe PS > 和进行计算之间的时区偏移量会发生变化(与 DST 一样)。但是时区(由“美国/芝加哥”之类的名称表示)不仅仅是偏移量,它还是用于计算历史上任何时间点的本地时间的一组规则。因此,无论您何时记录时区名称,它都会做正确的事情。

关于您发布的代码的其他一些说明:

  • 您可能只想在 LocationLocationHours 上使 location 唯一,除非您有意在同一工作日为同一地点允许多个开放时间.

  • 您的 weekeday 效率相当低。您不需要每次都获取所有 is_dt_within_location_hours() 对象并重新计算工作日。相反,首先计算本地时间,然后过滤 LocationHours 以仅包含该工作日的 location.hours 对象。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。