Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Detecting Conflicting Events
// Detecting Conflicting Events
// Detecting Overlap of Date Ranges
// Detecting Date Conflicts
// Written by Mark Ivanowich
// mark.ivanowich.ca
// February 2nd 2019
// Working with Google Calendar APIs, I was searching online for anyone who already figured out the logic of testing two sets of events for potential overlap.
// I didn't know what keywords to search for, so here I am taking personal time to build a pseudo-code snippet to hopefully help myself or someone else.
// Final code is uncommented, any code that is later condensed is double-commented / comment-indented.
// I'm not a maths person, so I don't know all the notation.
for(Event candidateEvent : candidateEvents){
DateTime candidateStart = candidateEvent.start;
DateTime candidateEnd = candidateEvent.end;
// arbitrary which for loop can be internal or external.
// instead of verifying the validity or state of a candidate by its position
// logic was intuitive when thinking of the candidate event as static, and the state of other events as mobile
for(Event blockingEvent : blockingEvents){
DateTime blockingStart = blockingEvent.start;
DateTime blockingEnd = blockingEvent.end;
// let C refer to a candidate event starting at time C_a and ending at C_b
// let B refer to an event to compare to, which may or may not be 'conflicting' or 'blocking', starting at time B_a and ending at B_b
// B_a within range [C_a, C_b) ; blocking event overlaps end of our candidate
// note when B_a == C_b is not conflicting ; compared event begins as our candidate ends
//// if(blockingStart >= candidateStart && blockingStart < candidateEnd){}
// B_b within range (C_a, C_b] ; blocking event overlaps start of our candidate
// note when B_b == C_a is not conflicting ; compared event ends as our candidate begins
//// if(blockingEnd > candidateStart && blockingEnd <= candidateEnd){}
// due to above rules, it is implicit that when B is completely within range C, both checks will pass
// eg: B_a >= C_a && B_a < C_b && B_b > C_a && B_b <= C_b
// these two rules are not XOR; one or both checks will catch conflicting events:
//// if( (blockingStart >= candidateStart && blockingStart < candidateEnd) || (blockingEnd > candidateStart && blockingEnd <= candidateEnd) ){
//// } else // only one other case remains for a conflicting event:
// range [B_a, B_b] is outside the range [C_a to C_b]; C is completely within range B; B_a <= C_a STRICTLY AND B_b >= C_b
// if B_a is to the left of C_a and B_b is also to the left of C_a, there is no conflict; B is to the left but does not overlap C. likewise:
// if B_b is to the right of C_b and B_a is also to the right of C_b, there is no conflict; B is to the right but does not overlap C.
//// if(blockingStart <= candidateStart && blockingEnd >= candidateEnd){}
//combining all above into single line:
if( ( (blockingStart >= candidateStart && blockingStart < candidateEnd) || (blockingEnd > candidateStart && blockingEnd <= candidateEnd) ) || (blockingStart <= candidateStart && blockingEnd >= candidateEnd) ){
// isConflicting()
}else{
// isNotConflicting()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment