Babel numbers format_currency function
I work on a site where we use many languages and we use Babel library to display price / currency. The problem is that when format_currency is called, the center part is always returned, even if the price is explicitly entered into an integer.
Example:
>>> print format_currency(100, 'EUR', locale='fr_FR')
100,00 €
>>> print format_currency(int(100), 'EUR', locale='fr_FR')
100,00 €
This is a way around this, so that the return value excludes the center section to have something like
>>> print format_currency(int(100), 'EUR', locale='fr_FR')
100 €
source to share
You can specify a custom format:
format_currency(100, 'EUR', format=u'#,##0\xa0¤', locale='fr_FR')
See the LDML markup specification for details ; the byte \xa0
is the character U + 00A0 NO-BREAK SPACE ; not regular space.
The fr_FR
for is used by default #,##0.00\xa0¤
, and the part .00
signals that the decimal part should be printed with two digits padded if not. My example above just removed the decimal part, you can also use .##
to allow a fraction if the number is not an exact integer, but note that in this case the value .5
is printed without the 2nd digit!
Demo:
>>> 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 €
source to share
You have to add currency_digits parameter with format to achieve your goal
>>> 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 €
source to share
In cases where the locale is arbitrary it would be painful to rewrite the format by hand, here is a solution that seems to work.
Just in case, here is the code suggested by Akx for the github release:
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'))
source to share