]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
Started docs on number formatting/parsing.
authorChristopher Lenz <cmlenz@gmail.com>
Mon, 4 Jun 2007 12:06:25 +0000 (12:06 +0000)
committerChristopher Lenz <cmlenz@gmail.com>
Mon, 4 Jun 2007 12:06:25 +0000 (12:06 +0000)
babel/numbers.py
doc/formatting.txt

index 1ef6325e2a78f73920de13561cad030975afff28..9c23e2413842bf92bf98ed62d12864cd74bbd9ba 100644 (file)
@@ -29,7 +29,7 @@ from babel.util import default_locale
 
 __all__ = ['format_number', 'format_decimal', 'format_currency',
            'format_percent', 'format_scientific', 'parse_number',
-           'parse_decimal']
+           'parse_decimal', 'NumberFormatError']
 __docformat__ = 'restructuredtext en'
 
 LC_NUMERIC = default_locale('LC_NUMERIC')
@@ -106,13 +106,14 @@ def format_decimal(number, format=None, locale=LC_NUMERIC):
         pattern = parse_pattern(format)
     return pattern.apply(number, locale)
 
-def format_currency(number, locale=LC_NUMERIC):
+def format_currency(number, currency, locale=LC_NUMERIC):
     """Returns formatted currency value.
     
-    >>> format_currency(1099.98, locale='en_US')
+    >>> format_currency(1099.98, 'USD', locale='en_US')
     u'1,099.98'
     
     :param number: the number to format
+    :param currency: the currency code
     :param locale: the `Locale` object or locale identifier
     :return: the formatted currency value
     :rtype: `unicode`
@@ -144,6 +145,12 @@ def format_percent(number, format=None, locale=LC_NUMERIC):
 def format_scientific(number, locale=LC_NUMERIC):
     raise NotImplementedError
 
+
+
+class NumberFormatError(ValueError):
+    """Exception raised when a string cannot be parsed into a number."""
+
+
 def parse_number(string, locale=LC_NUMERIC):
     """Parse localized number string into a long integer.
     
@@ -152,32 +159,52 @@ def parse_number(string, locale=LC_NUMERIC):
     >>> parse_number('1.099', locale='de_DE')
     1099L
     
+    When the given string cannot be parsed, an exception is raised:
+    
+    >>> parse_number('1.099,98', locale='de')
+    Traceback (most recent call last):
+        ...
+    NumberFormatError: '1.099,98' is not a valid number
+    
     :param string: the string to parse
     :param locale: the `Locale` object or locale identifier
     :return: the parsed number
     :rtype: `long`
-    :raise `ValueError`: if the string can not be converted to a number
+    :raise `NumberFormatError`: if the string can not be converted to a number
     """
-    return long(string.replace(get_group_symbol(locale), ''))
+    try:
+        return long(string.replace(get_group_symbol(locale), ''))
+    except ValueError:
+        raise NumberFormatError('%r is not a valid number' % string)
 
 def parse_decimal(string, locale=LC_NUMERIC):
     """Parse localized decimal string into a float.
     
     >>> parse_decimal('1,099.98', locale='en_US')
     1099.98
-    >>> parse_decimal('1.099,98', locale='de_DE')
+    >>> parse_decimal('1.099,98', locale='de')
     1099.98
     
+    When the given string cannot be parsed, an exception is raised:
+    
+    >>> parse_decimal('2,109,998', locale='de')
+    Traceback (most recent call last):
+        ...
+    NumberFormatError: '2,109,998' is not a valid decimal number
+    
     :param string: the string to parse
     :param locale: the `Locale` object or locale identifier
     :return: the parsed decimal number
     :rtype: `float`
