Localize.Currency (Localize v0.5.0)

Copy Markdown View Source

Defines a currency structure and functions to manage currency codes, validate currencies, and retrieve currency metadata.

Currency data is derived from the Unicode CLDR repository and includes all ISO 4217 currency codes and territory-to-currency mappings.

Locale-specific currency data (display names, pluralized names, symbols) is loaded on demand from the locale data provider.

Summary

Functions

Returns whether a currency name contains annotations.

Returns a map of all currencies for a given locale.

Filters a map of currencies by status predicates.

Returns the currency metadata for the requested currency code in the given locale.

Returns the effective currency format for a given locale.

Returns the effective currency for a given locale.

Returns the full currency history for a locale's territory.

Returns a map matching currency strings to currency codes for a given locale.

Returns whether a currency is currently in use.

Returns the current currency for a given territory.

Returns the current currency for a locale's territory.

Returns a map of territory codes to their current currency.

Returns the display name for a currency.

Returns whether a currency is historic (no longer in use).

Returns whether the given currency code is known.

Returns a list of all known currency codes.

Returns the appropriate currency display name based on plural rules for the locale.

Returns the list of strings that map to a given currency code in a locale.

Returns whether a currency is legal tender.

Returns a map of all territory codes to their currency history.

Returns the currency history for a specific territory.

Returns whether a currency name does not contain annotations.

Validates a currency code and returns its canonical atom form.

Types

currency_code()

@type currency_code() :: atom()

currency_status()

@type currency_status() :: :all | :current | :historic | :tender | :unannotated

filter()

@type filter() ::
  [currency_status() | currency_code()] | currency_status() | currency_code()

t()

@type t() :: %Localize.Currency{
  alt_code: currency_code(),
  cash_digits: non_neg_integer(),
  cash_rounding: non_neg_integer(),
  code: currency_code(),
  count: map() | nil,
  decimal_separator: String.t() | nil,
  digits: non_neg_integer(),
  from: Date.t() | nil,
  grouping_separator: String.t() | nil,
  iso_digits: non_neg_integer(),
  name: String.t(),
  narrow_symbol: String.t() | nil,
  rounding: non_neg_integer(),
  symbol: String.t(),
  tender: boolean(),
  to: Date.t() | nil
}

territory()

@type territory() :: atom() | String.t()

Functions

annotated?(currency)

@spec annotated?(t()) :: boolean()

Returns whether a currency name contains annotations.

Annotated currencies typically have parenthetical descriptions and are often financial instruments rather than legal tender.

Arguments

Returns

  • true or false.

currencies_for_locale(locale, only \\ :all, except \\ nil)

@spec currencies_for_locale(
  Localize.LanguageTag.t() | atom() | String.t(),
  filter(),
  filter()
) :: {:ok, map()} | {:error, Exception.t()}

Returns a map of all currencies for a given locale.

Each key is a currency code atom and each value is a Localize.Currency.t/0 struct with localized display names, symbols, and plural forms. The result can be filtered by currency status.

Arguments

  • locale is a locale identifier atom, string, or a Localize.LanguageTag.t/0.

  • only is a filter for currency status. The default is :all.

  • except is a filter for currencies to exclude. The default is nil.

Returns

  • {:ok, currencies_map} where currencies_map is a map of %{currency_code => Localize.Currency.t()}.

  • {:error, exception} if the locale data cannot be loaded.

currencies_for_locale!(locale, only \\ :all, except \\ nil)

@spec currencies_for_locale!(
  Localize.LanguageTag.t() | atom() | String.t(),
  filter(),
  filter()
) :: map()

Same as currencies_for_locale/3 but raises on error.

Arguments

  • locale is a locale identifier atom, string, or a Localize.LanguageTag.t/0.

  • only is a filter for currency status. The default is :all.

  • except is a filter for currencies to exclude. The default is nil.

Returns

  • A map of %{currency_code => Localize.Currency.t()}.

Raises

  • Raises an exception if the locale data cannot be loaded.

currency_filter(currencies, only \\ :all, except \\ nil)

@spec currency_filter(map(), filter(), filter()) :: map()

