Home > Enterprise >  How to query overlapping dates on Postgres DateRange field
How to query overlapping dates on Postgres DateRange field

Time:10-05

I have a model with a PostgreSQL DateRange field:

class MyModel(models.Model):
    date_range = DateRangeField()

If I want to query this to see if another date overlaps, that's easy enough:

MyModel.objects.filter(date_range__overlap=other_date)

But if I have built a list of DateRange objects, how can I search the list asking this same thing of the list (rather than the queryset). I.e. "Does this DateRange overlap with any of the DateRanges in this list?":

mylist = [DateRange([2021-10-04, 2021-10-05]), DateRange([2022-10-04, 2022-10-05])]

for dr in mylist:
    dr.overlap(query_date) # fails

Note: DateRange objects have no attribute overlap per docs.

CodePudding user response:

We know that two datetimes do not overlap if e1≤s2 or e2≤s1 with si and ei the start and end of fragment i respectively.

This thus means that the two do overlap in case e1>s2 and e2>s1. We thus can construct an overlap check with:

def is_overlap(dr1, dr2):
    return dr1.upper > dr2.lower and dr2.upper > dr1.lower

Next we can find out if any of the items overlaps with:

any(is_overlap(query_date, dr) for dr in mylist)

or we can construct a list of all DateRanges that overlap with query_date:

[dr for dr in mylist if is_overlap(query_date, dr)]
  • Related