excal v0.3.2 Excal.Recurrence.Iterator View Source

Elixir wrapper around a libical recurrence iterator.

The iterator is fundamentally a mutable resource, so it acts more like a stateful reference, rather than an immutable data structure. To create one, you will need a iCalendar recurrence rule string and a start date or datetime.

Link to this section Summary

Types

Possible errors returned from iterator initialization.

Possible errors returned from setting the start date or datetime of an iterator.

t()

A struct that represents a recurrence iterator. Consider all the fields to be internal implementation detail at this time, as they may change without notice.

Functions

Creates a new recurrence iterator from an iCalendar recurrence rule (RRULE) string and a start date or datetime.

Returns the next date or datetime occurrence of an existing iterator.

Sets the end date or datetime for an existing iterator.

Sets the start date or datetime for an existing iterator.

Link to this section Types

Link to this type

initialization_error() View Source
initialization_error() ::
  :unsupported_datetime_type
  | Excal.Interface.Recurrence.Iterator.initialization_error()

Possible errors returned from iterator initialization.

Link to this type

iterator_start_error() View Source
iterator_start_error() ::
  :unsupported_datetime_type
  | :datetime_type_mismatch
  | Excal.Interface.Recurrence.Iterator.iterator_start_error()

Possible errors returned from setting the start date or datetime of an iterator.

Link to this type

t() View Source
t() :: %Excal.Recurrence.Iterator{
  dtstart: Excal.date_or_datetime(),
  finished: boolean(),
  from: nil | Excal.date_or_datetime(),
  iterator: reference(),
  rrule: String.t(),
  type: Date | NaiveDateTime,
  until: nil | Excal.date_or_datetime()
}

A struct that represents a recurrence iterator. Consider all the fields to be internal implementation detail at this time, as they may change without notice.

Link to this section Functions

Link to this function

new(rrule, date_or_datetime) View Source
new(String.t(), Excal.date_or_datetime()) ::
  {:ok, t()} | {:error, initialization_error()}

Creates a new recurrence iterator from an iCalendar recurrence rule (RRULE) string and a start date or datetime.

Examples

A daily schedule starting on January 1st 2019:

  iex> {:ok, iter} = Iterator.new("FREQ=DAILY", ~D[2019-01-01])
  ...> {_occurrence, iter} = Iterator.next(iter)
  ...> {_occurrence, iter} = Iterator.next(iter)
  ...> {occurrence, _iter} = Iterator.next(iter)
  ...> occurrence
  ~D[2019-01-03]

A bi-weekly schedule every Monday, Wednesday and Friday:

  iex> {:ok, iter} = Iterator.new("FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR", ~D[2019-01-01])
  ...> {occurrence, _iter} = Iterator.next(iter)
  ...> occurrence
  ~D[2019-01-07]
Link to this function

next(iterator) View Source
next(t()) :: {Excal.date_or_datetime(), t()} | {nil, t()}

Returns the next date or datetime occurrence of an existing iterator.

If the iterator has reached the end of the set described by the RRULE, or has reached the end time specified by set_end/2, it will return nil.

Example

  iex> {:ok, iter} = Iterator.new("FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR", ~D[2019-01-01])
  ...> {occurrence, _iter} = Iterator.next(iter)
  ...> occurrence
  ~D[2019-01-07]
Link to this function

set_end(iterator, date_or_datetime) View Source
set_end(t(), Excal.date_or_datetime()) ::
  {:ok, t()} | {:error, :datetime_type_mismatch}

Sets the end date or datetime for an existing iterator.

Once an end time is set for an iterator, the iterator will return nil once it has reached the specified end.

Example

  iex> {:ok, iter} = Iterator.new("FREQ=DAILY", ~D[2019-01-01])
  ...> {:ok, iter} = Iterator.set_end(iter, ~D[2019-01-03])
  ...> {_occurrence, iter} = Iterator.next(iter)
  ...> {_occurrence, iter} = Iterator.next(iter)
  ...> {occurrence, _iter} = Iterator.next(iter)
  ...> occurrence
  nil
Link to this function

set_start(iterator, date_or_datetime) View Source
set_start(t(), Excal.date_or_datetime()) ::
  {:ok, t()} | {:error, iterator_start_error()}

Sets the start date or datetime for an existing iterator.

The iterator's start time is not the same thing as the schedule's start time. At creation time, an iterator is given a recurrence rule string and a schedule start date or datetime, but the iterator's start can be some time farther in the future than the schedules start time.

This can also be used to reset an existing iterator to a new starting time.

NOTE: You cannot call set_start/2 on an iterator whose RRULE contains a COUNT clause.

Example

Consider: an RRULE for Friday on every 3rd week starting January 1st 2016 might look like this:

  iex> {:ok, iter} = Iterator.new("FREQ=WEEKLY;INTERVAL=3", ~D[2016-01-01])
  ...> {next_occurrence, _iter} = Iterator.next(iter)
  ...> next_occurrence
  ~D[2016-01-01]

...but if you only cared about the instances starting in 2019, you can't change the start date because that would affect the cadence of the "every 3rd week" part of the schedule. Instead, just tell the iterator to skip ahead until 2019:

  iex> {:ok, iter} = Iterator.new("FREQ=WEEKLY;INTERVAL=3", ~D[2016-01-01])
  ...> {:ok, iter} = Iterator.set_start(iter, ~D[2019-01-01])
  ...> {next_occurrence, _iter} = Iterator.next(iter)
  ...> next_occurrence
  ~D[2019-01-18]