# Tempo v0.5.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.