Use JavaScript To Compare Time Ranges
Solution 1:
Since this is for an open source project, I was hoping that someone here likes SO points enough to come up with a more "best practice" or more elegant solution than what I did. I guess everyone in the comments hates SO points though.
So here's my solution.
angular.forEach($scope.timeSlots, function (timeSlot, index) {
var beginTimeHasIssue = ($scope.timeSlot.BeginTime >= timeSlot.BeginTime && $scope.timeSlot.BeginTime <= timeSlot.EndTime);
var endTimeHasIssue = ($scope.timeSlot.EndTime >= timeSlot.BeginTime && $scope.timeSlot.EndTime <= timeSlot.EndTime);
if (beginTimeHasIssue || endTimeHasIssue) {
hasError = true;
$scope.HasTimeSlotError = true;
return;
}
});
Solution 2:
The way you're doing it is as suggested, however it doesn't seem robust, e.g. if there are no current slots the forEach won't do much. Also, it goes all the way to the end rather than stopping once it's found a slot. Consider the following:
var timeSlots = [
{BeginTime: new Date("10/25/2015 8:00 AM"),
EndTime: new Date("10/25/2015 8:45 AM")},
{BeginTime: new Date("10/25/2015 9:00 AM"),
EndTime: new Date("10/25/2015 9:45 AM")},
{BeginTime: new Date("10/25/2015 9:50 AM"),
EndTime: new Date("10/25/2015 10:30 AM")}
];
/* @param {Object} slot - object with BeginTime and EndTime date objects
** @returns {Boolean} true if slot fits, otherwise false
*/
function slotFits(slot) {
if (timeSlots.length == 0) return true; // If no slots, must fit
return timeSlots.some(function(s, i) {
return (i == 0 && slot.EndTime <= s.BeginTime) || // slot is before all others
(s.EndTime <= slot.BeginTime && !timeSlots[i + 1]) || // slot is after all others
(s.EndTime <= slot.BeginTime && timeSlots[i + 1].BeginTime >= slot.EndTime) // Slot between others
});
}
[{BeginTime: new Date("10/25/2015 7:00 AM"), // before all, true
EndTime: new Date("10/25/2015 8:00 AM")},
{BeginTime: new Date("10/25/2015 10:30 AM"), // after all, true
EndTime: new Date("10/25/2015 11:00 AM")},
{BeginTime: new Date("10/25/2015 8:45 AM"), // between 0 and 1, true
EndTime: new Date("10/25/2015 9:00 AM")},
{BeginTime: new Date("10/25/2015 8:45 AM"), // Overlap 1, false
EndTime: new Date("10/25/2015 9:15 AM")}
].forEach(function(slot, i) {
console.log('Slot ' + i + ': ' + slotFits(slot));
});
This could also be optimised to stop once it's passed all chance of finding a slot, requires two more lines of code. You should be able to adapt this to your angular code.
PS. I would not usually create Dates this way using a string (i.e. using the built-in parser for non-standard strings), but it's sufficient for this example. The Dates really should be created using something like:
var date = moment('10/25/2015 9:15 AM', 'MM/DD/YYYY h:mm Z').toDate();
console.log(date.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
Solution 3:
addTimeSlot=function(newtimeSlot){
var beginTimeHasIssue = false;
var endTimeHasIssue = false;
timeSlots.forEach(function (timeSlot, index) {
if( newtimeSlot.BeginTime >= timeSlot.BeginTime && newtimeSlot.EndTime <= timeSlot.EndTime ) {
console.log('falls inbetween');
endTimeHasIssue = true;
}
if( newtimeSlot.BeginTime <= timeSlot.BeginTime && newtimeSlot.EndTime >= timeSlot.EndTime) {
console.log('falls inbetween');
beginTimeHasIssue = true;
}
});
if (beginTimeHasIssue || endTimeHasIssue) {
console.log('error');
return;
} else {
timeSlots.push(newtimeSlot)
console.log('saved');
}
if (timeSlots.length == 0) {
timeSlots.push(newtimeSlot);
}
}
Post a Comment for "Use JavaScript To Compare Time Ranges"