Tempo.JSCalendar (Tempo v2.1.0)

Copy Markdown View Source

Reads JSCalendar (RFC 8984) documents into Tempo: each Event an interval or, when it recurs, its occurrences, with the event's title, status and the rest as metadata; a Group its member events; a Task nothing, a task being work to do and not time taken.

The JSON is decoded by the optional jscalendar dependency, and this module is compiled only when it is present. An event's start is a local time in its timeZone, floating when it has none. Its recurrence rules are lowered to Tempo recurrences by Tempo.RRule, its excluded rules take occurrences away, and its recurrence overrides replace or remove the occurrence they name, or add one.

Not read: a rule's rscale other than Gregorian, a skip other than omit, and a first day of the week other than Monday.

Summary

Functions

The events of a JSCalendar object already decoded, as parse/2 gives them.

from_jscalendar/2, returning its answer or raising the error.

Reads a JSCalendar document into a set of intervals, one for each event or occurrence of an event, in order of start.

parse/2, returning its answer or raising the error.

Functions

from_jscalendar(object, options \\ [])

@spec from_jscalendar(struct(), keyword()) ::
  {:ok, Tempo.t()} | {:error, Exception.t()}

The events of a JSCalendar object already decoded, as parse/2 gives them.

Arguments

Options

Returns

  • {:ok, set} or {:error, exception}, as for parse/2.

Examples

iex> {:ok, object} =
...>   JSCalendar.decode(
...>     ~s({"@type":"Event","uid":"e","updated":"2026-06-01T09:00:00Z","start":"2026-06-02T09:00:00","duration":"PT1H"})
...>   )
iex> {:ok, events} = Tempo.JSCalendar.from_jscalendar(object)
iex> Tempo.IntervalSet.map(events, &Tempo.to_iso8601!/1)
["2026Y6M2DT9H0M0S/T10H0M0S"]

from_jscalendar!(object, options \\ [])

@spec from_jscalendar!(struct(), keyword()) :: Tempo.t()

from_jscalendar/2, returning its answer or raising the error.

Arguments

Options

Returns

  • What from_jscalendar/2 returns as {:ok, answer}, the answer alone. The error it returns as {:error, exception} is raised.

Examples

iex> json = ~s({"@type":"Event","uid":"e","updated":"2026-06-01T09:00:00Z","start":"2026-06-02T09:00:00","duration":"PT1H"})
iex> {:ok, object} = JSCalendar.decode(json)
iex> object |> Tempo.JSCalendar.from_jscalendar!() |> Tempo.IntervalSet.count()
1

parse(json, options \\ [])

@spec parse(binary(), keyword()) :: {:ok, Tempo.t()} | {:error, Exception.t()}

Reads a JSCalendar document into a set of intervals, one for each event or occurrence of an event, in order of start.

Arguments

  • json is a JSCalendar document as text.

  • options is a keyword list of options.

Options

  • :within is a Tempo.t/0, the window whose events are wanted: every occurrence that overlaps it is kept. It is required when an event recurs with neither count nor until.

Returns

  • {:ok, set}, a Tempo.t/0 of the :all form, each member's metadata its event's (:uid, :title, :description, :status, :free_busy_status, :privacy, :time_zone, :sequence).

  • {:error, %ArgumentError{}} when the document cannot be decoded, naming the reason the jscalendar library gives, and {:error, exception} when a zone is unknown, a rule is not supported or a recurrence has no end and no window is given.

Examples

iex> json = ~s({
...>   "@type": "Event",
...>   "uid": "review",
...>   "updated": "2026-06-01T09:00:00Z",
...>   "title": "Quarterly review",
...>   "start": "2026-06-02T09:00:00",
...>   "duration": "PT1H"
...> })
iex> {:ok, events} = Tempo.JSCalendar.parse(json)
iex> [review] = Tempo.IntervalSet.members(events)
iex> {Tempo.to_iso8601!(review), Tempo.metadata(review).title}
{"2026Y6M2DT9H0M0S/T10H0M0S", "Quarterly review"}

parse!(json, options \\ [])

@spec parse!(binary(), keyword()) :: Tempo.t()

parse/2, returning its answer or raising the error.

Arguments

  • The arguments are those of parse/2.

Options

Returns

  • What parse/2 returns as {:ok, answer}, the answer alone. The error it returns as {:error, exception} is raised.

Examples

iex> json = ~s({"@type":"Event","uid":"e","updated":"2026-06-01T09:00:00Z","start":"2026-06-02T09:00:00","duration":"PT1H"})
iex> json |> Tempo.JSCalendar.parse!() |> Tempo.IntervalSet.count()
1