Golang 中的货币格式使用来自 golang.org/x/text/currency 的currency.Symbol

And*_*ade 4 go currency-formatting

您好,我正在开发一个以货币格式格式化值的函数。我正在使用 golang.org/x/text/currency 来完成这项工作,但我得到的输出是逗号位置的点,没有千位分隔符。

func (produto *Produto) FormataPreco(valor int64) string {
    unit, _ := currency.ParseISO("BRL")
    p := message.NewPrinter(language.BrazilianPortuguese)
    return p.Sprint(currency.Symbol(unit.Amount(float64(valor) / 100)))
}
Run Code Online (Sandbox Code Playgroud)

预期结果应该是 R$ 123.456,78 但我得到 R$ 123456.78

- - 编辑 - -

我做了一个使用硬编码值的版本,但我想要一个使用系统区域设置资源的解决方案。

func (produto *Produto) FormataPreco(valor int64) string {
    p := message.NewPrinter(language.BrazilianPortuguese)
    return p.Sprintf("R$ %.2f", float64(valor/100))
}
Run Code Online (Sandbox Code Playgroud)

Cha*_*ert 7

在此示例中,我从语言代码推断了货币格式。

\n

https://goplay.space/#fqs9t8MG062

\n
n := display.Tags(language.English)\nfor _, lcode := range []string{"en_US", "pt_BR", "de", "ja", "hi"} {\n    lang := language.MustParse(lcode)\n    cur, _ := currency.FromTag(lang)\n    scale, _ := currency.Cash.Rounding(cur) // fractional digits\n    dec := number.Decimal(100000.00, number.Scale(scale))\n    p := message.NewPrinter(lang)\n    p.Printf("%24v (%v): %v%v\\n", n.Name(lang), cur, currency.Symbol(cur), dec)\n}\n\n//         American English (USD): $100,000.00\n//     Brazilian Portuguese (BRL): R$100.000,00\n//                   German (EUR): \xe2\x82\xac100.000,00\n//                 Japanese (JPY): \xef\xbf\xa5100,000\n//                    Hindi (INR): \xe2\x82\xb91,00,000.00\n
Run Code Online (Sandbox Code Playgroud)\n

您还可以解析 ISO 货币代码,但还必须指定用于格式化数字的语言。输出语言不会影响小数位数,但影响逗号和句点的使用位置:

\n

https://goplay.space/#DlxSmjZbHH6

\n
for _, iso := range []string{"USD", "BRL", "EUR", "JPY", "INR"} {\n    cur := currency.MustParseISO(iso)\n    scale, _ := currency.Cash.Rounding(cur) // fractional digits\n    dec := number.Decimal(100000.00, number.Scale(scale))\n    p := message.NewPrinter(language.English)\n    p.Printf("%v: %v%v\\n", cur, currency.Symbol(cur), dec)\n}\n\n// USD: $100,000.00\n// BRL: R$100,000.00\n// EUR: \xe2\x82\xac100,000.00\n// JPY: \xc2\xa5100,000\n// INR: \xe2\x82\xb9100,000.00\n
Run Code Online (Sandbox Code Playgroud)\n

某些货币按增量舍入,例如 0.05 或 0.50。对于这些情况,第二个返回值currency.Cash.Rounding(cur)将返回 5 或 50,而不是 1。为了向 Decimal 格式化程序提供它期望的 IncrementString,我们必须进行更多处理:

\n
package main\n\nimport (\n    "math"\n    "strconv"\n\n    "golang.org/x/text/currency"\n    "golang.org/x/text/language"\n    "golang.org/x/text/language/display"\n    "golang.org/x/text/message"\n    "golang.org/x/text/number"\n)\n\nfunc main() {\n    n := display.Tags(language.English)\n    for _, lcode := range []string{"en_US", "en_CA", "da", "ja"} {\n        lang := language.MustParse(lcode)\n        cur, _ := currency.FromTag(lang)\n        scale, incCents := currency.Cash.Rounding(cur) // fractional digits\n        incFloat := math.Pow10(-scale) * float64(incCents)\n        incFmt := strconv.FormatFloat(incFloat, \'f\', scale, 64)\n        dec := number.Decimal(100000.26,\n            number.Scale(scale), number.IncrementString(incFmt))\n        p := message.NewPrinter(lang)\n        p.Printf("%24v %v, %4s-rounding: %3v%v\\n",\n            n.Name(lang), cur, incFmt, currency.Symbol(cur), dec)\n    }\n}\n\n//    American English USD, 0.01-rounding: $100,000.26\n//    Canadian English CAD, 0.05-rounding: CA$100,000.25\n//              Danish DKK, 0.50-rounding: DKK100.000,50\n//            Japanese JPY,    1-rounding: \xc2\xa5100,000\n
Run Code Online (Sandbox Code Playgroud)\n