15.3. Locale l10n

15.3.1. Rationale

  • l10n = localization

15.3.2. Django

  • django.utils.timezone

  • from django.conf.locale.en import formats as en_formats

15.3.3. Numbers

15.3.4. Locale

LC_CTYPE

Locale category for the character type functions. Depending on the settings of this category, the functions of module string dealing with case change their behaviour.

LC_COLLATE

Locale category for sorting strings. The functions strcoll() and strxfrm() of the locale module are affected.

LC_TIME

Locale category for the formatting of time. The function time .strftime() follows these conventions.

LC_MONETARY

Locale category for formatting of monetary values. The available options are available from the localeconv() function.

LC_MESSAGES

Locale category for message display. Python currently does not support application specific locale-aware messages. Messages displayed by the operating system, like those returned by os .strerror() might be affected by this category.

LC_NUMERIC

Locale category for formatting numbers. The functions format(), atoi(), atof() and str() of the locale module are affected by that category. All other numeric formatting operations are not affected.

LC_ALL

Combination of all locale settings. If this flag is used when the locale is changed, setting the locale for all categories is attempted. If that fails for any category, no category is changed at all. When the locale is retrieved using this flag, a string indicating the setting for all categories is returned. This string can be later used to restore the settings.

Import module:

>>> import locale

Get current locale:

Returns the current setting for the given locale category as sequence containing language code, encoding. category may be one of the LC_* values except LC_ALL. It defaults to LC_CTYPE.

Except for the code 'C', the language code corresponds to RFC 1766. language code and encoding may be None if their values cannot be determined.

>>> locale.getlocale()
('en_US', 'UTF-8')

Tries to determine the default locale settings and returns them as a tuple of the form (language code, encoding):

>>> locale.getdefaultlocale()
('en_US', 'UTF-8')

According to POSIX, a program which has not called setlocale(LC_ALL, '') runs using the portable 'C' locale. Calling setlocale(LC_ALL, '') lets it use the default locale as defined by the LANG variable. Since we do not want to interfere with the current locale setting we thus emulate the behavior in the way described above.

Except for the code 'C', the language code corresponds to RFC 1766. language code and encoding may be None if their values cannot be determined.

Setting locale:

>>> locale.setlocale(locale.LC_ALL, '')
'C.UTF-8'

If locale is omitted or None, the current setting for category is returned:

Using locale:

>>> locale.currency(100)
Traceback (most recent call last):
ValueError: Currency formatting is not possible using the 'C' locale.
>>> locale.setlocale(locale.LC_ALL, 'pl_PL.UTF-8')  
'pl_PL.UTF-8'
>>> locale.currency(100)  
'zł 100,00'
>>> locale.localeconv()   
{'int_curr_symbol': '', 'currency_symbol': '', 'mon_decimal_point': '.',
 'mon_thousands_sep': '', 'mon_grouping': [], 'positive_sign': '',
 'negative_sign': '', 'int_frac_digits': 127, 'frac_digits': 127,
 'p_cs_precedes': 127, 'p_sep_by_space': 127, 'n_cs_precedes': 127,
 'n_sep_by_space': 127, 'p_sign_posn': 127, 'n_sign_posn': 127,
 'decimal_point': '.', 'thousands_sep': '', 'grouping': []}

All numeric values can be set to CHAR_MAX to indicate that there is no value specified in this locale.

The possible values for 'p_sign_posn' and 'n_sign_posn' are given below:

Value

Explanation

0

Currency and value are surrounded by parentheses.

1

The sign should precede the value and currency symbol.

2

The sign should follow the value and currency symbol.

3

The sign should immediately precede the value.

4

The sign should immediately follow the value.

CHAR_MAX

Nothing is specified in this locale.

Category

Key

Meaning

LC_NUMERIC

'decimal_point'

Decimal point character.

'grouping'

Sequence of numbers specifying which relative positions the 'thousands_sep' is expected. If the sequence is terminated with CHAR_MAX, no further grouping is performed. If the sequence terminates with a 0, the last group size is repeatedly used.

'thousands_sep'

Character used between groups.

LC_MONETARY

'int_curr_symbol'

International currency symbol.

'currency_symbol'

Local currency symbol.

'p_cs_precedes/n_cs_precedes'

Whether the currency symbol precedes the value (for positive resp. negative values).

'p_sep_by_space/n_sep_by_space'

Whether the currency symbol is separated from the value by a space (for positive resp. negative values).

'mon_decimal_point'

Decimal point used for monetary values.

'frac_digits'

Number of fractional digits used in local formatting of monetary values.

'int_frac_digits'

Number of fractional digits used in international formatting of monetary values.

'mon_thousands_sep'

Group separator used for monetary values.

'mon_grouping'

Equivalent to 'grouping', used for monetary values.

'positive_sign'

Symbol used to annotate a positive monetary value.

'negative_sign'

Symbol used to annotate a negative monetary value.

'p_sign_posn/n_sign_posn'

The position of the sign (for positive resp. negative values), see below.

15.3.5. Examples

pl_PL:

