Packages
ex_cldr
2.45.2
2.47.5
2.47.4
2.47.3
2.47.2
2.47.1
2.47.0
2.46.0
2.45.2
2.45.1
2.45.0
2.44.1
2.44.0
2.43.2
2.43.1
2.43.0
2.42.0
2.41.1
2.41.0
2.40.4
2.40.3
2.40.2
2.40.1
2.40.0
2.39.2
2.39.1
2.39.0
2.38.1
2.38.0
2.37.5
2.37.4
2.37.3
retired
2.37.2
2.37.1
2.37.0
2.36.0
2.35.1
2.35.0
retired
2.34.2
2.34.1
2.34.0
2.33.2
2.33.1
2.33.1-rc.0
2.33.0
2.32.1
2.32.0
2.31.0
2.30.0
2.29.0
2.28.0
2.27.1
2.27.0
retired
2.26.3
2.26.2
2.26.1
2.26.0
2.25.0
2.24.2
2.24.1
2.24.0
2.24.0-rc.6
2.24.0-rc.5
2.24.0-rc.4
2.24.0-rc.3
2.24.0-rc.2
2.24.0-rc.1
2.24.0-rc.0
2.23.2
2.23.1
2.23.0
2.22.1
2.22.0
2.21.0
2.20.0
2.20.0-rc.3
2.20.0-rc.2
2.20.0-rc.1
2.20.0-rc.0
2.19.1
2.19.0
2.18.2
2.18.1
2.18.0
2.18.0-rc.0
2.17.2
2.17.1
2.17.0
2.16.2
2.16.1
2.16.1-rc.0
2.16.0
2.15.0
2.14.1
2.14.0
2.14.0-rc.0
2.13.0
2.12.1
2.12.0
2.11.1
2.11.0
2.10.2
2.10.1
2.10.0
retired
2.9.0
2.8.1
2.8.0
2.7.2
2.7.1
2.7.0
2.6.2
2.6.1
2.6.0
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.2
2.3.1
2.3.0
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.1.0
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-rc.3
retired
2.0.0-rc.2
retired
2.0.0-rc.1
retired
2.0.0-rc.0
retired
1.8.2
1.8.1
1.8.0
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.2
1.5.1
1.5.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
retired
1.4.0-rc.3
retired
1.4.0-rc.2
retired
1.4.0-rc.1
retired
1.4.0-rc.0
retired
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.0
1.0.0-rc.3
retired
1.0.0-rc.2
retired
1.0.0-rc.1
retired
1.0.0-rc.0
retired
0.13.1
0.13.0
0.12.2
retired
0.12.1
retired
0.12.0
retired
0.11.0
retired
0.10.0
retired
0.9.0
retired
0.8.3
retired
0.8.2
retired
0.8.1
retired
0.8.0
retired
0.7.0
retired
0.6.2
retired
0.6.1
retired
0.6.0
retired
0.5.2
retired
0.5.1
retired
0.5.0
retired
0.4.2
retired
0.4.1
retired
0.4.0
retired
0.3.0
retired
0.2.1
retired
0.2.0
retired
0.1.3
retired
0.1.2
retired
0.1.1
retired
0.1.0
retired
0.0.20
retired
0.0.19
retired
0.0.18
retired
0.0.17
retired
0.0.16
retired
0.0.15
retired
0.0.14
retired
0.0.13
retired
0.0.12
retired
0.0.11
retired
0.0.10
retired
0.0.8
retired
0.0.7
retired
0.0.6
retired
0.0.5
retired
0.0.4
retired
0.0.3
retired
Common Locale Data Repository (CLDR) functions for Elixir to localize and format numbers, dates, lists, messages, languages, territories and units with support for over 700 locales for internationalized (i18n) and localized (L10N) applications.
Current section
Files
Jump to
Current section
Files
lib/cldr/timezone.ex
defmodule Cldr.Timezone do
@moduledoc """
Functions to map between the CLDR short time zone code and the
IANA timezone names.
The Unicode [locale](https://unicode.org/reports/tr35/#Locale)
[extension U](https://unicode.org/reports/tr35/#u_Extension)
allows the specification of the time zone requested for the provided locale.
This short timezone codes never change even if the IANA names change
over time. Therefore these short codes are always stable between CLDR
releases.
"""
alias Cldr.Locale
@type short_zone :: String.t()
@type timezone :: %{
aliases: [String.t(), ...],
preferred: nil | short_zone(),
territory: Locale.territory_code()
}
@unknown_zone "Etc/Unknown"
@timezones Cldr.Config.timezones()
@timezones_by_territory @timezones
|> Enum.group_by(
fn {_k, v} -> v.territory end,
fn {k, v} -> Map.put(v, :short_zone, k) end
)
|> Enum.map(fn
{nil, _} ->
nil
{k, v} ->
case Cldr.validate_territory(k) do
{:ok, territory} -> {territory, Elixir.List.flatten(v)}
end
end)
|> Enum.reject(&is_nil/1)
|> Map.new()
@territories_by_timezone @timezones_by_territory
|> Enum.map(fn {territory, zones} ->
Enum.map(zones, fn zone ->
Enum.map(zone.aliases, fn aliass -> {aliass, territory} end)
end)
end)
|> List.flatten()
|> Enum.reject(fn {_zone, territory} -> territory == :UT end)
|> Map.new()
@doc """
Returns a mapping of CLDR short zone codes to
IANA timezone names.
"""
@spec timezones() :: %{(zone_name :: String.t()) => timezone()}
def timezones do
@timezones
end
@doc false
@deprecated "Use timezones_by_territory/0 instead"
def timezones_for_territory do
timezones_by_territory()
end
@spec timezones_by_territory() ::
unquote(Cldr.Type.timezones_by_territory(@timezones_by_territory))
@doc """
Returns a mapping of territories to
their known IANA timezone names.
"""
@dialyzer {:nowarn_function, timezones_by_territory: 0}
def timezones_by_territory do
@timezones_by_territory
end
@doc """
Returns a mapping of time zone IDs to
their known territory.
A time zone can only belong to one
territory in CLDR.
"""
def territories_by_timezone do
@territories_by_timezone
end
@doc false
def timezones_for_territory(territory) do
timezones_by_territory()
|> Map.fetch(territory)
end
@doc false
def timezone_count_for_territory(territory) do
with {:ok, zones} <- timezones_for_territory(territory) do
Enum.count(zones)
end
end
@doc """
Returns a list of IANA time zone names for
a given CLDR short zone code, or `nil`.
The first time zone name in the list is
the canonical time zone name.
### Examples
iex> Cldr.Timezone.get_short_zone("ausyd")
%{
preferred: nil,
aliases: ["Australia/Sydney", "Australia/ACT", "Australia/Canberra", "Australia/NSW"],
territory: :AU
}
iex> Cldr.Timezone.get_short_zone("nope")
nil
"""
@spec get_short_zone(String.t(), String.t() | nil) :: map() | nil
def get_short_zone(short_zone, default \\ nil) do
Map.get(timezones(), short_zone, default)
end
@doc false
@deprecated "Use get_short_zone/1 instead"
def get(short_zone) do
get_short_zone(short_zone)
end
@doc """
Returns a `{:ok, list}` where list is a
list of IANA timezone names for
a given CLDR short zone code. If no such
short code exists then `:error` is returned.
### Example
iex> Cldr.Timezone.fetch_short_zone("ausyd")
{
:ok,
%{
preferred: nil,
aliases: ["Australia/Sydney", "Australia/ACT", "Australia/Canberra", "Australia/NSW"],
territory: :AU
}
}
iex> Cldr.Timezone.fetch_short_zone("nope")
:error
"""
@spec fetch_short_zone(String.t()) :: {:ok, map()} | :error
def fetch_short_zone(short_zone) do
Map.fetch(timezones(), short_zone)
end
@doc false
@deprecated "Use fetch_short_zone/1 instead"
def fetch(short_zone) do
fetch_short_zone(short_zone)
end
@doc false
@deprecated "Use validate_short_zone/1 instead"
def validate_timezone(short_zone) do
validate_short_zone(short_zone)
end
@doc false
@spec validate_short_zone(String.t()) :: {:ok, String.t()} | {:error, String.t()}
def validate_short_zone(short_zone) do
case fetch(short_zone) do
{:ok, %{aliases: [first_zone | _others]}} ->
{:ok, first_zone}
:error ->
{:error, @unknown_zone}
end
end
end