rrule能否设置从每小时半点起始的30分钟间隔重复规则?
rrule 半点起止的半小时重复规则实现方案
dateutil的rrule本身不支持byhour传入非整数值,不需要硬凑小数参数,通过现有参数组合就能直接实现「工作日16:30、17:00、17:30、18:00、18:30触发」的需求,有两种简单写法:
写法1:单条rrule + bysetpos 筛选
bysetpos参数可以在其他by规则筛选出的当日候选时间集中,按排序后的位置挑选需要的条目。
每个工作日下,byhour=range(16,19)+byminute=(0,30)会筛选出6个候选时间,按顺序为16:00、16:30、17:00、17:30、18:00、18:30,只要取第2到第6个位置的条目即可,代码如下:
from dateutil.rrule import * from dateutil.parser import parse list(rrule( MINUTELY, interval=30, count=20, byhour=range(16,19), byminute=(0,30), bysetpos=(2,3,4,5,6), byweekday=(MO,TU,WE,TH,FR), dtstart=parse("20220602T070000") ))
运行后输出的前6条结果为:
[datetime.datetime(2022, 6, 2, 16, 30), datetime.datetime(2022, 6, 2, 17, 0), datetime.datetime(2022, 6, 2, 17, 30), datetime.datetime(2022, 6, 2, 18, 0), datetime.datetime(2022, 6, 2, 18, 30), datetime.datetime(2022, 6, 3, 16, 30), ... ]
完全符合需求,不会出现多余的16:00触发点。
写法2:rruleset 拆分规则组合
如果不想手动计算候选集位置,可以用rruleset把两段规则拼起来,逻辑更直观,后续调整时间范围更方便:
from dateutil.rrule import * from dateutil.parser import parse rule_set = rruleset() # 单独添加工作日16:30的触发规则 rule_set.rrule(rrule( DAILY, byhour=16, byminute=30, byweekday=(MO,TU,WE,TH,FR), dtstart=parse("20220602T163000") )) # 添加工作日17、18点整/半点的触发规则 rule_set.rrule(rrule( MINUTELY, interval=30, byhour=(17,18), byminute=(0,30), byweekday=(MO,TU,WE,TH,FR), dtstart=parse("20220602T170000") )) # 取前20条结果 list(rule_set[:20])
rrule的参数设计是将年、月、日、时、分、秒作为独立的整数字段筛选,本身就不支持传入小数类的跨字段参数,配合bysetpos、rruleset能力可以覆盖绝大多数复杂重复规则场景,灵活性高于crontab。
内容的提问来源于stack exchange,提问作者sdittmar
相关产品推荐
相关产品推荐

