сумма алгоритма временного интервала python - PullRequest
4 голосов
/ 25 августа 2009

Предположим, у меня есть 2 временных интервала, например, 16:30 - 20:00 И 15:00 - 19:00, мне нужно найти общее время между этими двумя интервалами, чтобы результат составил 5 часов (я добавляю оба интервала и вычесть пересекающийся интервал), как я могу написать универсальную функцию, которая также имеет дело со всеми случаями, такими как один интервал внутри другого (так что результатом является интервал большего), без пересечения (так что результат является суммой обоих интервалы).

Моя структура входящих данных примитивна, просто строка типа "15:30", поэтому может потребоваться преобразование.

Спасибо

Ответы [ 4 ]

3 голосов
/ 25 августа 2009
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 голосов
/ 25 августа 2009

Вы захотите конвертировать ваши строки в datetime. Вы можете сделать это с 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)
0 голосов
/ 25 августа 2009

Код для случаев наложения, добавьте его в одно из своих решений:

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 голосов
/ 25 августа 2009

Я предполагаю, что вы можете сделать преобразование во что-то вроде datetime самостоятельно.

Суммируйте два интервала, затем вычтите любое перекрытие. Вы можете получить перекрытие, сравнивая минимальное и максимальное значения каждого из двух диапазонов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...