Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | 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:])

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据