python日期间隔交集

2024-06-11 20:55:30 发布

您现在位置:Python中文网/ 问答频道 /正文

作为一个普遍感兴趣的问题,我想知道是否有一种更优雅/更有效的方法来做到这一点。我有一个函数,它比较两个日期的开始/结束元组,如果它们相交,则返回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

等等

我很想知道是否有一种更像Python的/优雅的/更高效的/不那么冗长的/通常更好的方法,可以用mxDateTime来实现,或者用timedelta或set()来实现?

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

谢谢


Tags: andtruedatereturnifd2d1d3
3条回答

这并不是真正的Python,但你可以简单的逻辑来决定一个交叉点。这种特殊的问题经常出现:

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

要了解为什么这样做,请考虑两个间隔可以相交的不同可能方式,并查看一个间隔的起点必须始终在另一个间隔的范围内。

这是一个给你交集范围的版本。当然,这可能不是最优化的条件,但它清楚地显示了当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

另一种可能更容易理解的解决方案:

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)。请注意,最早开始可以等于最早结束。

应该注意的是,这假设A_start <= A_endB_start <= B_end

相关问题 更多 >