class DecimalCurrencyFormatter
Formats a currency using a standard decimal notation.
Definitions
def parse(string)
Parse a string into an amount using the configured separator and delimiter.
Signature
-
returns
BigDecimal
The parsed amount.
Implementation
def parse(string)
BigDecimal(
string.gsub(/[^\-0-9#{@separator}]/, '').gsub(@separator, '.')
)
end
def format(amount, places: @places, **options)
Formats the amount using the configured symbol, separator, delimiter, and places. e.g. "$5,000.00 NZD". Rounds the amount to the specified number of decimal places.
Signature
-
returns
String
The formatted string.
Implementation
def format(amount, places: @places, **options)
# Round to the desired number of places. Truncation used to be the default.
amount = amount.round(places).to_d
integral, fraction = amount.abs.to_s('F').split(/\./, 2)
# The sign of the number
sign = '-' if amount < 0
# Decimal places, e.g. the '.00' in '$10.00'
fraction = fraction[0...places].ljust(places, @zero)
# Grouping, e.g. the ',' in '$10,000.00'
remainder = integral.size % 3
groups = integral[remainder..-1].scan(/.{3}/).to_a
groups.unshift(integral[0...remainder]) if remainder > 0
symbol = options.fetch(:symbol, @symbol)
value = "#{sign}#{symbol}#{groups.join(@delimiter)}"
name = options.fetch(:name, @name)
suffix = name ? " #{name}" : ''
if places > 0
"#{value}#{@separator}#{fraction}#{suffix}"
else
"#{value}#{suffix}"
end
end
def to_integral(amount)
Converts the amount directly to an integer, truncating any decimal part, taking into account the number of specified decimal places.
Signature
-
parameter
amount
BigDecimal
The amount to convert to an integral.
-
returns
Integer
The converted whole number integer.
Implementation
def to_integral(amount)
(amount * 10**@places).to_i
end
def from_integral(amount)
Converts the amount to a decimal, taking into account the number of specified decimal places.
Signature
-
parameter
amount
Integer
The amount to convert to a decimal.
-
returns
BigDecimal
The converted amount.
Implementation
def from_integral(amount)
(amount.to_d / 10**@places)
end