# HG changeset patch # User cmlenz # Date 1182183590 0 # Node ID a72de8971819db6afc77f8d7f6d3177de12427d5 # Parent b12c6a776c44275c2335efbc6dc83bf8c19e2db6 Add currency formatting. diff --git a/babel/core.py b/babel/core.py --- a/babel/core.py +++ b/babel/core.py @@ -314,6 +314,17 @@ :type: `dict` """) + def currency_formats(self): + return self._data['currency_formats'] + currency_formats = property(currency_formats, doc=r"""\ + Locale patterns for currency number formatting. + + >>> print Locale('en', 'US').currency_formats[None] + + + :type: `dict` + """) + def percent_formats(self): return self._data['percent_formats'] percent_formats = property(percent_formats, doc="""\ @@ -325,6 +336,17 @@ :type: `dict` """) + def scientific_formats(self): + return self._data['scientific_formats'] + scientific_formats = property(scientific_formats, doc="""\ + Locale patterns for scientific number formatting. + + >>> Locale('en', 'US').scientific_formats[None] + + + :type: `dict` + """) + #{ Calendar Information and Date Formatting def periods(self): diff --git a/babel/numbers.py b/babel/numbers.py --- a/babel/numbers.py +++ b/babel/numbers.py @@ -33,6 +33,19 @@ LC_NUMERIC = default_locale('LC_NUMERIC') +def get_currency_symbol(currency, locale=LC_NUMERIC): + """Return the symbol used by the locale for the specified currency. + + >>> get_currency_symbol('USD', 'en_US') + u'$' + + :param currency: the currency code + :param locale: the `Locale` object or locale identifier + :return: the currency symbol + :rtype: `unicode` + """ + return Locale.parse(locale).currency_symbols.get(currency, currency) + def get_decimal_symbol(locale=LC_NUMERIC): """Return the symbol used by the locale to separate decimal fractions. @@ -88,8 +101,8 @@ The appropriate thousands grouping and the decimal separator are used for each locale: - >>> format_decimal(12345, locale='en_US') - u'12,345' + >>> format_decimal(12345.5, locale='en_US') + u'12,345.5' :param number: the number to format :param format: @@ -98,16 +111,25 @@ :rtype: `unicode` """ locale = Locale.parse(locale) - pattern = locale.decimal_formats.get(format) - if not pattern: - pattern = parse_pattern(format) + if not format: + format = locale.decimal_formats.get(format) + pattern = parse_pattern(format) return pattern.apply(number, locale) -def format_currency(number, currency, locale=LC_NUMERIC): +def format_currency(number, currency, format=None, locale=LC_NUMERIC): """Return formatted currency value. >>> format_currency(1099.98, 'USD', locale='en_US') - u'1,099.98' + u'$1,099.98' + >>> format_currency(1099.98, 'USD', locale='es_CO') + u'US$1.099,98' + >>> format_currency(1099.98, 'EUR', locale='de_DE') + u'1.099,98 \\u20ac' + + The pattern can also be specified explicitly: + + >>> format_currency(1099.98, 'EUR', u'\xa4\xa4 #,##0.00', locale='en_US') + u'EUR 1,099.98' :param number: the number to format :param currency: the currency code @@ -115,7 +137,11 @@ :return: the formatted currency value :rtype: `unicode` """ - return format_decimal(number, locale=locale) + locale = Locale.parse(locale) + if not format: + format = locale.currency_formats.get(format) + pattern = parse_pattern(format) + return pattern.apply(number, locale, currency=currency) def format_percent(number, format=None, locale=LC_NUMERIC): """Return formatted percent value for a specific locale. @@ -134,9 +160,9 @@ :rtype: `unicode` """ locale = Locale.parse(locale) - pattern = locale.percent_formats.get(format) - if not pattern: - pattern = parse_pattern(format) + if not format: + format = locale.percent_formats.get(format) + pattern = parse_pattern(format) return pattern.apply(number, locale) def format_scientific(number, locale=LC_NUMERIC): @@ -304,7 +330,7 @@ def __repr__(self): return '<%s %r>' % (type(self).__name__, self.pattern) - def apply(self, value, locale): + def apply(self, value, locale, currency=None): value *= self.scale negative = int(value < 0) a = self.format % value @@ -313,10 +339,14 @@ else: b = '' a = a.lstrip('-') - return '%s%s%s%s' % (self.prefix[negative], - self._format_int(a, locale), - self._format_frac(b, locale), - self.suffix[negative]) + retval = '%s%s%s%s' % (self.prefix[negative], + self._format_int(a, locale), + self._format_frac(b, locale), + self.suffix[negative]) + if u'¤' in retval: + retval = retval.replace(u'¤¤', currency.upper()) + retval = retval.replace(u'¤', get_currency_symbol(currency, locale)) + return retval def _format_int(self, value, locale): min, max = self.int_precision diff --git a/scripts/import_cldr.py b/scripts/import_cldr.py --- a/scripts/import_cldr.py +++ b/scripts/import_cldr.py @@ -277,15 +277,15 @@ for elem in tree.findall('//scientificFormats/scientificFormatLength'): if 'draft' in elem.attrib and elem.attrib.get('type') in scientific_formats: continue - # FIXME: should use numbers.parse_pattern - scientific_formats[elem.attrib.get('type')] = unicode(elem.findtext('scientificFormat/pattern')) + pattern = unicode(elem.findtext('scientificFormat/pattern')) + scientific_formats[elem.attrib.get('type')] = numbers.parse_pattern(pattern) currency_formats = data.setdefault('currency_formats', {}) for elem in tree.findall('//currencyFormats/currencyFormatLength'): if 'draft' in elem.attrib and elem.attrib.get('type') in currency_formats: continue - # FIXME: should use numbers.parse_pattern - currency_formats[elem.attrib.get('type')] = unicode(elem.findtext('currencyFormat/pattern')) + pattern = unicode(elem.findtext('currencyFormat/pattern')) + currency_formats[elem.attrib.get('type')] = numbers.parse_pattern(pattern) percent_formats = data.setdefault('percent_formats', {}) for elem in tree.findall('//percentFormats/percentFormatLength'):