Calendrical.TimeZone (Calendrical v0.13.0)

Copy Markdown

Resolve textual time-zone identifiers captured by the parser into UTC offsets.

The resolver tries these strategies in order:

  1. ISO 8601 offset — Z, ±HHMM, ±HH:MM, ±HH:MM:SS.

  2. GMT/UTC format — GMT, GMT+10, UTC-5:30.

  3. IANA region/city — Asia/Tokyo, America/New_York. Looked up via the host application's installed time-zone database (Tzdata or Tz) — whichever is loaded at runtime. If neither is loaded, IANA names are rejected (consumer should add :tzdata or :tz as a dependency to support them).

  4. Short abbreviation — PST, EST, JST. Resolved via a small static table for the most common abbreviations. Note that abbreviations are inherently ambiguous (CST could be Central or China Standard); the table picks the most common North-American/Asian/European reading.

  5. CLDR locale name — Pacific Time, Greenwich Mean Time. Looked up via Localize's CLDR timeZoneNames data for the parsing locale. Zone-specific names are tried first, then metazone names (Pacific Standard Time, Mitteleuropäische Zeit), which cover most localized zone names in CLDR. A metazone resolves to its representative zone for the locale's territory — Mitteleuropäische Zeit under a :de locale is Europe/Berlin — falling back to the metazone's golden zone (Europe/Paris).

When the parser captures a wall-clock instant alongside an IANA zone, the resolver uses the instant to pick between standard / daylight offsets (e.g. 2024-07-15 14:00 America/New_YorkEDT (-04:00), while 2024-01-15 14:00 America/New_YorkEST (-05:00)).

Summary

Functions

Resolves zone_string against a wall-clock NaiveDateTime.

Returns the time-zone database module, or nil when none is configured and no known implementation is loaded.

Functions

resolve(zone_string, naive_dt, options \\ [])

@spec resolve(String.t(), NaiveDateTime.t(), Keyword.t()) ::
  {:ok, DateTime.t()} | {:error, atom() | Exception.t()}

Resolves zone_string against a wall-clock NaiveDateTime.

Arguments

  • zone_string is the captured zone token (e.g. "PST", "+0530", "Asia/Tokyo", "Pacific Time").

  • naive_dt is the parsed wall-clock instant. Used to disambiguate standard vs daylight offsets for IANA zones (e.g. America/New_York is -05:00 in January and -04:00 in July).

  • options is a keyword list of options.

Options

  • :locale — locale to use when looking up CLDR-style names like "Pacific Time". Defaults to Localize.get_locale/0.

Returns

  • {:ok, DateTime.t()} when the zone resolves.

  • {:error, reason} when the zone string isn't recognizable.

Examples

iex> {:ok, datetime} = Calendrical.TimeZone.resolve("+05:30", ~N[2024-07-15 14:00:00])
iex> to_string(datetime)
"2024-07-15 14:00:00+05:30"

iex> {:ok, datetime} = Calendrical.TimeZone.resolve("GMT+02:00", ~N[2024-01-15 09:00:00])
iex> to_string(datetime)
"2024-01-15 09:00:00+02:00"

iex> {:ok, datetime} = Calendrical.TimeZone.resolve("Asia/Tokyo", ~N[2024-07-15 14:00:00])
iex> {datetime.zone_abbr, datetime.utc_offset}
{"JST", 32400}

iex> {:ok, datetime} = Calendrical.TimeZone.resolve("Pacific Standard Time", ~N[2024-07-15 14:00:00])
iex> datetime.time_zone
"America/Los_Angeles"

iex> {:ok, datetime} = Calendrical.TimeZone.resolve("Mitteleuropäische Zeit", ~N[2024-07-15 14:00:00], locale: :de)
iex> datetime.time_zone
"Europe/Berlin"

iex> Calendrical.TimeZone.resolve("Middle Earth Time", ~N[2024-07-15 14:00:00])
{:error, :unresolvable_zone}

tz_database()

@spec tz_database() :: module() | nil

Returns the time-zone database module, or nil when none is configured and no known implementation is loaded.

The database resolves, in order, from:

  1. The :elixir :time_zone_database application environment (config :elixir, :time_zone_database, Tz.TimeZoneDatabase) — Elixir's own UTC-only default is treated as "not configured".

  2. Tz.TimeZoneDatabase or Tzdata.TimeZoneDatabase when the respective library is loaded (Tz is preferred when both are available).

Consumers that want IANA name resolution should add a Calendar.TimeZoneDatabase implementation to their dependency list and configure it. The resolver works without one but rejects IANA names.

Returns

Examples

iex> Calendrical.TimeZone.tz_database()
Tz.TimeZoneDatabase