From: Isaac Jurado Date: Mon, 17 Nov 2014 17:24:47 +0000 (+0100) Subject: numbers: Use currency decimal digits by default X-Git-Tag: dev-2a51c9b95d06~10^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=201ed50bc0d8a7baf332eb0596d3c2ac944b7b43;p=thirdparty%2Fbabel.git numbers: Use currency decimal digits by default When formatting a price, the number of decimals to use should be defined by the currency. For example, JPY do not use decimal numbers at all. However, we still allow the user to override the currency decimal digits setting with the one from the number format. Fixes https://github.com/mitsuhiko/babel/issues/139 --- diff --git a/babel/numbers.py b/babel/numbers.py index 2117ce93..19a376be 100644 --- a/babel/numbers.py +++ b/babel/numbers.py @@ -256,7 +256,7 @@ def format_decimal(number, format=None, locale=LC_NUMERIC): return pattern.apply(number, locale) -def format_currency(number, currency, format=None, locale=LC_NUMERIC): +def format_currency(number, currency, format=None, locale=LC_NUMERIC, currency_digits=True): u"""Return formatted currency value. >>> format_currency(1099.98, 'USD', locale='en_US') @@ -276,15 +276,41 @@ def format_currency(number, currency, format=None, locale=LC_NUMERIC): >>> format_currency(1099.98, 'EUR', u'#,##0.00 \xa4\xa4\xa4', locale='en_US') u'1,099.98 euros' + Currencies usually have a specific number of decimal digits. This function + favours that information over the given format: + + >>> format_currency(1099.98, 'JPY', locale='en_US') + u'\\xa51,100' + >>> format_currency(1099.98, 'COP', u'#,##0.00', locale='es_ES') + u'1.100' + + However, the number of decimal digits can be overriden from the currency + information, by setting the last parameter to ``True``: + + >>> format_currency(1099.98, 'JPY', locale='en_US', currency_digits=False) + u'\\xa51,099.98' + >>> format_currency(1099.98, 'COP', u'#,##0.00', locale='es_ES', currency_digits=False) + u'1.099,98' + :param number: the number to format :param currency: the currency code :param locale: the `Locale` object or locale identifier + :param currency_digits: use the currency's number of decimal digits """ locale = Locale.parse(locale) if not format: format = locale.currency_formats.get(format) pattern = parse_pattern(format) - return pattern.apply(number, locale, currency=currency) + if currency_digits: + fractions = get_global('currency_fractions') + try: + digits = fractions[currency][0] + except KeyError: + digits = fractions['DEFAULT'][0] + frac = (digits, digits) + else: + frac = None + return pattern.apply(number, locale, currency=currency, force_frac=frac) def format_percent(number, format=None, locale=LC_NUMERIC): diff --git a/tests/test_numbers.py b/tests/test_numbers.py index 6fe67c04..741b7537 100644 --- a/tests/test_numbers.py +++ b/tests/test_numbers.py @@ -252,6 +252,17 @@ def test_format_currency(): assert (numbers.format_currency(1099.98, 'EUR', locale='nl_NL') != numbers.format_currency(-1099.98, 'EUR', locale='nl_NL')) + assert (numbers.format_currency(1099.98, 'JPY', locale='en_US') + == u'\xa51,100') + assert (numbers.format_currency(1099.98, 'COP', u'#,##0.00', locale='es_ES') + == u'1.100') + assert (numbers.format_currency(1099.98, 'JPY', locale='en_US', + currency_digits=False) + == u'\xa51,099.98') + assert (numbers.format_currency(1099.98, 'COP', u'#,##0.00', locale='es_ES', + currency_digits=False) + == u'1.099,98') + def test_format_percent(): assert numbers.format_percent(0.34, locale='en_US') == u'34%'