Babel 数字格式化 currency 函数

4 投票
3 回答
7900 浏览
提问于 2025-04-18 18:03

我正在做一个网站,这个网站使用了很多语言。为了正确显示价格和货币,我们使用了babel这个库。不过遇到了一个问题,就是当调用format_currency这个函数时,它总是返回包含分的部分,即使价格已经明确转换成了整数。

举个例子:

>>> print format_currency(100, 'EUR', locale='fr_FR')
100,00 €

>>> print format_currency(int(100), 'EUR', locale='fr_FR')
100,00 €

有没有办法解决这个问题,让返回的结果不包含分的部分,像这样:

>>> print format_currency(int(100), 'EUR', locale='fr_FR')
100 €

3 个回答

3

在某些情况下,如果地区设置是随意的,手动重新编写格式会很麻烦。这里有一个看起来有效的解决方案

顺便说一下,这里是Akx在这个GitHub问题中提出的代码:

from babel import Locale
from babel.numbers import decimal

def custom_format_currency(value, currency, locale):
    value = decimal.Decimal(value)
    locale = Locale.parse(locale)
    pattern = locale.currency_formats['standard']
    force_frac = ((0, 0) if value == int(value) else None)
    return pattern.apply(value, locale, currency=currency, force_frac=force_frac)

print(custom_format_currency('2.50', 'EUR', 'fi'))
print(custom_format_currency('2.00', 'EUR', 'fi'))
5

你可以指定一个自定义的格式:

format_currency(100, 'EUR', format=u'#,##0\xa0¤', locale='fr_FR')

想了解更多细节,可以查看LDML标记规范;这里提到的\xa0字节是一个U+00A0 不换行空格字符,它和普通空格不一样。

对于fr_FR,默认格式是#,##0.00\xa0¤,其中.00部分表示小数部分应该显示两位数字,如果没有则用0填充。我上面的例子只是去掉了小数部分,你也可以用.##来允许显示小数,如果这个数字不是整数,但要注意,在这种情况下,像.5这样的值会只显示一位数字!

演示:

>>> from babel.numbers import format_currency
>>> print format_currency(100, 'EUR', format=u'#,##0\xa0¤', locale='fr_FR')
100 €
>>> print format_currency(100.0, 'EUR', format=u'#,##0.##\xa0¤', locale='fr_FR')
100 €
6

你需要添加一个叫做currency_digits的参数,并且要设置格式,这样才能实现你的目标。

>>> print(format_currency(100, 'EUR', locale='fr_FR')
100,00 €
>>> print(format_currency(100, 'EUR', locale='fr_FR', currency_digits=False))
100,00 €
>>> print(format_currency(100, 'EUR', format=u'#,##0\xa0¤', locale='fr_FR'))
100,00 €
>>> print(format_currency(100, 'EUR', format=u'#,##0\xa0¤', locale='fr_FR', currency_digits=False))
100 €

撰写回答