I am trying to compare dates in array for overlapping but having problem. User can add as many dates they want and I need to check them to make sure no overlapping.
Dates Array (start and end dates combined with (-) between them:
dates (4) ["02/07/2018-02/07/2018", "02/05/2018-02/07/2018", "02/06/2018-02/06/2018", "02/08/2018-02/08/2018"]
My code:
function CheckOverlappingDates(dates) {
var startDate = [];
var endDate = [];
var isOverlap;
for (var i = 0; i < dates.length; i++) {
var split = dates[i].split('-'); // just split once
startDate.push(new Date(split[0]).toLocaleDateString());
endDate.push(new Date(split[1]).toLocaleDateString());
for (var x = 0; x < startDate.length; x++) {
if (startDate[x] >= startDate[x + 1] && startDate[x + 1] <= endDate[x + 1]) {
isOverlap = true;
} else {
isOverlap = false;
}
}
}
}
I split them into startdate and enddate like following
but my function does not compare multiple date range.
When comparing date strings, you can convert them to Date objects or keep them as strings and use localeCompare. Don't use the built-in Date parser as it's unreliable. A 2 line function can do the formatting as strings or conversion to date, strings may be more efficient but comparison as dates is less code.
To see if an array of ranges has overlaps, each range needs to be compared to those after it in the array. There's no need to check with those before as that's already been done.
It's not clear what should be done with overlapping ranges, so this function just returns an array of strings with "range A overlaps range B". It also assumes ranges are inclusive, so 02/05/2018-02/07/2018 overlaps 02/07/2018-02/08/2018.
e.g.
var dates = ["02/07/2018-02/07/2018", "02/05/2018-02/07/2018", "02/06/2018-02/06/2018", "02/08/2018-02/08/2018"];
// Assume array of ranges in format mm/dd/yyyy-mm/dd/yyyy
// Return array of overlapping ranges
function inRange(dates) {
// Parse date string to Date
function fn(s) {
var b = s.split(/\D/);
return new Date(b[2], b[0]-1, b[1]);
}
// Return true if range a overlaps range b
// where range is string in format mm/dd/yyyy-mm/dd/yyyy
// Overlaps if start or end of b are inside a, or
// a is wholly inside b
function overlaps(a, b) {
a = a.split('-').map(fn);
b = b.split('-').map(fn);
return (b[0] >= a[0] && b[0] <= a[1]) || // b start in a
(b[1] >= a[0] && b[1] <= a[1]) || // b end in a
(b[0] <= a[0] && b[1] >= a[1]); // b encloses a
}
// Array for overlapping ranges
var overlappers = [];
var max = dates.length - 1;
dates.forEach(function(date, i) {
// Don't test last as already tested
if (i < max) {
// Only test from this element to end of array
for (var j = i+1; j <= max; j++) {
// If overlaps, add to overlappers array
if (overlaps(date, dates[j])) {
overlappers.push(date + ' overlaps ' + dates[j]);
}
}
}
});
return overlappers;
}
console.log(inRange(dates));
The simple parser expects dates to be valid. If they need to be checked, an extra line of code is required in the parser and invalid dates need to be handled in the main function.