检查列表中的任何时间是否在两个时间戳之间

时间:2018-11-30 14:57:26

标签: python python-3.x datetime time

我正在用Python实现一些预定的任务。主程序运行24/7,并以类似于cron的方式运行各个任务。我需要确定是否应该不时地重新执行任务。

在这种情况下,我还将获得任务上一次运行的时间,当前时间(均为Unix时间戳,可通过datetime.datetime.utcnow().timestamp()获得,并可轻松转换为datetime.datetime对象)作为计划时间(例如,每小时每15分钟,例如0:151:15,...,23:15)。我想确定是否有任何安排的时间在上次运行时间和当前时间之间,可能是布尔值。确保计划的时间始终为“时间”(例如“ 2:00”),并且不包含“日期”(例如,每个月的1号或任何星期一)。

示例数据:

import datetime

scheduled = [datetime.time(h, m) for h, m in [(0, 15), (6, 15), (12, 15), (18, 15)]]
previous = datetime.datetime(2018, 11, 30, 5)
truthy = datetime.datetime(2018, 11, 30, 7)
falsey = datetime.datetime(2018, 11, 30, 6)

# some_method() is what I want
assert some_method(scheduled, previous, falsey) is False
assert some_method(scheduled, previous, truthy) is True

还有一些我想介绍的特殊情况

scheduled = [datetime.time(1, 0)]  # 1:00 AM
previous = datetime.datetime(2018, 11, 30, 23)
truthy = datetime.datetime(2018, 12, 1, 2, 0)
falsey = datetime.datetime(2018, 12, 1, 0, 30)

assert some_method(scheduled, previous, falsey) is False
assert some_method(scheduled, previous, truthy) is True

上面的示例应为True,因为计划时间“ 1 AM”在“ 11月30日晚上11点”和“ 12月1日下午2点”之间。我无法直接比较时间,因为“凌晨1点”不在同一天的“凌晨2点”和“下午11点”之间,而是在不同日期的两次之间。

2 个答案:

答案 0 :(得分:0)

一个简单的方法似乎是以下功能:

def some_method(scheduled, prev, next):
    date1 = prev.date()
    date2 = next.date()
    if (next - prev).total_seconds() > 86400:
       return True
    for s in scheduled:
        for date in {date1, date2}:
            temp = datetime.datetime(date.year, date.month, date.day, s.hour, s.minute, s.second)
            if prev < temp < next:
                return True
    return False

我会把它留给别人美化,但这似乎行得通。

答案 1 :(得分:0)

如何使用timedelta和比较timetuple

def some_method(scheduled, prev, datetime_to_check):
    yesterday = datetime_to_check - datetime.timedelta(days=1)
    schedule = [(*yesterday.timetuple()[:3], s.hour, s.minute) for s in scheduled]
    schedule.extend((*datetime_to_check.timetuple()[:3], s.hour, s.minute) for s in scheduled)
    prev_tup = prev.timetuple()
    check_tup = datetime_to_check.timetuple()
    for scheduled_time in schedule:
        if prev_tup < scheduled_time < check_tup:
            return True
    return False