Money formatting and parsing helpers for Column API amounts.
Column represents all monetary amounts as integer cents (or the smallest currency unit). This module provides helpers for converting between cents and display strings, and for formatting amounts for API payloads.
Examples
iex> Column.Money.to_cents(10.50, "USD")
1050
iex> Column.Money.from_cents(1050, "USD")
"10.50"
iex> Column.Money.format(100_000, "USD")
"$1,000.00"
iex> Column.Money.format(100_000, "EUR")
"€1,000.00"
iex> Column.Money.to_cents(0.10, "USD")
10Note on floating-point
Avoid using floats for financial amounts in production. Where possible,
accept integer cents from your UI layer and skip conversion altogether.
If you must convert, use Decimal (add the :decimal dep):
Decimal.new("10.50")
|> Decimal.mult(100)
|> Decimal.round(0)
|> Decimal.to_integer()
# => 1050
Summary
Functions
Return the number of decimal places for a currency.
Return currency metadata (symbol, decimals). Defaults to 2 decimal places for unknown currencies.
Format cents as a human-readable currency string with symbol.
Convert integer cents to a decimal string.
Convert a float or integer amount to integer cents.
Returns true if the amount is a valid positive integer cent amount.
Types
@type cents() :: non_neg_integer()
@type currency() :: String.t()
Functions
@spec currency_decimals(currency()) :: non_neg_integer()
Return the number of decimal places for a currency.
@spec currency_info(currency()) :: %{symbol: String.t(), decimals: non_neg_integer()}
Return currency metadata (symbol, decimals). Defaults to 2 decimal places for unknown currencies.
Format cents as a human-readable currency string with symbol.
Column.Money.format(100_000, "USD") # => "$1,000.00"
Column.Money.format(500, "EUR") # => "€5.00"
Convert integer cents to a decimal string.
Column.Money.from_cents(1050, "USD") # => "10.50"
Column.Money.from_cents(100, "JPY") # => "100"
Convert a float or integer amount to integer cents.
Uses banker's rounding (round-half-to-even) to minimise cumulative error.
Column.Money.to_cents(10.50, "USD") # => 1050
Column.Money.to_cents(1000, "USD") # => 1000 (already cents)
Returns true if the amount is a valid positive integer cent amount.