money

Currency amounts on Decimal: exact arithmetic, ISO 4217 minor units, and allocation that never loses a cent. Pure - no capabilities.

ecko get github.com/ecko-lang/money
import money

Pure computation: it declares no capabilities, so it cannot touch the network, the filesystem or the environment.

Version 0.38.0 - source - MIT.


minor_unit_table()

The ISO 4217 table: currency code -> decimal places.

minor_units(code)

How many decimal places this currency uses. A code that is not an active ISO 4217 currency is refused rather than guessed at.

normalize_code(code)

Uppercase a currency code and check its shape.

of(amount, code, rounding = false)

An amount from a Decimal and a currency code. An amount with more decimal places than the currency has (12.345 USD) is refused, because keeping it would round it later, out of sight; pass rounding: true to round it here, half away from zero.

parse(text, code, rounding = false)

An amount from a string: parse("19.99", "USD"). Refused, like of, when it has more decimal places than the currency; rounding: true rounds it.

zero(code)

Zero in the given currency.

to_minor(m)

The amount as an integer count of minor units: 10.50 USD -> 1050.

from_minor(units, code)

An amount from a count of minor units: 1050 with USD -> 10.50.

add(a, b)

a + b.

sub(a, b)

a - b.

mul(m, factor)

An amount scaled by a plain number.

neg(m)

The amount negated.

abs_of(m)

The amount without its sign.

sum(items, code)

The total of a list. code gives the currency for the empty case, where there is nothing to infer it from.

compare(a, b)

-1, 0 or 1. Both must be the same currency.

eq(a, b)

a == b.

lt(a, b)

a < b.

gt(a, b)

a > b.

is_zero(m)

Is the amount exactly zero?

is_negative(m)

Is the amount below zero?

split(m, n)

Split into n parts that sum back to the original exactly.

allocate(m, ratios)

Divide by ratio, in the currency's smallest unit, so nothing is lost.

The remainder is handed out one minor unit at a time from the first share onward, rather than rounded away. Allocating $0.05 as 3:7 gives 0.02 and 0.03: the shares are as close to the ratio as whole cents allow, and they still sum to five cents.

A negative amount allocates the same way with the sign carried through, so a refund splits like the charge it reverses.

to_string(m)

"10.50 USD", with the number of decimals the currency actually uses: yen render whole, dinar to three places.