检查两个时间间隔是否重叠

时间:2016-02-26 05:39:46

标签: python python-2.7 datetime time compare

我有两种不同的间隔集:

Intervals1:
{'ending_time': '2016-02-26 07:10:40.276504', 'starting_time': '2016-02-26 07:10:39.286168'}
{'ending_time': '2016-02-26 07:10:40.722193', 'starting_time': '2016-02-26 07:10:40.301116'}
{'ending_time': '2016-02-26 07:10:41.329731', 'starting_time': '2016-02-26 07:10:40.812676'}
{'ending_time': '2016-02-26 07:10:42.146669', 'starting_time': '2016-02-26 07:10:41.419473'}
{'ending_time': '2016-02-26 07:10:42.413005', 'starting_time': '2016-02-26 07:10:42.203540'}
{'ending_time': '2016-02-26 07:10:42.686456', 'starting_time': '2016-02-26 07:10:42.442964'}
{'ending_time': '2016-02-26 07:10:43.198191', 'starting_time': '2016-02-26 07:10:42.746994'}
{'ending_time': '2016-02-26 07:10:44.502593', 'starting_time': '2016-02-26 07:10:43.288611'}
{'ending_time': '2016-02-26 07:10:46.525823', 'starting_time': '2016-02-26 07:10:44.709627'}
{'ending_time': '2016-02-26 07:10:47.098280', 'starting_time': '2016-02-26 07:10:46.886541'}
--------------------------
Interval2:
{'ending_time': '2016-02-26 07:10:41.482954', 'starting_time': '2016-02-26 07:10:39.590220'}
{'ending_time': '2016-02-26 07:10:42.615738', 'starting_time': '2016-02-26 07:10:41.649375'}
{'ending_time': '2016-02-26 07:10:46.365902', 'starting_time': '2016-02-26 07:10:45.987907'}
{'ending_time': '2016-02-26 07:10:47.698375', 'starting_time': '2016-02-26 07:10:46.510641'}

我正在使用以下行将这些日期时间字符串转换为实际的日期时间对象:

datetime.datetime.strptime(dictionary['starting_time'], "%Y-%m-%d %H:%M:%S.%f")

我在这里要做的是通过比较这两个不同的集来匹配重叠的时间间隔。

例如;间隔1 [0]和间隔2 [0]重叠 但是Intervals1 [7]和Intervals2 [0]没有重叠。

那么这样做的正确方法是什么?对我来说,一个简短的解释就足够了。

3 个答案:

答案 0 :(得分:3)

datetime个对象支持比较,因此您只需要检查第一个开始时间是否在另一个的开始和结束之间,或者第一个结束时间是否在其他开始时间之间,反之亦然。

def overlap(first_inter,second_inter):
    for f,s in ((first_inter,second_inter), (second_inter,first_inter)):
        #will check both ways
        for time in (f["starting_time"], f["ending_time"]):
            if s["starting_time"] < time < s["ending_time"]:
                return True
    else:
        return False

编辑:还要注意,因为日期字符串的格式首先具有最重要的值,所以可以轻松比较而不将它们转换为datetime个对象。

Edit2:这是一个将所有组合及其结果记录到字典中的方法:

import itertools

combos = {(i1,i2):overlap(int1,int2)
             for (i1,int1),(i2,int2)
                in itertools.product(enumerate(Intervals1),enumerate(Intervals2))}

print(*combos.items(),sep="\n")

这种方式combos[0,1]Intervals[0]Intervals[1]重叠等等。

然后只需获得一组重叠时间即可:

overlapped = set(com for com,was_overlapped in combos.items() if was_overlapped)

最后编辑:我为使用非常长的dict comprehension道歉,如果原始的时间列表有一个模式然后只使用for循环部分,那么很难处理混乱格式的数据dict理解会产生预期的结果:

for (i1,int1),(i2,int2) in itertools.product(enumerate(Intervals1),enumerate(Intervals2)):
    if overlap(int1,int2):
        print(i1,i2)

或要对overlapped集进行排序,您可以使用sorted内置:

overlapped = sorted(overlapped) #this gives a list

答案 1 :(得分:1)

您可以比较这样的范围:

timerange1 = {'ending_time': '2016-02-26 07:10:40.276504', 'starting_time': '2016-02-26 07:10:39.286168'}
timerange2 = {'ending_time': '2016-02-26 07:10:41.482954', 'starting_time': '2016-02-26 07:10:39.590220'}

# use a function to make this 'interval' data structure (instead of me being lazy)
interval1 = [datetime.datetime.strptime(timerange1['starting_time'], "%Y-%m-%d %H:%M:%S.%f")]
             datetime.datetime.strptime(timerange1['ending_time'], "%Y-%m-%d %H:%M:%S.%f")]
interval2 = [datetime.datetime.strptime(timerange2['starting_time'], "%Y-%m-%d %H:%M:%S.%f")]
             datetime.datetime.strptime(timerange2['ending_time'], "%Y-%m-%d %H:%M:%S.%f")]

def overlaps(interval1, interval2):
    results = []
    for timestamp in interval1:
        results.append(interval2[0] < timestamp < interval2[1])
    for timestamp in interval2:
        results.append(interval1[0] < timestamp < interval1[1])
    return True in results

答案 2 :(得分:0)

下面的间隔2中的m个记录和间隔2中的n个记录仅需要2百万个比较,而不是4毫秒。

Intervals1 = [
    {'ending_time': '2016-02-26 07:10:40.276504', 'starting_time': '2016-02-26 07:10:39.286168'},
    {'ending_time': '2016-02-26 07:10:40.722193', 'starting_time': '2016-02-26 07:10:40.301116'},
    {'ending_time': '2016-02-26 07:10:41.329731', 'starting_time': '2016-02-26 07:10:40.812676'},
    {'ending_time': '2016-02-26 07:10:42.146669', 'starting_time': '2016-02-26 07:10:41.419473'},
    {'ending_time': '2016-02-26 07:10:42.413005', 'starting_time': '2016-02-26 07:10:42.203540'},
    {'ending_time': '2016-02-26 07:10:42.686456', 'starting_time': '2016-02-26 07:10:42.442964'},
    {'ending_time': '2016-02-26 07:10:43.198191', 'starting_time': '2016-02-26 07:10:42.746994'},
    {'ending_time': '2016-02-26 07:10:44.502593', 'starting_time': '2016-02-26 07:10:43.288611'},
    {'ending_time': '2016-02-26 07:10:46.525823', 'starting_time': '2016-02-26 07:10:44.709627'},
    {'ending_time': '2016-02-26 07:10:47.098280', 'starting_time': '2016-02-26 07:10:46.886541'}
    ]
Intervals2 = [
    {'ending_time': '2016-02-26 07:10:41.482954', 'starting_time': '2016-02-26 07:10:39.590220'},
    {'ending_time': '2016-02-26 07:10:42.615738', 'starting_time': '2016-02-26 07:10:41.649375'},
    {'ending_time': '2016-02-26 07:10:46.365902', 'starting_time': '2016-02-26 07:10:45.987907'},
    {'ending_time': '2016-02-26 07:10:47.698375', 'starting_time': '2016-02-26 07:10:46.510641'}
    ]

for i1, d1 in enumerate(Intervals1):
  for i2, d2 in enumerate(Intervals2):
    start1 = d1["starting_time"]
    start2 = d2["starting_time"]
    end1 = d1["ending_time"]
    end2 = d2["ending_time"]

    if end1 >= start2 and end2 >= start1:
        print("Intervals1", i1, "overlaps with Intervals2", i2)