File: icalendar-recur.el.html

For an overview of the iCalendar library, see icalendar-shortdoc.el.

This is a sub-library for working with recurrence rules and time zones, as defined by RFC5545 (see especially Secs. 3.3.10 and
3.8.5.3, which are required reading before you make any changes to
the code below) and related standards (especially RFC8984 Sec. 4.3, also strongly recommended reading). Recurrence rules and time zones are mutually dependent: to calculate the date and time of future instances of a recurring event, you must be able to apply time zone rules; and to apply time zone rules, you must be able to calculate the date and time of recurring events, namely the shifts between observances of standard and daylight savings time. For example, an event that occurs "on the last Friday of every month at 11AM" in a given time zone should recur at 11AM daylight savings time in July, but 11AM standard time in January, for a typical time zone that shifts from standard to DST and back once each year. These shifts occur at, say, "the last Sunday in March at 2AM" and "the first Sunday in November at 2AM". So to calculate an absolute time for a given instance of the original event, you first have to calculate the nearest instance of the shift between standard and daylight savings time, which itself involves applying a recurrence rule of the same form.

This mutual dependence between recurrence rules and time zones is not a *vicious* circle, because the shifts between time zone observances have fixed offsets from UTC time which are made explicit in iCalendar data. But it does make things complicated. RFC5545 focuses on making recurrence rules expressive enough to cover existing practices, including time zone observance shifts, rather than on being easy to implement.

So be forewarned: here be dragons. The code here was difficult to get working, in part because this mutual dependence means it is difficult to implement anything less than the whole system, in part because recurrence rules are very flexible in order to cover as many practical uses as possible, in part because time zone practices are themselves complicated, and in part because there are a *lot* of edge cases to worry about. Much of it is tedious and repetitive but doesn't lend itself to further simplification or abstraction. If you need to make changes, make them slowly, and use the tests in test/lisp/calendar/icalendar-recur-tests.el to make sure they don't break anything.

Notation: date/time with a slash in symbol names means "`date' or
`date-time'", i.e., is a way of indicating that a function can
accept either type of value, and dt is typically used for an argument of either type. date-time should always refer to *just* date-time values, not plain (calendar-style) dates.

Defined variables (0)

Defined functions (51)

icalendar-recur--key-from-interval(INTERVAL)
icalendar-recur--set-get-interval(COMPONENT INTERVAL)
icalendar-recur--set-put-interval(COMPONENT INTERVAL RECURRENCES)
icalendar-recur--tz-info-sexp-p(_ SEXP)
icalendar-recur--w/in-abs-p(DT START &optional END)
icalendar-recur--w/in-locally-p(DT START &optional END)
icalendar-recur-bysetpos-filter(SETPOS RECURRENCES)
icalendar-recur-current-tz-to-vtimezone(&optional TZ TZID START-YEAR)
icalendar-recur-date-time-occurs-twice-p(DT OBS-ONSET OBSERVANCE)
icalendar-recur-find-absolute-interval(TARGET DTSTART INTERVALSIZE FREQS &optional VTIMEZONE)
icalendar-recur-find-daily-interval(TARGET DTSTART INTERVALSIZE &optional VTIMEZONE)
icalendar-recur-find-hourly-interval(TARGET DTSTART INTERVALSIZE &optional VTIMEZONE)
icalendar-recur-find-interval(TARGET DTSTART RRULE &optional VTIMEZONE)
icalendar-recur-find-minutely-interval(TARGET DTSTART INTERVALSIZE &optional VTIMEZONE)
icalendar-recur-find-monthly-interval(TARGET DTSTART INTERVALSIZE &optional VTIMEZONE)
icalendar-recur-find-secondly-interval(TARGET DTSTART INTERVALSIZE &optional VTIMEZONE)
icalendar-recur-find-weekly-interval(TARGET DTSTART INTERVALSIZE &optional WEEKSTART VTIMEZONE)
icalendar-recur-find-yearly-interval(TARGET DTSTART INTERVALSIZE &optional VTIMEZONE)
icalendar-recur-interval-high(INTERVAL)
icalendar-recur-interval-low(INTERVAL)
icalendar-recur-interval-next(INTERVAL)
icalendar-recur-make-interval(LOW HIGH &optional NEXT-LOW)
icalendar-recur-next-interval(INTERVAL RRULE &optional VTIMEZONE)
icalendar-recur-nonexistent-date-time-p(DT OBS-ONSET OBSERVANCE)
icalendar-recur-nth-interval(N DTSTART RRULE &optional VTIMEZONE)
icalendar-recur-previous-interval(INTERVAL RRULE DTSTART &optional VTIMEZONE)
icalendar-recur-recurrences-in-interval(INTERVAL COMPONENT &optional VTIMEZONE NMAX)
icalendar-recur-recurrences-in-window(LOWER UPPER COMPONENT &optional VTIMEZONE)
icalendar-recur-recurrences-in-window-w/end-times(LOWER UPPER COMPONENT &optional VTIMEZONE)
icalendar-recur-recurrences-to-count(COMPONENT &optional VTIMEZONE)
icalendar-recur-refine-by(UNIT INTERVAL VALUES &optional BYDAY-INMONTH WEEKSTART VTIMEZONE)
icalendar-recur-refine-byday(INTERVAL WEEKDAYS &optional IN-MONTH VTIMEZONE)
icalendar-recur-refine-byhour(INTERVAL HOURS &optional VTIMEZONE)
icalendar-recur-refine-byminute(INTERVAL MINUTES &optional VTIMEZONE)
icalendar-recur-refine-bymonth(INTERVAL MONTHS &optional VTIMEZONE)
icalendar-recur-refine-bymonthday(INTERVAL MONTHDAYS &optional VTIMEZONE)
icalendar-recur-refine-bysecond(INTERVAL SECONDS &optional VTIMEZONE)
icalendar-recur-refine-byweekno(INTERVAL WEEKNOS &optional WEEKSTART VTIMEZONE)
icalendar-recur-refine-byyearday(INTERVAL YEARDAYS &optional VTIMEZONE)
icalendar-recur-refine-from-clauses(INTERVAL RRULE DTSTART &optional VTIMEZONE)
icalendar-recur-subintervals-to-date-times(SUBINTERVALS &optional VTIMEZONE)
icalendar-recur-subintervals-to-dates(SUBINTERVALS)
icalendar-recur-subintervals-to-recurrences(SUBINTERVALS DTSTART &optional VTIMEZONE)
icalendar-recur-tz--get-updated-in(DT OBS-ONSET OBSERVANCE)
icalendar-recur-tz-decode-time(TS VTIMEZONE)
icalendar-recur-tz-for(TZID VTIMEZONES)
icalendar-recur-tz-observance-on(DT VTIMEZONE &optional UPDATE NONEXISTENT)
icalendar-recur-tz-offset-in(OBSERVANCE)
icalendar-recur-tz-set-zone(DT VTIMEZONE &optional NONEXISTENT)
icalendar-recur-tz-set-zones-in(VTIMEZONES NODE)
icalendar-recur-tzname-on(DT VTIMEZONE)

Defined faces (0)