2010-09-01 51 views
1

我有三個列表定義,當一個任務應該執行:如何計算timedelta直到下一次執行安排事件

  1. 分鐘:從0-59代表的會議紀要整數列表執行應該發生的時間;
  2. 小時:從0-23表示一天,執行應該發生
  3. DAY_OF_WEEK的的小時數的整數列表:整數0-6,A列表,其中星期日= 0和星期六= 6,這代表了執行應該發生一週的日子。

有沒有簡單的方法來計算什麼是timedelta直到下一次在Python中執行?

謝謝!

編輯: 例如,如果我們有以下列表:

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

任務應該在一個星期在1:00和1:30每週日運行兩次。 我想根據當前時間來計算timedelta,直到下一次發生。

+0

您是否希望使用'day_of_week x hour x minute'所有可能的產品來構造日期時間?例如,如果day_of_week有2個元素,小時有3個元素,分鐘有4個元素,你會發生什麼?會有24個日期嗎? – unutbu 2010-09-01 14:26:15

+0

我只對下一個日期時間感興趣,不管每個列表有多少個元素。 – jbochi 2010-09-01 14:30:49

回答

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

這下timedelta:

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

這裏是對應的日期時間:

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

請注意,dateutil使用大會星期一= 0,星期日= 6.

+0

恐怕這不正確。列表不需要具有相同的大小。我爲我的問題添加了一個例子。無論如何,感謝dateutil的建議。 – jbochi 2010-09-01 14:16:10

+0

順便說一句,使用你生成的contactors,下一次出現將是2010-09-02 01:04:00 – jbochi 2010-09-01 14:21:12

+0

@jbochi:數據是隨機生成的。每次你運行腳本的時候都會有所不同。 – unutbu 2010-09-01 14:29:34

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)