时间片计算
版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc
###起因
要进行预约时间的计算,干脆做一个简单的模块专门用于时间片的计算,等时间有空了会传到pypi上
1. 时间片的合并
ll = []
dd = {
"start_time": "20:00",
"end_time": "22:00"
}
ll.append(dd)
dd = {
"start_time": "10:00",
"end_time": "12:00"
}
ll.append(dd)
dd = {
"start_time": "14:00",
"end_time": "18:00"
}
ll.append(dd)
dd = {
"start_time": "15:00",
"end_time": "17:00"
}
ll.append(dd)
dd = {
"start_time": "11:00",
"end_time": "15:00"
}
ll.append(dd)
dd = {
"start_time": "18:00",
"end_time": "19:00"
}
ll.append(dd)
res = TimeFrame.merge(ll)
record = res[0]
assert record['start_time'] == "10:00"
assert record['end_time'] == "19:00"
record = res[1]
assert record['start_time'] == "20:00"
assert record['end_time'] == "22:00"
2. 时间片相减
item_list1 = []
dd = {
"start_time": "08:00",
"end_time": "15:00",
}
item_list1.append(dd)
item_list2 = []
dd = {
"start_time": "09:00",
"end_time": "10:00",
}
item_list2.append(dd)
dd = {
"start_time": "11:00",
"end_time": "12:00",
}
item_list2.append(dd)
res_list = TimeFrame.minus(item_list1, item_list2)
record = res_list[0]
assert record['start_time'] == "08:00"
assert record['end_time'] == "09:00"
record = res_list[1]
assert record['start_time'] == "10:00"
assert record['end_time'] == "11:00"
record = res_list[2]
assert record['start_time'] == "12:00"
assert record['end_time'] == "15:00"
代码如下
time_frame.py
# encoding=utf-8
class TimeFrame(object):
@staticmethod
def merge(record_list):
record_list = sorted(record_list, key=lambda x: x['start_time'])
return TimeFrame.aggs(record_list)
@staticmethod
def minus(record_list1, record_list2):
record_list1 = TimeFrame.merge(record_list1)
record_list2 = TimeFrame.merge(record_list2)
for record2 in record_list2:
res_list = []
for record1 in record_list1:
res_list.extend(TimeFrame.minus_record(record1, record2))
record_list1 = res_list
res_list = TimeFrame.merge(res_list)
return res_list
@staticmethod
def minus_record(record1, record2):
if not TimeFrame.is_overlap(record1, record2):
return [record1]
res = []
if record1['start_time'] <= record2['start_time'] and record1['end_time'] >= record2['end_time']:
temp = {
"start_time": record1['start_time'],
"end_time": record2['start_time']
}
res.append(temp)
temp = {
"start_time": record2['end_time'],
"end_time": record1['end_time']
}
res.append(temp)
elif record1['start_time'] <= record2['start_time'] and record1['end_time'] <= record2['end_time']:
temp = {
"start_time": record1['start_time'],
"end_time": record2['start_time']
}
res.append(temp)
elif record1['start_time'] >= record2['start_time'] and record1['end_time'] >= record2['end_time']:
temp = {
"start_time": record2['end_time'],
"end_time": record1['end_time']
}
res.append(temp)
# record1['start_time'] >= record2['start_time'] and record1['end_time'] <= record2['end_time']:
ll = []
for record in res:
if record['end_time'] > record['start_time']:
ll.append(record)
return ll
@staticmethod
def is_overlap(item1, item2):
'''
item1的start_time小于等于item2的start_time
:param item1:
:param item2:
:return:
'''
# case 1
# |_________|
# |_______|
if item2['end_time'] >= item1['start_time'] and item2['end_time'] <= item1['end_time']:
return True
# case 2
# |_________|
# |_______|
if item2['start_time'] >= item1['start_time'] and item2['start_time'] <= item1['end_time']:
return True
return False
@staticmethod
def aggs(record_list):
if len(record_list) < 2:
return record_list
item1 = record_list[0]
item2 = record_list[1]
if TimeFrame.is_overlap(item1, item2):
dd = {
"start_time": min(item1['start_time'], item2['start_time']),
"end_time": max(item1['end_time'], item2['end_time'])
}
if len(record_list) > 2:
return TimeFrame.aggs([dd] + record_list[2:])
else:
return [dd]
else:
return [item1] + TimeFrame.aggs(record_list[1:])