Лучшее предложение: судите их всех. Это не займет много времени.
Мой фаворит: Jinja2 (милей)
Это имеет достойный синтаксис, может проследить ошибки через него и sandboxable.
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
Код на случай перекрытия, добавьте его в одно из ваших решений:
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
Я предполагаю, что вы можете выполнить преобразование во что-то вроде 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)