Reputation: 623
I see with interest the following RRULE:
Every four years, the first Tuesday after a Monday in November, 3 occurrences (U.S. Presidential Election day):
>>> list(rrule(YEARLY, interval=4, count=3, bymonth=11,
... byweekday=TU, bymonthday=(2,3,4,5,6,7,8),
... dtstart=parse("19961105T090000")))
[datetime.datetime(1996, 11, 5, 9, 0),
datetime.datetime(2000, 11, 7, 9, 0),
datetime.datetime(2004, 11, 2, 9, 0)]
What I'd like to know, is how to create the general algorithm for the Nth WEEKDAY before or after a different WEEKDAY with an RRULE. (Prefer in python but pseudo-code is fine.)
Upvotes: 0
Views: 800
Reputation: 6277
Let's first understand how the US Presidential Election day rule works.
the first Tuesday after a Monday in November
Starting with the obvious: BYWEEYKDAY=TU
limit the occurrences to Tuesdays, and BYMONTH=11
to November.
However this would return all Tuesdays in November.
How to create "the first Tuesday after a Monday"?
The 1st of November can only be one of the 7 weekdays. If the 1st of November is a Monday, then the first Tuesday would be the 2nd. If the 1st of November is a Sunday, then the 2nd of November is a Monday, then the first Tuesday is the 3rd. And so on, until the last possible option: if the 1st of November is a Tuesday, then the 7th of November is a Monday and then 8th if the first Tuesday after a Monday in November.
Therefore the first Tuesday after a Monday in November can only be either the 2nd, 3rd, 4th, 5th, 6th, 7th or 8th. That's what BYMONTHDAY=2,3,4,5,6,7,8
is doing.
how to create the general algorithm for the Nth WEEKDAY before or after a different WEEKDAY
You will simply need to generalize this logic. A month can only start with one of the 7 week days, so you really only have 7 solutions each time. I'll try to describe the general approach, but you'll probably need some trial and error to fix the exact formula.
Let's take the first Wednesday after a Monday. Wednesday - Monday = 2
. Monday can be the 1st to the 7th. So the first Wednesday after a Monday can be the 1+2=3rd to the 7+2=9th. BYWEEYKDAY=WE
+ BYMONTHDAY=3,4,5,6,7,8,9
The second Wednesday after a Monday would be 1+2+7=10th to the 7+2+7=16th. BYWEEYKDAY=WE
+ BYMONTHDAY=10,11,12,13,14,15,16
.
And so on.
Upvotes: 1