[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: BYDAY and YEARLY




Dan wrote on 07/07/2003 03:16:10 PM:
> The issue is the use of BYDAY as follows to mean the last Sunday in October.
> RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
>
> The BYDAY on yearly refers to weeks of the year and not weeks of the month
> so this really means the last Sunday of the year but only if it occurs in
> October.  The last week of the year will always be in December of course so
> the above rule never resolves to any valid dates.

I think a couple points from 2445 may help here (all from Section 4.3.10 Recurrence Rule).  The first tidbit:

   Each BYDAY value can also be preceded by a positive (+n) or negative
  (-n) integer. If present, this indicates the nth occurrence of the
  specific day within the MONTHLY or YEARLY RRULE. For example, within
  a MONTHLY rule, +1MO (or simply 1MO) represents the first Monday
  within the month, whereas -1MO represents the last Monday of the
  month. If an integer modifier is not present, it means all days of
  this type within the specified frequency. For example, within a
  MONTHLY rule, MO represents all Mondays within the month.

The second tidbit is:

   BYxxx rule parts modify the recurrence in some manner. BYxxx rule
  parts for a period of time which is the same or greater than the
  frequency generally reduce or limit the number of occurrences of the
  recurrence generated. For example, "FREQ=DAILY;BYMONTH=1" reduces the
  number of recurrence instances from all days (if BYMONTH tag is not
  present) to all days in January. BYxxx rule parts for a period of
  time less than the frequency generally increase or expand the number
  of occurrences of the recurrence. For example,
  "FREQ=YEARLY;BYMONTH=1,2" increases the number of days within the
  yearly recurrence set from 1 (if BYMONTH tag is not present) to 2.

  If multiple BYxxx rule parts are specified, then after evaluating the
  specified FREQ and INTERVAL rule parts, the BYxxx rule parts are
  applied to the current set of evaluated occurrences in the following
  order: BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, BYDAY, BYHOUR,
  BYMINUTE, BYSECOND and BYSETPOS; then COUNT and UNTIL are evaluated.


This second tidbit describes the case in Dans example rule; the BYDAY and BYMONTH modify the recurrence by expanding the set.  However since the BYMONTH and BYDAY parts only have 1 value each the set is not actually expanded but more modified.

By applying the first tidbit alone to just RRULE:FREQ=YEARLY;BYDAY=-1SU alone I would get the last Sunday in the year (the date is calculatable, the time is inherited from DTSTART).  However as Ki noted (from the second tidbit) there are other modifiers in play here and that is BYMONTH (or BYDAY if you follow the expressed order in the last paragraph cited).

Thus evaluating the rule:

RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10

You start with DTSTART and apply the FREQ and INTERVAL to get "Repeats yearly on the DTSTART date/time".

Then you apply the BYxxx rule parts in the order proscribed.  The first would be BYMONTH resulting in "Repeats yearly on the DTSTART date/time in the month of October" (the day and time are inherited, the month is overridden by BYMONTH).  The next step would be to apply the next BYxxx rule part we have, BYDAY.  This would result in "Repeats yearly on the Last Sunday (at the DTSTART time) in the month of October".

So the final set of instances would be DTSTART and on the last Sunday in October that immediately follows the DTSTART (it could be the next year or the same year depending on when DTSTART was).  At least thats how I take the text from the RFCs on recurrence rule evaluation.

In rechecking Dans text I see that he said "The BYDAY on yearly refers to weeks of the year and not weeks of the month" but BYDAY is defined as:

   The BYDAY rule part specifies a COMMA character (US-ASCII decimal 44)
  separated list of days of the week; MO indicates Monday; TU indicates
  Tuesday; WE indicates Wednesday; TH indicates Thursday; FR indicates
  Friday; SA indicates Saturday; SU indicates Sunday.


which is not quite the same.  BYWEEK would be "weeks of the year".  BYDAY is defined as "days of the week".

> If the opinion is that "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10" does mean
> the last Sunday in October, then that raises further questions.  For
> example, what dates would the following rule resolve to?
> RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10,11,12

With a BYMONTH=10,11,12 we would follow the same evaluation logic above and get 3 instances (the last Sundays of October, November and December) and that exactly jives w/the bit about "expand the number of occurences of the recurrence" from 2445.

The same expansion logic can be confirmed by using more than 1 value for the BYDAY as well.  

Bruce
===========================================================================
Bruce Kahn                                INet: Bruce_Kahn@xxxxxxxxxxxxxxxx
Messaging & Collaboration                 Phone: 978.399.6496
IBM Software Group                         FAX: and nothing but the FAX...
Standard disclaimers apply, even where prohibited by law...