如何使用Python dateutil的rrule创建特定重复规则的rruleset?
Got it, let's figure out how to build that repeating schedule with dateutil's rruleset. The pattern you want—3 consecutive Mondays, then skip a week, repeat—can be implemented in two straightforward ways, depending on which approach clicks better for you.
Method 1: Single rrule with Interval and BYSETPOS
This is the most concise way. We'll define a 4-week cycle and pick the first 3 Mondays of each cycle.
from dateutil.rrule import rrule, WEEKLY, MO from dateutil.parser import parse # Define your starting Monday (adjust this to your desired start date) start_date = parse("2024-01-01") # This is a Monday, perfect for our example # Create the rule: 4-week cycles, pick the first 3 Mondays in each cycle weekly_rule = rrule( WEEKLY, dtstart=start_date, byweekday=MO, interval=4, # Each full cycle is 4 weeks bysetpos=(1, 2, 3), # Grab the 1st, 2nd, 3rd Mondays in each 4-week cycle count=10 # Generate 10 dates to test the pattern ) # Print the results to verify print(list(weekly_rule))
Let me break this down:
FREQ=WEEKLYtells rrule we're working with weekly intervalsbyweekday=MOlocks us to Mondaysinterval=4sets a 4-week "super cycle"bysetpos=(1,2,3)selects the first three Mondays in each 4-week cycle (so 3 consecutive weeks of Mondays), then automatically skips the 4th week before repeating the cycle.
Method 2: Rruleset with Inclusion + Exclusion Rules
If you prefer a more explicit approach, you can first include all Mondays, then exclude the ones that fall in the 4th week of each cycle.
from dateutil.rrule import rruleset, rrule, WEEKLY, MO from dateutil.parser import parse from dateutil.relativedelta import relativedelta start_date = parse("2024-01-01") # Initialize the ruleset rs = rruleset() # Add the base rule: every Monday starting from our start date rs.rrule(rrule(WEEKLY, dtstart=start_date, byweekday=MO)) # Add the exclusion rule: skip every 4th Monday, starting 3 weeks after the first rs.exrule(rrule( WEEKLY, dtstart=start_date + relativedelta(weeks=3), byweekday=MO, interval=4 )) # Test by generating the first 10 dates print(list(rs)[:10])
This works by:
- First including all possible Mondays in the schedule
- Then excluding the Monday that falls exactly 3 weeks after the start, then every 4th Monday after that (which is the 4th week of each cycle we want to skip)
Both methods will produce the same pattern: 3 Mondays in a row, then a week off, then repeat indefinitely (or until you set a count or until parameter to stop it).
内容的提问来源于stack exchange,提问作者Muling

