This case can be handled by a slight generalization of Charles Bretana's excellent answer to that question.
Let CondA Mean DateRange A Completely After DateRange B (True if StartA > EndB)
Let CondB Mean DateRange A Completely Before DateRange B (True if EndA < StartB)
In this case, assuming you want a null date to represent "no starting/ending bound," the conditions are modified. For CondA
, for instance, in order for DateRange A to be completely after DateRange B, DateRange A must have a defined starting time, DateRange B must have a defined ending time, and the starting time of A must be after the ending time of B:
CondA := (StartA != null) && (EndB != null) && (StartA > EndB)
CondB
is the same with A and B switched:
CondB := (StartB != null) && (EndA != null) && (StartB > EndA)
Continuing,
Then Overlap exists if Neither A Nor B is true
Overlap := !(CondA || CondB)
and
Now deMorgan's law, I think it is, says that
Not (A Or B) <=> Not A And Not B
Overlap == !CondA && !CondB
== ![(StartA != null) && (EndB != null) && (StartA > EndB)] &&
![(StartB != null) && (EndA != null) && (StartB > EndA)]
== [(StartA == null) || (EndB == null) || (StartA <= EndB)] &&
[(StartB == null) || (EndA == null) || (StartB <= EndA)]
I think this is actually a bit more robust than the solution you developed, because if EndB == NULL
but StartA
is not null, your first condition will wind up comparing StartA <= NULL
. In most languages I'm familiar with, that's an error condition.