Packages
ex_cldr_numbers
2.35.1
2.38.3
2.38.2
2.38.1
2.38.0
2.37.0
2.36.0
2.35.2
2.35.1
2.35.0
2.34.1
2.34.0
2.33.6
2.33.5
2.33.4
2.33.3
2.33.2
2.33.1
2.33.0
2.32.4
2.32.3
2.32.2
2.32.1
2.32.0
retired
2.31.3
retired
2.31.2
2.31.1
2.31.0
2.30.1
2.30.0
2.29.0
2.28.0
2.27.3
2.27.2
2.27.1
2.27.0
2.26.0
2.25.2
2.25.1
2.25.0
2.24.0
2.23.3
2.23.2
2.23.1
2.23.0
2.23.0-rc.4
2.23.0-rc.3
2.23.0-rc.2
2.23.0-rc.1
2.23.0-rc.0
2.22.1
2.22.0
2.21.0
2.20.0
2.19.0
2.18.4
2.18.3
2.18.2
2.18.1
2.18.0
2.17.0
2.17.0-rc.1
2.17.0-rc.0
2.16.1
2.16.0
2.16.0-rc.0
2.15.4
2.15.3
2.15.2
2.15.1
2.15.0
2.14.0
2.13.2
2.13.1
2.13.0
2.13.0-rc.0
2.12.1
2.12.0
2.11.0
2.10.0
2.9.0
2.8.0
2.7.2
2.7.1
2.7.0
2.6.4
2.6.3
2.6.2
2.6.1
2.6.0
2.5.0
2.4.4
2.4.3
2.4.2
2.4.1
2.4.0
2.3.0
2.2.0
2.1.1
2.1.0
2.0.0
2.0.0-rc.0
1.6.0
1.5.2
1.5.1
1.5.0
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.1
1.3.0
1.3.0-rc.1
1.3.0-rc.0
retired
1.2.0
1.1.0
1.0.1
1.0.0
1.0.0-rc.0
retired
0.3.3
0.3.2
retired
0.3.1
retired
0.3.0
retired
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Number and currency localization and formatting functions for the Common Locale Data Repository (CLDR).
Current section
Files
Jump to
Current section
Files
lib/cldr/number/formatter/currency_formatter.ex
defmodule Cldr.Number.Formatter.Currency do
@moduledoc """
Number formatter for the `:currency` `:long` format.
This formatter implements formatting a currency in a long form. This
is not the same as decimal formatting with a currency placeholder.
To explain the difference, look at the following examples:
iex> Cldr.Number.to_string 123, TestBackend.Cldr, format: :currency, currency: "USD"
{:ok, "$123.00"}
iex> Cldr.Number.to_string 123, TestBackend.Cldr, format: :long, currency: "USD"
{:ok, "123 US dollars"}
In the first example the format is defined by a decimal mask. In this example
the format mask comes from:
iex> {:ok, formats} = Cldr.Number.Format.all_formats_for("en", TestBackend.Cldr)
...> formats.latn.currency
"¤#,##0.00"
In the second example we are using a format that combines the number with
a language translation of the currency name. In this example the format
comes from:
iex> {:ok, formats} = Cldr.Number.Format.all_formats_for("en", TestBackend.Cldr)
...> formats.latn.currency_long
%{one: [0, " ", 1], other: [0, " ", 1]}
Where "{0}" is replaced with the number formatted using the `:standard`
decimal format and "{1} is replaced with locale-specific name of the
currency adjusted for the locales plural rules."
**This module is not part of the public API and is subject
to change at any time.**
"""
alias Cldr.Number.{Format, System}
alias Cldr.{Substitution, Currency}
alias Cldr.Number.Format.Options
alias Cldr.Number.Formatter
import DigitalToken, only: [is_digital_token: 1]
@doc false
def to_string(number, _format, _backend, _options) when is_binary(number) do
{:error,
{
ArgumentError,
"Not a number: #{inspect(number)}. Currency long formats only support number or Decimal arguments"
}}
end
# The format :currency_long_with_symbol is a composition of :currency_long
# and the default :currency format. It is a derived format, not one
# defined by CLDR.
def to_string(number, :currency_long_with_symbol, backend, options) do
decimal_options = decimal_options(options, backend, number)
decimal_format = decimal_options.format
number
|> Cldr.Number.to_string!(backend, long_options(options))
|> Formatter.Decimal.to_string(decimal_format, backend, decimal_options)
end
def to_string(number, :currency_long, backend, options) do
locale = options.locale
number_system = System.system_name_from!(options.number_system, locale, backend)
cardinal = Module.concat(backend, Number.Cardinal)
if !(formats = Format.formats_for!(locale, number_system, backend).currency_long) do
raise ArgumentError,
message:
"No :currency_long format known for " <>
"locale #{inspect(locale)} and number system #{inspect(number_system)}."
end
options =
options
|> Map.put(:format, :standard)
|> set_fractional_digits(options.currency, options.fractional_digits)
|> Options.resolve_standard_format(backend)
currency_string = currency_string(number, options.currency, cardinal, locale, backend)
number_string = Cldr.Number.to_string!(number, backend, options)
format = cardinal.pluralize(number, locale, formats)
Substitution.substitute([number_string, currency_string], format)
|> :erlang.iolist_to_binary()
end
defp currency_string(number, %Cldr.Currency{} = currency, cardinal, locale, _backend) do
cardinal.pluralize(number, locale, currency.count)
end
defp currency_string(_number, currency, _cardinal, _locale, _backend)
when is_digital_token(currency) do
{:ok, currency_string} = DigitalToken.long_name(currency)
currency_string
end
defp set_fractional_digits(options, %Cldr.Currency{}, nil) do
Map.put(options, :fractional_digits, 0)
end
defp set_fractional_digits(options, _currency, _digits) do
options
end
defp long_options(options) do
options
|> Map.put(:format, :decimal_long)
|> Map.put(:currency, nil)
end
defp decimal_options(options, backend, number) do
currency_format = Currency.currency_format_from_locale(options.locale)
options = Map.put(options, :format, currency_format)
options
|> Options.resolve_standard_format(backend)
|> Options.maybe_expand_currency_symbol(number)
end
end