代码之家  ›  专栏  ›  技术社区  ›  jbochi

如何计算定时事件下次执行前的时间增量

  •  1
  • jbochi  · 技术社区  · 14 年前

    1. 分钟 :0-59之间的整数列表,表示执行时间的分钟数;
    2. 小时 :0-23之间的整数列表,表示一天中应执行的时间
    3. 每周的第天 :0-6之间的整数列表,其中星期日=0,星期六=6,表示一周中应执行的天数。

    有没有一种简单的方法来计算Python下一次执行之前的timedelta是多少?

    谢谢!

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

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

    该任务应在每周1:00和1:30运行两次。 我想根据当前时间计算下一次发生前的时间差。

    2 回复  |  直到 14 年前
        1
  •  1
  •   unutbu    14 年前

    使用 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()
    

    这是下一次Delta:

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

    下面是相应的日期时间:

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

    注意,dateutil使用约定Monday=0,Sunday=6。

        2
  •  0
  •   jbochi    14 年前

    以防有人感兴趣,这是我用~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)