snoopyjc
snoopyjc

Reputation: 623

Creating an RRULE for the Nth WEEKDAY before or after a different WEEKDAY

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

Answers (1)

rlanvin
rlanvin

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

Related Questions