Closed Bug 266298 Opened 20 years ago Closed 18 years ago

Add support for BYDAY nth occurrences in RRULE

Categories

(Calendar :: Internal Components, enhancement)

enhancement
Not set
normal

Tracking

(Not tracked)

RESOLVED WORKSFORME

People

(Reporter: a.l.m.buxey, Unassigned)

Details

User-Agent:       Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040914 Firefox/0.10.1
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040914 Firefox/0.10.1

sunbird has issue with inserting ical events which are annual, tied to a
date with day specification...eg 

27th October or last sunday of October.

with iCal, this is set correctly to 31st October  (date that british summer time
ends) - with WebCalendar this is 31/10/2004, with sunbird this is incorrectly
set to wed 27 and thur 28th October!


Reproducible: Always
Steps to Reproduce:
1. go to Apples shared Ical section
2. download the UK Holiday iCal
3. look at events in october in sunbird

Actual Results:  
wrong date/event is shown.

Expected Results:  
with WebCalendar I get the expected result:

Date:  	Sunday, 31 October, 2004
Repeat Type: 	Sunday, 27 October, 2002  (every October / last Sunday)
MozCal does not currently support the -1SU in the RRULE
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
-----
You'd be much better off using the UK calendars at
http://www.wildfire.dircon.co.uk/holidays.html
which are good till 2012 as there are many UK holidays that do not repeat properly
HTH
suggest ENHANCEMENT rather than bug; change summary to

Add support for BYDAY nth occurrences in RRULE

rfc2445
===
4.3.10 Recurrence Rule
[...]
   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 day of week problem can be addressed by setting the repeat interval to 12
months, then you'll see "last Sunday of the month" as one of the choices.
this isn't a libical issue, but with our layer around it.
Component: libical → libxpical
Summary: ical import fails to work properly with annual events → Add support for BYDAY nth occurrences in RRULE
Perhaps related to this bug. If not, feel free to relocate as needed:

