Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient date range overlap calculation in python?

I have two date ranges where each range is determined by a start and end date (obviously, datetime.date() instances). The two ranges can overlap or not. I need the number of days of the overlap. Of course I can pre-fill two sets with all dates within both ranges and the perform a set intersection but this is possibly inefficient...is there a better way apart from another solution using a long if-elif section covering all cases ?

like image 889
Andreas Jung Avatar asked Jan 28 '12 09:01

Andreas Jung


People also ask

How do you determine overlapping date ranges?

You can do this by swapping the ranges if necessary up front. Then, you can detect overlap if the second range start is: less than or equal to the first range end (if ranges are inclusive, containing both the start and end times); or. less than (if ranges are inclusive of start and exclusive of end).

How does Python determine overlapping data?

You can also look for overlapping data in sets by using the . intersection() method on a set and passing another set as an argument. It will return an empty set if nothing matches.

How do you know if two time intervals overlap Python?

overlaps() method is used to Check whether Interval objects are overlapping. Two intervals, including closed ends, overlap if they share the same point.


1 Answers

  • Determine the latest of the two start dates and the earliest of the two end dates.
  • Compute the timedelta by subtracting them.
  • If the delta is positive, that is the number of days of overlap.

Here is an example calculation:

>>> from datetime import datetime >>> from collections import namedtuple >>> Range = namedtuple('Range', ['start', 'end'])  >>> r1 = Range(start=datetime(2012, 1, 15), end=datetime(2012, 5, 10)) >>> r2 = Range(start=datetime(2012, 3, 20), end=datetime(2012, 9, 15)) >>> latest_start = max(r1.start, r2.start) >>> earliest_end = min(r1.end, r2.end) >>> delta = (earliest_end - latest_start).days + 1 >>> overlap = max(0, delta) >>> overlap 52 
like image 161
Raymond Hettinger Avatar answered Sep 19 '22 02:09

Raymond Hettinger