# Tempo v0.6.0 - Table of Contents

> Time as an interval, not an instant — ISO 8601 and IXDTF-compliant date, time, interval, duration, recurrence, and set-algebra library for Elixir. Calendar- and timezone-aware.

## Pages

- [Tempo](readme.md)
- [License](license.md)
- [Changelog](changelog.md)

- Cookbooks
  - [Tempo Cookbook](cookbook.md)
  - [Holidays — Planning with a Real Holiday Calendar](holidays.md)
  - [Scheduling](scheduling.md)
  - [Working with Workdays and Weekends](workdays-and-weekends.md)

- Guides
  - [Enumeration semantics](enumeration-semantics.md)
  - [Falsehoods Programmers Believe About Time](falsehoods.md)
  - [iCalendar integration](ical-integration.md)
  - [Pattern matching with sigils](pattern-matching-with-sigils.md)
  - [Set operations](set-operations.md)
  - [When to Use Tempo](when-to-use-tempo.md)

- Reference
  - [ISO 8601 Conformance Guide](iso8601-conformance.md)
  - [RFC 5545 RRULE Conformance](rfc5545_rrule_conformance.md)
  - [A shared AST for ISO 8601 and RFC 5545 RRULE](shared-ast-iso8601-and-rrule.md)

## Modules

- [Tempo.Cron](Tempo.Cron.md): Parser for cron expressions, producing the same
`t:Tempo.RRule.Rule.t/0` AST that the ISO 8601 / RFC 5545 RRULE
parser produces.
- [Tempo.LeapSeconds](Tempo.LeapSeconds.md): The canonical list of positive leap seconds announced by the
International Earth Rotation and Reference Systems Service
(IERS) since the UTC–TAI framework began in 1972.
- [Tempo.Sigils](Tempo.Sigils.md): Sigils for constructing and pattern-matching `%Tempo{}` values at
compile time.

- Core
  - [Tempo](Tempo.md): Documentation for `Tempo`.
  - [Tempo.Duration](Tempo.Duration.md): A calendar-relative duration — a list of `{unit, amount}`
pairs such as `[year: 1, month: 6]`. Produced by the ISO 8601
parser (`P1Y6M`), the RRULE encoder (as the `FREQ + INTERVAL`
cadence), and arithmetic helpers in `Tempo.Math`.

  - [Tempo.Interval](Tempo.Interval.md): An explicit bounded span on the time line.
  - [Tempo.IntervalSet](Tempo.IntervalSet.md): A sorted, non-overlapping, coalesced list of `t:Tempo.Interval.t/0`
values — the multi-interval counterpart to `Tempo.Interval`.
  - [Tempo.Range](Tempo.Range.md): A pair of Tempo values denoting a range, produced by the ISO
