Skip to content

EXDATE with comma-separated values on a single line silently drops to empty list (RDATE works correctly) #43

Description

@kipcole9

Environment

  • ical from github: "expothecary/ical" (main branch)
  • Elixir 1.20.0-rc.4-otp-28
  • Tested via ICal.from_ics/1

Summary

RFC 5545 §3.8.5.1 (EXDATE) and §3.8.5.2 (RDATE) both permit multiple values either as separate properties OR as one property with comma-separated values. Per the RFC grammar:

exdate     = "EXDATE" exdtparam ":" exdtval *("," exdtval) CRLF
rdate      = "RDATE" rdtparam ":" rdtval *("," rdtval) CRLF

ical handles comma-separated values correctly for RDATE but silently parses EXDATE as an empty list. This is an asymmetry — both fields have identical RFC syntax.

Minimal reproduction

ics_exdate = """
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//T//EN
BEGIN:VEVENT
UID:m
DTSTAMP:20220101T000000Z
DTSTART:20220601T090000Z
DTEND:20220601T100000Z
RRULE:FREQ=WEEKLY;COUNT=4
EXDATE:20220608T090000Z,20220622T090000Z
END:VEVENT
END:VCALENDAR
"""

ics_rdate = """
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//T//EN
BEGIN:VEVENT
UID:m
DTSTAMP:20220101T000000Z
DTSTART:20220601T090000Z
DTEND:20220601T100000Z
RRULE:FREQ=WEEKLY;COUNT=1
RDATE:20220615T140000Z,20220620T100000Z
END:VEVENT
END:VCALENDAR
"""

%ICal{events: [e_ex]} = ICal.from_ics(ics_exdate)
%ICal{events: [e_rd]} = ICal.from_ics(ics_rdate)

IO.inspect(e_ex.exdates, label: "exdates")
IO.inspect(e_rd.rdates, label: "rdates")

Actual restult

exdates: []
rdates: [~U[2022-06-15 14:00:00Z], ~U[2022-06-20 10:00:00Z]]

Expected result

exdates: [~U[2022-06-08 09:00:00Z], ~U[2022-06-22 09:00:00Z]]
rdates:  [~U[2022-06-15 14:00:00Z], ~U[2022-06-20 10:00:00Z]]

Workaround

Using one EXDATE property per value works as expected:

EXDATE:20220608T090000Z
EXDATE:20220622T090000Z

This parses correctly into the expected 2-element list.

Impact

EXDATE:d1,d2,… is a common form in real-world .ics exports (including Google Calendar and Apple Calendar). Events using it silently lose their exclusions — the calendar renders "extra" occurrences that should have been removed.

Suspected location

Whatever handler splits RDATE's comma-separated values isn't being invoked for EXDATE. Likely a missing String.split(",") (or equivalent) in the EXDATE parse path, while the RDATE path has it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions