python日期间隔交集

时间:2010-09-15 19:47:29

标签: python datetime intersection

作为一个普遍关注的问题,我想知道是否有更优雅/更有效的方法来做到这一点。我有一个函数比较两个日期的开始/结束元组,如果它们相交,则返回true。

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

所以如果:

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

然后:

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

我很想知道是否有一个更pythonic /更优雅/更有效/更简洁/更好的方式来做这个可能mxDateTime或一些聪明的黑客与timedelta或set()?

另一个有用的形式是函数返回交集的开始/结束元组(如果找到一个)

由于

6 个答案:

答案 0 :(得分:20)

这不是更多的Pythonic,但你可以简单地用逻辑来决定一个交叉点。这个特殊的问题出现了很多:

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

要了解为什么这个有效可以考虑两个区间可以交叉的不同可能方式,并看到一个区间的起点必须始终在另一个区间的范围内。

答案 1 :(得分:7)

另一种希望更容易理解的解决方案:

def has_overlap(A_start, A_end, B_start, B_end):
    latest_start = max(A_start, B_start)
    earliest_end = min(A_end, B_end)
    return latest_start <= earliest_end:

我们可以轻松获得重叠的间隔,它是(latest_start, earliest_end)。请注意,latest_start可以等于earliest_end。

应该注意,这假定为A_start <= A_endB_start <= B_end

答案 2 :(得分:6)

这是一个为您提供交叉范围的版本。恕我直言,它可能不是最优化的条件,但它清楚地显示t2何时与t1重叠。如果您只想要真/假,可以根据其他答案进行修改。

if (t1start <= t2start <= t2end <= t1end):
    return t2start,t2end
elif (t1start <= t2start <= t1end):
    return t2start,t1end
elif (t1start <= t2end <= t1end):
    return t1start,t2end
elif (t2start <= t1start <= t1end <= t2end):
    return t1start,t1end
else:
    return None

答案 3 :(得分:3)

Final Comparison: start <= other_finish and other_start <= finish

# All of the conditions below result in overlap I have left out the non overlaps

start <= other_start | start <= other_finish | other_start <= finish | finish <= other_finish 

      0                        1                        1                        0                   
      0                        1                        1                        1
      1                        1                        1                        0          
      1                        1                        1                        1

只有开始&lt; = other_finish other_start&lt; = finish 才能返回重叠。

答案 4 :(得分:2)

intersection_length = min(t1end, t2end) - max(t1start, t2start)
return intersection_length >= 0 

这将接受由单个点组成的交点;否则请使用> 0

直觉是相交的间隔(如果存在)从最高起点开始,在最低终点结束。有两种可能性:

  1. 这是一个正确的间隔,长度可能为零。

  2. 起点和终点最终被切换。这意味着两个间隔之间有一个间隙,您可以将其称为“负相交”。

答案 5 :(得分:0)

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

那不会涵盖所有交叉集吗?