5

16:30 - 20:00 および 15:00 - 19:00 などの 2 つの時間間隔があると仮定すると、これら 2 つの間隔の間の合計時間を見つける必要があるため、結果は 5 時間になります (両方の間隔を加算して、交差する間隔)、他の間隔内の 1 つの間隔 (したがって、結果はより大きな間隔)、交差なし (結果は両方の間隔の合計) などのすべてのケースも処理する汎用関数を作成するにはどうすればよいですか?

私の受信データ構造はプリミティブで、「15:30」のような単純な文字列であるため、変換が必要になる場合があります。

ありがとう

4

4 に答える 4

4
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
于 2009-08-24T21:20:39.900 に答える
0

自分でdatetimeのようなものに変換できると思います。

2 つの間隔を合計してから、重複を減算します。2 つの範囲のそれぞれの最小値と最大値を比較することで、重複を取得できます。

于 2009-08-24T21:12:39.603 に答える
0

重複がある場合のコードは、ソリューションの 1 つに追加してください。

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
于 2009-08-24T21:30:44.670 に答える
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)
于 2009-08-24T22:55:39.833 に答える