0đź‘Ť
Postgres supports converting a time to a local time using the at time zone
syntax. For example to find the current time in New Zealand:
select (current_timestamp at time zone 'NZDT')::time;
You could use this to select shops that are open at 10:00:
where ('10:00'::time at time zone time_zone)::time
between opens and closes
Where time_zone
is the timezone for the shop, opens
the time it opens, and closes
the time it closes. Full example at regtester.com.
1đź‘Ť
Cool question. Continuing Andomar’s answer above, assuming you are handling a few timezones with “unexpected” daylight saving date ranges, one option would would be:
-
Save the timezone in a
CharField
, andopens
andcloses
in aTimeField
: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")
-
Calculate “now” as UTC:
now_utc = "10:30"
-
Annotate and filter your queryset with 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)
Another solution would be to query the db for each timezone:
# 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)
If you index_together
fields (tz
, opens
, closes
), the query should utilize the index. However, this does not mean your query will be faster.
Keep in mind you will have to keep your opening hours that surrounds midnight in two records “22:00”-“00:00” and “00:00”-“03:00” instead of “22:00”-“03:00”.
- Is there an easier way to either create or re-write exist object? django
- Python function when added to cron using django-crontab gives "No JSON object could be decoded" ERROR
- How to delete an record from Django model
- Deploying a React app on Heroku