В будущем, но по отношению к этому утру
Я пытаюсь вычислить следующий момент времени, который соответствует некоторым простым правилам.
Включайте только дни недели, указанные в списке (в примере ниже, пн-пт). Вернуть только те часы, которые указаны (12:00, 18:00).
Я хотел бы получить первый такой момент, начиная с After
дата предоставлена.
Я дошел до этого, но он возвращает "необоснованное" время, которое кажется постоянным смещением от текущего времени.
def NextRunTime(After=django.utils.timezone.now()):
Sched = {'Hours': [12,18], 'Days': [0,1,2,3,4]}
rule = DateRule.rrule(DateRule.HOURLY,
byweekday=Sched['Days'],
byhour=Sched['Hours'],
dtstart=After,
count=1)
return rule[0]
Это в настоящее время возвращается 2013-05-01 18:53:39+01
который, кажется, относительно текущего времени дня.
Может кто-нибудь сказать мне, как я могу получить правило использовать время относительно полуночи, но возвращать даты после After
?
Явные примеры желаемого результата
After Output
Mon 10:11:12 Mon 12:00:00
Mon 11:22:33 Mon 12:00:00
Mon 12:00:01 Mon 18:00:00
Fri 12:00:01 Fri 18:00:00
Fri 18:00:01 Mon 12:00:00 (Following Monday)
2 ответа
Я думаю, что вы ищете bysetpos = 1. Этот параметр вызывает rrule
возвращать даты, которые находятся в "позиции 1" в наборе совпадений. "позиция 1" относительно byweekday
, byhour
, byminute
, bysecond
и т. д. Итак, установив byminute=0
а также bysecond=0
, а также bysetpos=1
, rrule
всегда возвращает час 12 или час 18:
import dateutil.rrule as DateRule
import datetime as DT
def NextRunTime(After):
Sched = {'Hours': [12,18], 'Days': [0,1,2,3,4]}
rule = DateRule.rrule(DateRule.HOURLY,
byweekday=Sched['Days'],
byhour=Sched['Hours'],
byminute=0,
bysecond=0,
bysetpos=1,
# dtstart=After means rule might return After
dtstart=After,
# To ensure NextRunTime returns something after After, use
# dtstart=After+DT.timedelta(seconds=1),
count=1)
return rule[0]
tests = [
(DT.datetime(2013,4,29,10,11,12),
DT.datetime(2013,4,29,12,0,0)),
(DT.datetime(2013,4,29,11,22,33),
DT.datetime(2013,4,29,12,0,0)),
(DT.datetime(2013,4,29,12,0,1),
DT.datetime(2013,4,29,18,0,0)),
(DT.datetime(2013,5,3,12,0,1),
DT.datetime(2013,5,3,18,0,0)),
(DT.datetime(2013,5,3,18,0,1),
DT.datetime(2013,5,6,12,0,0)),
(DT.datetime(2013,4,29,12,0,0), # Note that NextRunTime(After) returns After
DT.datetime(2013,4,29,12,0,0)),
]
for After, answer in tests:
result = NextRunTime(After)
try:
assert result == answer
except AssertionError:
print('''\
result:
{result}
answer:
{answer}
'''.format(**locals()))
raise
Вы должны либо использовать dtstart
с минутами =0 и секундами =0 или самостоятельно отрежьте время от возвращенного значения.
Потому что это как rrule
как ожидается, будет работать - это добавляет некоторые интервалы к пройденному dtstart
, который в вашем случае включает в себя минуты и секунды.