Tempo.TimeZoneDatabase (Tempo v1.0.0)

Copy Markdown View Source

Access to the time zone database Tempo uses for zone validation, offset resolution, and DST-aware arithmetic.

Tempo is time zone database agnostic: it works against the standard Calendar.TimeZoneDatabase behaviour rather than any specific implementation. The database is resolved, in order, from:

  1. The :ex_tempo, :time_zone_database application environment.

  2. Elixir's own configured database, Calendar.get_time_zone_database/0 (set with config :elixir, :time_zone_database, ... or Calendar.put_time_zone_database/1).

Any implementation works — tz, tzdata, time_zone_info, or zoneinfo. Configure one at boot, for example:

config :elixir, :time_zone_database, Tz.TimeZoneDatabase

When no database is configured (Elixir's default is Calendar.UTCOnlyTimeZoneDatabase), parsing remains fully functional: zone names in IXDTF suffixes are accepted without registry validation, and only the operations that genuinely need zone rules — UTC projection, shift_zone/2, DST-aware walks — degrade or error.

Summary

Types

A time zone period as returned by the Calendar.TimeZoneDatabase behaviour — at minimum :utc_offset, :std_offset, and :zone_abbr.

Functions

The Calendar.TimeZoneDatabase implementation Tempo resolves for this call — see the module doc for the resolution order.

The period in effect in zone at a UTC instant given as gregorian seconds (seconds since year 0, :calendar's epoch).

The period(s) matching a wall-clock reading in zone, given as gregorian seconds.

The total UTC offset of a period in seconds — the standard offset plus any daylight-saving adjustment.

Return whether zone is a time zone known to the configured database.

Types

period()

A time zone period as returned by the Calendar.TimeZoneDatabase behaviour — at minimum :utc_offset, :std_offset, and :zone_abbr.

Functions

database()

@spec database() :: Calendar.time_zone_database()

The Calendar.TimeZoneDatabase implementation Tempo resolves for this call — see the module doc for the resolution order.

Returns

period_at_utc(zone, utc_seconds)

@spec period_at_utc(String.t(), integer()) :: {:ok, period()} | {:error, term()}

The period in effect in zone at a UTC instant given as gregorian seconds (seconds since year 0, :calendar's epoch).

Pre-common-era instants return a zero-offset local-mean-time period without consulting the database.

Arguments

  • zone is an IANA zone name.

  • utc_seconds is the instant in gregorian seconds, UTC.

Returns

  • {:ok, period} — a UTC instant is never ambiguous.

  • {:error, reason} from the database (unknown zone, or no real database configured).

period_at_wall(zone, wall_seconds)

@spec period_at_wall(String.t(), integer()) ::
  {:ok, period()}
  | {:ambiguous, period(), period()}
  | {:gap, {period(), Calendar.naive_datetime()},
     {period(), Calendar.naive_datetime()}}
  | {:error, term()}

The period(s) matching a wall-clock reading in zone, given as gregorian seconds.

Returns the standard behaviour shapes: {:ok, period} for an unambiguous reading, {:ambiguous, first, second} for a DST fall-back, {:gap, ...} for a spring-forward reading that does not exist, or {:error, reason}. Pre-common-era readings return {:ok, local-mean-time} without consulting the database.

Arguments

  • zone is an IANA zone name.

  • wall_seconds is the wall-clock reading in gregorian seconds.

Returns

  • {:ok, period} | {:ambiguous, period, period} | {:gap, {period, limit}, {period, limit}} | {:error, reason}.

total_offset(map)

@spec total_offset(period()) :: number()

The total UTC offset of a period in seconds — the standard offset plus any daylight-saving adjustment.

Arguments

Returns

  • An offset in seconds. Always an integer in practice; the spec is number() because the behaviour's period field specs admit floats.

zone_exists?(zone)

@spec zone_exists?(String.t()) :: boolean()

Return whether zone is a time zone known to the configured database.

When no real database is configured (the resolver answers with Elixir's UTC-only default), any syntactically valid zone name is accepted — parsing must not depend on zone data being present; operations that need the zone's rules surface their own errors.

Arguments

  • zone is an IANA zone name ("Europe/Paris", …).

Returns

  • true or false.