{"id":29710625,"url":"https://github.com/radical-app/money","last_synced_at":"2025-07-23T21:15:17.478Z","repository":{"id":46244133,"uuid":"250080668","full_name":"radical-app/money","owner":"radical-app","description":"GoLang Money library to make working with money safer, easier, and fun!","archived":false,"fork":false,"pushed_at":"2023-03-15T14:36:25.000Z","size":70,"stargazers_count":18,"open_issues_count":1,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-06-20T22:41:58.633Z","etag":null,"topics":["domain-driven-design","go","golang","money","value-object"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/radical-app.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-25T20:10:32.000Z","updated_at":"2024-06-17T21:30:27.000Z","dependencies_parsed_at":"2024-06-20T21:58:35.024Z","dependency_job_id":"f85f9e42-3d1d-408d-9743-24029ff5acb4","html_url":"https://github.com/radical-app/money","commit_stats":null,"previous_names":["radicalcompany/money"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/radical-app/money","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-app%2Fmoney","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-app%2Fmoney/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-app%2Fmoney/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-app%2Fmoney/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/radical-app","download_url":"https://codeload.github.com/radical-app/money/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-app%2Fmoney/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266749678,"owners_count":23978445,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["domain-driven-design","go","golang","money","value-object"],"created_at":"2025-07-23T21:15:16.659Z","updated_at":"2025-07-23T21:15:17.471Z","avatar_url":"https://github.com/radical-app.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoLang Money\n\nGoLang library to make working with money safer, easier, and fun!\n\n|![golang money](./assets/radical-golang-money.png \"Money\") | - No dependencies\u003cbr\u003e- No anaemic model\u003cbr\u003e- JSON formatter\u003cbr\u003e- SQL driver\u003cbr\u003e- Localized formatter(s)| \n|     :---:      | :--- |\n|  \u003cstrong\u003eMoney Value Object\u003c/strong\u003e | \u003cblockquote\u003e \"If I had a dime for every time I've seen someone use FLOAT to store currency, I'd have $999.997634\"\u003c/blockquote\u003e -- [Bill Karwin](https://twitter.com/billkarwin/status/347561901460447232) \u003cbr\u003e\u003cbr\u003eIn short: You shouldn't represent monetary values by a float.\u003cbr\u003eWherever you need to represent money, use this Money value object.    |\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"github.com/radical-app/money\"\n)\n\nfunc main() {\n    fiveEur := money.EUR(500) // see list of all currencies\n    tenEur, err := fiveEur.Add(fiveEur)\n    fmt.Print(err)\n    \n    zeroEur, err := tenEur.Subtract(tenEur)\n    fmt.Print(err)\n    \n    zeroEur.IsZero() // true\n    \n    anotherFiveEur,err := zeroEur.Add(fiveEur)\n    fmt.Print(err)\n    \n    fiveEur.IsEquals(anotherFiveEur) // true\n\n    fmt.Print(fiveEur.String()) // EUR 500 for beautiful formatter see below \n}\n```\n\n## .Forge and .Parse \n\n\n\u003cdetails\u003e\u003csummary\u003e\nMoney from Int and only if you really-really-really need ...Forge from Float\u003cbr\u003e\u003cbr\u003e\n\n```go\nusd312 := money.USD(312)\nusd312, err := money.Forge(312, \"USD\")\n```\n\n\u003c/summary\u003e\n\u003cp\u003e\n\n```go\nusd312 := money.FloatUSD(3.12)\nusd312, err := money.ForgeFloat(3.12, \"USD\")\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n        \n   \n### More .Parse() from string\n\n\u003cdetails\u003e\u003csummary\u003e\n.Parse() is the opposite of .String()\u003cbr\u003e\u003cbr\u003e\n\n```go\nusd312, err := money.Parse(\"USD 312\")\nusd312.String() // \"USD 312\"\n```\n\u003c/summary\u003e\n\u003cp\u003e\n\n```go\neur312, err := money.ParseWithFallback(\"312\", \"EUR\")\n \n// this uses EUR because the string has it   \neur312, err := money.ParseWithFallback(\"EUR 312\", \"JPY\")\n\n// not suggested solution use ParseWithFallback if you have to deal with multiple currencies\nmoney.DefaultCurrencyCode=\"JPY\"\njpy312, err := money.Parse(\"312\")\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n[example at parse_test.go](./parse_test.go)\n        \n## Marshal/UnMarshal Custom Formatter \n\n\u003cdetails\u003e\u003csummary\u003e\nCustom Marshaller from and to Json\u003cbr\u003e\u003cbr\u003e\n\n```go\njson.Marshal(money.EUR(123))\n```\n\n\u003c/summary\u003e\n\u003cp\u003e\n\nwill produce the simplified json for `money.DTO`:\n\n```json\n{\"amount\":123,\"currency\":\"EUR\",\"symbol\":\"€\",\"cents\":100}\n```\n\nand\n\n```go\nm := \u0026Money{}\njson.Unmarshal([]byte('{\"amount\":123,\"currency\":\"EUR\",\"symbol\":\"€\",\"cents\":100}'), m)\n```\n\nwill produce the `money.EUR(123)`  \n\n\u003c/p\u003e\n\u003c/details\u003e\n\n[example at marshal_test.go](./marshal_test.go)\n\n## .String()\n\n```go\nmoney.EUR(123).String() // \"EUR 123\"\n```\n\n## .Display() beautiful money depending based on locale \n\n```go\nimport \"github.com/radical-app/money/moneyfmt\"\nimport \"github.com/radical-app/money\"\n\nmoneyfmt.Display(money.EUR(123400), \"ru\") // € 1 234\nmoneyfmt.Display(money.EUR(123456), \"ru\") // € 1 234,56\n\nmoneyfmt.Display(money.EUR(123456), \"it\") // € 1.234,56\nmoneyfmt.Display(money.EUR(123400), \"it\") // € 1.234\n\nmoneyfmt.Display(money.EUR(123456), \"en\") // € 1,234.56\nmoneyfmt.Display(money.EUR(123456), \"jp\") // € 1,234.56\nmoneyfmt.Display(money.EUR(123456), \"zh\") // € 1,234.56\n```\n\n[example at moneyfmt/moneyfmt_test.go](./moneyfmt/moneyfmt_test.go)\n    \n     \n## SQL custom field support driver \n\nIs possible to use in mysql the field as `int` or `varchar` or if you really really need `decimal(13,4)`\n\n```go\n_, err := db.Exec(\"insert into blablabla int, string, decimal (?,?,?)\",\n  money.EUR(123).Int64(),\n  money.EUR(123).String(),\n  money.EUR(123).Float()\n)  \n```\n\nand the Scan during a select is auto-magically done: \n\n```go\nrows.Scan(\u0026moneyStoredAsInt64,\n  \u0026moneyStoredAsString,\n  \u0026moneyStoredAsFloat\n)\n```\n\n[Real example: driver_integration_test.go](./driver_integration_test.go)\n   \n## Limit\n\nThe biggest amount you can store in is `92.233.720.368.547.758,07` the `math.MaxInt64 / currency.cents`    ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradical-app%2Fmoney","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fradical-app%2Fmoney","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradical-app%2Fmoney/lists"}