# Tempo v0.20.0 - Table of Contents > Time as an interval, not an instant — ISO 8601 / IXDTF date, time, interval, duration, recurrence, set-algebra, scheduling, and constraint-network 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 - [Using Tempo with an AI assistant](ai-assistance.md) - [Chronological networks](chronological-networks.md) - [Enumeration semantics](enumeration-semantics.md) - [Falsehoods Programmers Believe About Time](falsehoods.md) - [iCalendar integration](ical-integration.md) - [Converting to and from Elixir date/time types](interop.md) - [Pattern matching with sigils](pattern-matching-with-sigils.md) - [Set operations](set-operations.md) - [Dating under uncertainty](uncertain-dates.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) - Foundations - [Custom calendars — fiscal years, retail weeks, academic years](custom-calendars.md) - [Temporal formalisms and where Tempo fits](temporal-formalisms.md) ## Modules - [Tempo.Cron](Tempo.Cron.md): Parses cron expressions into recurring `t:Tempo.Interval.t/0` values — the same first-class recurrence that `Tempo.RRule.parse/2` and native ISO 8601 repeating intervals produce. - [Tempo.Interval.Steps](Tempo.Interval.Steps.md): Closed-form step arithmetic for interval enumeration. - [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.Microsecond](Tempo.Microsecond.md): Conversions for Tempo's sub-second component. - [Tempo.Network](Tempo.Network.md): A chronological network — a set of time-periods together with the sequences and relations that constrain them. - [Tempo.Network.Normalize](Tempo.Network.Normalize.md): Reduce a `t:Tempo.Network.t/0` to a Simple Temporal Problem: a set of boundary nodes and integer-weighted constraints of the single shape `b₁ − b₂ ≤ k`. - [Tempo.Network.Relation](Tempo.Network.Relation.md): A chronological relation — a constraint between the boundaries of two time-periods. - [Tempo.Network.Solver](Tempo.Network.Solver.md): Consistency checking and bound tightening for a chronological network, by solving its Simple Temporal Problem. - [Tempo.Network.TimePeriod](Tempo.Network.TimePeriod.md): A single time-period in a chronological network — a reign, era, or the time-span of a stratum. - [Tempo.Schedule](Tempo.Schedule.md): Constraint-based project scheduling over `Tempo.Network`. - [Tempo.Schedule.Slot](Tempo.Schedule.Slot.md): A solved task in a `Tempo.Schedule` — when the task is scheduled and how much room it has to move. - [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.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. - 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.InvalidCalendarError](Tempo.InvalidCalendarError.md): Exception returned (or raised, by the `!` variants) when a calendar argument to `Tempo.from_iso8601/2` is not a usable calendar module. - [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.RequiresAnchorError](Tempo.RequiresAnchorError.md): Exception returned when arithmetic on an un-anchored value (one with no `:year`) would depend on the missing year, so it cannot be resolved. - [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. - [Tempo.ZoneOffsetMismatchError](Tempo.ZoneOffsetMismatchError.md): Exception raised (or returned) when an IXDTF value's explicit numeric offset disagrees with its IANA time zone at the value's wall instant.