A library to handle monetary values and currencies.
This library is still in development. While it works and most of its functionality is tested by unit tests, the API may have breaking changes until version 1.0.0 is reached.
- Uses shopspring/decimal for arbitrary precision fixed-point decimal numbers.
- Values are immutable by default.
- ISO 4217 currencies.
- Extensible with custom currencies.
- Tests to ensure uniqueness and correctness of currencies (including user-defined ones).
- Useful mathematical operations, including a way to split a monetary value into n parts.
- Data bindings for JSON, binary, text, gob encodings.
- Implements scanner and valuer interfaces for databases.
- Implements
GormDBDataTypeInterface
. - Supports postgresql composite types.
Planned:
- Include cryptocurrencies and tokens.
- Split locale and currency information.
- Formatting of values with specified locale. Support CLDR as good as possible, also
go generate
support to convert LDML based data into go code and structures. - Migration field for currencies, e.g. to describe how custom currencies will map to official supported currencies.
- Generate currency data from the official ISO 4217 sources via
go generate
.
A high performance library to do number crunching with. Although this library is not slow, it is not intended for processing large tables of monetary values. The focus of this library is on correctness and ease of use.
To be able to use this library, first download it via
go get github.com/Dadido3/D3money
And then import it with
import money "github.com/Dadido3/D3money"
A simple way to create a monetary value is by using FromString(...)
.
value1, err := money.FromString("123.45 ISO4217-EUR") // Value with ISO4217 EUR as currency.
value2, err := money.FromString("123.45") // Value without currency or unit.
It's also possible to create a value by using a currency object.
value, err := money.FromStringAndCurrency("123.45", money.Currencies.ByUniqueCode("ISO4217-EUR"))
For non user-input strings, the MustFrom...
variants can be used.
They will not return any error, but panic if something is wrong.
value1 := money.MustFromString("123.45 ISO4217-EUR")
value2 := money.MustFromStringAndCurrency("123.45 ISO4217-EUR", money.Currencies.ByUniqueCode("ISO4217-EUR"))
value3 := money.MustFromString("123.45 FOO-BAR") // Will panic if FOO-BAR is not a registered currency.
Selecting from all available currencies.
eur := money.Currencies.ByUniqueCode("ISO4217-EUR")
Selecting a currency from ISO 4217 by its code or unique code.
usd := money.ISO4217Currencies.ByCode("USD")
eur := money.ISO4217Currencies.ByUniqueCode("ISO4217-EUR")
Assert currency standard.
eur := money.Currencies.ByUniqueCode("ISO4217-EUR")
_, isISO4217 := eur.(money.ISO4217Currency) // isISO4217 will be true
To create custom currencies, you need to create a type that implements the money.Currency
interface.
For an example, see currency-iso4217.go.
You can check if your instances are valid by using.
err := money.ValidateCurrency(customCurrency)
Afterwards you can register the currency by adding it to the library by using.
err := money.Currencies.Add(customCurrency) // Register single custom currency.
err := money.Currencies.Add(customCurrencies...) // Register list of custom currencies.
If you add custom currencies, make sure to only use negative unique IDs to prevent ID collisions with official currencies in the future.