Use of "BYDAY=nWD"
where n is an int 1-5
(assuming there is a valid day for that n in the month) or n is a negative value to count instances from the end of the month, backwards.)
(assuming "WD" is actually a day of the week, like "MO" or "TH" etc.

The following does generate instances in the calendar, even though it shows up as  and event in the list of all events.

(Appears i nthe top "frame" but no instances appear in the lower "frame"



BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN
BEGIN:VEVENT
CREATED:20060323T203941Z
LAST-MODIFIED:20060323T203941Z
DTSTAMP:20060314T075247Z
UID:1.0.36.userhost@example.com
SUMMARY:Sample summary
STATUS:CONFIRMED
CLASS:PUBLIC
ORGANIZER:MAILTO:
 InvalidEmail.DC-Forum.UserID.4000.user@example.com
ATTENDEE:RSVP=FALSE
RRULE:FREQ=MONTHLY;UNTIL=20000314T170000Z;INTERVAL=2;BYDAY=2TH
DTSTART:20000111T170000Z
DTEND:20000111T190000Z
LOCATION:my new location
DESCRIPTION:Sample Text in description.
CATEGORIES:Projects
SEQUENCE:1
END:VEVENT
END:VCALENDAR

Status of support for this part of ical?

Used this nightly build:
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a1) Gecko/20060320 Mozilla Sunbird/0.3a1+
(In reply to comment #5)
> (Appears in the top "frame" but no instances appear in the lower "frame"

In the event list it appears as an event on DTSTART, but the date of DTSTART doesn't match the recurrence rule. The view shows the correct events according to the recurrence rule. So unifinder treats the event wrong. I don't know if it is a RFC-conform VEVENT when DTSTART doesn't represent a date that matches the recurrence rule.

Maybe this should be filed as a separate bug report.
Assignee: gray → base
Severity: normal → enhancement
Component: libxpical → Base
OS: Linux → All
QA Contact: gurganbl → base
Hardware: PC → All
Version: unspecified → Trunk
per comment 5, and comment 6

> The following does generate instances in the calendar, even though it shows up
> as an event in the list of all events.
>
> (Appears in the top "frame" but no instances appear in the lower "frame"

Presumed to mean: (not sure)
 -  'unifinder' does NOT show all occurences of multi-occurence event in 'All Events' view
  OR
 -  'unifinder' does show entry for this event, BUT does not show event(s) in 'calendar view'

Duplicate of Bug 299651 (unifinder 'all events' is inconsistent with other views)

OR

Re-tested on Sunbird nightly (20060509 Sunbird/0.3a2) using:

  RRULE:FREQ=MONTHLY;UNTIL=20000314T170000Z;INTERVAL=2;BYDAY=2TH
  DTSTART:20000111T170000Z
  DTEND:20000111T190000Z

This produces 2 events (Jan-14, and Mar-10), as it should.
 - FREQ=MONTHLY
    period of occurence: each month
 - UNTIL 2000-03-14  17:00:00 UTC
    excludes occurences after this date (Tuesday).
 - INTERVAL=2
    every 2nd month (after 1st occurence)
 - DTSTART 2000-01-11 17:00:00 UTC
    date is before first occurrence, but still allowed by  rfc2445  std.
 - DTEND 2000-01-11  19:00:00 UTC
    used to define length (duration: of 2 hours), relative to start DTSTART date/time
 - BYDAY=2TH
    to occur on 2nd Thursday of month


Per rfc2445 ..

Section  4.8.5.1  discusses the exact precedence and use of  DTSTART property when used alongside RRULE, RDATE, EXDATE and EXRULE properties.  Sunbird appears to handle this type of case correctly.
BYDAY nth occurrence in RRULE now works.

This bug could probably be closed, unless someone wants to test the exact example from Apples 'shared Ical section'.
The ics in comment 5 is not valid because DTSTART is not the first instance of the RRULE (see RFC 2445: 4.8.5.4 Recurrence Rule). So no separate bug report needed.

BUT in Sunbird when creating a new event with a recurrence and the currently selected day doesn't correspond to the day of the first occurrence, the selected day is saved as DTSTART. (e.g. select a Monday and set a recurrence every Thursday, then DTSTART is the selected Monday)

This is definitely a bug that doesn't produce a RFC-conform ics.

Andrew, I think you are mistaken with you interpretation of DTSTART for a RRULE because the RFC states "The "DTSTART" property defines the first instance in the recurrence set.".
> The ics in comment 5 is not valid because DTSTART is not the first instance of
> the RRULE (see RFC 2445: 4.8.5.4 Recurrence Rule). So no separate bug report
> needed.
>
> BUT in Sunbird when creating a new event with a recurrence and the currently
> selected day doesn't correspond to the day of the first occurrence, the
> selected day is saved as DTSTART. (e.g. select a Monday and set a recurrence
> every Thursday, then DTSTART is the selected Monday)
>
> This is definitely a bug that doesn't produce a RFC-conform ics.
>
> Andrew, I think you are mistaken with you interpretation of DTSTART for a RRULE
> because the RFC states "The "DTSTART" property defines the first instance in
> the recurrence set.".

My analysis, of rfc2445 ..  [ Note: all rfc2445 references are included below ]

(a.)  The recurrence set is generated from DTSTART property, along with RRULE, RDATE, EXDATE and EXRULE properties.

(b.)  DTSTART property defines first instance in the recurrence set.
 -  Meaning? :  Instances can't occur before DTSTART.
 -  For an exception to this, see 4.8.4.4  (RECURRENCE-ID)

(c.)  DTSTART property, if specified, counts as the first occurrence.
 -  Meaning? :  If DTSTART is before first instance (from RRULE, RDATE), you lose a 1 count.
     -  This has no effect, unless COUNT or BYSETPOS are being used.
 -  Simpler (alternative) interpretation: each time/date instance within recurrence set is counted.
     -  For our example, DTSTART instance is NOT within recurrence set (and NOT counted).

(d.)  information, otherwise NOT contained in rule, is derived from DTSTART entry.
 -  Implies additional detail is derives from rules, rather than DTSTART.

(e.)  BYxxx (eg. BYDAY) elements modify the recurrence in some manner.
 -  BYxxx  are elements of RRULE and EXRULE properties.
     -  For our example, DTSTART instance is NOT within recurrence set.

If we can determine the correct interpretation of these details, then we can define correct exception behaviour (when to ignore, what to count) for Sunbird and iCal files. 

-----------------------------------------------------------------------

rfc2445

4.3.10 Recurrence Rule  (RECUR)

   The COUNT rule part defines the number of occurrences at which to
   range-bound the recurrence. The "DTSTART" property value, if
   specified, counts as the first occurrence.  - (c.)

   Information, not contained in the rule, necessary to determine the
   various recurrence instance start time and dates are derived from the
   Start Time (DTSTART) entry attribute.  - (d.)

   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.
   .. BYxxx rule parts for a period of
   time less than the frequency generally increase or expand the number
   of occurrences of the recurrence.  - (e.)

4.6.1 Event Component  (VEVENT)

   The "DTSTART" property for a "VEVENT" specifies the inclusive start
   of the event. For recurring events, it also specifies the very first
   instance in the recurrence set. The "DTEND" property for a "VEVENT"
   calendar component specifies the non-inclusive end of the event. For
   cases where a "VEVENT" calendar component specifies a "DTSTART"
   property with a DATE data type but no "DTEND" property, the events
   non-inclusive end is the end of the calendar date specified by the
   "DTSTART" property. For cases where a "VEVENT" calendar component
   specifies a "DTSTART" property with a DATE-TIME data type but no
   "DTEND" property, the event ends on the same calendar date and time
   of day specified by the "DTSTART" property.  - (b.)

4.8.4.4 Recurrence ID  (RECURRENCE-ID)

   The date/time value is set to the time when the original recurrence
   instance would occur; meaning that if the intent is to change a
   Friday meeting to Thursday, the date/time is still set to the
   original Friday meeting.

4.8.5.1 Exception Date/Times  (EXDATE)

   .. The recurrence set is the complete set of
   recurrence instances for a calendar component. The recurrence set is
   generated by considering the initial "DTSTART" property along with
   the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained
   within the iCalendar object. The "DTSTART" property defines the first
   instance in the recurrence set. Multiple instances of the "RRULE" and
   "EXRULE" properties can also be specified to define more
   sophisticated recurrence sets. The final recurrence set is generated
   by gathering all of the start date-times generated by any of the
   specified "RRULE" and "RDATE" properties, and then excluding any
   start date and times which fall within the union of start date and
   times generated by any specified "EXRULE" and "EXDATE" properties.
   This implies that start date and times within exclusion related
   properties (i.e., "EXDATE" and "EXRULE") take precedence over those
   specified by inclusion properties (i.e., "RDATE" and "RRULE"). Where
   duplicate instances are generated by the "RRULE" and "RDATE"
   properties, only one recurrence is considered. Duplicate instances
   are ignored.  - (a.)
(Correction: remove 'initial', in context 'initial "DTSTART" property')
(Correction: remove 'start' x4, in context 'start date and times' or 'start date-times')

   The "EXDATE" property can be used to exclude the value specified in
   "DTSTART". However, in such cases the original "DTSTART" date MUST
   still be maintained by the calendaring and scheduling system because
   the original "DTSTART" value has inherent usage dependencies by other
   properties such as the "RECURRENCE-ID".

4.8.5.2 Exception Rule  (EXRULE)

   .. The recurrence set is the .. (same as 4.8.5.1)

   The "EXRULE" property can be used to exclude the value specified in
   "DTSTART". However, in such cases .. (same as 4.8.5.1)

4.8.5.3 Recurrence Date/Times  (RDATE)

   .. The recurrence set is the .. (same as 4.8.5.1)

4.8.5.4 Recurrence Rule  (RRULE)

   .. The recurrence set is the .. (same as 4.8.5.1)

   The "DTSTART" and "DTEND" property pair or "DTSTART" and "DURATION"
   property pair, specified within the iCalendar object defines the
   first instance of the recurrence. When used with a recurrence rule,
   the "DTSTART" and "DTEND" properties MUST be specified in local time
   and the appropriate set of "VTIMEZONE" calendar components MUST be
   included. For detail on the usage of the "VTIMEZONE" calendar
   component, see the "VTIMEZONE" calendar component definition.
 (Correction: .. must be specified in local time, ONLY if defined as: date and time)

6 Recommended Practices

   4.  When the combination of the "RRULE" and "RDATE" properties on an
       iCalendar object produces multiple instances having the same
       start date/time, they should be collapsed to, and considered as,
       a single instance.
(Correction: unless RDATE and RRULE properties have different duration)
The original steps to reproduce in this bug now work fine for me.  (We properly display British Summer Time on the last Sunday in October.)  There have been several attempts to morph this bug into other junk, and I'm not buying it.  Closing as WFM.  File new bugs if you feel there are other areas related to this that need to be addressed.
Status: UNCONFIRMED → RESOLVED
Closed: 18 years ago
Resolution: --- → WORKSFORME
Works for me, so I concur.  See my comment8 and comment 10, if you need more detail.
The bugspam monkeys have struck again. They are currently chewing on default assignees for Calendar. Be afraid for your sanity!
Assignee: base → nobody
You need to log in before you can comment on or make changes to this bug.