Today’s programming challenge was to validate that two time ranges in the same day were not overlapping.
I had written over 50 lines of JavaScript with if this is before that then if this if after that other one then this – OR – the same in reverse and so on and so on. It was a lot of what seemed unnecessary code – un-elegant was how it felt (if that is a word).
So in the spirit of approaching a problem differently (no bullshit box terms here) I came up with the following solution.
We have time range A: 1AM to 3AM
We have time range B: 3AM to 4AM
orΒ we could have the second range before the first
Range A: 3pm to 5pm
Range B: 1pm to 3pm
and I need to make sure they do not overlap – that is the only requirement
So I figured: if I make an array of every minute representing each time range and compared them, if there is no matches then there is no “overlap”.
So for the first time range I create an array of the minute-in-the-day (e.g. 1:01 am would be 61) from start to finish which looks like this [60, 61, 62, 63, 64] and then create another array of the second range [120, 121, 122, 123 ,124 etc] and do a comparison. If no matches then no overlap.
here is the functions:
function createMinuteArray(date1, date2){ //this function creates an array of the number of minutes (in the day) between the start and end time // e.g.[60, 61, 62, 63] var arr = [] var startMinute=(date1.getHours()*60)+date1.getMinutes() var endMinute=(date2.getHours()*60)+date2.getMinutes() for (var i=startMinute; i<endMinute; i++){ arr.push(i) } return arr } function diffArray(arr1, arr2){ //this function runs a test on all the values in arr1 and checks to see if that value is in arr2 //if that is the case then there is overlap of the arrays and therefore return true for (i=0; i<arr1.length; i++){ //I used jQuery inArray because I have IE8 requirement and arr1.indexOf is not supported if ($.inArray(arr1[i], arr2)>-1){ //we have a match and therefore an overlap return true } } return false }
and this is how they are called
var mealbreak = createMinuteArray(startTime1, endTime1) var otherbreak = createMinuteArray(startTime2, endTime2) //Check to see if any of the minutes in one array overlap with the minutes in the other one var overlap = diffArray(mealbreak, otherbreak)
From there we can determine if(overlap) then fail validation
This could be used for comparing dates but would really be impractical – because that would be enormous arrays to create and compare.
I posted this as much in the spirit of – hey this is a different way of solving a problem, more so that a recommendation for how you should validate dates and times. Just something different π
I had to do something like this in the past for a plane booking website. I’m going from memory, but in your case I think you could just do something like this:
startTime1 < endTime2 && startTime2 < endTime1;
If you wanted it to handle situations like an end time of 1pm and start time of 1pm for the other considered an overlap, just make it
startTime1 <= endTime2 && startTime2 <= endTime1;
and if you wanted to just check hours, add .getHours()
Carl – thanks for the comment π
Unfortunately in my case I have two “break” periods in a work day and they could be before or after each other. So I have to do multiple checks – for example if:
start1 < start2 then end1 must be start1 then end 1 must be < start 2
or
start2 < start 1 then end 2 start2 then end2 < start1
and so on it was doing my head in. Afternoon food coma might have contributed as well…..
I am not saying the above solution is elegant – just different π
That formula will check for any overlap, so if start2 is before start1, start1 is before start 2 etc. it doesn’t matter. I wasn’t saying your solutions was inelegant, just giving you a much shorter alternative π
(facepalm)