Filters a map of currencies by status predicates.

Arguments

  • currencies is a map of %{currency_code => Localize.Currency.t()}.

  • only is a filter or list of filters to include. The default is :all.

  • except is a filter or list of filters to exclude. The default is nil.

Returns

  • A filtered map of currencies.

currency_for_code(currency_code, options \\ [])

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

Returns the currency metadata for the requested currency code in the given locale.

Looks up localized currency data (display name, symbol, plural forms) for a specific currency code.

Arguments

  • currency_code is an atom or string currency code.

  • options is a keyword list of options.

Options

Returns

  • {:ok, Localize.Currency.t()} with localized currency metadata.

  • {:error, exception} if the currency code is unknown or the locale data cannot be loaded.

currency_for_code!(currency_code, options \\ [])

@spec currency_for_code!(atom() | String.t(), Keyword.t()) :: t()

Same as currency_for_code/2 but raises on error.

Arguments

  • currency_code is an atom or string currency code.

  • options is a keyword list of options.

Options

Returns

Raises

  • Raises an exception if the currency code is unknown or the locale data cannot be loaded.

currency_format_from_locale(locale)

@spec currency_format_from_locale(Localize.LanguageTag.t() | String.t() | atom()) ::
  {:ok, :currency | :accounting} | {:error, Exception.t()}

Returns the effective currency format for a given locale.

If the language tag has a cf Unicode extension key set to :account, returns :accounting. Otherwise returns :currency.

Arguments

Returns

  • {:ok, format} where format is :currency or :accounting.

  • {:error, exception} if the locale is not valid.

Examples

iex> {:ok, tag} = Localize.LanguageTag.parse("en-US")
iex> Localize.Currency.currency_format_from_locale(tag)
{:ok, :currency}

iex> Localize.Currency.currency_format_from_locale("en-US")
{:ok, :currency}

currency_from_locale(locale)

@spec currency_from_locale(Localize.LanguageTag.t() | String.t() | atom()) ::
  {:ok, currency_code()} | {:error, Exception.t()}

Returns the effective currency for a given locale.

If the language tag has a cu Unicode extension key set, that currency is returned. Otherwise, the current currency for the tag's territory is returned.

Arguments

Returns

  • {:ok, currency_code} where currency_code is an atom.

  • {:error, exception} if the locale is not valid.

Examples

iex> {:ok, tag} = Localize.LanguageTag.parse("en-US")
iex> Localize.Currency.currency_from_locale(tag)
{:ok, :USD}

iex> Localize.Currency.currency_from_locale("en-AU")
{:ok, :AUD}

currency_history_for_locale(locale)

@spec currency_history_for_locale(Localize.LanguageTag.t() | String.t() | atom()) ::
  {:ok, map()} | {:error, Exception.t()}

Returns the full currency history for a locale's territory.

Resolves the territory from the locale using Localize.Territory.territory_from_locale/1 (which considers the rg extension, the explicit territory, and likely subtags), then returns the currency history for that territory.

Arguments

Returns

  • {:ok, currency_map} where currency_map is a map of %{currency_code => %{from: date, to: date, ...}} entries.

  • {:error, exception} if the locale or territory cannot be resolved.

Examples

iex> {:ok, history} = Localize.Currency.currency_history_for_locale("en-US")
iex> Map.has_key?(history, :USD)
true

iex> {:ok, history} = Localize.Currency.currency_history_for_locale("de")
iex> Map.has_key?(history, :EUR)
true

iex> {:ok, history} = Localize.Currency.currency_history_for_locale("ja")
iex> Map.has_key?(history, :JPY)
true

currency_strings(locale, only \\ :all, except \\ nil)

@spec currency_strings(
  Localize.LanguageTag.t() | atom() | String.t(),
  filter(),
  filter()
) :: {:ok, map()} | {:error, Exception.t()}

Returns a map matching currency strings to currency codes for a given locale.

A currency string is a localized name or symbol representing a currency in a locale-specific manner. The map can be used to parse user input into currency codes.