DECIMAL_SEPARATOR = ','
THOUSAND_SEPARATOR = ' '
NUMBER_GROUPING = 3

DATE_FORMAT = 'j E Y'
TIME_FORMAT = 'H:i'
DATETIME_FORMAT = 'j E Y H:i'
YEAR_MONTH_FORMAT = 'F Y'
MONTH_DAY_FORMAT = 'j E'
SHORT_DATE_FORMAT = 'd-m-Y'
SHORT_DATETIME_FORMAT = 'd-m-Y  H:i'
FIRST_DAY_OF_WEEK = 1  # Monday

DATE_INPUT_FORMATS = [
    '%d.%m.%Y', '%d.%m.%y',     # '25.10.2006', '25.10.06'
    '%y-%m-%d',                 # '06-10-25'
    # '%d. %B %Y', '%d. %b. %Y',  # '25. October 2006', '25. Oct. 2006'
]

DATETIME_INPUT_FORMATS = [
    '%d.%m.%Y %H:%M:%S',     # '25.10.2006 14:30:59'
    '%d.%m.%Y %H:%M:%S.%f',  # '25.10.2006 14:30:59.000200'
    '%d.%m.%Y %H:%M',        # '25.10.2006 14:30'
]

en_GB:

DECIMAL_SEPARATOR = '.'
THOUSAND_SEPARATOR = ','
NUMBER_GROUPING = 3

DATE_FORMAT = 'j M Y'                   # '25 Oct 2006'
TIME_FORMAT = 'P'                       # '2:30 p.m.'
DATETIME_FORMAT = 'j M Y, P'            # '25 Oct 2006, 2:30 p.m.'
YEAR_MONTH_FORMAT = 'F Y'               # 'October 2006'
MONTH_DAY_FORMAT = 'j F'                # '25 October'
SHORT_DATE_FORMAT = 'd/m/Y'             # '25/10/2006'
SHORT_DATETIME_FORMAT = 'd/m/Y P'       # '25/10/2006 2:30 p.m.'
FIRST_DAY_OF_WEEK = 1                   # Monday

DATE_INPUT_FORMATS = [
    '%d/%m/%Y', '%d/%m/%y',             # '25/10/2006', '25/10/06'
    # '%b %d %Y', '%b %d, %Y',          # 'Oct 25 2006', 'Oct 25, 2006'
    # '%d %b %Y', '%d %b, %Y',          # '25 Oct 2006', '25 Oct, 2006'
    # '%B %d %Y', '%B %d, %Y',          # 'October 25 2006', 'October 25, 2006'
    # '%d %B %Y', '%d %B, %Y',          # '25 October 2006', '25 October, 2006'
]
DATETIME_INPUT_FORMATS = [
    '%Y-%m-%d %H:%M:%S',                # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M:%S.%f',             # '2006-10-25 14:30:59.000200'
    '%Y-%m-%d %H:%M',                   # '2006-10-25 14:30'
    '%d/%m/%Y %H:%M:%S',                # '25/10/2006 14:30:59'
    '%d/%m/%Y %H:%M:%S.%f',             # '25/10/2006 14:30:59.000200'
    '%d/%m/%Y %H:%M',                   # '25/10/2006 14:30'
    '%d/%m/%y %H:%M:%S',                # '25/10/06 14:30:59'
    '%d/%m/%y %H:%M:%S.%f',             # '25/10/06 14:30:59.000200'
    '%d/%m/%y %H:%M',                   # '25/10/06 14:30'
]

en_US:

DECIMAL_SEPARATOR = '.'
THOUSAND_SEPARATOR = ','
NUMBER_GROUPING = 3

DATE_FORMAT = 'N j, Y'
TIME_FORMAT = 'P'
DATETIME_FORMAT = 'N j, Y, P'
YEAR_MONTH_FORMAT = 'F Y'
MONTH_DAY_FORMAT = 'F j'
SHORT_DATE_FORMAT = 'm/d/Y'
SHORT_DATETIME_FORMAT = 'm/d/Y P'
FIRST_DAY_OF_WEEK = 0  # Sunday

DATE_INPUT_FORMATS = [
    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y',  # '2006-10-25', '10/25/2006', '10/25/06'
    # '%b %d %Y', '%b %d, %Y',            # 'Oct 25 2006', 'Oct 25, 2006'
    # '%d %b %Y', '%d %b, %Y',            # '25 Oct 2006', '25 Oct, 2006'
    # '%B %d %Y', '%B %d, %Y',            # 'October 25 2006', 'October 25, 2006'
    # '%d %B %Y', '%d %B, %Y',            # '25 October 2006', '25 October, 2006'
]

DATETIME_INPUT_FORMATS = [
    '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M:%S.%f',  # '2006-10-25 14:30:59.000200'
    '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
    '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
    '%m/%d/%Y %H:%M:%S.%f',  # '10/25/2006 14:30:59.000200'
    '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
    '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
    '%m/%d/%y %H:%M:%S.%f',  # '10/25/06 14:30:59.000200'
    '%m/%d/%y %H:%M',        # '10/25/06 14:30'
]

15.3.6. Further Reading