Import iCalendar (RFC 5545) data into %Tempo.IntervalSet{}.
This module wraps the ical
parser and translates each VEVENT into a %Tempo.Interval{}
with full event metadata (summary, description, location,
attendees, status, …) attached to the interval's :metadata
map. The VCALENDAR envelope's metadata (product id, version,
calendar scale, method) attaches to the IntervalSet's
:metadata map.
Every pipeline step that accepts a Tempo value — set
operations, Enum.take/2, resolution alignment — preserves
the metadata through to the result. That lets free/busy and
scheduling queries stay connected to their source events.
The ical dependency is declared optional: true in mix.exs.
Tempo.ICal is only compiled when ical is available in the
dependency tree; projects that don't import calendar data don't
pay the compile cost.
Required reading
- RFC 5545 — the iCalendar spec.
guides/set-operations.mdfor how the imported data is used downstream.
RFC 5545 coverage
| Property | Status |
|---|---|
RRULE | Fully supported — every BY* part, WKST, and |
BYSETPOS flow through the interpreter. | |
RDATE | Supported — extra occurrences with the event's |
| own span. | |
EXDATE | Supported — start-moment match removes the |
| corresponding occurrence. | |
EXRULE | Not surfaced by the underlying ical library, so |
| not implementable at this layer. EXRULE is also | |
| RFC-deprecated (RFC 2445 → 5545). | |
| Multiple | RFC 5545 says SHOULD NOT; some exports do it |
RRULE | anyway. The ical library exposes only the |
| per | first RRULE on event.rrule, so we materialise |
VEVENT | that one and silently ignore the rest. |
Summary
Functions
Parse an iCalendar string and return a %Tempo.IntervalSet{}.
Parse an iCalendar file and return a %Tempo.IntervalSet{}.
Functions
@spec from_ical( binary(), keyword() ) :: {:ok, Tempo.IntervalSet.t()} | {:error, term()}
Parse an iCalendar string and return a %Tempo.IntervalSet{}.
Every VEVENT becomes one %Tempo.Interval{} in the result.
All-day events (DTSTART as a Date) use day-resolution
endpoints; datetime events use the matching datetime
resolution. The event's SUMMARY, DESCRIPTION, LOCATION,
UID, STATUS, TRANSPARENCY, CATEGORIES, attendees, and
organizer all flow into the interval's :metadata map.
The calendar-level metadata (PRODID, VERSION, CALSCALE,
METHOD, and the user-visible name from X-WR-CALNAME when
present) attaches to the IntervalSet's :metadata map.
Arguments
icsis an iCalendar string (the contents of an.icsfile).
Options
:bound— aTempo.t/0,Tempo.Interval.t/0, orTempo.IntervalSet.t/0within which recurring events (those with anRRULE) are expanded. Required when any event in the input has a recurrence rule; ignored when there are none. An unbounded recurrence is infinite and refused at set-op time.
Returns
{:ok, interval_set}— sorted, coalesced IntervalSet of the events.{:error, reason}when parsing fails or a recurring event requires a:boundthat wasn't supplied.
Examples
iex> ics = """
...> BEGIN:VCALENDAR
...> VERSION:2.0
...> PRODID:-//Test//Test//EN
...> BEGIN:VEVENT
...> UID:test-1
...> DTSTAMP:20220101T000000Z
...> DTSTART:20220615T100000Z
...> DTEND:20220615T110000Z
...> SUMMARY:Test meeting
...> LOCATION:Paris
...> END:VEVENT
...> END:VCALENDAR
...> """
iex> {:ok, set} = Tempo.ICal.from_ical(ics)
iex> length(set.intervals)
1
iex> [iv] = set.intervals
iex> iv.metadata.summary
"Test meeting"
iex> iv.metadata.location
"Paris"
@spec from_ical_file( binary(), keyword() ) :: {:ok, Tempo.IntervalSet.t()} | {:error, term()}
Parse an iCalendar file and return a %Tempo.IntervalSet{}.
Wraps from_ical/2 with File.read/1.
Arguments
pathis a path to an.icsfile.
Options
See from_ical/2.
Returns
{:ok, interval_set}or{:error, reason}.