What is recurrence?
A recurring event is one that repeats at regular or irregular intervals. For example, a weekly lunch meeting, an anniversary, etc. These often occur in real life and thus need to be represented in digital calendars and iCalendar. Recurring events are often the source of interoperability problems with iCalendar, so deserve special attention.
In the real world, a recurrence pattern is typically based on common intervals of time (a day, a week, a month, a year, etc). Often times, a recurrence is not every week, but every other week, for example. So there needs to be a way to express an interval between each recurrence. Some types of recurrence never end - typically anniversaries, though often it is because no obvious end point can be identified. In other cases there is a well-known end point, determined either by the total number of recurrences (e.g., every day for the next three days), or a fixed end date (e.g., every week until the end of the month).
A number of more complex situations can arise, such as patterns tied to a specific day of the week within a month (e.g., the first Monday of each month), or an offset within the month (e.g., “pay day” - the last weekday of each month). All of these need to be represented in some fashion in a digital calendar.
Sometimes an event in a recurrence set needs to be removed (e.g., an every Monday pattern would produce an event that falls on a holiday, so that event needs to be cancelled). Alternatively, an event in a recurrence set mighty need to be rescheduled (e.g., due to a holiday, an event in an every Monday pattern is moved to Tuesday, rather than being cancelled). Such changes to the normal pattern of occurrence is called an exception.
Sometimes an irregular pattern exists - for example the Easter holiday is determined by a complex astronomical calculation that would not be trivial to represent in iCalendar. Or additional one-off meetings are scheduled (e.g., during one weekly meeting the participants agree to have a follow-up later in the week). To cope with these, it is possible to specify explicit dates for items in a recurrence set, rather than use a rule.
iCalendar’s Implementation of Recurrences
iCalendar supports recurrences by allowing rules, specific dates, specific exception dates, and overridden instances to all be specified using properties and components. The recurrence properties can only appear in the component defining the master instance of a recurrence set - they can never be used in components representing overridden instances. This means that if the recurrence pattern needs to change in a significant manner (e.g., switching from a weekly meeting to a monthly meeting) then two separate events are needed: one for the old set of events with the original recurrence pattern, and one for the new set with the new pattern.
Recurrence rules are defined via the
RRULE property. The value of this property is a semicolon separated list of items describing various aspects of the recurrence pattern, such as the frequency (e.g., daily, weekly, monthly, yearly), the interval (e.g., every two weeks, or every fourth month), the total number of items the rule generates (e.g., repeat for five times), the point in time where the recurrence stops (e.g., repeat until the 4th of June).
Here are some simple examples:
- An event that occurs once a year on a specific date. i.e., an anniversary.
- An event that occurs every day for three days only.
- An event that occurs every two weeks.
- An event that occurs on the last day of every month.
RRULE property can appear at most once in a calendar component. It is used only in the component that defines the master instance of a recurrence set (it can never be used in an overridden instance).
In order to determine a set of recurrences generated by a particular
RRULE, a starting point is required. The starting point is defined by the value of the
DTSTART property in the master component. For example, if
DTSTART is set to the 4th of July of some year, and a yearly
RRULE is specified, then the event occurs on the 4th of July of all years on or after the year specified in
RRULE itself might constrain what values are allowed for the
DTSTART property - for example an
RRULE that specifies a recurring event on the first Monday of every month, requires that the
DTSTART of the master component falls on the first Monday of a month. i.e., the
DTSTART of the master component must match the first instance of the recurrence pattern.
The full ics file for this example with three occurrences now looks like:
BEGIN:VCALENDAR VERSION:2.0 PRODID:-//ABC Corporation//NONSGML My Product//EN BEGIN:VEVENT SUMMARY:Lunchtime meeting UID:email@example.com DTSTART;TZID=America/New_York:20160420T120000 DURATION:PT1H LOCATION:Mo's bar - back room RRULE:FREQ=WEEKLY;COUNT=3 END:VEVENT END:VCALENDAR
RDATE property is used to specify one-off instances in a recurrence set. This is useful for cases where a “regular” pattern cannot be defined, or one off “exceptions” to a regular pattern. e.g., a weekly occurring event needs one additional event in one particular week to follow-up on items discussed in the previous meeting. The value of the
RDATE determines the start (and possibly duration) of the one-off instance. The recurrence instance specified by the
RDATE can also be overridden if some other aspect of the event differs from the master component.
EXDATE property is used to remove instances from a recurrence set defined by an
RRULE. For example, a weekly meeting might occur on a public holiday, and thus won’t take place so needs to be removed from the recurrence set.
The full ics file for this example with three occurrences without the second one now looks like:
BEGIN:VCALENDAR VERSION:2.0 PRODID:-//ABC Corporation//NONSGML My Product//EN BEGIN:VEVENT SUMMARY:Lunchtime meeting UID:ff808181-1fd7389e-011f-d7389ef9-00000003 DTSTART;TZID=America/New_York:20160420T120000 DURATION:PT1H LOCATION:Mo's bar - back room RRULE:FREQ=WEEKLY;COUNT=3 EXDATE;TZID=America/New_York:20160427T120000 END:VEVENT END:VCALENDAR
There is also a RRule Generator tool on icalendar.org helping you to generate the needed syntax for daily, weekly and yearly rules.
An overridden instance is one where one or more properties from the event are changed. This may be because the organizer has explicitly changed the property, for example by updating the
DESCRIPTION with a meeting agenda. It may also happen as a result of scheduling where the attendees
PARTSTAT is stored in the overridden instance.
An override is stored as a
COMPLETE copy of the master with the
DTEND set to the dates for the instance and will contain a
RECURRENCE-ID property to identify which instance it is. It
MUST NOT contain any
This override mechanism is one of the problems with long running recurring events. If every instance is modified the event data becomes very large over time.