Format currency with babel without Unicode?

92 views Asked by At

Using Babel I get this:

>>> babel.numbers.format_currency(1099.98, 'CHF', locale='fr_CH')
'1\u202f099,98\xa0CHF'

I would like this format:

"CHF 1'099.98"

Is it possible to specify a custom format with babel?

My current ugly workaround is:

>>> num = 1099.998
>>> s = f"CHF {num:,.2f}".replace(',',"'")
>>> s
"CHF 1'100.00"

But it also round my number :(

2

There are 2 answers

0
Andj On BEST ANSWER

The simpliest solution is to change the locale from fr_CH to de_CH. This seems to be the currency formatting locale you require.

import babel.numbers
amount = babel.numbers.format_currency(1099.98, 'CHF', locale='de_CH')
print(amount)
# CHF 1’099.98

It can also be achieved using PyICU:

import icu
formatter = (
    icu.NumberFormatter.with_()
    .notation(icu.Notation.simple())
    .unit(icu.CurrencyUnit("CHF"))
    .precision(icu.Precision.minMaxFraction(2, 2))
    .locale(icu.Locale("de_CH"))
)
print(formatter.formatDouble(1099.98))
# CHF 1’099.98

Where as the French (Switzerland) locale gives:

amount_fr = babel.numbers.format_currency(1099.98, 'CHF', locale='fr_CH')
print(amount_fr)
# 1 099,98 CHF

and

formatter_fr = (
    icu.NumberFormatter.with_()
    .notation(icu.Notation.simple())
    .unit(icu.CurrencyUnit("CHF"))
    .precision(icu.Precision.minMaxFraction(2, 2))
    .locale(icu.Locale("fr_CH"))
)
print(formatter_fr.formatDouble(1099.98))
# 1 099.98 CHF
2
OM222O On

The problem is your .2f (round to 2 decimal places). If you want more precision use a larger number (for example .10f) or if you don't want any rounding just pass your number directly.

f"CHF {num:,f}".replace(",","'")