8601-2 range operator (`2022..2024`). The first and last
bounds are inclusive — contrast with `%Tempo.Interval{}`
which uses the half-open `[from, to)` convention.
  - [Tempo.Set](Tempo.Set.md): A Tempo-valued set — either **all-of** (`{a, b, c}` in ISO
8601-2, free/busy semantics) or **one-of** (`[a, b, c]`,
epistemic disjunction — "it was one of these, I don't know
which").

- Clock and current time
  - [Tempo.Clock](Tempo.Clock.md): A behaviour for providing the current time to Tempo.
  - [Tempo.Clock.System](Tempo.Clock.System.md): Default implementation of `Tempo.Clock` using Erlang's system
time via `DateTime.utc_now/0`.
  - [Tempo.Clock.Test](Tempo.Clock.Test.md): A process-local deterministic clock for use in tests.

- Set algebra and comparison
  - [Tempo.Compare](Tempo.Compare.md): Shared comparison primitives for Tempo values.
  - [Tempo.Math](Tempo.Math.md): Time-unit arithmetic primitives used by enumeration, interval
materialisation (`Tempo.to_interval/1`), and eventually
`Tempo + Duration` / `Tempo − Duration` operations.
  - [Tempo.Operations](Tempo.Operations.md): Set operations on Tempo values — union, intersection,
complement, difference, symmetric difference — plus the
companion predicates (`disjoint?/2`, `overlaps?/2`,
`subset?/2`, `contains?/2`, `equal?/2`).
  - [Tempo.Select](Tempo.Select.md): Narrow a Tempo span by a selector — the composition primitive
for "workdays of June", "the 15th of every month", "every
Dec 25 in the next decade", and user-supplied holidays.
  - [Tempo.Territory](Tempo.Territory.md): Territory resolution — the bridge between the CLDR/BCP 47
territory world (`:US`, `:SA`, `:GB`) and Tempo's
locale-dependent constructors (`Tempo.workdays/1`,
`Tempo.weekend/1`, and future holiday helpers).

- Recurrence (RRULE)
  - [Tempo.RRule](Tempo.RRule.md): Parses [iCalendar RFC 5545](https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.10)
`RRULE` strings into Tempo AST (`%Tempo.Interval{}` with a
`%Tempo.Duration{}` cadence and, where needed, a `repeat_rule`
built from selection tokens).
  - [Tempo.RRule.Expander](Tempo.RRule.Expander.md): Materialise an RFC 5545 RRULE into concrete occurrences by
forming the right AST and handing it to Tempo's interpreter.
  - [Tempo.RRule.Rule](Tempo.RRule.Rule.md): A canonical, typed representation of an RFC 5545 RRULE.
  - [Tempo.RRule.Selection](Tempo.RRule.Selection.md): Resolve RRULE `BY*` selection tokens during recurrence expansion.

- iCalendar integration
  - [Tempo.ICal](Tempo.ICal.md): Import iCalendar (RFC 5545) data into `%Tempo.IntervalSet{}`.

- ISO 8601 and IXDTF
  - [Tempo.Iso8601.Tokenizer](Tempo.Iso8601.Tokenizer.md): Tokenizes an ISO 8601 (parts 1 and 2) or IXDTF string into a
list of tagged tokens that the internal parser then converts
into a `t:Tempo.t/0` struct.
  - [Tempo.Iso8601.Tokenizer.Extended](Tempo.Iso8601.Tokenizer.Extended.md): Tokenizer combinators and post-processing for the
Internet Extended Date/Time Format (IXDTF) defined in
[draft-ietf-sedate-datetime-extended-09](https://www.ietf.org/archive/id/draft-ietf-sedate-datetime-extended-09.html).
  - [Tempo.Iso8601.Tokenizer.Grammar](Tempo.Iso8601.Tokenizer.Grammar.md)
  - [Tempo.Iso8601.Tokenizer.Helpers](Tempo.Iso8601.Tokenizer.Helpers.md)
  - [Tempo.Iso8601.Tokenizer.Numbers](Tempo.Iso8601.Tokenizer.Numbers.md): Numbers aren't just numbers in ISO8601 when considering
the extension formats. In some situations they may

- Explanation and inspection
  - [Tempo.Explain](Tempo.Explain.md): Plain-English explanations of Tempo values, in a form renderers
can style.
  - [Tempo.Explanation](Tempo.Explanation.md): A structured explanation of a Tempo value.
  - [Tempo.Format](Tempo.Format.md): Locale-aware formatting for `Tempo` values, dispatching to the
Localize library.

- Visualizer
  - [Tempo.Visualizer](Tempo.Visualizer.md): A web-based visualizer for ISO 8601 / ISO 8601-2 / IXDTF strings.
  - [Tempo.Visualizer.Standalone](Tempo.Visualizer.Standalone.md): A helper that runs `Tempo.Visualizer` as a standalone web server
for local exploration.

- Exceptions
  - [Tempo.AmbiguousZoneError](Tempo.AmbiguousZoneError.md): Exception raised when a wall-clock reading occurs twice in the
given time zone — the DST fall-back ambiguity. The wall time
exists, but with two different UTC offsets; the caller must
disambiguate with an explicit offset.
  - [Tempo.ConversionError](Tempo.ConversionError.md): Exception raised when a `Tempo` value cannot be converted to
the requested target — typically a standard-library
`t:Date.t/0`, `t:Time.t/0`, `t:NaiveDateTime.t/0`, or
`t:DateTime.t/0`, or in the reverse direction an ISO 8601 or
IXDTF encoding that the target type does not support.
  - [Tempo.CronError](Tempo.CronError.md): Exception raised when a cron expression cannot be parsed or
when one of its fields is outside the valid range for that
cron field.
  - [Tempo.DuplicateZoneError](Tempo.DuplicateZoneError.md): Exception raised when an IXDTF suffix contains more than one
time-zone annotation. The standard permits at most one zone
identifier per value.
  - [Tempo.FloatingTempoError](Tempo.FloatingTempoError.md): Exception raised when an operation requires zone or offset
information but the supplied `Tempo` value is floating — no
`[IANA/Zone]` tag, no `Z`, no numeric offset.
  - [Tempo.IntervalEndpointsError](Tempo.IntervalEndpointsError.md): Exception raised when an operation requires an interval whose
endpoints are both concrete `%Tempo{}` structs, but the
supplied interval carries recurrence, duration-only, or
otherwise non-concrete endpoints.
  - [Tempo.InvalidDateError](Tempo.InvalidDateError.md): Exception raised when date components do not form a valid date
under the chosen calendar.
  - [Tempo.InvalidTimeError](Tempo.InvalidTimeError.md): Exception raised when time-of-day components do not form a valid
time.
  - [Tempo.InvalidUnitError](Tempo.InvalidUnitError.md): Exception raised when an unrecognised time-unit atom is passed
to a function expecting one of `:year`, `:month`, `:week`,
`:day`, `:hour`, `:minute`, `:second`, `:day_of_year`, or
`:day_of_week`.
  - [Tempo.MaterialisationError](Tempo.MaterialisationError.md): Exception raised when a value cannot be materialised into an
explicit `Tempo.Interval` or `Tempo.IntervalSet`.
  - [Tempo.NonAnchoredError](Tempo.NonAnchoredError.md): Exception raised when an operation requires a `Tempo` value
anchored to the time line (that is, carrying at least a
year component) but the caller supplied a non-anchored value.
  - [Tempo.ParseError](Tempo.ParseError.md): Exception raised when an ISO 8601 or IXDTF string cannot be
parsed.
  - [Tempo.RRuleError](Tempo.RRuleError.md): Exception raised when an RFC 5545 RRULE cannot be parsed,
validated, or encoded. Reasons include a missing `FREQ`,
mutually exclusive `UNTIL`/`COUNT`, and invalid BY-rule
combinations.
  - [Tempo.ResolutionError](Tempo.ResolutionError.md): Exception raised when a resolution operation cannot be performed
— truncating to a finer unit than the current resolution,
extending to a coarser unit, or following a unit-successor chain
that terminates before the target under a particular calendar.
  - [Tempo.RoundingError](Tempo.RoundingError.md): Exception raised when a rounding operation cannot be performed
— typically because the target unit is not reachable from the
value's current resolution under the active calendar.
  - [Tempo.UnboundedRecurrenceError](Tempo.UnboundedRecurrenceError.md): Exception raised when a caller attempts to materialise an
unbounded recurrence (`recurrence: :infinity` with no `UNTIL`
and no `:bound` option) into a concrete `IntervalSet`.
  - [Tempo.UnknownZoneError](Tempo.UnknownZoneError.md): Exception raised when a time-zone identifier is not present in
the loaded `Tzdata` database.
  - [Tempo.ZoneGapError](Tempo.ZoneGapError.md): Exception raised when a wall-clock reading does not exist in
the given time zone.

