Money
An amount of money: a whole number of its currency's minor units and its Currency, written GBP 10.50.
Money and banking; ordered; since Jadpo 0.1.0.
Make one
text.parse(raw, as: Money) reads one from its text; text that isn't one at all fails malformed, such as 10.50, GBP 10.505 or GBP 10.5.
These operations give one: money.allocate, money.convert, money.from_minor, money.of, money.split and money.sum.
Text, JSON and storage
text.from writes its canonical text, the one form text.parse reads back. JSON sends an object of its parts.
| Text | JSON |
|---|---|
GBP -5.00 |
{"amount":-500,"currency":"GBP"} |
GBP 0.05 |
{"amount":5,"currency":"GBP"} |
GBP 10.50 |
{"amount":1050,"currency":"GBP"} |
GBP 1234.50 |
{"amount":123450,"currency":"GBP"} |
It is stored in 2 columns, each named for the field, _ and its suffix. This is GBP 10.50:
| Column | Type | Holds |
|---|---|---|
<field>_amount |
bigint |
1050 |
<field>_currency |
char(3) |
'GBP' |
Shown to people
text.format(value, locale:) shows it to people in their locale. A call may also give precision:, display: or sign:.
With locale: Locale.en_gb:
| Value | Shown |
|---|---|
GBP -5.00 |
-£5.00 |
GBP 0.05 |
£0.05 |
GBP 10.50 |
£10.50 |
GBP 1234.50 |
£1,234.50 |
Operations
money.allocate(total: Money, ratios: List<Int>) -> List<Money>:totalshared in proportion toratios, whole numbers never below 0, at least one of them; a share of ratio 0 is nothing.money.convert(value: Money, rate: ExchangeRate) -> Money:valueinrate'stocurrency, from itsfromone: the major units timesrate.rate, rounded half to even to a minor unit, so £10.50 at aGBP/EURrate of 1.17 is €12.28. It fails withcurrency_mismatchwhenvalueisn't inrate.from, unless that is known: an inverted rate is then a compile error. The rate is one the app holds; nothing here fetches one.money.currency(value: Money) -> Currency: The currencyvalueis in.money.from_minor(amount: Int, currency: Currency) -> Money:amountminor units ofcurrency:money.from_minor(1050, Currency.gbp)is £10.50.money.minor(value: Money) -> Int:value's minor units: 1050 for £10.50.money.of(amount: Decimal, currency: Currency) -> Money:amountmajor units ofcurrency, aDecimal:money.of(10.50, Currency.gbp)is £10.50. It fails withtoo_many_placesfor more places than the currency has (10.505 in pounds), unless the currency is written out and the amount proved to have no more.money.split(total: Money, parts: Int) -> List<Money>:totalinpartsnear-equal shares,partsat least 1: £10.00 in 3 is £3.34, £3.33 and £3.33.money.sum(items: List<Money>, currency: Currency) -> Money: The items added up incurrency, the zero an empty list gives. It fails withcurrency_mismatchfor an item in another currency, unless the items' type fixescurrency.
Like every standard type, it also has the contract's own operations: text.parse, text.from, text.format, json.read, json.write and ==. It is ordered, so < and sorting take it. Every standard type meets one contract says how they work.
Markdown for agents: /docs/types/type-money.md.Built from Jadpo main at e00e61f.