python date interval intersection

jjon picture jjon · Sep 15, 2010 · Viewed 12.1k times · Source

As a matter of general interest I'm wondering if there's a more elegant/efficient way to do this. I have a function that compares two start/end tuples of dates returning true if they intersect.

from datetime import date
def date_intersection(t1, t2):
    t1start, t1end = t1[0], t1[1]
    t2start, t2end = t2[0], t2[1]

    if t1end < t2start: return False
    if t1end == t2start: return True
    if t1start == t2start: return True
    if t1start < t2start and t2start < t1end: return True
    if t1start > t2start and t1end < t2end: return True
    if t1start < t2start and t1end > t2end: return True
    if t1start < t2end and t1end > t2end: return True
    if t1start > t2start and t1start < t2end: return True
    if t1start == t2end: return True
    if t1end == t2end: return True 
    if t1start > t2end: return False

so if:

d1 = date(2000, 1, 10)
d2 = date(2000, 1, 11)
d3 = date(2000, 1, 12)
d4 = date(2000, 1, 13)

then:

>>> date_intersection((d1,d2),(d3,d4))
False
>>> date_intersection((d1,d2),(d2,d3))
True
>>> date_intersection((d1,d3),(d2,d4))
True

etc.

I'm curious to know if there's a more pythonic/elegant/more efficient/less verbose/generally better, way to do this with maybe mxDateTime or some clever hack with timedelta or set()?

An alternative and useful form would be for the function to return a start/end tuple of the intersection if one is found

Thanks

Answer

Andrew picture Andrew · Sep 15, 2010

It's not really more Pythonic, but you can simply the logic to decide on an intersection somewhat. This particular problems crops up a lot:

return (t1start <= t2start <= t1end) or (t2start <= t1start <= t2end)

To see why this works think about the different possible ways that the two intervals can intersect and see that the starting point of one must always be within the range of the other.