如何计算timedelta直到下次执行预定事件

时间:2010-09-01 13:28:29

标签: python datetime

我有三个列表定义何时应该执行任务:

  1. 分钟:0-59之间的整数列表,表示执行应该发生的一小时的分钟数;
  2. 小时:0-23之间的整数列表,表示执行一天的小时数
  3. day_of_week :0-6的整数列表,其中星期日= 0,星期六= 6,表示应执行一周的日期。
  4. 有没有一种简单的方法来计算在Python下次执行之前的timedelta是什么时候?

    谢谢!

    修改 例如,如果我们有以下列表:

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

    任务应该每周运行两次,每周日1:00和1:30。 我想根据当前时间计算timedelta直到下一次出现。

2 个答案:

答案 0 :(得分:1)

使用dateutil(编辑以解决OP的更新问题):

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使用约定Monday = 0,Sunday = 6。

答案 1 :(得分: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)