查询本地时间



对于一家商店,我希望该商店的商店开门和关门时间是当地时间。例:

Shop1 于当地时间 8:00 (

t1( 开盘,并于当地时间 16:00 (t2( 关闭。Shop1 位于欧洲/伦敦 (tz(。

Shop2 当地时间 8:00 开门,当地时间 16:00 关门。Shop2 位于欧洲/哥本哈根。

问题:如何在给定时间选择营业的商店?我需要考虑 DST:在夏季的这个示例中,

Shop1 的营业时间为 08:00+01:00,Shop2 的营业时间为 08:00+02:00,而在冬季,Shop1 的营业时间为 08:00+00:00,Shop2 的营业时间为 08:00+01:00。

将从具有许多行的表中进行选择,因此我需要对此进行索引。

使用 Django + PostgreSQL。

很酷的问题。 继续上面的Andomar的回答,假设您正在处理具有"意外"夏令时日期范围的几个时区,一种选择是:

  • 将时区保存在CharField中,并在TimeFieldopenscloses

    class Shop(models.Model):
        tz = models.CharField(max_length=200)
        opens = models.TimeField()
        closes = models.TimeField()
    Shop.objects.create(opens="8:00", closes="19:00", tz="Europe/Moscow")
    Shop.objects.create(opens="8:00", closes="19:00", tz="Europe/Berlin")
    Shop.objects.create(opens="8:00", closes="19:00", tz="UTC")
    Shop.objects.create(opens="8:00", closes="19:00", tz="Asia/Jerusalem")
    Shop.objects.create(opens="8:00", closes="19:00", tz="Europe/London")
    Shop.objects.create(opens="8:00", closes="19:00", tz="Europe/Copenhagen")
    
  • 将"现在"计算为 UTC:

    now_utc = "10:30"  
    
  • 使用 RawSQL 批注和筛选查询集:

    qs = Shop.objects.annotate(is_open=RawSQL("(%s::time at time zone tz)::time between opens and closes", (now_utc,))).filter(is_open=True)
    

另一种解决方案是查询每个时区的数据库:

# pseudocode
for tz in all_timezones:
    now_local = convert_to_timezone(now, tz) # beware - this might fail when DST is currently changing!
    shops = Shop.objects.filter(tz=tz, opens__lte=now_local, closes__gte=now_local)

如果index_together字段(tzopenscloses(,查询应利用索引。 但是,这并不意味着您的查询会更快。

请记住,您必须将午夜周围的营业时间保留在两个记录

"22:00"-"00:00"和"00:00"-"03:00"而不是"22:00"-"03:00"中。

Postgres支持使用at time zone语法将时间转换为本地时间。 例如,要查找新西兰的当前时间:

select (current_timestamp at time zone 'NZDT')::time;

您可以使用它来选择在 10:00 营业的商店:

where   ('10:00'::time at time zone time_zone)::time
        between opens and closes

其中time_zone是商店的时区,opens商店的营业时间,closes关闭时间。 regtester.com 的完整示例。

相关内容

  • 没有找到相关文章

最新更新