4

I am working on a site where we use many languages and in order to display the price/currency accordingly we make use of babel library. The issue is when calling the format_currency it returns always the cent part if even if the price is explicitly casted 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 €

Is it a way around this so that the return value excludes the cent part to have something like

>>> print format_currency(int(100), 'EUR', locale='fr_FR')
100 €
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Palmer
  • 493
  • 4
  • 13

3 Answers3

6

You must 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 €
Ibrahim
  • 104
  • 1
  • 6
5

You can specify a custom format:

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

See the LDML markup spec for more details; the \xa0 byte is a U+00A0 NO-BREAK SPACE character; rather than a regular space.

For fr_FR the default is #,##0.00\xa0¤, and the .00 part signals that a decimal portion should be printed with two digits, padded if not present. My example above simply removed the decimal portion, you also could use .## to allow for a fraction if the number is not an exact integer, but note that in that case a .5 value is printed without a 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 €
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • If I understand correctly, this solution involves re-writing every format depending on the selected locale? In the case where the locale is not constant, is there a way to truncate the number for an arbitrary locale? – cglacet Jun 07 '19 at 11:56
  • 1
    I found the answer [here](https://github.com/python-babel/babel/issues/478#issuecomment-290365787). – cglacet Jun 07 '19 at 12:20
1

In the cases where the locale is arbitrary, it would be painful to rewrite the format manually, here is a solution that seems to work.

Just in case here is the code proposed by Akx on this github issue:

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'))
cglacet
  • 8,873
  • 4
  • 45
  • 60