Packages
ex_cldr_calendars
1.13.0-rc.0
2.4.4
2.4.3
2.4.2
2.4.1
2.4.0
2.3.1
2.3.0
2.2.0
2.1.1
2.1.0
2.0.0
1.26.4
1.26.3
1.26.2
1.26.1
1.26.0
1.25.2
1.25.1
1.25.0
1.24.2
1.24.1
1.24.0
retired
1.23.1
1.23.0
1.22.1
1.22.0
1.21.0
1.20.0
1.19.0
1.18.1
1.18.0
1.17.3
1.17.2
1.17.1
1.17.0
1.17.0-rc.3
1.17.0-rc.2
1.17.0-rc.1
1.17.0-rc.0
1.16.0
1.15.3
1.15.2
1.15.1
1.15.0
1.14.1
1.14.0
1.13.0
1.13.0-rc.1
1.13.0-rc.0
1.12.1
1.12.0
1.11.0
1.11.0-rc.0
1.10.1
1.10.0
1.9.0
1.8.1
1.8.0
1.8.0-rc.0
1.7.1
1.7.0
1.6.0
1.5.1
1.5.0
retired
1.4.0
retired
1.3.0
retired
1.2.0
retired
1.1.0
retired
1.0.0
retired
0.9.0
retired
0.8.0
retired
0.7.0
retired
0.6.0
retired
0.5.0
retired
0.4.1
0.4.0
retired
0.3.0
retired
0.2.0
retired
0.1.0
retired
Localized month- and week-based calendars and calendar functions based upon CLDR data.
Current section
Files
Jump to
Current section
Files
lib/cldr/calendar/preference.ex
defmodule Cldr.Calendar.Preference do
alias Cldr.LanguageTag
@territory_preferences Cldr.Config.calendar_preferences()
@doc false
def territory_preferences do
@territory_preferences
end
@doc false
def preferences_for_territory(territory) do
with {:ok, territory} <- Cldr.validate_territory(territory) do
territory_preferences = territory_preferences()
default_territory = Cldr.default_territory()
the_world = Cldr.the_world()
preferences =
Map.get(territory_preferences, territory) ||
Map.get(territory_preferences, default_territory) ||
Map.get(territory_preferences, the_world)
{:ok, preferences}
end
end
@doc """
Returns the calendar module preferred for
a territory.
## Arguments
* `territory` is any valid ISO3166-2 code as
an `String.t` or upcased `atom()`
## Returns
* `{:ok, calendar_module}` or
* `{:error, {exception, reason}}`
## Examples
iex> Cldr.Calendar.Preference.calendar_from_territory :US
{:ok, Cldr.Calendar.US}
iex> Cldr.Calendar.Preference.calendar_from_territory :XX
{:error, {Cldr.UnknownTerritoryError, "The territory :XX is unknown"}}
## Notes
The overwhelming majority of territories have
`:gregorian` as their first preferred calendar
and therefore `Cldr.Calendar.Gregorian`
will be returned for most territories.
Returning any other calendar module would require:
1. That another calendar is preferred over `:gregorian`
for a territory
2. That a calendar module is available to support
that calendar.
As an example, Iran (territory `:IR`) prefers the
`:persian` calendar. If the optional library
[ex_cldr_calendars_persian](https://hex.pm/packages/ex_cldr_calendars_persian)
is installed, the calendar module `Cldr.Calendar.Persian` will
be returned. If it is not installed, `Cldr.Calendar.Gregorian`
will be returned as `:gregorian` is the second preference
for `:IR`.
"""
def calendar_from_territory(territory) when is_atom(territory) do
with {:ok, preferences} <- preferences_for_territory(territory),
{:ok, calendar_module} <- find_calendar(preferences) do
if calendar_module == Cldr.Calendar.default_calendar() do
Cldr.Calendar.calendar_for_territory(territory)
else
{:ok, calendar_module}
end
end
end
def calendar_from_territory(territory, calendar) when is_atom(territory) do
with {:ok, preferences} <- preferences_for_territory(territory),
{:ok, calendar_module} <- find_calendar(preferences, calendar) do
if calendar_module == Cldr.Calendar.default_calendar() do
Cldr.Calendar.calendar_for_territory(territory)
else
{:ok, calendar_module}
end
end
end
@deprecated "Use calendar_from_territory/1"
defdelegate calendar_for_territory(territory), to: __MODULE__, as: :calendar_from_territory
defp find_calendar(preferences) do
error = {:error, Cldr.unknown_calendar_error(preferences)}
Enum.reduce_while(preferences, error, fn calendar, acc ->
module = calendar_module(calendar)
if Code.ensure_loaded?(module) do
{:halt, {:ok, module}}
else
{:cont, acc}
end
end)
end
defp find_calendar(preferences, calendar) do
if preferred = Enum.find(preferences, &(&1 == calendar)) do
find_calendar([preferred])
else
find_calendar(preferences)
end
end
@doc """
Return the calendar module for a locale.
## Arguments
* `:locale` is any locale or locale name validated
by `Cldr.validate_locale/2`. The default is
`Cldr.get_locale()` which returns the locale
set for the current process
## Returns
* `{:ok, calendar_module}` or
* `{:error, {exception, reason}}`
## Examples
iex> Cldr.Calendar.Preference.calendar_from_locale "en-GB"
{:ok, Cldr.Calendar.GB}
iex> Cldr.Calendar.Preference.calendar_from_locale "en-GB-u-ca-gregory"
{:ok, Cldr.Calendar.GB}
iex> Cldr.Calendar.Preference.calendar_from_locale "en"
{:ok, Cldr.Calendar.US}
iex> Cldr.Calendar.Preference.calendar_from_locale "fa-IR"
{:ok, Cldr.Calendar.Persian}
iex> Cldr.Calendar.Preference.calendar_from_locale "fa-IR-u-ca-gregory"
{:ok, Cldr.Calendar.IR}
"""
def calendar_from_locale(locale \\ Cldr.get_locale())
def calendar_from_locale(%LanguageTag{locale: %{calendar: nil}} = locale) do
locale
|> Cldr.Locale.territory_from_locale()
|> calendar_from_territory
end
def calendar_from_locale(%LanguageTag{locale: %{calendar: calendar}} = locale) do
locale
|> Cldr.Locale.territory_from_locale()
|> calendar_from_territory(calendar)
end
def calendar_from_locale(%LanguageTag{} = locale) do
locale
|> Cldr.Locale.territory_from_locale()
|> calendar_from_territory
end
def calendar_from_locale(locale) when is_binary(locale) do
calendar_from_locale(locale, Cldr.default_backend!())
end
def calendar_from_locale(other) do
{:error, Cldr.Locale.locale_error(other)}
end
def calendar_from_locale(locale, backend) when is_binary(locale) do
with {:ok, locale} <- Cldr.validate_locale(locale, backend) do
calendar_from_locale(locale)
end
end
@deprecated "Use calendar_from_locale/1"
defdelegate calendar_for_locale(locale), to: __MODULE__, as: :calendar_from_locale
@base_calendar Cldr.Calendar
@known_calendars Cldr.known_calendars()
@calendar_modules @known_calendars
|> Enum.map(fn c ->
{c,
Module.concat(@base_calendar, c |> Atom.to_string() |> Macro.camelize())}
end)
|> Map.new()
def calendar_modules do
@calendar_modules
end
def calendar_module(calendar) when calendar in @known_calendars do
Map.fetch!(calendar_modules(), calendar)
end
def calendar_module(other) do
{:error, Cldr.unknown_calendar_error(other)}
end
def calendar_from_name(name) do
calendar_module = calendar_module(name)
if Code.ensure_loaded?(calendar_module) do
calendar_module
else
nil
end
end
end