Amounts
Making one
From minor units, from text, or from a decimal:
def a as money.Money init money.fromMinor(1234, "EUR"); # 12.34 EUR
def b as money.Money init money.parse("12.34", "EUR"); # the same
def c as money.Money init money.zero("JPY");
def d as money.Money init money.fromDecimal(decimal.from("12.345"), "EUR", "half-even"); # 12.34 EURA currency is its ISO 4217 code in capitals. An unknown code is an error, never a guess; see Currencies.
Text
parse reads digits with an optional - and a fraction after a dot. It refuses everything else: an exponent, spaces, +, a decimal comma, digit separators. Places beyond the currency's are refused unless they are zeros:
money.parse("12.3", "EUR"); # 12.30 EUR
money.parse("12.340", "EUR"); # 12.34 EUR
money.parse("12.345", "EUR"); # error: more than 2 decimal places for EUR
money.parse("1200", "JPY"); # 1200 JPYTo accept more places and round them, go through decimal:
money.fromDecimal(decimal.from($text), "EUR", "half-up");format writes what parse reads, always with the currency's places:
money.format(money.fromMinor(500, "EUR")); # "5.00"
money.format(money.fromMinor(-5, "EUR")); # "-0.05"
money.format(money.fromMinor(1200, "JPY")); # "1200"
money.format(money.fromMinor(1, "KWD")); # "0.001"There is no grouping, currency symbol or decimal comma: how an amount is shown is a matter of locale, which this deck leaves to the program.
Storing
Keep amount as an integer column or JSON number and currency beside it, and rebuild the value with fromMinor. An int holds about 9.2 x 10^16 minor units, 92 quadrillion euros. A result past that is a money error, not a wrapped number.
An amount whose currency the deck does not know, such as the zero value of Money or one built by hand, is refused by every function that computes with it.
Comparing
== is equality; amounts of different currencies are simply not equal. Ordering refuses to compare across currencies:
if (money.lessThan($balance, $price)) {
# not enough
}
money.compare($a, $b); # -1, 0 or 1
money.isZero($m);
money.isNegative($m);
money.isPositive($m);Decimals
toDecimal gives the amount in major units as a decimal.Decimal at the currency's scale, for computations the deck does not offer:
def value as decimal.Decimal init money.toDecimal(money.fromMinor(1200, "EUR")); # 12.00Bring the result back with fromDecimal and a rounding mode.