python中有效的date范围重叠计算?

我有两个date范围,其中每个范围由开始和结束date(显然,datetime.date()实例)确定。 这两个范围可以重叠或不重叠。 我需要重叠的天数。 当然,我可以预先填写两个范围内的所有date,并执行一组交叉口,但这可能是低效的…除了另一个解决scheme,使用一个长的if-elif部分涵盖所有情况,有更好的方法吗?

  • 确定两个开始date中的最晚date和两个结束date中最早的date。
  • 通过减去它们来计算timedelta。
  • 如果增量是正数,那就是重叠的天数。

这是一个计算示例:

>>> 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) >>> overlap = (earliest_end - latest_start).days + 1 >>> overlap 52 

函数调用比算术运算更昂贵。

这样做的最快方法包括2次减法和1分钟():

 min(r1.end - r2.start, r2.end - r1.start).days + 1 

与需要1次减法的次好的1分钟()和最大()

 (min(r1.end, r2.end) - max(r1.start, r2.start)).days + 1 

当然,对于这两个expression式,你仍然需要检查一个正面的重叠。

伪代码:

  1 + max( -1, min( a.dateEnd, b.dateEnd) - max( a.dateStart, b.dateStart) ) 
 def get_overlap(r1,r2): latest_start=max(r1[0],r2[0]) earliest_end=min(r1[1],r2[1]) delta=(earliest_end-latest_start).days if delta>0: return delta+1 else: return 0