2009-08-24 286 views
3

假設我有兩個時間間隔,例如16:30 - 20:00和15:00 - 19:00,我需要找到這兩個時間間隔之間的總時間,所以結果是5小時(我加上兩個區間並減去相交區間),我該如何編寫一個通用函數,該函數還處理所有情況,例如一個區間內的其他區域(所以結果是大區間的區間),沒有交點(所以結果是兩個區間的總和)。python時間間隔算法總和

我的傳入數據結構是原始的,只是字符串像「15:30」,所以可能需要轉換。

感謝

回答

3
from datetime import datetime, timedelta 

START, END = xrange(2) 
def tparse(timestring): 
    return datetime.strptime(timestring, '%H:%M') 

def sum_intervals(intervals): 
    times = [] 
    for interval in intervals: 
     times.append((tparse(interval[START]), START)) 
     times.append((tparse(interval[END]), END)) 
    times.sort() 

    started = 0 
    result = timedelta() 
    for t, type in times: 
     if type == START: 
      if not started: 
       start_time = t 
      started += 1 
     elif type == END: 
      started -= 1 
      if not started: 
       result += (t - start_time) 
    return result 

測試你的時間從一個問題:

intervals = [ 
       ('16:30', '20:00'), 
       ('15:00', '19:00'), 
      ] 
print sum_intervals(intervals) 

,打印:

5:00:00 

測試它與數據一起不重疊

intervals = [ 
       ('16:30', '20:00'), 
       ('15:00', '19:00'), 
       ('03:00', '04:00'), 
       ('06:00', '08:00'), 
       ('07:30', '11:00'), 
      ] 
print sum_intervals(intervals) 

結果:

11:00:00 
+0

如果沒有重疊不工作。 – 2009-08-24 21:23:32

0

我假設你可以做轉換到你自己像datetime

總結兩個間隔,然後減去任何重疊。您可以通過比較兩個範圍中的每個範圍的最小值和最大值來獲得重疊。

0

代碼時存在重疊,請把它添加到您的解決方案之一:

def interval(i1, i2): 
    minstart, minend = [min(*e) for e in zip(i1, i2)] 
    maxstart, maxend = [max(*e) for e in zip(i1, i2)] 

    if minend < maxstart: # no overlap 
     return minend-minstart + maxend-maxstart 
    else: # overlap 
     return maxend-minstart 
0

你會想你的字符串轉換成日期時間。你可以用datetime.datetime.strptime來做到這一點。

鑑於datetime.datetime對象的時間間隔,如果間隔:

int1 = (start1, end1) 
int2 = (start2, end2) 

那麼是不是隻是:

if end1 < start2 or end2 < start1: 
    # The intervals are disjoint. 
    return (end1-start1) + (end2-start2) 
else: 
    return max(end1, end2) - min(start1, start2)