Install go-money
masterTo use this package in your Go project, install it using go get:
$ go get github.com/Rhymond/go-moneyrepository·master·Indexed 23 days ago
https://github.com/rhymond/go-moneyA Go library for handling monetary values using the smallest currency unit to avoid floating-point precision errors. It provides precise operations for arithmetic, comparison, splitting, and allocation, along with support for ISO 4217 currency codes. The library includes features for formatting money for display, custom currency registration, and implements sql.Scanner and driver.Valuer for database storage.
To use this package in your Go project, install it using go get:
$ go get github.com/Rhymond/go-moneyYou can initialize a Money object in two ways:
100 represents 1 unit of the currency (e.g., 100 cents for 1 pound).NewFromFloat to initialize money using a direct decimal amount.Currency is specified using money.Currency instances, and constants are provided for all ISO 4217 currency codes (e.g., money.GBP, money.EUR).
Convert Money objects into human-readable strings or float64 values:
Display(): Returns a formatted string (e.g., €1,234,567.89).AsMajorUnits(): Returns a float64 representing the amount in the currency's major unit (e.g., 1234567.89).Use these methods to check the state of a Money value:
IsZero(): Returns true if the value is zero.IsPositive(): Returns true if the value is greater than zero.IsNegative(): Returns true if the value is less than zero.pound := money.New(100, money.GBP)
pound.IsZero() // false
pound.IsPositive() // true
pound.IsNegative() // falsePerform basic math on Money objects. All operations (except Multiply) require the currencies to match.
Operations:
Add(other Money) (Money, error): Adds two money amounts.Subtract(other Money) (Money, error): Subtracts one money amount from another.Multiply(factor float64) Money: Multiplies the amount by a factor.Absolute() Money: Returns the absolute value.Negative() Money: Returns the negative value.pound := money.New(100, money.GBP)
twoPounds := money.New(200, money.GBP)
result, err := pound.Add(twoPounds) // £3.00, nil
result, err = pound.Subtract(twoPounds) // -£1.00, nil
result := pound.Multiply(2) // £2.00
result := pound.Absolute() // £1.00 (if input was -100)
result := pound.Negative() // -£1.00To divide money among multiple parties without losing pennies to rounding, use Split or Allocate.
Splitting: Split(n int) ([]Money, error) divides the money into n parts. Leftover pennies are distributed round-robin among the parties (the first parties in the slice receive the extra pennies).
Allocation: Allocate(ratios ...int) ([]Money, error) divides money based on provided integer ratios. This is a variadic function that can accept ratios as separate arguments or a slice using the ... operator. It also uses the round-robin principle for leftover pennies.
The package provides several comparison methods. Note: Comparisons must be made between the same currency units. If currencies do not match, methods like Equals will return an error, and Compare will return ErrCurrencyMismatch.
Comparison Methods:
Equals(other Money) (bool, error)GreaterThan(other Money) (bool, error)GreaterThanOrEqual(other Money) (bool, error)LessThan(other Money) (bool, error)LessThanOrEqual(other Money) (bool, error)Compare(other Money) (int, error): Returns 1 if greater, -1 if less, and 0 if equal.pound := money.New(100, money.GBP)
twoPounds := money.New(200, money.GBP)
twoEuros := money.New(200, 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, ErrCurrencyMismatchThe go-money package uses a global variable DBMoneyValueSeparator to determine how Money instances are serialized to and deserialized from strings in the database.
DefaultDBMoneyValueSeparator: A constant set to |.DBMoneyValueSeparator: The active separator used by Money.Value() and Money.Scan(). You can change this to a different character if your database storage requirements differ.money.Money type implements json.Marshaler and json.Unmarshaller. If you need to change how Money is serialized or deserialized, you can overwrite the package-level injection points:GetCurrency(code string) to retrieve a *Currency from the built-in collection. The input code is case-insensitive and will be converted to uppercase. If the currency is not found in the internal registry, it returns nil.The library provides specialized methods for dividing money without losing subunits (pennies).
Split(n int): Divides the money into n parts. If the amount isn't perfectly divisible, leftover subunits are distributed round-robin to the first parties.Allocate(rs ...int): Divides the money based on provided ratios. Leftover subunits are distributed round-robin to the first parties.The ToMajorUnits method converts an integer amount (representing the smallest sub-unit of a currency) into a float64 representing the major unit (e.g., converting cents to dollars). It uses the Fraction field defined in the Formatter to determine the scale.
Example: If Fraction is 2, an amount of 100 becomes 1.0.