I think you are looking for bysetpos = 1. This parameter causes rrule
to return datetimes which are at "position 1" in a set of matches. "position 1" is relative to the byweekday
, byhour
, byminute
, bysecond
, etc. So by setting byminute=0
and bysecond=0
, and bysetpos=1
, rrule
always returns hour 12 or hour 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