Tom Nolan Tom Nolan - 1 month ago 12
PHP Question

How to search a range of dates between another range with Laravel?

I'm pretty new to using Laravel, but I've managed to create a pretty basic API. I'm starting to try and add filters to the API, and the primary filter I need is to see if a date range overlaps another date range.

For example, here is a typical data object returned from my database:

{
id: 1,
name: 'This is the name',
start_date: '2017-01-03',
end_date: '2017-01-29'
}


The users would typically filter by a smaller date range. For example, give me results whose start and end range fall between 2017-01-28 and 2017-02-04.

So something like:

data start data end
|------------------------|
|----------------|
search start search end


Throughout my research, I can only find answers relating to searching if a single date falls in a range, not if any part of a range falls inside another range.

This is what I currently have:

$closures = Closures::where('start_date', '>=', $from)->where('end_date', '<=', $to)->get();


The problem with this approach is that it doesn't really account for partial overlaps. In the above example, my search date is indeed greater than or equal to the data's, but since the end date is actually greater than the data's end date, it will not be returned.

The obvious would be to make the second stipulation and
orWhere
, but then that returns literally all data with a less than date which does not work.

I basically need to check if any part of of my search range falls within the data's range. Is this even possible, if so, any ideas on how I could achieve this.

Answer

You would check to see if any of the 2 dates provided falls between a range in your data. I would use nested wheres to avoid any logic spill over.

$closures = Closures::where(function($query) use ($start) {
    return $query->where('start_date', '<=', $start)->where('end_date', '>=', $start);
})
->orWhere(function($query) use ($end) {
    return $query->where('start_date', '<=', $end)->where('end_date', '>=', $end);
})
->get();
Comments