(StartA <= EndB) and (EndA >= StartB)

Proof:
Let ConditionA Mean that DateRange A Completely After DateRange B
`_ |---- DateRange A ------| |---Date Range B -----| _`
(True if `StartA > EndB`)

Let ConditionB Mean that DateRange A is Completely Before DateRange B
`|---- DateRange A -----| _ _ |---Date Range B ----|`
(True if `EndA < StartB`)

Then Overlap exists if Neither A Nor B is true -
(If one range is neither completely after the other,
nor completely before the other, then they must overlap.)

Now one of De Morgan's laws says that:

`Not (A Or B)` <=> `Not A And Not B`

Which translates to: `(StartA <= EndB) and (EndA >= StartB)`

NOTE: This includes conditions where the edges overlap exactly. If you wish to exclude that,
change the `>=` operators to `>`, and `<=` to `<`

NOTE2. Thanks to @Baodad, see this blog, the actual overlap is least of:
{ `endA-startA`, `endA - startB`, `endB-startA`, `endB - startB` }

`(StartA <= EndB) and (EndA >= StartB)` `(StartA <= EndB) and (StartB <= EndA)`

NOTE3. Thanks to @tomosius, a shorter version reads:
`DateRangesOverlap = max(start1, start2) < min(end1, end2)`
This is actually a syntactical shortcut for what is a longer implementation, which includes extra checks to verify that the start dates are on or before the endDates. Deriving this from above:

If start and end dates can be out of order, i.e., if it is possible that `startA > endA` or `startB > endB`, then you also have to check that they are in order, so that means you have to add two additional validity rules:
`(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB)` or:
`(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB)` or,
`(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB))` or:
`(Max(StartA, StartB) <= Min(EndA, EndB)`

But to implement `Min()` and `Max()`, you have to code, (using C ternary for terseness),:
`(StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)`