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