项目作者: radical-app

项目描述 :
GoLang Money library to make working with money safer, easier, and fun!
高级语言: Go
项目地址: git://github.com/radical-app/money.git
创建时间: 2020-03-25T20:10:32Z
项目社区:https://github.com/radical-app/money

开源协议:

下载


GoLang Money

GoLang library to make working with money safer, easier, and fun!

golang money - No dependencies
- No anaemic model
- JSON formatter
- SQL driver
- Localized formatter(s)
Money Value Object
“If I had a dime for every time I’ve seen someone use FLOAT to store currency, I’d have $999.997634”
Bill Karwin

In short: You shouldn’t represent monetary values by a float.
Wherever you need to represent money, use this Money value object.
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/radical-app/money"
  5. )
  6. func main() {
  7. fiveEur := money.EUR(500) // see list of all currencies
  8. tenEur, err := fiveEur.Add(fiveEur)
  9. fmt.Print(err)
  10. zeroEur, err := tenEur.Subtract(tenEur)
  11. fmt.Print(err)
  12. zeroEur.IsZero() // true
  13. anotherFiveEur,err := zeroEur.Add(fiveEur)
  14. fmt.Print(err)
  15. fiveEur.IsEquals(anotherFiveEur) // true
  16. fmt.Print(fiveEur.String()) // EUR 500 for beautiful formatter see below
  17. }

.Forge and .Parse


Money from Int and only if you really-really-really need …Forge from Float



go usd312 := money.USD(312) usd312, err := money.Forge(312, "USD")




go usd312 := money.FloatUSD(3.12) usd312, err := money.ForgeFloat(3.12, "USD")


More .Parse() from string


.Parse() is the opposite of .String()



go usd312, err := money.Parse("USD 312") usd312.String() // "USD 312"



go eur312, err := money.ParseWithFallback("312", "EUR") // this uses EUR because the string has it eur312, err := money.ParseWithFallback("EUR 312", "JPY") // not suggested solution use ParseWithFallback if you have to deal with multiple currencies money.DefaultCurrencyCode="JPY" jpy312, err := money.Parse("312")


example at parse_test.go

Marshal/UnMarshal Custom Formatter


Custom Marshaller from and to Json



go json.Marshal(money.EUR(123))




will produce the simplified json for money.DTO:

json {"amount":123,"currency":"EUR","symbol":"€","cents":100}

and

go m := &Money{} json.Unmarshal([]byte('{"amount":123,"currency":"EUR","symbol":"€","cents":100}'), m)

will produce the money.EUR(123)


example at marshal_test.go

.String()

  1. money.EUR(123).String() // "EUR 123"

.Display() beautiful money depending based on locale

  1. import "github.com/radical-app/money/moneyfmt"
  2. import "github.com/radical-app/money"
  3. moneyfmt.Display(money.EUR(123400), "ru") // € 1 234
  4. moneyfmt.Display(money.EUR(123456), "ru") // € 1 234,56
  5. moneyfmt.Display(money.EUR(123456), "it") // € 1.234,56
  6. moneyfmt.Display(money.EUR(123400), "it") // € 1.234
  7. moneyfmt.Display(money.EUR(123456), "en") // € 1,234.56
  8. moneyfmt.Display(money.EUR(123456), "jp") // € 1,234.56
  9. moneyfmt.Display(money.EUR(123456), "zh") // € 1,234.56

example at moneyfmt/moneyfmt_test.go

SQL custom field support driver

Is possible to use in mysql the field as int or varchar or if you really really need decimal(13,4)

  1. _, err := db.Exec("insert into blablabla int, string, decimal (?,?,?)",
  2. money.EUR(123).Int64(),
  3. money.EUR(123).String(),
  4. money.EUR(123).Float()
  5. )

and the Scan during a select is auto-magically done:

  1. rows.Scan(&moneyStoredAsInt64,
  2. &moneyStoredAsString,
  3. &moneyStoredAsFloat
  4. )

Real example: driver_integration_test.go

Limit

The biggest amount you can store in is 92.233.720.368.547.758,07 the math.MaxInt64 / currency.cents