pub fn patch_rrule(
recurrence: &str,
prev_datetime: &str,
new_datetime: &str,
tzid: &str,
) -> StringExpand description
Patches a recurrence (RRULE) to reflect moving one occurrence from prev_datetime to new_datetime.
Semantics and timezone rules:
- prev_datetime and new_datetime are iso date or datetime. IMPORTANT: the datetime should be in local timezone, and therefore without the trailing Z.
- tzid is the calendar timezone context. All calendar comparisons (weekday, monthday, month) are performed after converting prev_datetime and new_datetime to tzid. (this is mostly useful for the computation of the until, the passed date and datetime are already assumed to be in local time)
- The produced changes are as if the rule was authored in tzid. For example, moving an event to a different local day (in tzid) will update BYDAY/BYMONTHDAY to match the new local date.
- If the rule has an UNTIL:
- UNTIL with trailing Z (e.g., 20250617T220000Z) is interpreted as a UTC datetime and compared in UTC.
- UNTIL as date-only (e.g., 20250617) is interpreted as local date in tzid at 00:00 and then converted to UTC for comparison.
- If UNTIL is before new_datetime, it will be updated using the same shape (date-only stays date-only; datetime Z stays datetime Z).
What gets updated:
- Weekly (FREQ=WEEKLY): updates BYDAY when the local weekday changes. For multi-day lists, replaces only the matching old day with the new one (if not already present).
- Monthly (FREQ=MONTHLY):
- If BYMONTHDAY is present, updates the day value(s) that match the old day (supports multiple comma-separated values).
- If BYDAY contains a position (e.g., 1MO, -1FR), updates both the weekday and the position, handling “last” week (-1) correctly.
- Yearly (FREQ=YEARLY):
- If BYMONTHDAY contains a single day value, updates it when the local monthday changes.
- If BYMONTH is present with a single value and the local month changes, updates BYMONTH accordingly.
- If BYMONTH is not present and the local month changes, appends BYMONTH with the new month.
- Note: yearly handling currently targets the single-day birthday-like use case; lists are not modified.
Other behavior:
- If the input contains multiple lines (e.g., EXDATE + RRULE), only the RRULE line is modified/returned.
- Parameters unrelated to the above remain untouched (e.g., INTERVAL, COUNT unless UNTIL update requires ignoring COUNT elsewhere).
Arguments:
recurrence: full recurrence string or RRULE line.prev_datetime: previous occurrence date or datetime (local, no timezone). format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSnew_datetime: new occurrence date or datetime (local, no timezone). format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SStzid: timezone ID used for calendar logic.
Returns: Modified RRULE string (single line).