-    :raise `ValueError`: if the string can not be converted to a decimal number
+    :raise `NumberFormatError`: if the string can not be converted to a
+                                decimal number
     """
     locale = Locale.parse(locale)
-    string = string.replace(get_group_symbol(locale), '') \
-                   .replace(get_decimal_symbol(locale), '.')
-    return float(string)
+    try:
+        return float(string.replace(get_group_symbol(locale), '')
+                           .replace(get_decimal_symbol(locale), '.'))
+    except ValueError:
+        raise NumberFormatError('%r is not a valid decimal number' % string)
 
 
 PREFIX_END = r'[^0-9@#.,]'
index 4800a9a0502d2428cc08ab363fd25a280e902658..ff3870b897cd7a3017f286c280bb139953a931d7 100644 (file)
@@ -234,10 +234,90 @@ Babel can also parse date and time information in a locale-sensitive manner::
 Number Formatting
 =================
 
+Support for locale-specific formatting and parsing of numbers is provided by
+the ``babel.numbers`` module::
+
+    >>> from babel.numbers import format_number, format_decimal, format_percent
+
+Examples::
+
+    >>> format_decimal(1.2345, locale='en_US')
+    u'1.234'
+    >>> format_decimal(1.2345, locale='sv_SE')
+    u'1,234'
+    >>> format_decimal(12345, locale='de_DE')
+    u'12.345'
+
 
 Pattern Syntax
 --------------
 
+While Babel makes it simple to use the appropriate number format for a given
+locale, you can also force it to use custom patterns. As with date/time
+formatting patterns, the patterns Babel supports for number formatting are
+based on the `Locale Data Markup Language specification`_ (LDML).
+
+Examples::
+
+    >>> format_decimal(-1.2345, format='#,##0.##;-#', locale='en')
+    u'-1.23'
+    >>> format_decimal(-1.2345, format='#,##0.##;(#)', locale='en')
+    u'(1.23)'
+
+The syntax for custom number format patterns is described in detail in the
+the specification. The following table is just a relatively brief overview.
+
+  +----------+-----------------------------------------------------------------+
+  | Symbol   | Description                                                     |
+  +==========+=================================================================+
+  | ``0``    | Digit                                                           |
+  +----------+-----------------------------------------------------------------+
+  | ``1-9``  | '1' through '9' indicate rounding.                              |
+  +----------+-----------------------------------------------------------------+
+  | ``@``    | Significant digit                                               |
+  +----------+-----------------------------------------------------------------+
+  | ``#``    | Digit, zero shows as absent                                     |
+  +----------+-----------------------------------------------------------------+
+  | ``.``    | Decimal separator or monetary decimal separator                 |
+  +----------+-----------------------------------------------------------------+
+  | ``-``    | Minus sign                                                      |
+  +----------+-----------------------------------------------------------------+
+  | ``,``    | Grouping separator                                              |
+  +----------+-----------------------------------------------------------------+
+  | ``E``    | Separates mantissa and exponent in scientific notation          |
+  +----------+-----------------------------------------------------------------+
+  | ``+``    | Prefix positive exponents with localized plus sign              |
+  +----------+-----------------------------------------------------------------+
+  | ``;``    | Separates positive and negative subpatterns                     |
+  +----------+-----------------------------------------------------------------+
+  | ``%``    | Multiply by 100 and show as percentage                          |
+  +----------+-----------------------------------------------------------------+
+  | ``‰``    | Multiply by 1000 and show as per mille                          |
+  +----------+-----------------------------------------------------------------+
+  | ``¤``    | Currency sign, replaced by currency symbol. If doubled,         |
+  |          | replaced by international currency symbol. If tripled, uses the |
+  |          | long form of the decimal symbol.                                |
+  +----------+-----------------------------------------------------------------+
+  | ``'``    | Used to quote special characters in a prefix or suffix          |
+  +----------+-----------------------------------------------------------------+
+  | ``*``    | Pad escape, precedes pad character                              |
+  +----------+-----------------------------------------------------------------+
+
 
 Parsing Numbers
 ---------------
+
+Babel can also parse numeric data in a locale-sensitive manner::
+
+    >>> from babel.dates import parse_decimal, parse_number
+
+Examples::
+
+    >>> parse_decimal('1,099.98', locale='en_US')
+    1099.98
+    >>> parse_decimal('1.099,98', locale='de')
+    1099.98
+    >>> parse_decimal('2,109,998', locale='de')
+    Traceback (most recent call last):
+        ...
+    NumberFormatError: '2,109,998' is not a valid decimal number