Arguments

  • locale is a locale identifier atom, string, or a Localize.LanguageTag.t/0.

  • only is a filter for currency status. The default is :all.

  • except is a filter for currencies to exclude. The default is nil.

Returns

  • {:ok, string_map} where string_map is a map of %{downcased_string => currency_code}.

  • {:error, exception} if the locale data cannot be loaded.

currency_strings!(locale, only \\ :all, except \\ nil)

@spec currency_strings!(
  Localize.LanguageTag.t() | atom() | String.t(),
  filter(),
  filter()
) :: map()

Same as currency_strings/3 but raises on error.

Arguments

  • locale is a locale identifier atom, string, or a Localize.LanguageTag.t/0.

  • only is a filter for currency status. The default is :all.

  • except is a filter for currencies to exclude. The default is nil.

Returns

  • A map of %{downcased_string => currency_code}.

Raises

  • Raises an exception if the locale data cannot be loaded.

current?(currency)

@spec current?(t()) :: boolean()

Returns whether a currency is currently in use.

Arguments

Returns

  • true or false.

current_currency_for_territory(territory)

@spec current_currency_for_territory(atom() | String.t()) :: currency_code() | nil

Returns the current currency for a given territory.

The current currency is the one with no :to end date and where :tender is not false.

Arguments

  • territory is a territory code atom or string.

Returns

  • A currency code atom, or nil if no current currency exists.

Examples

iex> Localize.Currency.current_currency_for_territory(:US)
:USD

iex> Localize.Currency.current_currency_for_territory(:AU)
:AUD

current_currency_from_locale(locale)

@spec current_currency_from_locale(Localize.LanguageTag.t() | String.t() | atom()) ::
  {:ok, currency_code() | nil} | {:error, Exception.t()}

Returns the current currency for a locale's territory.

This function does not consider the U extension parameter cu. Use currency_from_locale/1 to get the effective currency including overrides.

Arguments

Returns

  • {:ok, currency_code} where currency_code is an atom.

  • {:ok, nil} if the locale has no territory or the territory has no current currency.

  • {:error, exception} if the locale is not valid.

Examples

iex> {:ok, tag} = Localize.LanguageTag.parse("en-AU")
iex> Localize.Currency.current_currency_from_locale(tag)
{:ok, :AUD}

iex> Localize.Currency.current_currency_from_locale("en-US")
{:ok, :USD}

current_territory_currencies()

@spec current_territory_currencies() :: %{required(atom()) => currency_code()}

Returns a map of territory codes to their current currency.

Territories with no current currency are excluded.

Returns

  • A map of %{territory_code => currency_code}.

Examples

iex> map = Localize.Currency.current_territory_currencies()
iex> Map.get(map, :US)
:USD

display_name(currency, options \\ [])

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

Returns the display name for a currency.

When given a Localize.Currency.t/0 struct, returns its :name field directly. When given a currency code, looks up the localized name from the locale data.

Arguments

  • currency is a currency code atom, string, or a Localize.Currency.t/0 struct.

  • options is a keyword list of options.

Options

Returns

  • {:ok, display_name} where display_name is a string.

  • {:error, exception} if the currency has no display name or is unknown.

display_name!(currency, options \\ [])

@spec display_name!(atom() | String.t() | t(), Keyword.t()) :: String.t()

Same as display_name/2 but raises on error.

Arguments

  • currency is a currency code atom, string, or a Localize.Currency.t/0 struct.

  • options is a keyword list of options.

Options

Returns

  • A display name string.

Raises

  • Raises an exception if the currency has no display name or is unknown.

historic?(currency)

@spec historic?(t()) :: boolean()

Returns whether a currency is historic (no longer in use).

Arguments

Returns

  • true or false.

known_currency_code?(currency_code)

@spec known_currency_code?(atom() | String.t()) :: boolean()

Returns whether the given currency code is known.

Arguments

  • currency_code is an atom or string currency code.

Returns

  • true or false.

Examples

iex> Localize.Currency.known_currency_code?(:USD)
true

iex> Localize.Currency.known_currency_code?("GGG")
false

known_currency_codes()

@spec known_currency_codes() :: [currency_code(), ...]

