Check if times overlap using moment?
You can sort timeSegments
by start_time
(using Array.prototype.sort
) and iterate through the sorted list and check if end_time
of the current timeSegment is greater than start_time
of the next one.
If that happens, there is an overlap.
You can see an example of implementation below:
const checkOverlap = (timeSegments) => {
if (timeSegments.length === 1) return false;
timeSegments.sort((timeSegment1, timeSegment2) =>
timeSegment1[0].localeCompare(timeSegment2[0])
);
for (let i = 0; i < timeSegments.length - 1; i++) {
const currentEndTime = timeSegments[i][1];
const nextStartTime = timeSegments[i + 1][0];
if (currentEndTime > nextStartTime) {
return true;
}
}
return false;
};
const timeSegments1 = [
["03:00", "04:00"],
["02:00", "07:00"],
["12:00", "15:00"]
];
const timeSegments2 = [
["05:00", "07:00"],
["03:00", "04:00"],
["12:00", "15:00"]
];
console.log(checkOverlap(timeSegments1)); // prints true
console.log(checkOverlap(timeSegments2)); // prints false
Note that Array.prototype.sort
mutates the array, performing the sort in-place. If you want to preserve the array passed to checkOverlap
(which is, in general, a good practice), you can create a copy of timeSegments
(using the spread syntax, for example):
const sortedTimeSegments = [...timeSegments].sort(...);
You can use moment-range plugin. You can create a range using moment.range
function passing moment objects as input (parse your input strings using moment(String, String)
). Then you can use the overlap
method that checks if two ranges overlap.
Here a live sample:
window['moment-range'].extendMoment(moment);
let overlap = (timeSegments) => {
let ret = false;
let i = 0;
while( !ret && i<timeSegments.length-1 ){
let seg1 = timeSegments[i];
let seg2 = timeSegments[i+1];
let range1 = moment.range( moment(seg1[0], 'HH:mm'), moment(seg1[1], 'HH:mm'));
let range2 = moment.range( moment(seg2[0], 'HH:mm'), moment(seg2[1], 'HH:mm'));
if( range1.overlaps(range2) ){
ret = true;
}
i++;
return ret;
}
};
let timeSegments = [];
timeSegments.push(["02:00", "07:00"])
timeSegments.push(["03:00", "04:00"])
console.log( overlap(timeSegments) ); // true
timeSegments = [];
timeSegments.push(["14:00", "18:00"])
timeSegments.push(["15:00", "19:00"])
console.log( overlap(timeSegments) ); // true
timeSegments = [];
timeSegments.push(["14:00", "18:00"])
timeSegments.push(["19:00", "21:00"])
console.log( overlap(timeSegments) ); // false
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-range/3.0.3/moment-range.min.js"></script>
you can take the reference form the following code. I am using core JavaScript for this.
<script>
var obj = [{ "from": "08:00", "to": "9:01" }, { "from": "18:45", "to": "19:00" }, { "from": "08:00", "to": "09:00" }, { "from": "12:00", "to": "14:00" }];
obj = sortTime(obj);
console.log(obj);
if (checkoverlapping(obj)) {
alert("yes time overlaps");
} else {
alert("No overlapping")
}
function sortTime(obj) {
obj.sort(function (a, b) {
KeyA = minuteValue(a.from);
KeyB = minuteValue(b.from);
if (KeyA < KeyB) return -1;
else if (KeyA > KeyB) return 1;
else {
a = minuteValue(a.to);
b = minuteValue(b.to);
if (a < b) return -1;
if (a > b) return 1;
return 0
}
})
return obj;
}
function minuteValue(time) {
time = time.split(":");
return (time[0] * 60) + (time[1] * 1);
}
function checkoverlapping(obj) {
let previous = obj[0], current, overlapping = false;
for (let i = 1; i < obj.length; i++) {
current = obj[i]
if (minuteValue(previous.to) > minuteValue(current.from)) {
overlapping = true;
break;
}
}
return overlapping;
}
</script>