如何计算计划事件下一次执行的时间间隔

1 投票
2 回答
652 浏览
提问于 2025-04-16 03:35

我有三个列表,用来定义一个任务应该什么时候执行:

  1. 分钟:一个包含0到59的整数的列表,表示任务在一个小时内的具体分钟数;
  2. 小时:一个包含0到23的整数的列表,表示任务在一天内的具体小时数;
  3. 星期几:一个包含0到6的整数的列表,其中0代表星期天,6代表星期六,表示任务在一周内的具体哪一天执行。

有没有简单的方法可以计算出下次执行的时间间隔(timedelta)呢?

谢谢!

补充说明:

比如,如果我们有以下列表:

day_of_week = [0]
hour = [1]
minute = [0, 30]

这个任务应该每周在星期天的1:00和1:30执行两次。我想根据当前时间计算出到下次执行的时间间隔。

2 个回答

0

如果有人感兴趣的话,这里是我根据~unutbu的建议写的代码。它的主要优点是能够很好地扩展。

import datetime
import dateutil.relativedelta as dr

def next_ocurrance(minutes, hours, days_of_week):
    # days_of_week convention: Sunday = 0, Saturday = 6
    # dateutil convention: Monday = 0, Sunday = 6

    now = datetime.datetime.now()
    weekday = now.isoweekday()
    execute_this_hour = weekday in days_of_week \
                        and now.hour in hours \
                        and now.minute < max(minutes)

    if execute_this_hour:
        next_minute = min([minute for minute in minutes
                           if minute > now.minute])
        return now + dr.relativedelta(minute=next_minute,
                                      second=0,
                                      microsecond=0)
    else:
        next_minute = min(minutes)

    execute_today = weekday in day_of_week \
                    and (now.hour < max(hours) or execute_this_hour)

    if execute_today:
        next_hour = min([hour for hour in hours if hour > now.hour])
        return now + dr.relativedelta(hour=next_hour,
                                      minute=next_minute,
                                      second=0,
                                      microsecond=0)
    else:
        next_hour = min(hours)
        next_day = min([day for day in days_of_week if day > weekday] \
                       or days_of_week)

        return now + dr.relativedelta(weekday=(next_day - 1) % 7,
                                      hour=next_hour,
                                      minute=next_minute,
                                      second=0,
                                      microsecond=0)
if __name__=='__main__':
    day_of_week = [4]
    hour = [1, 10, 12, 13]
    minute = [4, 14, 34, 51, 58]
    print next_ocurrance(minute, hour, day_of_week)
1

使用 dateutil编辑以回应提问者更新的问题):

import datetime
import random
import dateutil.relativedelta as dr
import itertools

day_of_week = [1,3,5,6]
hour = [1,10,15,17,20]
minute = [4,34,51,58]

now=datetime.datetime.now()
deltas=[]

for min,hr,dow in itertools.product(minute,hour,day_of_week):
    # dateutil convention: Monday = 0, Sunday = 6.
    next_dt=now+dr.relativedelta(minute=min,hour=hr,weekday=dow)
    delta=next_dt-now
    deltas.append(delta)

deltas.sort()

这是下一个时间间隔:

print(deltas[0])
# 4 days, 14:22:00

这里是对应的日期时间:

print(now+deltas[0])
# 2010-09-02 01:04:23.258204

请注意,dateutil 采用的规则是:星期一 = 0,星期天 = 6。

撰写回答