Returns a list of all known currency codes.

Returns

  • A list of atom currency codes.

Examples

iex> codes = Localize.Currency.known_currency_codes()
iex> :USD in codes
true

pluralize(number, currency, options \\ [])

@spec pluralize(number(), currency_code(), Keyword.t()) ::
  {:ok, String.t()} | {:error, Exception.t()}

Returns the appropriate currency display name based on plural rules for the locale.

Uses the locale's cardinal plural rules to determine which plural form of the currency name to use for the given number.

Arguments

  • number is an integer, float, or Decimal.

  • currency is a currency code atom.

  • options is a keyword list of options.

Options

Returns

  • {:ok, pluralized_name} where pluralized_name is the appropriate plural form string.

  • {:error, exception} if the currency is unknown or the locale data cannot be loaded.

strings_for_currency(currency, locale)

@spec strings_for_currency(
  currency_code() | String.t(),
  Localize.LanguageTag.t() | atom() | String.t()
) :: {:ok, [String.t()]} | {:error, Exception.t()}

Returns the list of strings that map to a given currency code in a locale.

This is the inverse of currency_strings/3 filtered to a single currency. It returns all localized representations (name, symbol, plural forms) that identify the currency.

Arguments

Returns

  • {:ok, strings} where strings is a list of downcased strings that represent the currency in the locale.

  • {:error, exception} if the currency is unknown or the locale data cannot be loaded.

strings_for_currency!(currency, locale)

@spec strings_for_currency!(
  currency_code() | String.t(),
  Localize.LanguageTag.t() | atom() | String.t()
) :: [String.t()]

Same as strings_for_currency/2 but raises on error.

Arguments

Returns

  • A list of downcased strings that represent the currency in the locale.

Raises

  • Raises an exception if the currency is unknown or the locale data cannot be loaded.

tender?(currency)

@spec tender?(t()) :: boolean()

Returns whether a currency is legal tender.

Arguments

Returns

  • true or false.

territory_currencies()

@spec territory_currencies() :: %{required(atom()) => %{required(atom()) => map()}}

Returns a map of all territory codes to their currency history.

Each territory maps to a map of currency codes with date ranges indicating when each currency was in use.

Returns

  • A map of %{territory_code => %{currency_code => date_info}}.

Examples

iex> currencies = Localize.Currency.territory_currencies()
iex> us = Map.get(currencies, :US)
iex> Map.has_key?(us, :USD)
true

territory_currencies(territory)

@spec territory_currencies(territory()) :: {:ok, map()} | {:error, Exception.t()}

Returns the currency history for a specific territory.

Arguments

  • territory is a territory code atom or string (e.g., :US or "US").

Returns

  • {:ok, currency_map} with currency codes and date ranges.

  • {:error, Localize.UnknownCurrencyError.t()} if no currencies are found for the territory.

Examples

iex> {:ok, currencies} = Localize.Currency.territory_currencies(:US)
iex> Map.has_key?(currencies, :USD)
true

territory_currencies!(territory)

@spec territory_currencies!(territory()) :: map()

Same as territory_currencies/1 but raises on error.

Arguments

  • territory is a territory code atom or string (e.g., :US or "US").

Returns

  • A map of currency codes and date ranges.

Raises

  • Raises an exception if no currencies are found for the territory.

unannotated?(currency)

@spec unannotated?(t()) :: boolean()

Returns whether a currency name does not contain annotations.

Arguments

Returns

  • true or false.

validate_currency(currency_code)

@spec validate_currency(atom() | String.t()) ::
  {:ok, currency_code()} | {:error, Exception.t()}

Validates a currency code and returns its canonical atom form.

Checks both ISO 4217 codes and registered custom currencies.

Arguments

  • currency_code is an atom or string currency code.

Returns

  • {:ok, currency_code} where currency_code is an atom.

  • {:error, Localize.UnknownCurrencyError.t()} if the code is not known.

Examples

iex> Localize.Currency.validate_currency("AUD")
{:ok, :AUD}

iex> Localize.Currency.validate_currency(:USD)
{:ok, :USD}