recurrence rule and Calendar expands it into concrete
occurrences automatically: over the visible range in the month, week, day,
3days, and custom modes, and over a rolling three-month window in schedule
(the agenda has no bounded viewport of its own). Non-recurring events pass through
untouched, so you can mix both freely.
expandRecurringEvents and pass the
result as events:
freq—"daily","weekly","monthly", or"yearly".interval— every N periods (e.g. every 2 weeks).count— stop after N occurrences.until— stop on or before a date.weekdays— which days, forweeklyrules (0 = Sunday).nthWeekday— formonthly/yearly, repeat on the Nth weekday instead of the day-of-month, e.g.{ week: 3, weekday: 1 }(the 3rd Monday) or{ week: -1, weekday: 5 }(the last Friday).monthDays— formonthly, the day(s) of the month to repeat on, e.g.[1, 15](the 1st and 15th) or[-1](the last day; negatives count from the month’s end). Days a month lacks (the 31st in February) are skipped.months— foryearly, the month(s) to repeat in (1 = January … 12 = December), keeping the start date’s day-of-month, e.g.[3, 9](every March and September).exdates— dates to skip (exceptions). A date at local midnight skips every occurrence on that calendar day; a date with a time skips only the occurrence starting at that exact instant, so two same-day occurrences can be cancelled independently.rdates— extra one-off dates added to the set, even ones the rule wouldn’t produce.
RRULE/BYMONTHDAY/BYMONTH/EXDATE/RDATE — see iCalendar.
Expansion fast-forwards to the range you ask for, so a long-lived rule (a daily
event started years ago) stays cheap to query far in the future. A single
expandRecurringEvents call emits at most 5000 occurrences within the range;
pass a count/until, or query a tighter window, if you need more.