Golang 中的货币格式使用来自 golang 的 currency.Symbol。org/x/text/currency
Currency Format in Golang using currency.Symbol from golang.org/x/text/currency
您好,我正在开发一个以货币格式设置值的函数。我正在使用 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)))
}
预期结果应该是 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))
}
在这个例子中,我从语言代码推断出货币格式。
https://goplay.space/#fqs9t8MG062
n := display.Tags(language.English)
for _, lcode := range []string{"en_US", "pt_BR", "de", "ja", "hi"} {
lang := language.MustParse(lcode)
cur, _ := currency.FromTag(lang)
scale, _ := currency.Cash.Rounding(cur) // fractional digits
dec := number.Decimal(100000.00, number.Scale(scale))
p := message.NewPrinter(lang)
p.Printf("%24v (%v): %v%v\n", n.Name(lang), cur, currency.Symbol(cur), dec)
}
// American English (USD): 0,000.00
// Brazilian Portuguese (BRL): R0.000,00
// German (EUR): €100.000,00
// Japanese (JPY): ¥100,000
// Hindi (INR): ₹1,00,000.00
您还可以解析 ISO 货币代码,但您还必须指定用于设置数字格式的语言。输出语言不会影响小数位数,但会影响逗号和句点的使用位置:
https://goplay.space/#DlxSmjZbHH6
for _, iso := range []string{"USD", "BRL", "EUR", "JPY", "INR"} {
cur := currency.MustParseISO(iso)
scale, _ := currency.Cash.Rounding(cur) // fractional digits
dec := number.Decimal(100000.00, number.Scale(scale))
p := message.NewPrinter(language.English)
p.Printf("%v: %v%v\n", cur, currency.Symbol(cur), dec)
}
// USD: 0,000.00
// BRL: R0,000.00
// EUR: €100,000.00
// JPY: ¥100,000
// INR: ₹100,000.00
某些货币以增量形式四舍五入,例如 0.05 或 0.50。对于这些情况,currency.Cash.Rounding(cur)
的第二个 return 值将 return 5 或 50 而不是 1。要为 Decimal 格式化程序提供它期望的 IncrementString,我们必须做更多的处理:
package main
import (
"math"
"strconv"
"golang.org/x/text/currency"
"golang.org/x/text/language"
"golang.org/x/text/language/display"
"golang.org/x/text/message"
"golang.org/x/text/number"
)
func main() {
n := display.Tags(language.English)
for _, lcode := range []string{"en_US", "en_CA", "da", "ja"} {
lang := language.MustParse(lcode)
cur, _ := currency.FromTag(lang)
scale, incCents := currency.Cash.Rounding(cur) // fractional digits
incFloat := math.Pow10(-scale) * float64(incCents)
incFmt := strconv.FormatFloat(incFloat, 'f', scale, 64)
dec := number.Decimal(100000.26,
number.Scale(scale), number.IncrementString(incFmt))
p := message.NewPrinter(lang)
p.Printf("%24v %v, %4s-rounding: %3v%v\n",
n.Name(lang), cur, incFmt, currency.Symbol(cur), dec)
}
}
// American English USD, 0.01-rounding: 0,000.26
// Canadian English CAD, 0.05-rounding: CA0,000.25
// Danish DKK, 0.50-rounding: DKK100.000,50
// Japanese JPY, 1-rounding: ¥100,000
您可能会注意到,golang。org/x/text/currency 仍在进行中,有一段时间没有更新了。
NOTE: the formatting functionality is currently under development and
may change without notice.
如果您更喜欢使用简单的辅助函数来完成工作,您可以使用类似这样的方法:
func formatMoney(value int32, thousand, decimal string) string {
var result string
var isNegative bool
if value < 0 {
value = value * -1
isNegative = true
}
// apply the decimal separator
result = fmt.Sprintf("%s%02d%s", decimal, value%100, result)
value /= 100
// for each 3 dígits put a dot "."
for value >= 1000 {
result = fmt.Sprintf("%s%03d%s", thousand, value%1000, result)
value /= 1000
}
if isNegative {
return fmt.Sprintf("$ -%d%s", value, result)
}
return fmt.Sprintf("$ %d%s", value, result)
}
用法:
formatMoney(10, ",", ".") // $ 0.10
formatMoney(12345, ",", ".") // $ 123.45
formatMoney(1234567, ",", ".") // $ 12,345.67
formatMoney(-1234567, ",", ".") // $ -12,345.67
您好,我正在开发一个以货币格式设置值的函数。我正在使用 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)))
}
预期结果应该是 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))
}
在这个例子中,我从语言代码推断出货币格式。
https://goplay.space/#fqs9t8MG062
n := display.Tags(language.English)
for _, lcode := range []string{"en_US", "pt_BR", "de", "ja", "hi"} {
lang := language.MustParse(lcode)
cur, _ := currency.FromTag(lang)
scale, _ := currency.Cash.Rounding(cur) // fractional digits
dec := number.Decimal(100000.00, number.Scale(scale))
p := message.NewPrinter(lang)
p.Printf("%24v (%v): %v%v\n", n.Name(lang), cur, currency.Symbol(cur), dec)
}
// American English (USD): 0,000.00
// Brazilian Portuguese (BRL): R0.000,00
// German (EUR): €100.000,00
// Japanese (JPY): ¥100,000
// Hindi (INR): ₹1,00,000.00
您还可以解析 ISO 货币代码,但您还必须指定用于设置数字格式的语言。输出语言不会影响小数位数,但会影响逗号和句点的使用位置:
https://goplay.space/#DlxSmjZbHH6
for _, iso := range []string{"USD", "BRL", "EUR", "JPY", "INR"} {
cur := currency.MustParseISO(iso)
scale, _ := currency.Cash.Rounding(cur) // fractional digits
dec := number.Decimal(100000.00, number.Scale(scale))
p := message.NewPrinter(language.English)
p.Printf("%v: %v%v\n", cur, currency.Symbol(cur), dec)
}
// USD: 0,000.00
// BRL: R0,000.00
// EUR: €100,000.00
// JPY: ¥100,000
// INR: ₹100,000.00
某些货币以增量形式四舍五入,例如 0.05 或 0.50。对于这些情况,currency.Cash.Rounding(cur)
的第二个 return 值将 return 5 或 50 而不是 1。要为 Decimal 格式化程序提供它期望的 IncrementString,我们必须做更多的处理:
package main
import (
"math"
"strconv"
"golang.org/x/text/currency"
"golang.org/x/text/language"
"golang.org/x/text/language/display"
"golang.org/x/text/message"
"golang.org/x/text/number"
)
func main() {
n := display.Tags(language.English)
for _, lcode := range []string{"en_US", "en_CA", "da", "ja"} {
lang := language.MustParse(lcode)
cur, _ := currency.FromTag(lang)
scale, incCents := currency.Cash.Rounding(cur) // fractional digits
incFloat := math.Pow10(-scale) * float64(incCents)
incFmt := strconv.FormatFloat(incFloat, 'f', scale, 64)
dec := number.Decimal(100000.26,
number.Scale(scale), number.IncrementString(incFmt))
p := message.NewPrinter(lang)
p.Printf("%24v %v, %4s-rounding: %3v%v\n",
n.Name(lang), cur, incFmt, currency.Symbol(cur), dec)
}
}
// American English USD, 0.01-rounding: 0,000.26
// Canadian English CAD, 0.05-rounding: CA0,000.25
// Danish DKK, 0.50-rounding: DKK100.000,50
// Japanese JPY, 1-rounding: ¥100,000
您可能会注意到,golang。org/x/text/currency 仍在进行中,有一段时间没有更新了。
NOTE: the formatting functionality is currently under development and may change without notice.
如果您更喜欢使用简单的辅助函数来完成工作,您可以使用类似这样的方法:
func formatMoney(value int32, thousand, decimal string) string {
var result string
var isNegative bool
if value < 0 {
value = value * -1
isNegative = true
}
// apply the decimal separator
result = fmt.Sprintf("%s%02d%s", decimal, value%100, result)
value /= 100
// for each 3 dígits put a dot "."
for value >= 1000 {
result = fmt.Sprintf("%s%03d%s", thousand, value%1000, result)
value /= 1000
}
if isNegative {
return fmt.Sprintf("$ -%d%s", value, result)
}
return fmt.Sprintf("$ %d%s", value, result)
}
用法:
formatMoney(10, ",", ".") // $ 0.10
formatMoney(12345, ",", ".") // $ 123.45
formatMoney(1234567, ",", ".") // $ 12,345.67
formatMoney(-1234567, ",", ".") // $ -12,345.67