Reputation: 1697
I have a Business Hours that I need to compare and I'm getting incomplete results if the business hours are past midnight
My Model
class Hours(models.Model):
dayofweek = models.ForeignKey('Dayofweek')
opentime = models.TimeField(blank=True, null=True)
closetime = models.TimeField(blank=True, null=True)
...
If I just need to display hours everything works OK such: Saturday 5pm - 2am
Now when I'm trying to query the hours to check if the business is even open, those with past midnight hours will return False
for exists()
:
my query
if Hours.objects.filter(
business__id=id,
dayofweek__pyday=dt,
opentime__lte=mytime,
closetime__gte=mytime).exists():
#do something
Any suggestions how to tell Django that the 2am is after 5pm?
Upvotes: 6
Views: 1058
Reputation: 226
(Q(daily_starts_at__lte=F('daily_ends_at')) &
Q(daily_starts_at__lte=now_time, daily_ends_at__gte=now_time)) |
(Q(daily_starts_at__gt=F('daily_ends_at')) &
(Q(daily_starts_at__lte=now_time) | Q(daily_ends_at__gte=now_time))
This is how I solved the same case, use this in your filter() clause (and replace my daily_starts/ends_at with your names and now_time with now().time() or something). The logic is like in the other answers here, the comparison has to be different depending on if the range crosses midnight.
You also need to & with a Q() clause containing your other filter parameters.
Upvotes: 0
Reputation: 11606
What about using F and Q expressions through two queries:
one for the simple case (opening time <= closing time)
Hours.objects.filter(
opentime__lte=F('closetime'),
business__id=id,
dayofweek__pyday=dt,
opentime__lte=mytime,
closetime__gte=mytime).exists():
and one for the odd case (closing time < opening time)
Hours.objects.filter(
opentime__gt=F('closetime'),
business__id=id,
dayofweek__pyday=dt,
Q(opentime__lte=mytime) | Q(closetime__gte=mytime)).exists():
Upvotes: 2
Reputation: 10508
A day can have multiple periods, but no matter what, the day ends at 11:59 PM. If that extends into the next day, you have to break up your time intervals. So the logic of your filters will be like so...
# Spans over 2 days
if opentime > closetime:
Hours.objects.filter(
business_id=id,
dayofweek_pyday=dt,
opentime_tye=myOpenTime,
closetime_gte=11:59:99
).exists() ||
Hours.objects.filter(
business_id=id,
# Next date
dayofweek_pyday=dt + 1,
opentime_tye=00:00:00,
closetime_gte=myCloseTime
).exists()
# Spans over 1 day
else:
Hours.objects.filter(
business__id=id,
dayofweek__pyday=dt,
opentime__lte=myOpentime,
closetime__gte=myClosetime).exists()
I don't know django so this is just some pseudo code and an alternative approach I would use.
Upvotes: 2