This is a fork of go-money that uses (github.com/shopspring/decimal) instead of int64 to store the amount. This allows for more functionality when working with money, including but not limited to multiply and divide operations by float values.
GoMoney provides ability to work with monetary value using a currency's smallest unit. This package provides basic and precise Money operations such as rounding, splitting and allocating. Monetary values should not be stored as floats due to small rounding differences.
package main
import (
"log"
"github.com/rezaalavi/gmoney"
)
func main() {
pound := money.New(1.00, money.GBP)
twoPounds, err := pound.Add(pound)
if err != nil {
log.Fatal(err)
}
parties, err := twoPounds.Split(3)
if err != nil {
log.Fatal(err)
}
parties[0].Display() // £0.67
parties[1].Display() // £0.67
parties[2].Display() // £0.66
}
Get the package:
$ go get github.com/rezaalavi/gmoney
- Provides a Money struct which stores information about an Money amount value and its currency.
- Provides a
Money.Amount
struct which encapsulates all information about a monetary unit. - Represents monetary values as decimals. This avoids floating point rounding errors.
- Represents currency as
Money.Currency
instances providing a high level of flexibility.
Initialize Money by using smallest unit value (e.g 100 represents 1 pound). Use ISO 4217 Currency Code to set money Currency. Note that constants are also provided for all ISO 4217 currency codes.
pound := money.New(1.00, money.GBP)
Or initialize Money using the any other numerical values.
Gmoney provides base compare operations like:
- Equals
- GreaterThan
- GreaterThanOrEqual
- LessThan
- LessThanOrEqual
- Compare
Comparisons must be made between the same currency units.
pound := money.New(1.00, money.GBP)
twoPounds := money.New(2.00, money.GBP)
twoEuros := money.New(2.00, money.EUR)
pound.GreaterThan(twoPounds) // false, nil
pound.LessThan(twoPounds) // true, nil
twoPounds.Equals(twoEuros) // false, error: Currencies don't match
twoPounds.Compare(pound) // 1, nil
pound.Compare(twoPounds) // -1, nil
pound.Compare(pound) // 0, nil
pound.Compare(twoEuros) // pound.amount, ErrCurrencyMismatch
- IsZero
- IsNegative
- IsPositive
To assert if Money value is equal to zero use IsZero()
pound := money.New(1.00, money.GBP)
result := pound.IsZero() // false
To assert if Money value is more than zero use IsPositive()
pound := money.New(1.00, money.GBP)
pound.IsPositive() // true
To assert if Money value is less than zero use IsNegative()
pound := money.New(1.00, money.GBP)
pound.IsNegative() // false
- Add
- Subtract
- Multiply
- Absolute
- Negative
Comparisons must be made between the same currency units.
Additions can be performed using Add()
.
pound := money.New(1.00, money.GBP)
twoPounds := money.New(2.00, money.GBP)
result, err := pound.Add(twoPounds) // £3.00, nil
Subtraction can be performed using Subtract()
.
pound := money.New(1.00, money.GBP)
twoPounds := money.New(2.00, money.GBP)
result, err := pound.Subtract(twoPounds) // -£1.00, nil
Multiplication can be performed using Multiply()
.
pound := money.New(1.00, money.GBP)
result := pound.Multiply(decimal.NewFromFloat(2.5)) // £2.50
Return absolute
value of Money structure
pound := money.New(-1.00, money.GBP)
result := pound.Absolute() // £1.00
Return negative
value of Money structure
pound := money.New(1.00, money.GBP)
result := pound.Negative() // -£1.00
- Split
- Allocate
In order to split Money for parties without losing any pennies due to rounding differences, use Split()
.
After division leftover pennies will be distributed round-robin amongst the parties. This means that parties listed first will likely receive more pennies than ones that are listed later.
pound := money.New(100, money.GBP)
parties, err := pound.Split(3)
if err != nil {
log.Fatal(err)
}
parties[0].Display() // £0.34
parties[1].Display() // £0.33
parties[2].Display() // £0.33
To format and return Money as a string use Display()
.
money.New(1234567.89, money.EUR).Display() // €1,234,567.89
To format and return Money as a float64 representing the amount value in the currency's subunit use AsMajorUnits()
.
money.New(1234567.89, money.EUR).AsMajorUnits() // 1234567.89
Thank you for considering contributing! Please use GitHub issues and Pull Requests for contributing.
The MIT License (MIT). Please see License File for more information.