diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 950b5547db..e970c12792 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -103,6 +103,10 @@ USE_I18N = True LOCALE_PATHS = () LANGUAGE_COOKIE_NAME = 'django_language' +# If you set this to True, Django will format dates, numbers and calendars +# according to user current locale +USE_L10N = False + # Not-necessarily-technical managers of the site. They get broken link # notifications and other various e-mails. MANAGERS = ADMINS @@ -265,6 +269,12 @@ FILE_UPLOAD_TEMP_DIR = None # you'd pass directly to os.chmod; see http://docs.python.org/lib/os-file-dir.html. FILE_UPLOAD_PERMISSIONS = None +# Python module path where user will place custom format definition. +# The directory where this setting is pointing should contain subdirectories +# named as the locales, containing a formats.py file +# (i.e. "myproject.locale" for myproject/locale/en/formats.py etc. use) +FORMAT_MODULE_PATH = None + # Default formatting for date objects. See all available format strings here: # http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now DATE_FORMAT = 'N j, Y' @@ -287,6 +297,70 @@ YEAR_MONTH_FORMAT = 'F Y' # http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now MONTH_DAY_FORMAT = 'F j' +# Default shortformatting for date objects. See all available format strings here: +# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now +SHORT_DATE_FORMAT = 'm/d/Y' + +# Default short formatting for datetime objects. +# See all available format strings here: +# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now +SHORT_DATETIME_FORMAT = 'm/d/Y P' + +# Default formats to be used when parsing dates from input boxes, in order +# See all available format string here: +# http://docs.python.org/library/datetime.html#strftime-behavior +# * Note that these format strings are different from the ones to display dates +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' +) + +# Default formats to be used when parsing times from input boxes, in order +# See all available format string here: +# http://docs.python.org/library/datetime.html#strftime-behavior +# * Note that these format strings are different from the ones to display dates +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' +) + +# Default formats to be used when parsing dates and times from input boxes, +# in order +# See all available format string here: +# http://docs.python.org/library/datetime.html#strftime-behavior +# * Note that these format strings are different from the ones to display dates +DATETIME_INPUT_FORMATS = ( + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' + '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' + '%m/%d/%Y %H:%M', # '10/25/2006 14:30' + '%m/%d/%Y', # '10/25/2006' + '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' + '%m/%d/%y %H:%M', # '10/25/06 14:30' + '%m/%d/%y', # '10/25/06' +) + +# First day of week, to be used on calendars +# 0 means Sunday, 1 means Monday... +FIRST_DAY_OF_WEEK = 0 + +# Decimal separator symbol +DECIMAL_SEPARATOR = '.' + +# Boolean that sets whether to add thousand separator when formatting numbers +USE_THOUSAND_SEPARATOR = False + +# Number of digits that will be togheter, when spliting them by THOUSAND_SEPARATOR +# 0 means no grouping, 3 means splitting by thousands... +NUMBER_GROUPING = 0 + +# Thousand separator symbol +THOUSAND_SEPARATOR = ',' + # Do you want to manage transactions manually? # Hint: you really don't! TRANSACTIONS_MANAGED = False diff --git a/django/conf/locale/__init__.py b/django/conf/locale/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ar/__init__.py b/django/conf/locale/ar/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ar/formats.py b/django/conf/locale/ar/formats.py new file mode 100644 index 0000000000..d8d627f820 --- /dev/null +++ b/django/conf/locale/ar/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F، Y' +TIME_FORMAT = 'g:i:s A' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd‏/m‏/Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/bg/__init__.py b/django/conf/locale/bg/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/bg/formats.py b/django/conf/locale/bg/formats.py new file mode 100644 index 0000000000..045543a7ac --- /dev/null +++ b/django/conf/locale/bg/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'd F Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd.m.Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/bn/__init__.py b/django/conf/locale/bn/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/bn/formats.py b/django/conf/locale/bn/formats.py new file mode 100644 index 0000000000..46e5da9392 --- /dev/null +++ b/django/conf/locale/bn/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F, Y' +TIME_FORMAT = 'g:i:s A' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M, Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +# NUMBER_GROUPING = diff --git a/django/conf/locale/ca/__init__.py b/django/conf/locale/ca/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ca/formats.py b/django/conf/locale/ca/formats.py new file mode 100644 index 0000000000..aebaea3d07 --- /dev/null +++ b/django/conf/locale/ca/formats.py @@ -0,0 +1,30 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j \de F \de Y' +TIME_FORMAT = 'G:i:s' +DATETIME_FORMAT = 'j \de F \de Y \\a \le\s G:i' +YEAR_MONTH_FORMAT = 'F \de\l Y' +MONTH_DAY_FORMAT = 'j \de F' +SHORT_DATE_FORMAT = 'd/m/Y' +SHORT_DATETIME_FORMAT = 'd/m/Y G:i' +FIRST_DAY_OF_WEEK = 1 # Monday +DATE_INPUT_FORMATS = ( + # '31/12/2009', '31/12/09' + '%d/%m/%Y', '%d/%m/%y' +) +TIME_INPUT_FORMATS = ( + # '14:30:59', '14:30' + '%H:%M:%S', '%H:%M' +) +DATETIME_INPUT_FORMATS = ( + '%d/%m/%Y %H:%M:%S', + '%d/%m/%Y %H:%M', + '%d/%m/%y %H:%M:%S', + '%d/%m/%y %H:%M', +) +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +NUMBER_GROUPING = 3 + diff --git a/django/conf/locale/cs/__init__.py b/django/conf/locale/cs/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/cs/formats.py b/django/conf/locale/cs/formats.py new file mode 100644 index 0000000000..327e77e868 --- /dev/null +++ b/django/conf/locale/cs/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y' +TIME_FORMAT = 'G:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'j.n.Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/cy/__init__.py b/django/conf/locale/cy/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/cy/formats.py b/django/conf/locale/cy/formats.py new file mode 100644 index 0000000000..a58d81f479 --- /dev/null +++ b/django/conf/locale/cy/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'd F Y' +TIME_FORMAT = 'g:i:s A' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +# MONTH_DAY_FORMAT = +SHORT_DATE_FORMAT = 'j M Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +# DECIMAL_SEPARATOR = +# THOUSAND_SEPARATOR = +# NUMBER_GROUPING = diff --git a/django/conf/locale/da/__init__.py b/django/conf/locale/da/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/da/formats.py b/django/conf/locale/da/formats.py new file mode 100644 index 0000000000..9982014cba --- /dev/null +++ b/django/conf/locale/da/formats.py @@ -0,0 +1,26 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y' +TIME_FORMAT = 'H:i' +DATETIME_FORMAT = 'j. F Y H:i' +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'd.m.Y' +SHORT_DATETIME_FORMAT = 'd.m.Y H:i' +FIRST_DAY_OF_WEEK = 1 +DATE_INPUT_FORMATS = ( + '%d.%m.%Y', # '25.10.2006' +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' +) +DATETIME_INPUT_FORMATS = ( + '%d.%m.%Y %H:%M:%S', # '25.10.2006 14:30:59' + '%d.%m.%Y %H:%M', # '25.10.2006 14:30' +) +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/de/__init__.py b/django/conf/locale/de/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/de/formats.py b/django/conf/locale/de/formats.py new file mode 100644 index 0000000000..89b57846b6 --- /dev/null +++ b/django/conf/locale/de/formats.py @@ -0,0 +1,32 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y' +TIME_FORMAT = 'H:i:s' +DATETIME_FORMAT = 'j. F Y H:i:s' +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'd.m.Y' +SHORT_DATETIME_FORMAT = 'd.m.Y H:i:s' +FIRST_DAY_OF_WEEK = 1 # Monday +DATE_INPUT_FORMATS = ( + '%d.%m.%Y', '%d.%m.%y', # '25.10.2006', '25.10.06' + '%Y-%m-%d', '%y-%m-%d', # '2006-10-25', '06-10-25' + '%d. %B %Y', '%d. %b. %Y', # '25. October 2006', '25. Oct. 2006' +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' +) +DATETIME_INPUT_FORMATS = ( + '%d.%m.%Y %H:%M:%S', # '25.10.2006 14:30:59' + '%d.%m.%Y %H:%M', # '25.10.2006 14:30' + '%d.%m.%Y', # '25.10.2006' + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' +) +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/el/__init__.py b/django/conf/locale/el/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/el/formats.py b/django/conf/locale/el/formats.py new file mode 100644 index 0000000000..d476ab3885 --- /dev/null +++ b/django/conf/locale/el/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'd F Y' +TIME_FORMAT = 'g:i:s A' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd M Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/en/__init__.py b/django/conf/locale/en/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/en/formats.py b/django/conf/locale/en/formats.py new file mode 100644 index 0000000000..3a507cd27e --- /dev/null +++ b/django/conf/locale/en/formats.py @@ -0,0 +1,38 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +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' +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' +) +DATETIME_INPUT_FORMATS = ( + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' + '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' + '%m/%d/%Y %H:%M', # '10/25/2006 14:30' + '%m/%d/%Y', # '10/25/2006' + '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' + '%m/%d/%y %H:%M', # '10/25/06 14:30' + '%m/%d/%y', # '10/25/06' +) +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +NUMBER_GROUPING = 3 + diff --git a/django/conf/locale/es/__init__.py b/django/conf/locale/es/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/es/formats.py b/django/conf/locale/es/formats.py new file mode 100644 index 0000000000..349810f0fe --- /dev/null +++ b/django/conf/locale/es/formats.py @@ -0,0 +1,30 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j \de F \de Y' +TIME_FORMAT = 'H:i:s' +DATETIME_FORMAT = 'j \de F \de Y \a \l\a\s H:i' +YEAR_MONTH_FORMAT = 'F \de Y' +MONTH_DAY_FORMAT = 'j \de F' +SHORT_DATE_FORMAT = 'd/m/Y' +SHORT_DATETIME_FORMAT = 'd/m/Y H:i' +FIRST_DAY_OF_WEEK = 1 # Monday +DATE_INPUT_FORMATS = ( + # '31/12/2009', '31/12/09' + '%d/%m/%Y', '%d/%m/%y' +) +TIME_INPUT_FORMATS = ( + # '14:30:59', '14:30' + '%H:%M:%S', '%H:%M' +) +DATETIME_INPUT_FORMATS = ( + '%d/%m/%Y %H:%M:%S', + '%d/%m/%Y %H:%M', + '%d/%m/%y %H:%M:%S', + '%d/%m/%y %H:%M', +) +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +NUMBER_GROUPING = 3 + diff --git a/django/conf/locale/es_AR/__init__.py b/django/conf/locale/es_AR/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/es_AR/formats.py b/django/conf/locale/es_AR/formats.py new file mode 100644 index 0000000000..6d71786415 --- /dev/null +++ b/django/conf/locale/es_AR/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +# DATE_FORMAT = +# TIME_FORMAT = +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +# MONTH_DAY_FORMAT = +# SHORT_DATE_FORMAT = +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +# DECIMAL_SEPARATOR = +# THOUSAND_SEPARATOR = +# NUMBER_GROUPING = diff --git a/django/conf/locale/et/__init__.py b/django/conf/locale/et/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/et/formats.py b/django/conf/locale/et/formats.py new file mode 100644 index 0000000000..b96420c0c1 --- /dev/null +++ b/django/conf/locale/et/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'G:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd.m.Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/eu/__init__.py b/django/conf/locale/eu/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/eu/formats.py b/django/conf/locale/eu/formats.py new file mode 100644 index 0000000000..475f924fe8 --- /dev/null +++ b/django/conf/locale/eu/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'Yeko M\re\n d\a' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +# MONTH_DAY_FORMAT = +SHORT_DATE_FORMAT = 'Y M j' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/fa/__init__.py b/django/conf/locale/fa/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/fa/formats.py b/django/conf/locale/fa/formats.py new file mode 100644 index 0000000000..dc11281790 --- /dev/null +++ b/django/conf/locale/fa/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'G:i:s' +DATETIME_FORMAT = 'j F Y، ساعت G:i:s' +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'Y/n/j' +SHORT_DATETIME_FORMAT = 'Y/n/j،‏ G:i:s' +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/fi/__init__.py b/django/conf/locale/fi/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/fi/formats.py b/django/conf/locale/fi/formats.py new file mode 100644 index 0000000000..670e26841a --- /dev/null +++ b/django/conf/locale/fi/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y' +TIME_FORMAT = 'G.i.s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'j.n.Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/fr/__init__.py b/django/conf/locale/fr/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/fr/formats.py b/django/conf/locale/fr/formats.py new file mode 100644 index 0000000000..1d670d7f6a --- /dev/null +++ b/django/conf/locale/fr/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'H:i:s' +DATETIME_FORMAT = 'j F Y H:i:s' +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M Y' +SHORT_DATETIME_FORMAT = 'j M Y H:i:s' +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/ga/__init__.py b/django/conf/locale/ga/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ga/formats.py b/django/conf/locale/ga/formats.py new file mode 100644 index 0000000000..f177bb28d4 --- /dev/null +++ b/django/conf/locale/ga/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +# NUMBER_GROUPING = diff --git a/django/conf/locale/gl/__init__.py b/django/conf/locale/gl/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/gl/formats.py b/django/conf/locale/gl/formats.py new file mode 100644 index 0000000000..e0a95d5106 --- /dev/null +++ b/django/conf/locale/gl/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'd F Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M, Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/he/__init__.py b/django/conf/locale/he/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/he/formats.py b/django/conf/locale/he/formats.py new file mode 100644 index 0000000000..8d7c7f2a4a --- /dev/null +++ b/django/conf/locale/he/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j בF Y' +TIME_FORMAT = 'H:i:s' +DATETIME_FORMAT = 'j בF Y H:i:s' +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j בF' +SHORT_DATE_FORMAT = 'd/m/Y' +SHORT_DATETIME_FORMAT = 'd/m/Y H:i:s' +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +# NUMBER_GROUPING = diff --git a/django/conf/locale/hi/__init__.py b/django/conf/locale/hi/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/hi/formats.py b/django/conf/locale/hi/formats.py new file mode 100644 index 0000000000..6afa2581b9 --- /dev/null +++ b/django/conf/locale/hi/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'g:i:s A' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd-m-Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +# NUMBER_GROUPING = diff --git a/django/conf/locale/hr/__init__.py b/django/conf/locale/hr/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/hr/formats.py b/django/conf/locale/hr/formats.py new file mode 100644 index 0000000000..62d1a7edf5 --- /dev/null +++ b/django/conf/locale/hr/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y.' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y.' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'j.n.Y.' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/hu/__init__.py b/django/conf/locale/hu/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/hu/formats.py b/django/conf/locale/hu/formats.py new file mode 100644 index 0000000000..6ee2db0cd5 --- /dev/null +++ b/django/conf/locale/hu/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'Y. F j.' +TIME_FORMAT = 'G:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'F j.' +SHORT_DATE_FORMAT = 'Y.m.d.' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/is/__init__.py b/django/conf/locale/is/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/is/formats.py b/django/conf/locale/is/formats.py new file mode 100644 index 0000000000..b6377db40b --- /dev/null +++ b/django/conf/locale/is/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'j.n.Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/it/__init__.py b/django/conf/locale/it/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/it/formats.py b/django/conf/locale/it/formats.py new file mode 100644 index 0000000000..fe86b5bd70 --- /dev/null +++ b/django/conf/locale/it/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'd F Y' +TIME_FORMAT = 'H.i.s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd/M/Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/ja/__init__.py b/django/conf/locale/ja/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ja/formats.py b/django/conf/locale/ja/formats.py new file mode 100644 index 0000000000..853056d8da --- /dev/null +++ b/django/conf/locale/ja/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'Y年n月j日' +TIME_FORMAT = 'G:i:s' +DATETIME_FORMAT = 'Y年n月j日G:i:s' +YEAR_MONTH_FORMAT = 'Y年n月' +MONTH_DAY_FORMAT = 'n月j日' +SHORT_DATE_FORMAT = 'Y/m/d' +SHORT_DATETIME_FORMAT = 'Y/m/d G:i:s' +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +# NUMBER_GROUPING = diff --git a/django/conf/locale/ka/__init__.py b/django/conf/locale/ka/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ka/formats.py b/django/conf/locale/ka/formats.py new file mode 100644 index 0000000000..665a73fcfc --- /dev/null +++ b/django/conf/locale/ka/formats.py @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'l, j F, Y' +TIME_FORMAT = 'h:i:s a' +DATETIME_FORMAT = 'j F, Y h:i:s a' +YEAR_MONTH_FORMAT = 'F, Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j.M.Y' +SHORT_DATETIME_FORMAT = 'j.M.Y H:i:s' +FIRST_DAY_OF_WEEK = 1 # (Monday) +DATE_INPUT_FORMATS = ( + '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06' + '%d %b %Y', '%d %b, %Y', '%d %b. %Y', # '25 Oct 2006', '25 Oct, 2006', '25 Oct. 2006' + '%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006' + '%d.%m.%Y', '%d.%m.%y', # '25.10.2006', '25.10.06' +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' +) +DATETIME_INPUT_FORMATS = ( + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' + '%d.%m.%Y %H:%M:%S', # '25.10.2006 14:30:59' + '%d.%m.%Y %H:%M', # '25.10.2006 14:30' + '%d.%m.%Y', # '25.10.2006' + '%d.%m.%y %H:%M:%S', # '25.10.06 14:30:59' + '%d.%m.%y %H:%M', # '25.10.06 14:30' + '%d.%m.%y', # '25.10.06' + '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' + '%m/%d/%Y %H:%M', # '10/25/2006 14:30' + '%m/%d/%Y', # '10/25/2006' + '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' + '%m/%d/%y %H:%M', # '10/25/06 14:30' + '%m/%d/%y', # '10/25/06' +) +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = " " +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/km/__init__.py b/django/conf/locale/km/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/km/formats.py b/django/conf/locale/km/formats.py new file mode 100644 index 0000000000..3736d574fb --- /dev/null +++ b/django/conf/locale/km/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j ខែ F ឆ្នាំ Y' +TIME_FORMAT = 'G:i:s' +DATETIME_FORMAT = 'j ខែ F ឆ្នាំ Y, G:i:s' +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M Y' +SHORT_DATETIME_FORMAT = 'j M Y, G:i:s' +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/kn/__init__.py b/django/conf/locale/kn/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/kn/formats.py b/django/conf/locale/kn/formats.py new file mode 100644 index 0000000000..fa7a7b9546 --- /dev/null +++ b/django/conf/locale/kn/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'h:i:s A' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +# DECIMAL_SEPARATOR = +# THOUSAND_SEPARATOR = +# NUMBER_GROUPING = diff --git a/django/conf/locale/ko/__init__.py b/django/conf/locale/ko/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ko/formats.py b/django/conf/locale/ko/formats.py new file mode 100644 index 0000000000..619047dae0 --- /dev/null +++ b/django/conf/locale/ko/formats.py @@ -0,0 +1,44 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'Y년 n월 j일' +TIME_FORMAT = 'A g:i:s' +DATETIME_FORMAT = 'Y년 n월 j일 g:i:s A' +YEAR_MONTH_FORMAT = 'Y년 F월' +MONTH_DAY_FORMAT = 'F월 j일' +SHORT_DATE_FORMAT = 'Y-n-j.' +SHORT_DATETIME_FORMAT = 'Y-n-j H:i' +# FIRST_DAY_OF_WEEK = +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' + '%Y년 %m월 %d일', # '2006년 10월 25일', with localized suffix. +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' + '%H시 %M분 %S초', # '14시 30분 59초' + '%H시 %M분', # '14시 30분' +) +DATETIME_INPUT_FORMATS = ( + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' + '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' + '%m/%d/%Y %H:%M', # '10/25/2006 14:30' + '%m/%d/%Y', # '10/25/2006' + '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' + '%m/%d/%y %H:%M', # '10/25/06 14:30' + '%m/%d/%y', # '10/25/06' + + '%Y년 %m월 %d일 %H시 %M분 %S초', # '2006년 10월 25일 14시 30분 59초' + '%Y년 %m월 %d일 %H시 %M분', # '2006년 10월 25일 14시 30분' +) + +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/lt/__init__.py b/django/conf/locale/lt/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/lt/formats.py b/django/conf/locale/lt/formats.py new file mode 100644 index 0000000000..d9fb0c86f7 --- /dev/null +++ b/django/conf/locale/lt/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'Y \m. F j \d.' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +# MONTH_DAY_FORMAT = +SHORT_DATE_FORMAT = 'Y.m.d' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/lv/__init__.py b/django/conf/locale/lv/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/lv/formats.py b/django/conf/locale/lv/formats.py new file mode 100644 index 0000000000..5dc211cfc0 --- /dev/null +++ b/django/conf/locale/lv/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'Y. \g\a\d\a j. F' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'Y. \g. F' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'Y. \g\a\d\a j. M' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/mk/__init__.py b/django/conf/locale/mk/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/mk/formats.py b/django/conf/locale/mk/formats.py new file mode 100644 index 0000000000..746ac0ea9f --- /dev/null +++ b/django/conf/locale/mk/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'd F Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +# MONTH_DAY_FORMAT = +SHORT_DATE_FORMAT = 'd.n.Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/nl/__init__.py b/django/conf/locale/nl/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/nl/formats.py b/django/conf/locale/nl/formats.py new file mode 100644 index 0000000000..dcef8c1eb7 --- /dev/null +++ b/django/conf/locale/nl/formats.py @@ -0,0 +1,48 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' # '20 januari 2009' +TIME_FORMAT = 'H:i' # '15:23' +DATETIME_FORMAT = 'j F Y H:i' # '20 januari 2009 15:23' +YEAR_MONTH_FORMAT = 'F Y' # 'januari 2009' +MONTH_DAY_FORMAT = 'j F' # '20 januari' +SHORT_DATE_FORMAT = 'j-n-Y' # '20-1-2009' +SHORT_DATETIME_FORMAT = 'j-n-Y H:i' # '20-1-2009 15:23' +FIRST_DAY_OF_WEEK = 1 # Monday (in Dutch 'maandag') +DATE_INPUT_FORMATS = ( + '%d-%m-%Y', '%d-%m-%y', '%Y-%m-%d', # '20-01-2009', '20-01-09', '2009-01-20' + '%d %b %Y', '%d %b %y', # '20 jan 2009', '20 jan 09' + '%d %B %Y', '%d %B %y', # '20 januari 2009', '20 januari 09' +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '15:23:35' + '%H.%M:%S', # '15.23:35' + '%H.%M', # '15.23' + '%H:%M', # '15:23' +) +DATETIME_INPUT_FORMATS = ( + # With time in %H:%M:%S : + '%d-%m-%Y %H:%M:%S', '%d-%m-%y %H:%M:%S', '%Y-%m-%d %H:%M:%S', # '20-01-2009 15:23:35', '20-01-09 15:23:35', '2009-01-20 15:23:35' + '%d %b %Y %H:%M:%S', '%d %b %y %H:%M:%S', # '20 jan 2009 15:23:35', '20 jan 09 15:23:35' + '%d %B %Y %H:%M:%S', '%d %B %y %H:%M:%S', # '20 januari 2009 15:23:35', '20 januari 2009 15:23:35' + # With time in %H.%M:%S : + '%d-%m-%Y %H.%M:%S', '%d-%m-%y %H.%M:%S', # '20-01-2009 15.23:35', '20-01-09 15.23:35' + '%d %b %Y %H.%M:%S', '%d %b %y %H.%M:%S', # '20 jan 2009 15.23:35', '20 jan 09 15.23:35' + '%d %B %Y %H.%M:%S', '%d %B %y %H.%M:%S', # '20 januari 2009 15.23:35', '20 januari 2009 15.23:35' + # With time in %H:%M : + '%d-%m-%Y %H:%M', '%d-%m-%y %H:%M', '%Y-%m-%d %H:%M', # '20-01-2009 15:23', '20-01-09 15:23', '2009-01-20 15:23' + '%d %b %Y %H:%M', '%d %b %y %H:%M', # '20 jan 2009 15:23', '20 jan 09 15:23' + '%d %B %Y %H:%M', '%d %B %y %H:%M', # '20 januari 2009 15:23', '20 januari 2009 15:23' + # With time in %H.%M : + '%d-%m-%Y %H.%M', '%d-%m-%y %H.%M', # '20-01-2009 15.23', '20-01-09 15.23' + '%d %b %Y %H.%M', '%d %b %y %H.%M', # '20 jan 2009 15.23', '20 jan 09 15.23' + '%d %B %Y %H.%M', '%d %B %y %H.%M', # '20 januari 2009 15.23', '20 januari 2009 15.23' + # Without time : + '%d-%m-%Y', '%d-%m-%y', '%Y-%m-%d', # '20-01-2009', '20-01-09', '2009-01-20' + '%d %b %Y', '%d %b %y', # '20 jan 2009', '20 jan 09' + '%d %B %Y', '%d %B %y', # '20 januari 2009', '20 januari 2009' +) +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/no/__init__.py b/django/conf/locale/no/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/no/formats.py b/django/conf/locale/no/formats.py new file mode 100644 index 0000000000..62ee886f11 --- /dev/null +++ b/django/conf/locale/no/formats.py @@ -0,0 +1,34 @@ +DATE_FORMAT = 'j. F Y' +TIME_FORMAT = 'H:i' +DATETIME_FORMAT = 'j. F Y H:i' +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'd.m.Y' +SHORT_DATETIME_FORMAT = 'd.m.Y H:i' +FIRST_DAY_OF_WEEK = 1 # Monday +DATE_INPUT_FORMATS = ( + '%Y-%m-%d', '%j.%m.%Y', '%j.%m.%y', # '2006-10-25', '25.10.2006', '25.10.06' + '%Y-%m-%j', # '2006-10-25', + '%j. %b %Y', '%j %b %Y', # '25. okt 2006', '25 okt 2006' + '%j. %b. %Y', '%j %b. %Y', # '25. okt. 2006', '25 okt. 2006' + '%j. %B %Y', '%j %B %Y', # '25. oktober 2006', '25 oktober 2006' +) +TIME_INPUT_FORMATS = ( + '%H:%i:%S', # '14:30:59' + '%H:%i', # '14:30' +) +DATETIME_INPUT_FORMATS = ( + '%Y-%m-%d %H:%i:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%i', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' + '%Y-%m-%j', # '2006-10-25' + '%j.%m.%Y %H:%i:%S', # '25.10.2006 14:30:59' + '%j.%m.%Y %H:%i', # '25.10.2006 14:30' + '%j.%m.%Y', # '25.10.2006' + '%j.%m.%y %H:%i:%S', # '25.10.06 14:30:59' + '%j.%m.%y %H:%i', # '25.10.06 14:30' + '%j.%m.%y', # '25.10.06' +) +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/pl/__init__.py b/django/conf/locale/pl/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/pl/formats.py b/django/conf/locale/pl/formats.py new file mode 100644 index 0000000000..860a4a88ca --- /dev/null +++ b/django/conf/locale/pl/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd-m-Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/pt/__init__.py b/django/conf/locale/pt/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/pt/formats.py b/django/conf/locale/pt/formats.py new file mode 100644 index 0000000000..053a48af53 --- /dev/null +++ b/django/conf/locale/pt/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j \de F \de Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F \de Y' +MONTH_DAY_FORMAT = 'j \de F' +SHORT_DATE_FORMAT = 'd/m/Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/pt_BR/__init__.py b/django/conf/locale/pt_BR/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/pt_BR/formats.py b/django/conf/locale/pt_BR/formats.py new file mode 100644 index 0000000000..f30d5c4dfc --- /dev/null +++ b/django/conf/locale/pt_BR/formats.py @@ -0,0 +1,35 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j \\de N \\de Y' +TIME_FORMAT = 'H:i' +DATETIME_FORMAT = 'j \\de N \\de Y à\\s H:i' +YEAR_MONTH_FORMAT = 'F \\de Y' +MONTH_DAY_FORMAT = 'j \\de F' +SHORT_DATE_FORMAT = 'd/m/Y' +SHORT_DATETIME_FORMAT = 'd/m/Y H:i' +FIRST_DAY_OF_WEEK = 0 # Sunday +DATE_INPUT_FORMATS = ( + '%Y-%m-%d', '%d/%m/%Y', '%d/%m/%y', # '2006-10-25', '25/10/2006', '25/10/06' + '%d de %b de %Y', '%d de %b, %Y', # '25 de Out de 2006', '25 Out, 2006' + '%d de %B de %Y', '%d de %B, %Y', # '25 de Outubro de 2006', '25 de Outubro, 2006' +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' +) +DATETIME_INPUT_FORMATS = ( + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' + '%d/%m/%Y %H:%M:%S', # '25/10/2006 14:30:59' + '%d/%m/%Y %H:%M', # '25/10/2006 14:30' + '%d/%m/%Y', # '25/10/2006' + '%d/%m/%y %H:%M:%S', # '25/10/06 14:30:59' + '%d/%m/%y %H:%M', # '25/10/06 14:30' + '%d/%m/%y', # '25/10/06' +) +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/ro/__init__.py b/django/conf/locale/ro/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ro/formats.py b/django/conf/locale/ro/formats.py new file mode 100644 index 0000000000..6d6e800467 --- /dev/null +++ b/django/conf/locale/ro/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'H:i:s' +DATETIME_FORMAT = 'j F Y, H:i:s' +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd.m.Y' +SHORT_DATETIME_FORMAT = 'd.m.Y, H:i:s' +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/ru/__init__.py b/django/conf/locale/ru/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ru/formats.py b/django/conf/locale/ru/formats.py new file mode 100644 index 0000000000..9a9ee96561 --- /dev/null +++ b/django/conf/locale/ru/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y г.' +TIME_FORMAT = 'G:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'd.m.Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/sk/__init__.py b/django/conf/locale/sk/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/sk/formats.py b/django/conf/locale/sk/formats.py new file mode 100644 index 0000000000..1bc3549dcf --- /dev/null +++ b/django/conf/locale/sk/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y' +TIME_FORMAT = 'G:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'j.n.Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/sl/__init__.py b/django/conf/locale/sl/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/sl/formats.py b/django/conf/locale/sl/formats.py new file mode 100644 index 0000000000..4007f10707 --- /dev/null +++ b/django/conf/locale/sl/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'd. F Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'j. M. Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/sr/__init__.py b/django/conf/locale/sr/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/sr/formats.py b/django/conf/locale/sr/formats.py new file mode 100644 index 0000000000..6dc19cf788 --- /dev/null +++ b/django/conf/locale/sr/formats.py @@ -0,0 +1,44 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y.' +TIME_FORMAT = 'H:i' +DATETIME_FORMAT = 'j. F Y. H:i' +YEAR_MONTH_FORMAT = 'F Y.' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'j.m.Y.' +SHORT_DATETIME_FORMAT = 'j.m.Y. H:i' +FIRST_DAY_OF_WEEK = 1 +DATE_INPUT_FORMATS = ( + '%Y-%m-%d', # '2006-10-25' + '%d.%m.%Y.', '%d.%m.%y.', # '25.10.2006.', '25.10.06.' + '%d. %m. %Y.', '%d. %m. %y.', # '25. 10. 2006.', '25. 10. 06.' + '%d. %b %y.', '%d. %B %y.', # '25. Oct 06.', '25. October 06.' + '%d. %b \'%y.', '%d. %B \'%y.', # '25. Oct '06.', '25. October '06.' + '%d. %b %Y.', '%d. %B %Y.', # '25. Oct 2006.', '25. October 2006.' +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' +) +DATETIME_INPUT_FORMATS = ( + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' + '%d.%m.%Y. %H:%M:%S', # '25.10.2006. 14:30:59' + '%d.%m.%Y. %H:%M', # '25.10.2006. 14:30' + '%d.%m.%Y.', # '25.10.2006.' + '%d.%m.%y. %H:%M:%S', # '25.10.06. 14:30:59' + '%d.%m.%y. %H:%M', # '25.10.06. 14:30' + '%d.%m.%y.', # '25.10.06.' + '%d. %m. %Y. %H:%M:%S', # '25. 10. 2006. 14:30:59' + '%d. %m. %Y. %H:%M', # '25. 10. 2006. 14:30' + '%d. %m. %Y.', # '25. 10. 2006.' + '%d. %m. %y. %H:%M:%S', # '25. 10. 06. 14:30:59' + '%d. %m. %y. %H:%M', # '25. 10. 06. 14:30' + '%d. %m. %y.', # '25. 10. 06.' +) +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/sr_Latn/__init__.py b/django/conf/locale/sr_Latn/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/sr_Latn/formats.py b/django/conf/locale/sr_Latn/formats.py new file mode 100644 index 0000000000..6dc19cf788 --- /dev/null +++ b/django/conf/locale/sr_Latn/formats.py @@ -0,0 +1,44 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j. F Y.' +TIME_FORMAT = 'H:i' +DATETIME_FORMAT = 'j. F Y. H:i' +YEAR_MONTH_FORMAT = 'F Y.' +MONTH_DAY_FORMAT = 'j. F' +SHORT_DATE_FORMAT = 'j.m.Y.' +SHORT_DATETIME_FORMAT = 'j.m.Y. H:i' +FIRST_DAY_OF_WEEK = 1 +DATE_INPUT_FORMATS = ( + '%Y-%m-%d', # '2006-10-25' + '%d.%m.%Y.', '%d.%m.%y.', # '25.10.2006.', '25.10.06.' + '%d. %m. %Y.', '%d. %m. %y.', # '25. 10. 2006.', '25. 10. 06.' + '%d. %b %y.', '%d. %B %y.', # '25. Oct 06.', '25. October 06.' + '%d. %b \'%y.', '%d. %B \'%y.', # '25. Oct '06.', '25. October '06.' + '%d. %b %Y.', '%d. %B %Y.', # '25. Oct 2006.', '25. October 2006.' +) +TIME_INPUT_FORMATS = ( + '%H:%M:%S', # '14:30:59' + '%H:%M', # '14:30' +) +DATETIME_INPUT_FORMATS = ( + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' + '%Y-%m-%d', # '2006-10-25' + '%d.%m.%Y. %H:%M:%S', # '25.10.2006. 14:30:59' + '%d.%m.%Y. %H:%M', # '25.10.2006. 14:30' + '%d.%m.%Y.', # '25.10.2006.' + '%d.%m.%y. %H:%M:%S', # '25.10.06. 14:30:59' + '%d.%m.%y. %H:%M', # '25.10.06. 14:30' + '%d.%m.%y.', # '25.10.06.' + '%d. %m. %Y. %H:%M:%S', # '25. 10. 2006. 14:30:59' + '%d. %m. %Y. %H:%M', # '25. 10. 2006. 14:30' + '%d. %m. %Y.', # '25. 10. 2006.' + '%d. %m. %y. %H:%M:%S', # '25. 10. 06. 14:30:59' + '%d. %m. %y. %H:%M', # '25. 10. 06. 14:30' + '%d. %m. %y.', # '25. 10. 06.' +) +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +NUMBER_GROUPING = 3 diff --git a/django/conf/locale/sv/__init__.py b/django/conf/locale/sv/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/sv/formats.py b/django/conf/locale/sv/formats.py new file mode 100644 index 0000000000..df4e633562 --- /dev/null +++ b/django/conf/locale/sv/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'H.i.s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'Y F' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/ta/__init__.py b/django/conf/locale/ta/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/ta/formats.py b/django/conf/locale/ta/formats.py new file mode 100644 index 0000000000..69fa17df33 --- /dev/null +++ b/django/conf/locale/ta/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F, Y' +TIME_FORMAT = 'g:i:s A' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M, Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +# DECIMAL_SEPARATOR = +# THOUSAND_SEPARATOR = +# NUMBER_GROUPING = diff --git a/django/conf/locale/te/__init__.py b/django/conf/locale/te/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/te/formats.py b/django/conf/locale/te/formats.py new file mode 100644 index 0000000000..e805872d52 --- /dev/null +++ b/django/conf/locale/te/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'g:i:s A' +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +# DECIMAL_SEPARATOR = +# THOUSAND_SEPARATOR = +# NUMBER_GROUPING = diff --git a/django/conf/locale/th/__init__.py b/django/conf/locale/th/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/th/formats.py b/django/conf/locale/th/formats.py new file mode 100644 index 0000000000..7091dc6b98 --- /dev/null +++ b/django/conf/locale/th/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y' +TIME_FORMAT = 'G:i:s' +DATETIME_FORMAT = 'j F Y, G:i:s' +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M Y' +SHORT_DATETIME_FORMAT = 'j M Y, G:i:s' +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = '.' +THOUSAND_SEPARATOR = ',' +# NUMBER_GROUPING = diff --git a/django/conf/locale/tr/__init__.py b/django/conf/locale/tr/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/tr/formats.py b/django/conf/locale/tr/formats.py new file mode 100644 index 0000000000..b97878865b --- /dev/null +++ b/django/conf/locale/tr/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'd F Y' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'd F' +SHORT_DATE_FORMAT = 'd M Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = '.' +# NUMBER_GROUPING = diff --git a/django/conf/locale/uk/__init__.py b/django/conf/locale/uk/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/uk/formats.py b/django/conf/locale/uk/formats.py new file mode 100644 index 0000000000..8e41bf020d --- /dev/null +++ b/django/conf/locale/uk/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +DATE_FORMAT = 'j F Y р.' +TIME_FORMAT = 'H:i:s' +# DATETIME_FORMAT = +YEAR_MONTH_FORMAT = 'F Y' +MONTH_DAY_FORMAT = 'j F' +SHORT_DATE_FORMAT = 'j M Y' +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +DECIMAL_SEPARATOR = ',' +THOUSAND_SEPARATOR = ' ' +# NUMBER_GROUPING = diff --git a/django/conf/locale/zh_CN/__init__.py b/django/conf/locale/zh_CN/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/zh_CN/formats.py b/django/conf/locale/zh_CN/formats.py new file mode 100644 index 0000000000..6d71786415 --- /dev/null +++ b/django/conf/locale/zh_CN/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +# DATE_FORMAT = +# TIME_FORMAT = +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +# MONTH_DAY_FORMAT = +# SHORT_DATE_FORMAT = +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +# DECIMAL_SEPARATOR = +# THOUSAND_SEPARATOR = +# NUMBER_GROUPING = diff --git a/django/conf/locale/zh_TW/__init__.py b/django/conf/locale/zh_TW/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/conf/locale/zh_TW/formats.py b/django/conf/locale/zh_TW/formats.py new file mode 100644 index 0000000000..6d71786415 --- /dev/null +++ b/django/conf/locale/zh_TW/formats.py @@ -0,0 +1,18 @@ +# -*- encoding: utf-8 -*- +# This file is distributed under the same license as the Django package. +# + +# DATE_FORMAT = +# TIME_FORMAT = +# DATETIME_FORMAT = +# YEAR_MONTH_FORMAT = +# MONTH_DAY_FORMAT = +# SHORT_DATE_FORMAT = +# SHORT_DATETIME_FORMAT = +# FIRST_DAY_OF_WEEK = +# DATE_INPUT_FORMATS = +# TIME_INPUT_FORMATS = +# DATETIME_INPUT_FORMATS = +# DECIMAL_SEPARATOR = +# THOUSAND_SEPARATOR = +# NUMBER_GROUPING = diff --git a/django/contrib/admin/media/js/calendar.js b/django/contrib/admin/media/js/calendar.js index 90351763a7..3f57145041 100644 --- a/django/contrib/admin/media/js/calendar.js +++ b/django/contrib/admin/media/js/calendar.js @@ -25,6 +25,7 @@ function quickElement() { var CalendarNamespace = { monthsOfYear: gettext('January February March April May June July August September October November December').split(' '), daysOfWeek: gettext('S M T W T F S').split(' '), + firstDayOfWeek: parseInt(gettext('FIRST_DAY_OF_WEEK')), isLeapYear: function(year) { return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0)); }, @@ -56,10 +57,10 @@ var CalendarNamespace = { // Draw days-of-week header var tableRow = quickElement('tr', tableBody); for (var i = 0; i < 7; i++) { - quickElement('th', tableRow, CalendarNamespace.daysOfWeek[i]); + quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]); } - var startingPos = new Date(year, month-1, 1).getDay(); + var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); var days = CalendarNamespace.getDaysInMonth(month, year); // Draw blanks before first of month diff --git a/django/contrib/admin/templates/admin/object_history.html b/django/contrib/admin/templates/admin/object_history.html index 38b1c34ac8..9e6223acb9 100644 --- a/django/contrib/admin/templates/admin/object_history.html +++ b/django/contrib/admin/templates/admin/object_history.html @@ -27,7 +27,7 @@ {% for action in action_list %} - {{ action.action_time|date:_("DATETIME_FORMAT") }} + {{ action.action_time|date }} {{ action.user.username }}{% if action.user.get_full_name %} ({{ action.user.get_full_name }}){% endif %} {{ action.change_message }} diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index 5a02ab01be..cd05957197 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -3,11 +3,11 @@ from django.contrib.admin.views.main import ALL_VAR, EMPTY_CHANGELIST_VALUE from django.contrib.admin.views.main import ORDER_VAR, ORDER_TYPE_VAR, PAGE_VAR, SEARCH_VAR from django.core.exceptions import ObjectDoesNotExist from django.db import models -from django.utils import dateformat +from django.utils import formats from django.utils.html import escape, conditional_escape from django.utils.text import capfirst from django.utils.safestring import mark_safe -from django.utils.translation import get_date_formats, get_partial_date_formats, ugettext as _ +from django.utils.translation import ugettext as _ from django.utils.encoding import smart_unicode, smart_str, force_unicode from django.template import Library import datetime @@ -189,25 +189,24 @@ def items_for_result(cl, result, form): # Dates and times are special: They're formatted in a certain way. elif isinstance(f, models.DateField) or isinstance(f, models.TimeField): if field_val: - (date_format, datetime_format, time_format) = get_date_formats() - if isinstance(f, models.DateTimeField): - result_repr = capfirst(dateformat.format(field_val, datetime_format)) - elif isinstance(f, models.TimeField): - result_repr = capfirst(dateformat.time_format(field_val, time_format)) - else: - result_repr = capfirst(dateformat.format(field_val, date_format)) + result_repr = formats.localize(field_val) + else: + result_repr = EMPTY_CHANGELIST_VALUE + elif isinstance(f, models.DecimalField): + if field_val: + result_repr = formats.number_format(field_val, f.decimal_places) + else: + result_repr = EMPTY_CHANGELIST_VALUE + row_class = ' class="nowrap"' + elif isinstance(f, models.FloatField): + if field_val: + result_repr = formats.number_format(field_val) else: result_repr = EMPTY_CHANGELIST_VALUE row_class = ' class="nowrap"' # Booleans are special: We use images. elif isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField): result_repr = _boolean_icon(field_val) - # DecimalFields are special: Zero-pad the decimals. - elif isinstance(f, models.DecimalField): - if field_val is not None: - result_repr = ('%%.%sf' % f.decimal_places) % field_val - else: - result_repr = EMPTY_CHANGELIST_VALUE # Fields with choices are special: Use the representation # of the choice. elif f.flatchoices: @@ -268,7 +267,6 @@ def date_hierarchy(cl): year_lookup = cl.params.get(year_field) month_lookup = cl.params.get(month_field) day_lookup = cl.params.get(day_field) - year_month_format, month_day_format = get_partial_date_formats() link = lambda d: cl.get_query_string(d, [field_generic]) @@ -278,9 +276,9 @@ def date_hierarchy(cl): 'show': True, 'back': { 'link': link({year_field: year_lookup, month_field: month_lookup}), - 'title': dateformat.format(day, year_month_format) + 'title': capfirst(formats.date_format(day, 'YEAR_MONTH_FORMAT')) }, - 'choices': [{'title': dateformat.format(day, month_day_format)}] + 'choices': [{'title': capfirst(formats.date_format(day, 'MONTH_DAY_FORMAT'))}] } elif year_lookup and month_lookup: days = cl.query_set.filter(**{year_field: year_lookup, month_field: month_lookup}).dates(field_name, 'day') @@ -292,7 +290,7 @@ def date_hierarchy(cl): }, 'choices': [{ 'link': link({year_field: year_lookup, month_field: month_lookup, day_field: day.day}), - 'title': dateformat.format(day, month_day_format) + 'title': capfirst(formats.date_format(day, 'MONTH_DAY_FORMAT')) } for day in days] } elif year_lookup: @@ -305,7 +303,7 @@ def date_hierarchy(cl): }, 'choices': [{ 'link': link({year_field: year_lookup, month_field: month.month}), - 'title': dateformat.format(month, year_month_format) + 'title': capfirst(formats.date_format(month, 'YEAR_MONTH_FORMAT')) } for month in months] } else: diff --git a/django/contrib/databrowse/datastructures.py b/django/contrib/databrowse/datastructures.py index 5fdbdbe134..369f825f0e 100644 --- a/django/contrib/databrowse/datastructures.py +++ b/django/contrib/databrowse/datastructures.py @@ -4,9 +4,8 @@ convenience functionality and permalink functions for the databrowse app. """ from django.db import models -from django.utils import dateformat +from django.utils import formats from django.utils.text import capfirst -from django.utils.translation import get_date_formats from django.utils.encoding import smart_unicode, smart_str, iri_to_uri from django.utils.safestring import mark_safe from django.db.models.query import QuerySet @@ -156,13 +155,12 @@ class EasyInstanceField(object): objs = dict(self.field.choices).get(self.raw_value, EMPTY_VALUE) elif isinstance(self.field, models.DateField) or isinstance(self.field, models.TimeField): if self.raw_value: - date_format, datetime_format, time_format = get_date_formats() if isinstance(self.field, models.DateTimeField): - objs = capfirst(dateformat.format(self.raw_value, datetime_format)) + objs = capfirst(formats.date_format(self.raw_value, 'DATETIME_FORMAT')) elif isinstance(self.field, models.TimeField): - objs = capfirst(dateformat.time_format(self.raw_value, time_format)) + objs = capfirst(formats.date_format(self.raw_value, 'TIME_FORMAT')) else: - objs = capfirst(dateformat.format(self.raw_value, date_format)) + objs = capfirst(formats.date_format(self.raw_value, 'DATE_FORMAT')) else: objs = EMPTY_VALUE elif isinstance(self.field, models.BooleanField) or isinstance(self.field, models.NullBooleanField): diff --git a/django/forms/extras/widgets.py b/django/forms/extras/widgets.py index e36b8a1d67..173ef2e1de 100644 --- a/django/forms/extras/widgets.py +++ b/django/forms/extras/widgets.py @@ -8,6 +8,8 @@ import re from django.forms.widgets import Widget, Select from django.utils.dates import MONTHS from django.utils.safestring import mark_safe +from django.utils.formats import get_format +from django.conf import settings __all__ = ('SelectDateWidget',) @@ -45,38 +47,27 @@ class SelectDateWidget(Widget): if match: year_val, month_val, day_val = [int(v) for v in match.groups()] + choices = [(i, i) for i in self.years] + year_html = self.create_select(name, self.year_field, value, year_val, choices) + choices = MONTHS.items() + month_html = self.create_select(name, self.month_field, value, month_val, choices) + choices = [(i, i) for i in range(1, 32)] + day_html = self.create_select(name, self.day_field, value, day_val, choices) + + format = get_format('DATE_FORMAT') + escaped = False output = [] - - if 'id' in self.attrs: - id_ = self.attrs['id'] - else: - id_ = 'id_%s' % name - - month_choices = MONTHS.items() - if not (self.required and value): - month_choices.append(self.none_value) - month_choices.sort() - local_attrs = self.build_attrs(id=self.month_field % id_) - s = Select(choices=month_choices) - select_html = s.render(self.month_field % name, month_val, local_attrs) - output.append(select_html) - - day_choices = [(i, i) for i in range(1, 32)] - if not (self.required and value): - day_choices.insert(0, self.none_value) - local_attrs['id'] = self.day_field % id_ - s = Select(choices=day_choices) - select_html = s.render(self.day_field % name, day_val, local_attrs) - output.append(select_html) - - year_choices = [(i, i) for i in self.years] - if not (self.required and value): - year_choices.insert(0, self.none_value) - local_attrs['id'] = self.year_field % id_ - s = Select(choices=year_choices) - select_html = s.render(self.year_field % name, year_val, local_attrs) - output.append(select_html) - + for char in format: + if escaped: + escaped = False + elif char == '\\': + escaped = True + elif char in 'Yy': + output.append(year_html) + elif char in 'bFMmNn': + output.append(month_html) + elif char in 'dj': + output.append(day_html) return mark_safe(u'\n'.join(output)) def id_for_label(self, id_): @@ -90,5 +81,27 @@ class SelectDateWidget(Widget): if y == m == d == "0": return None if y and m and d: - return '%s-%s-%s' % (y, m, d) + if settings.USE_L10N: + input_format = get_format('DATE_INPUT_FORMATS')[0] + try: + date_value = datetime.date(int(y), int(m), int(d)) + except ValueError: + pass + else: + return date_value.strftime(input_format) + else: + return '%s-%s-%s' % (y, m, d) return data.get(name, None) + + def create_select(self, name, field, value, val, choices): + if 'id' in self.attrs: + id_ = self.attrs['id'] + else: + id_ = 'id_%s' % name + if not (self.required and value): + choices.insert(0, self.none_value) + local_attrs = self.build_attrs(id=field % id_) + s = Select(choices=choices) + select_html = s.render(field % name, val, local_attrs) + return select_html + diff --git a/django/forms/fields.py b/django/forms/fields.py index c0ee2f0955..a4904d452d 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -7,6 +7,7 @@ import os import re import time import urlparse +import warnings from decimal import Decimal, DecimalException try: from cStringIO import StringIO @@ -17,6 +18,7 @@ import django.core.exceptions import django.utils.copycompat as copy from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import smart_unicode, smart_str +from django.utils.formats import get_format from util import ErrorList, ValidationError from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput, SplitDateTimeWidget, SplitHiddenDateTimeWidget @@ -36,6 +38,20 @@ __all__ = ( # These values, if given to to_python(), will trigger the self.required check. EMPTY_VALUES = (None, '') +def en_format(name): + """ + Helper function to stay backward compatible. + """ + from django.conf.locale.en import formats + warnings.warn( + "`django.forms.fields.DEFAULT_%s` is deprecated; use `django.utils.formats.get_format('%s')` instead." % (name, name), + PendingDeprecationWarning + ) + return getattr(formats, name) + +DEFAULT_DATE_INPUT_FORMATS = en_format('DATE_INPUT_FORMATS') +DEFAULT_TIME_INPUT_FORMATS = en_format('TIME_INPUT_FORMATS') +DEFAULT_DATETIME_INPUT_FORMATS = en_format('DATETIME_INPUT_FORMATS') class Field(object): widget = TextInput # Default widget to use when rendering this type of Field. @@ -200,7 +216,9 @@ class FloatField(Field): if not self.required and value in EMPTY_VALUES: return None try: - value = float(value) + # We always accept dot as decimal separator + if isinstance(value, str) or isinstance(value, unicode): + value = float(value.replace(get_format('DECIMAL_SEPARATOR'), '.')) except (ValueError, TypeError): raise ValidationError(self.error_messages['invalid']) if self.max_value is not None and value > self.max_value: @@ -236,7 +254,9 @@ class DecimalField(Field): return None value = smart_str(value).strip() try: - value = Decimal(value) + # We always accept dot as decimal separator + if isinstance(value, str) or isinstance(value, unicode): + value = Decimal(value.replace(get_format('DECIMAL_SEPARATOR'), '.')) except DecimalException: raise ValidationError(self.error_messages['invalid']) @@ -264,14 +284,6 @@ class DecimalField(Field): raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) return value -DEFAULT_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' -) - class DateField(Field): widget = DateInput default_error_messages = { @@ -280,7 +292,7 @@ class DateField(Field): def __init__(self, input_formats=None, *args, **kwargs): super(DateField, self).__init__(*args, **kwargs) - self.input_formats = input_formats or DEFAULT_DATE_INPUT_FORMATS + self.input_formats = input_formats def clean(self, value): """ @@ -294,18 +306,13 @@ class DateField(Field): return value.date() if isinstance(value, datetime.date): return value - for format in self.input_formats: + for format in self.input_formats or get_format('DATE_INPUT_FORMATS'): try: return datetime.date(*time.strptime(value, format)[:3]) except ValueError: continue raise ValidationError(self.error_messages['invalid']) -DEFAULT_TIME_INPUT_FORMATS = ( - '%H:%M:%S', # '14:30:59' - '%H:%M', # '14:30' -) - class TimeField(Field): widget = TimeInput default_error_messages = { @@ -314,7 +321,7 @@ class TimeField(Field): def __init__(self, input_formats=None, *args, **kwargs): super(TimeField, self).__init__(*args, **kwargs) - self.input_formats = input_formats or DEFAULT_TIME_INPUT_FORMATS + self.input_formats = input_formats def clean(self, value): """ @@ -326,25 +333,13 @@ class TimeField(Field): return None if isinstance(value, datetime.time): return value - for format in self.input_formats: + for format in self.input_formats or get_format('TIME_INPUT_FORMATS'): try: return datetime.time(*time.strptime(value, format)[3:6]) except ValueError: continue raise ValidationError(self.error_messages['invalid']) -DEFAULT_DATETIME_INPUT_FORMATS = ( - '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' - '%Y-%m-%d %H:%M', # '2006-10-25 14:30' - '%Y-%m-%d', # '2006-10-25' - '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' - '%m/%d/%Y %H:%M', # '10/25/2006 14:30' - '%m/%d/%Y', # '10/25/2006' - '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' - '%m/%d/%y %H:%M', # '10/25/06 14:30' - '%m/%d/%y', # '10/25/06' -) - class DateTimeField(Field): widget = DateTimeInput default_error_messages = { @@ -353,7 +348,7 @@ class DateTimeField(Field): def __init__(self, input_formats=None, *args, **kwargs): super(DateTimeField, self).__init__(*args, **kwargs) - self.input_formats = input_formats or DEFAULT_DATETIME_INPUT_FORMATS + self.input_formats = input_formats def clean(self, value): """ @@ -373,7 +368,7 @@ class DateTimeField(Field): if len(value) != 2: raise ValidationError(self.error_messages['invalid']) value = '%s %s' % tuple(value) - for format in self.input_formats: + for format in self.input_formats or get_format('DATETIME_INPUT_FORMATS'): try: return datetime.datetime(*time.strptime(value, format)[:6]) except ValueError: diff --git a/django/forms/widgets.py b/django/forms/widgets.py index d59e6343e5..aabd1b017d 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -10,6 +10,7 @@ from django.utils.html import escape, conditional_escape from django.utils.translation import ugettext from django.utils.encoding import StrAndUnicode, force_unicode from django.utils.safestring import mark_safe +from django.utils.formats import localize from django.utils import datetime_safe from datetime import time from util import flatatt @@ -208,7 +209,7 @@ class Input(Widget): final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) if value != '': # Only add the 'value' attribute if a value is non-empty. - final_attrs['value'] = force_unicode(value) + final_attrs['value'] = force_unicode(localize(value, is_input=True)) return mark_safe(u'' % flatatt(final_attrs)) class TextInput(Input): diff --git a/django/template/__init__.py b/django/template/__init__.py index 8764bfada4..4c386bea30 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -60,6 +60,7 @@ from django.utils.text import smart_split, unescape_string_literal from django.utils.encoding import smart_unicode, force_unicode, smart_str from django.utils.translation import ugettext as _ from django.utils.safestring import SafeData, EscapeData, mark_safe, mark_for_escaping +from django.utils.formats import localize from django.utils.html import escape __all__ = ('Template', 'Context', 'RequestContext', 'compile_string') @@ -815,6 +816,7 @@ def _render_value_in_context(value, context): means escaping, if required, and conversion to a unicode object. If value is a string, it is expected to have already been translated. """ + value = localize(value) value = force_unicode(value) if (context.autoescape and not isinstance(value, SafeData)) or isinstance(value, EscapeData): return escape(value) diff --git a/django/template/debug.py b/django/template/debug.py index c58c854858..382fb75ebd 100644 --- a/django/template/debug.py +++ b/django/template/debug.py @@ -2,6 +2,7 @@ from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, Templ from django.utils.encoding import force_unicode from django.utils.html import escape from django.utils.safestring import SafeData, EscapeData +from django.utils.formats import localize class DebugLexer(Lexer): def __init__(self, template_string, origin): @@ -84,7 +85,9 @@ class DebugNodeList(NodeList): class DebugVariableNode(VariableNode): def render(self, context): try: - output = force_unicode(self.filter_expression.resolve(context)) + output = self.filter_expression.resolve(context) + output = localize(output) + output = force_unicode(output) except TemplateSyntaxError, e: if not hasattr(e, 'source'): e.source = self.source diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index a8c25670f6..26b6b5ec4e 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -18,6 +18,7 @@ from django.conf import settings from django.utils.translation import ugettext, ungettext from django.utils.encoding import force_unicode, iri_to_uri from django.utils.safestring import mark_safe, SafeData +from django.utils.formats import date_format, number_format register = Library() @@ -166,14 +167,14 @@ def floatformat(text, arg=-1): return input_val if not m and p < 0: - return mark_safe(u'%d' % (int(d))) + return mark_safe(number_format(u'%d' % (int(d)), 0)) if p == 0: exp = Decimal(1) else: exp = Decimal('1.0') / (Decimal(10) ** abs(p)) try: - return mark_safe(u'%s' % str(d.quantize(exp, ROUND_HALF_UP))) + return mark_safe(number_format(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)), abs(p))) except InvalidOperation: return input_val floatformat.is_safe = True @@ -685,9 +686,12 @@ def date(value, arg=None): if arg is None: arg = settings.DATE_FORMAT try: - return format(value, arg) + return date_format(value, arg) except AttributeError: - return '' + try: + return format(value, arg) + except AttributeError: + return '' date.is_safe = False def time(value, arg=None): @@ -698,9 +702,12 @@ def time(value, arg=None): if arg is None: arg = settings.TIME_FORMAT try: - return time_format(value, arg) + return date_format(value, arg) except AttributeError: - return '' + try: + return time_format(value, arg) + except AttributeError: + return '' time.is_safe = False def timesince(value, arg=None): diff --git a/django/utils/formats.py b/django/utils/formats.py new file mode 100644 index 0000000000..e18e120b36 --- /dev/null +++ b/django/utils/formats.py @@ -0,0 +1,97 @@ +import decimal +import datetime + +from django.conf import settings +from django.utils.translation import get_language, to_locale, check_for_language +from django.utils.importlib import import_module +from django.utils import dateformat +from django.utils import numberformat + +def get_format_modules(): + """ + Returns an iterator over the format modules found in the project and Django + """ + modules = [] + if not check_for_language(get_language()): + return modules + locale = to_locale(get_language()) + if settings.FORMAT_MODULE_PATH: + format_locations = [settings.FORMAT_MODULE_PATH + '.%s'] + else: + format_locations = [] + format_locations.append('django.conf.locale.%s') + for location in format_locations: + for l in (locale, locale.split('_')[0]): + try: + mod = import_module('.formats', location % l) + except ImportError: + pass + else: + # Don't return duplicates + if mod not in modules: + modules.append(mod) + return modules + +def get_format(format_type): + """ + For a specific format type, returns the format for the current + language (locale), defaults to the format in the settings. + format_type is the name of the format, e.g. 'DATE_FORMAT' + """ + if settings.USE_L10N: + for module in get_format_modules(): + try: + return getattr(module, format_type) + except AttributeError: + pass + return getattr(settings, format_type) + +def date_format(value, format=None): + """ + Formats a datetime.date or datetime.datetime object using a + localizable format + """ + return dateformat.format(value, get_format(format or 'DATE_FORMAT')) + +def number_format(value, decimal_pos=None): + """ + Formats a numeric value using localization settings + """ + return numberformat.format( + value, + get_format('DECIMAL_SEPARATOR'), + decimal_pos, + get_format('NUMBER_GROUPING'), + get_format('THOUSAND_SEPARATOR'), + ) + +def localize(value, is_input=False): + """ + Checks value, and if it has a localizable type (date, + number...) it returns the value as a string using + current locale format + """ + if settings.USE_L10N: + if isinstance(value, decimal.Decimal): + return number_format(value) + elif isinstance(value, float): + return number_format(value) + elif isinstance(value, int): + return number_format(value) + elif isinstance(value, datetime.datetime): + if not is_input: + return date_format(value, 'DATETIME_FORMAT') + else: + return value.strftime(get_format('DATETIME_INPUT_FORMATS')[0]) + elif isinstance(value, datetime.date): + if not is_input: + return date_format(value) + else: + return value.strftime(get_format('DATE_INPUT_FORMATS')[0]) + elif isinstance(value, datetime.time): + if not is_input: + return date_format(value, 'TIME_FORMAT') + else: + return value.strftime(get_format('TIME_INPUT_FORMATS')[0]) + return value + diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py new file mode 100644 index 0000000000..78ecb2fbdb --- /dev/null +++ b/django/utils/numberformat.py @@ -0,0 +1,42 @@ +from django.conf import settings + +def format(number, decimal_sep, decimal_pos, grouping=0, thousand_sep=''): + """ + Gets a number (as a number or string), and returns it as a string, + using formats definied as arguments: + + * decimal_sep: Decimal separator symbol (for example ".") + * decimal_pos: Number of decimal positions + * grouping: Number of digits in every group limited by thousand separator + * thousand_sep: Thousand separator symbol (for example ",") + + """ + # sign + if float(number) < 0: + sign = '-' + else: + sign = '' + # decimal part + str_number = unicode(number) + if str_number[0] == '-': + str_number = str_number[1:] + if '.' in str_number: + int_part, dec_part = str_number.split('.') + if decimal_pos: + dec_part = dec_part[:decimal_pos] + else: + int_part, dec_part = str_number, '' + if decimal_pos: + dec_part = dec_part + ('0' * (decimal_pos - len(dec_part))) + if dec_part: dec_part = decimal_sep + dec_part + # grouping + if settings.USE_THOUSAND_SEPARATOR and grouping: + int_part_gd = '' + for cnt, digit in enumerate(int_part[::-1]): + if cnt and not cnt % grouping: + int_part_gd += thousand_sep + int_part_gd += digit + int_part = int_part_gd[::-1] + + return sign + int_part + dec_part + diff --git a/django/utils/translation/trans_null.py b/django/utils/translation/trans_null.py index 98c6de6197..50f41a2c23 100644 --- a/django/utils/translation/trans_null.py +++ b/django/utils/translation/trans_null.py @@ -2,6 +2,7 @@ # that don't actually do anything. This is purely for performance, so that # settings.USE_I18N = False can use this module rather than trans_real.py. +import warnings from django.conf import settings from django.utils.encoding import force_unicode from django.utils.safestring import mark_safe, SafeData @@ -18,10 +19,10 @@ activate = lambda x: None deactivate = deactivate_all = lambda: None get_language = lambda: settings.LANGUAGE_CODE get_language_bidi = lambda: settings.LANGUAGE_CODE in settings.LANGUAGES_BIDI -get_date_formats = lambda: (settings.DATE_FORMAT, settings.DATETIME_FORMAT, settings.TIME_FORMAT) -get_partial_date_formats = lambda: (settings.YEAR_MONTH_FORMAT, settings.MONTH_DAY_FORMAT) check_for_language = lambda x: True +# date formats shouldn't be used using gettext anymore. This +# is kept for backward compatibility TECHNICAL_ID_MAP = { "DATE_WITH_TIME_FULL": settings.DATETIME_FORMAT, "DATE_FORMAT": settings.DATE_FORMAT, @@ -51,3 +52,21 @@ def to_locale(language): def get_language_from_request(request): return settings.LANGUAGE_CODE + +# get_date_formats and get_partial_date_formats aren't used anymore by Django +# but are kept for backward compatibility. +def get_date_formats(): + warnings.warn( + '`django.utils.translation.get_date_formats` is deprecated. ' + 'Please update your code to use the new i18n aware formatting.', + PendingDeprecationWarning + ) + return settings.DATE_FORMAT, settings.DATETIME_FORMAT, settings.TIME_FORMAT + +def get_partial_date_formats(): + warnings.warn( + '`django.utils.translation.get_partial_date_formats` is deprecated. ' + 'Please update your code to use the new i18n aware formatting.', + PendingDeprecationWarning + ) + return settings.YEAR_MONTH_FORMAT, settings.MONTH_DAY_FORMAT diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index 48ed7cc885..8b7db0f123 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -4,6 +4,7 @@ import locale import os import re import sys +import warnings import gettext as gettext_module from cStringIO import StringIO @@ -266,15 +267,16 @@ def do_translate(message, translation_function): translation object to use. If no current translation is activated, the message will be run through the default translation object. """ + eol_message = message.replace('\r\n', '\n').replace('\r', '\n') global _default, _active t = _active.get(currentThread(), None) if t is not None: - result = getattr(t, translation_function)(message) + result = getattr(t, translation_function)(eol_message) else: if _default is None: from django.conf import settings _default = translation(settings.LANGUAGE_CODE) - result = getattr(_default, translation_function)(message) + result = getattr(_default, translation_function)(eol_message) if isinstance(message, SafeData): return mark_safe(result) return result @@ -389,39 +391,6 @@ def get_language_from_request(request): return settings.LANGUAGE_CODE -def get_date_formats(): - """ - Checks whether translation files provide a translation for some technical - message ID to store date and time formats. If it doesn't contain one, the - formats provided in the settings will be used. - """ - from django.conf import settings - date_format = ugettext('DATE_FORMAT') - datetime_format = ugettext('DATETIME_FORMAT') - time_format = ugettext('TIME_FORMAT') - if date_format == 'DATE_FORMAT': - date_format = settings.DATE_FORMAT - if datetime_format == 'DATETIME_FORMAT': - datetime_format = settings.DATETIME_FORMAT - if time_format == 'TIME_FORMAT': - time_format = settings.TIME_FORMAT - return date_format, datetime_format, time_format - -def get_partial_date_formats(): - """ - Checks whether translation files provide a translation for some technical - message ID to store partial date formats. If it doesn't contain one, the - formats provided in the settings will be used. - """ - from django.conf import settings - year_month_format = ugettext('YEAR_MONTH_FORMAT') - month_day_format = ugettext('MONTH_DAY_FORMAT') - if year_month_format == 'YEAR_MONTH_FORMAT': - year_month_format = settings.YEAR_MONTH_FORMAT - if month_day_format == 'MONTH_DAY_FORMAT': - month_day_format = settings.MONTH_DAY_FORMAT - return year_month_format, month_day_format - dot_re = re.compile(r'\S') def blankout(src, char): """ @@ -537,3 +506,52 @@ def parse_accept_lang_header(lang_string): result.append((lang, priority)) result.sort(lambda x, y: -cmp(x[1], y[1])) return result + +# get_date_formats and get_partial_date_formats aren't used anymore by Django +# and are kept for backward compatibility. +# Note, it's also important to keep format names marked for translation. +# For compatibility we still want to have formats on translation catalogs. +# That makes template code like {{ my_date|date:_('DATE_FORMAT') }} still work +def get_date_formats(): + """ + Checks whether translation files provide a translation for some technical + message ID to store date and time formats. If it doesn't contain one, the + formats provided in the settings will be used. + """ + warnings.warn( + '`django.utils.translation.get_date_formats` is deprecated. ' + 'Please update your code to use the new i18n aware formatting.', + PendingDeprecationWarning + ) + from django.conf import settings + date_format = ugettext('DATE_FORMAT') + datetime_format = ugettext('DATETIME_FORMAT') + time_format = ugettext('TIME_FORMAT') + if date_format == 'DATE_FORMAT': + date_format = settings.DATE_FORMAT + if datetime_format == 'DATETIME_FORMAT': + datetime_format = settings.DATETIME_FORMAT + if time_format == 'TIME_FORMAT': + time_format = settings.TIME_FORMAT + return date_format, datetime_format, time_format + +def get_partial_date_formats(): + """ + Checks whether translation files provide a translation for some technical + message ID to store partial date formats. If it doesn't contain one, the + formats provided in the settings will be used. + """ + warnings.warn( + '`django.utils.translation.get_partial_date_formats` is deprecated. ' + 'Please update your code to use the new i18n aware formatting.', + PendingDeprecationWarning + ) + from django.conf import settings + year_month_format = ugettext('YEAR_MONTH_FORMAT') + month_day_format = ugettext('MONTH_DAY_FORMAT') + if year_month_format == 'YEAR_MONTH_FORMAT': + year_month_format = settings.YEAR_MONTH_FORMAT + if month_day_format == 'MONTH_DAY_FORMAT': + month_day_format = settings.MONTH_DAY_FORMAT + return year_month_format, month_day_format + diff --git a/django/views/i18n.py b/django/views/i18n.py index 0280698aae..ddd75203a7 100644 --- a/django/views/i18n.py +++ b/django/views/i18n.py @@ -1,10 +1,12 @@ +import os +import gettext as gettext_module + from django import http from django.conf import settings from django.utils import importlib from django.utils.translation import check_for_language, activate, to_locale, get_language from django.utils.text import javascript_quote -import os -import gettext as gettext_module +from django.utils.formats import get_format_modules def set_language(request): """ @@ -32,6 +34,24 @@ def set_language(request): response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code) return response +def get_formats(): + """ + Returns an iterator over all formats in formats file + """ + FORMAT_SETTINGS = ('DATE_FORMAT', 'DATETIME_FORMAT', 'TIME_FORMAT', + 'YEAR_MONTH_FORMAT', 'MONTH_DAY_FORMAT', 'SHORT_DATE_FORMAT', + 'SHORT_DATETIME_FORMAT', 'FIRST_DAY_OF_WEEK', 'DECIMAL_SEPARATOR', + 'THOUSAND_SEPARATOR', 'NUMBER_GROUPING') + + result = {} + for module in [settings] + get_format_modules(): + for attr in FORMAT_SETTINGS: + try: + result[attr] = getattr(module, attr) + except AttributeError: + pass + return result + NullSource = """ /* gettext identity library */ @@ -185,10 +205,13 @@ def javascript_catalog(request, domain='djangojs', packages=None): else: raise TypeError, k csrc.sort() - for k,v in pdict.items(): + for k, v in pdict.items(): src.append("catalog['%s'] = [%s];\n" % (javascript_quote(k), ','.join(["''"]*(v+1)))) + for k, v in get_formats().items(): + src.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(unicode(v)))) src.extend(csrc) src.append(LibFoot) src.append(InterPolate) src = ''.join(src) return http.HttpResponse(src, 'text/javascript') + diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 2e44e418bc..1bd58ec0b3 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -62,6 +62,18 @@ their deprecation, as per the :ref:`Django deprecation policy backwards compatibility. These have been deprecated since the 1.2 release. + * ``django.utils.translation.get_date_formats()`` and + ``django.utils.translation.get_partial_date_formats()``. These + functions are replaced by the new locale aware formatting; use + ``django.utils.formats.get_format()`` to get the appropriate + formats. + + * In ``django.forms.fields``: ``DEFAULT_DATE_INPUT_FORMATS``, + ``DEFAULT_TIME_INPUT_FORMATS`` and + ``DEFAULT_DATETIME_INPUT_FORMATS``. Use + ``django.utils.formats.get_format()`` to get the appropriate + formats. + * 2.0 * ``django.views.defaults.shortcut()``. This function has been moved to ``django.contrib.contenttypes.views.shortcut()`` as part of the diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 1feb34a90b..bd8be27e5f 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -372,12 +372,32 @@ DATE_FORMAT Default: ``'N j, Y'`` (e.g. ``Feb. 4, 2003``) -The default formatting to use for date fields on Django admin change-list -pages -- and, possibly, by other parts of the system. See -:ttag:`allowed date format strings `. +The default formatting to use for date fields in any part of the system. +Note that if ``USE_L10N`` is set to ``True``, then locale format will +be applied. See :ttag:`allowed date format strings `. -See also ``DATETIME_FORMAT``, ``TIME_FORMAT``, ``YEAR_MONTH_FORMAT`` -and ``MONTH_DAY_FORMAT``. +See also ``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``SHORT_DATE_FORMAT``. + +.. setting:: DATE_INPUT_FORMATS + +DATE_INPUT_FORMATS +------------------ + +Default:: + + ('%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', + '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', + '%B %d, %Y', '%d %B %Y', '%d %B, %Y') + +A tuple of formats that will be accepted when inputting data on a date +field. Formats will be tried in order, using the first valid. +Note that these format strings are specified in Python's datetime_ module +syntax, that is different from the one used by Django for formatting dates +to be displayed. + +See also ``DATETIME_INPUT_FORMATS`` and ``TIME_INPUT_FORMATS``. + +.. _datetime: http://docs.python.org/library/datetime.html#strftime-behavior .. setting:: DATETIME_FORMAT @@ -386,12 +406,32 @@ DATETIME_FORMAT Default: ``'N j, Y, P'`` (e.g. ``Feb. 4, 2003, 4 p.m.``) -The default formatting to use for datetime fields on Django admin change-list -pages -- and, possibly, by other parts of the system. See -:ttag:`allowed date format strings `. +The default formatting to use for datetime fields in any part of the system. +Note that if ``USE_L10N`` is set to ``True``, then locale format will +be applied. See :ttag:`allowed date format strings `. -See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT``, -``YEAR_MONTH_FORMAT`` and ``MONTH_DAY_FORMAT``. +See also ``DATE_FORMAT``, ``TIME_FORMAT`` and ``SHORT_DATETIME_FORMAT``. + +.. setting:: DATETIME_INPUT_FORMATS + +DATETIME_INPUT_FORMATS +---------------------- + +Default:: + + ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d', + '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M', '%m/%d/%Y', + '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M', '%m/%d/%y') + +A tuple of formats that will be accepted when inputting data on a datetime +field. Formats will be tried in order, using the first valid. +Note that these format strings are specified in Python's datetime_ module +syntax, that is different from the one used by Django for formatting dates +to be displayed. + +See also ``DATE_INPUT_FORMATS`` and ``TIME_INPUT_FORMATS``. + +.. _datetime: http://docs.python.org/library/datetime.html#strftime-behavior .. setting:: DEBUG @@ -431,6 +471,14 @@ will be suppressed, and exceptions will propagate upwards. This can be useful for some test setups, and should never be used on a live site. +.. setting:: DECIMAL_SEPARATOR + +DECIMAL_SEPARATOR +----------------- + +Default: ``'.'`` (Dot) + +Default decimal separator used when formatting decimal numbers. .. setting:: DEFAULT_CHARSET @@ -680,6 +728,21 @@ system's standard umask. .. _documentation for os.chmod: http://docs.python.org/lib/os-file-dir.html +.. setting:: FIRST_DAY_OF_WEEK + +FIRST_DAY_OF_WEEK +----------------- + +Default: ``0`` (Sunday) + +Number representing the first day of the week. This is especially useful +when displaying a calendar. This value is only used when not using +format internationalization, or when a format cannot be found for the +current locale. + +The value must be an integer from 0 to 6, where 0 means Sunday, 1 means +Monday and so on. + .. setting:: FIXTURE_DIRS FIXTURE_DIRS @@ -701,6 +764,34 @@ environment variable in any HTTP request. This setting can be used to override the server-provided value of ``SCRIPT_NAME``, which may be a rewritten version of the preferred value or not supplied at all. +.. setting:: FORMAT_MODULE_PATH + +FORMAT_MODULE_PATH +------------------ + +Default: ``None`` + +A full Python path to a Python package that contains format definitions for +project locales. If not ``None``, Django will check for a ``formats.py`` +file, under the directory named as the current locale, and will use the +formats defined on this file. + +For example, if ``FORMAT_MODULE_PATH`` is set to ``mysite.formats``, and +current language is ``en`` (English), Django will expect a directory tree +like:: + + mysite/ + formats/ + __init__.py + en/ + __init__.py + formats.py + +Available formats are ``DATE_FORMAT``, ``TIME_FORMAT``, ``DATETIME_FORMAT``, +``YEAR_MONTH_FORMAT``, ``MONTH_DAY_FORMAT``, ``SHORT_DATE_FORMAT``, +``SHORT_DATETIME_FORMAT``, ``FIRST_DAY_OF_WEEK``, ``DECIMAL_SEPARATOR``, +``THOUSAND_SEPARATOR`` and ``NUMBER_GROUPING``. + .. setting:: IGNORABLE_404_ENDS IGNORABLE_404_ENDS @@ -845,7 +936,7 @@ LOGIN_URL Default: ``'/accounts/login/'`` -The URL where requests are redirected for login, specially when using the +The URL where requests are redirected for login, especially when using the :func:`~django.contrib.auth.decorators.login_required` decorator. .. setting:: LOGOUT_URL @@ -970,6 +1061,21 @@ locales have different formats. For example, U.S. English would say See :ttag:`allowed date format strings `. See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``YEAR_MONTH_FORMAT``. +.. setting:: NUMBER_GROUPING + +NUMBER_GROUPING +---------------- + +Default: ``0`` + +Number of digits grouped together on the integer part of a number. Common use +is to display a thousand separator. If this setting is ``0``, then, no grouping +will be applied to the number. If this setting is greater than ``0`` then the +setting ``THOUSAND_SEPARATOR`` will be used as the separator between those +groups. + +See also ``THOUSAND_SEPARATOR`` + .. setting:: PREPEND_WWW PREPEND_WWW @@ -1173,6 +1279,32 @@ Default: ``False`` Whether to save the session data on every request. See :ref:`topics-http-sessions`. +.. setting:: SHORT_DATE_FORMAT + +SHORT_DATE_FORMAT +----------------- + +Default: ``m/d/Y`` (e.g. ``12/31/2003``) + +An available formatting that can be used for date fields on templates. +Note that if ``USE_L10N`` is set to ``True``, then locale format will +be applied. See :ttag:`allowed date format strings `. + +See also ``DATE_FORMAT`` and ``SHORT_DATETIME_FORMAT``. + +.. setting:: SHORT_DATETIME_FORMAT + +SHORT_DATETIME_FORMAT +--------------------- + +Default: ``m/d/Y P`` (e.g. ``12/31/2003 4 p.m.``) + +An available formatting that can be used for datetime fields on templates. +Note that if ``USE_L10N`` is set to ``True``, then locale format will +be applied. See :ttag:`allowed date format strings `. + +See also ``DATE_FORMAT`` and ``SHORT_DATETIME_FORMAT``. + .. setting:: SITE_ID SITE_ID @@ -1277,6 +1409,18 @@ The name of the method to use for starting the test suite. See .. _Testing Django Applications: ../testing/ +.. setting:: THOUSAND_SEPARATOR + +THOUSAND_SEPARATOR +------------------ + +Default ``,`` (Comma) + +Default thousand separator used when formatting numbers. This setting is +used only when ``NUMBER_GROUPPING`` is set. + +See also ``NUMBER_GROUPPING``, ``DECIMAL_SEPARATOR`` + .. setting:: TIME_FORMAT TIME_FORMAT @@ -1284,12 +1428,28 @@ TIME_FORMAT Default: ``'P'`` (e.g. ``4 p.m.``) -The default formatting to use for time fields on Django admin change-list -pages -- and, possibly, by other parts of the system. See -:ttag:`allowed date format strings `. +The default formatting to use for time fields in any part of the system. +Note that if ``USE_L10N`` is set to ``True``, then locale format will +be applied. See :ttag:`allowed date format strings `. -See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT``, -``YEAR_MONTH_FORMAT`` and ``MONTH_DAY_FORMAT``. +See also ``DATE_FORMAT`` and ``DATETIME_FORMAT``. + +.. setting:: TIME_INPUT_FORMATS + +TIME_INPUT_FORMATS +------------------ + +Default: ``('%H:%M:%S', '%H:%M')`` + +A tuple of formats that will be accepted when inputting data on a time +field. Formats will be tried in order, using the first valid. +Note that these format strings are specified in Python's datetime_ module +syntax, that is different from the one used by Django for formatting dates +to be displayed. + +See also ``DATE_INPUT_FORMATS`` and ``DATETIME_INPUT_FORMATS``. + +.. _datetime: http://docs.python.org/library/datetime.html#strftime-behavior .. setting:: TIME_ZONE @@ -1344,6 +1504,19 @@ A boolean that specifies whether to output the "Etag" header. This saves bandwidth but slows down performance. This is only used if ``CommonMiddleware`` is installed (see :ref:`topics-http-middleware`). +.. setting:: USE_L10N + +USE_L10N +-------- + +Default ``False`` + +A boolean that specifies if data will be localized by default or not. If this +is set to ``True``, e.g. Django will display numbers and dates using the +format of the current locale. + +See also ``USE_I18N`` and ``LANGUAGE_CODE`` + .. setting:: USE_I18N USE_I18N @@ -1356,6 +1529,22 @@ enabled. This provides an easy way to turn it off, for performance. If this is set to ``False``, Django will make some optimizations so as not to load the internationalization machinery. +See also ``USE_L10N`` + +.. setting:: USE_THOUSAND_SEPARATOR + +USE_THOUSAND_SEPARATOR +---------------------- + +Default ``False`` + +A boolean that specifies wheter to display numbers using a thousand separator. +If this is set to ``True``, Django will use values from ``THOUSAND_SEPARATOR`` +and ``NUMBER_GROUPING`` from current locale, to format the number. +``USE_L10N`` must be set to ``True``, in order to format numbers. + +See also ``THOUSAND_SEPARATOR`` and ``NUMBER_GROUPING``. + .. setting:: YEAR_MONTH_FORMAT YEAR_MONTH_FORMAT diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index bf2d9e899c..b7afa15f7f 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -1047,7 +1047,12 @@ If ``value`` is ``"String with spaces"``, the output will be ``"Stringwithspaces date ~~~~ -Formats a date according to the given format (same as the `now`_ tag). +Formats a date according to the given format. + +Given format can be one of the predefined ones ``DATE_FORMAT``, +``DATETIME_FORMAT``, ``SHORT_DATE_FORMAT`` or ``SHORT_DATETIME_FORMAT``, +or a custom format, same as the `now`_ tag. Note that predefined formats may +vary depending on the current locale. For example:: @@ -1062,7 +1067,7 @@ When used without a format string:: {{ value|date }} ...the formatting string defined in the :setting:`DATE_FORMAT` setting will be -used. +used, without applying any localization. .. templatefilter:: default @@ -1610,7 +1615,11 @@ output will be ``"Joel is a slug"``. time ~~~~ -Formats a time according to the given format (same as the `now`_ tag). +Formats a time according to the given format. + +Given format can be the predefined one ``TIME_FORMAT``, or a custom format, +same as the `now`_ tag. Note that the predefined format is locale depending. + The time filter will only accept parameters in the format string that relate to the time of day, not the date (for obvious reasons). If you need to format a date, use the `date`_ filter. @@ -1627,7 +1636,7 @@ When used without a format string:: {{ value|time }} ...the formatting string defined in the :setting:`TIME_FORMAT` setting will be -used. +used, without aplying any localization. .. templatefilter:: timesince diff --git a/docs/releases/1.2.txt b/docs/releases/1.2.txt index 2111212054..200fb4a5b6 100644 --- a/docs/releases/1.2.txt +++ b/docs/releases/1.2.txt @@ -318,6 +318,41 @@ For more information, see the full :ref:`messages documentation `. You should begin to update your code to use the new API immediately. +Date format helper functions +---------------------------- + +``django.utils.translation.get_date_formats()`` and +``django.utils.translation.get_partial_date_formats()`` have been deprecated +in favor of the appropriate calls to ``django.utils.formats.get_format()`` +which is locale aware when :setting:`USE_L10N` is set to ``True``, and falls +back to default settings if set to ``False``. + +To get the different date formats, instead of writing:: + + from django.utils.translation import get_date_formats + date_format, datetime_format, time_format = get_date_formats() + +use:: + + from django.utils import formats + + date_format = formats.get_format('DATE_FORMAT') + datetime_format = formats.get_format('DATETIME_FORMAT') + time_format = formats.get_format('TIME_FORMAT') + +or, when directly formatting a date value:: + + from django.utils import formats + value_formatted = formats.date_format(value, 'DATETIME_FORMAT') + +The same applies to the globals found in ``django.forms.fields``: + + * ``DEFAULT_DATE_INPUT_FORMATS`` + * ``DEFAULT_TIME_INPUT_FORMATS`` + * ``DEFAULT_DATETIME_INPUT_FORMATS`` + +Use ``django.utils.formats.get_format()`` to get the appropriate formats. + What's new in Django 1.2 ======================== @@ -440,3 +475,13 @@ The ``test`` subcommand of ``django-admin.py``, and the ``runtests.py`` script used to run Django's own test suite, support a new ``--failfast`` option. When specified, this option causes the test runner to exit after encountering a failure instead of continuing with the test run. + +Improved localization +--------------------- + +Django's :ref:`internationalization framework ` has been +expanded by locale aware formatting and form processing. That means, if +enabled, dates and numbers on templates will be displayed using the format +specified for the current locale. Django will also use localized formats +when parsing data in forms. +See :ref:`Format localization ` for more details. diff --git a/docs/topics/i18n.txt b/docs/topics/i18n.txt index c5f4ab6481..993c7b5285 100644 --- a/docs/topics/i18n.txt +++ b/docs/topics/i18n.txt @@ -4,20 +4,20 @@ Internationalization ==================== -Django has full support for internationalization of text in code and templates. -Here's how it works. +Django has full support for internationalization of text in code and +templates, and format localization of dates and numbers. Here's how it works. Overview ======== The goal of internationalization is to allow a single Web application to offer -its content and functionality in multiple languages. +its content and functionality in multiple languages and locales. -You, the Django developer, can accomplish this goal by adding a minimal amount -of hooks to your Python code and templates. These hooks are called -**translation strings**. They tell Django: "This text should be translated into -the end user's language, if a translation for this text is available in that -language." +For text translation, you, the Django developer, can accomplish this goal by +adding a minimal amount of hooks to your Python code and templates. These hooks +are called **translation strings**. They tell Django: "This text should be +translated into the end user's language, if a translation for this text is +available in that language." Django takes care of using these hooks to translate Web apps, on the fly, according to users' language preferences. @@ -29,6 +29,12 @@ Essentially, Django does two things: * It uses these hooks to translate Web apps for particular users according to their language preferences. +For format localization, it's just necessary to set +:setting:`USE_L10N = True ` in your settings file. If +:setting:`USE_L10N` is set to ``True``, Django will display +numbers and dates in the format of the current locale. That includes field +representation on templates, and allowed input formats on the admin. + If you don't need internationalization in your app ================================================== @@ -1074,3 +1080,53 @@ have been found to not support this command. Do not attempt to use Django translation utilities with a ``gettext`` package if the command ``xgettext --version`` entered at a Windows command prompt causes a popup window saying "xgettext.exe has generated errors and will be closed by Windows". + +.. _format-localization: + +Format localization +=================== + +Django's formatting system is disabled by default. To enable it, it's necessay +to set :setting:`USE_L10N = True ` in your settings file. + +When using Django's formatting system, dates and numbers on templates will be +displayed using the format specified for the current locale. Two users +accessing the same content, but in different language, will see date and +number fields formatted in different ways, depending on the format for their +current locale. + +Django will also use localized formats when parsing data in forms. That means +Django uses different formats for different locales when guessing the format +used by the user when inputting data on forms. Note that Django uses different +formats for displaying data, and for parsing it. + +Creating custom format files +---------------------------- + +Django provides format definitions for many locales, but sometimes you might +want to create your own, because a format files doesn't exist for your locale, +or because you want to overwrite some of the values. + +To use custom formats, first thing to do, is to specify the path where you'll +place format files. To do that, just set your :setting:`FORMAT_MODULE_PATH` +setting to the the path (in the format ``'foo.bar.baz``) where format files +will exists. + +Files are not placed directly in this directory, but in a directory named as +the locale, and must be named ``formats.py``. + +To customize the English formats, a structure like this would be needed:: + + mysite/ + formats/ + __init__.py + en/ + __init__.py + formats.py + +where :file:`formats.py` contains custom format definitions. For example:: + + THOUSAND_SEPARATOR = ' ' + +to use a space as a thousand separator, instead of the default for English, +a comma. diff --git a/tests/regressiontests/i18n/misc.py b/tests/regressiontests/i18n/misc.py deleted file mode 100644 index f8f35ad4e4..0000000000 --- a/tests/regressiontests/i18n/misc.py +++ /dev/null @@ -1,114 +0,0 @@ -import sys - -tests = """ ->>> from django.utils.translation.trans_real import parse_accept_lang_header ->>> p = parse_accept_lang_header - -# -# Testing HTTP header parsing. First, we test that we can parse the values -# according to the spec (and that we extract all the pieces in the right order). -# - -Good headers. ->>> p('de') -[('de', 1.0)] ->>> p('en-AU') -[('en-AU', 1.0)] ->>> p('*;q=1.00') -[('*', 1.0)] ->>> p('en-AU;q=0.123') -[('en-AU', 0.123)] ->>> p('en-au;q=0.1') -[('en-au', 0.10000000000000001)] ->>> p('en-au;q=1.0') -[('en-au', 1.0)] ->>> p('da, en-gb;q=0.25, en;q=0.5') -[('da', 1.0), ('en', 0.5), ('en-gb', 0.25)] ->>> p('en-au-xx') -[('en-au-xx', 1.0)] ->>> p('de,en-au;q=0.75,en-us;q=0.5,en;q=0.25,es;q=0.125,fa;q=0.125') -[('de', 1.0), ('en-au', 0.75), ('en-us', 0.5), ('en', 0.25), ('es', 0.125), ('fa', 0.125)] ->>> p('*') -[('*', 1.0)] ->>> p('de;q=0.') -[('de', 1.0)] ->>> p('') -[] - -Bad headers; should always return []. ->>> p('en-gb;q=1.0000') -[] ->>> p('en;q=0.1234') -[] ->>> p('en;q=.2') -[] ->>> p('abcdefghi-au') -[] ->>> p('**') -[] ->>> p('en,,gb') -[] ->>> p('en-au;q=0.1.0') -[] ->>> p('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZ,en') -[] ->>> p('da, en-gb;q=0.8, en;q=0.7,#') -[] ->>> p('de;q=2.0') -[] ->>> p('de;q=0.a') -[] ->>> p('') -[] - -# -# Now test that we parse a literal HTTP header correctly. -# - ->>> from django.utils.translation.trans_real import get_language_from_request ->>> g = get_language_from_request ->>> from django.http import HttpRequest ->>> r = HttpRequest ->>> r.COOKIES = {} - -These tests assumes the es, es_AR, pt and pt_BR translations exit in the Django -source tree. ->>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'} ->>> g(r) -'pt-br' ->>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt'} ->>> g(r) -'pt' ->>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es,de'} ->>> g(r) -'es' ->>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'} ->>> g(r) -'es-ar' -""" - -# Python 2.3 and 2.4 return slightly different results for completely bogus -# locales, so we omit this test for that anything below 2.4. It's relatively -# harmless in any cases (GIGO). This also means this won't be executed on -# Jython currently, but life's like that sometimes. (On those platforms, -# passing in a truly bogus locale will get you the default locale back.) -if sys.version_info >= (2, 5): - tests += """ -This test assumes there won't be a Django translation to a US variation -of the Spanish language, a safe assumption. When the user sets it -as the preferred language, the main 'es' translation should be selected -instead. ->>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'} ->>> g(r) -'es' -""" - -tests += """ -This tests the following scenario: there isn't a main language (zh) -translation of Django but there is a translation to variation (zh_CN) -the user sets zh-cn as the preferred language, it should be selected by -Django without falling back nor ignoring it. ->>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-cn,de'} ->>> g(r) -'zh-cn' -""" diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py index 94e792cf54..c356970166 100644 --- a/tests/regressiontests/i18n/tests.py +++ b/tests/regressiontests/i18n/tests.py @@ -1,72 +1,375 @@ -# coding: utf-8 -import misc +import sys +from django.test import TestCase, client +from django.utils.translation import ugettext, ugettext_lazy, activate, deactivate, gettext_lazy -regressions = ur""" -Format string interpolation should work with *_lazy objects. +class TranslationTests(TestCase): ->>> from django.utils.translation import ugettext, ugettext_lazy, activate, deactivate, gettext_lazy ->>> s = ugettext_lazy('Add %(name)s') ->>> d = {'name': 'Ringo'} ->>> s % d -u'Add Ringo' ->>> activate('de') ->>> s % d -u'Ringo hinzuf\xfcgen' ->>> activate('pl') ->>> s % d -u'Dodaj Ringo' ->>> deactivate() + def test_lazy_objects(self): + """ + Format string interpolation should work with *_lazy objects. + """ + s = ugettext_lazy('Add %(name)s') + d = {'name': 'Ringo'} + self.assertEqual(u'Add Ringo', s % d) + activate('de') + self.assertEqual(u'Ringo hinzuf\xfcgen', s % d) + activate('pl') + self.assertEqual(u'Dodaj Ringo', s % d) + deactivate() -It should be possible to compare *_lazy objects. + # It should be possible to compare *_lazy objects. + s1 = ugettext_lazy('Add %(name)s') + self.assertEqual(True, s == s1) + s2 = gettext_lazy('Add %(name)s') + s3 = gettext_lazy('Add %(name)s') + self.assertEqual(True, s2 == s3) + self.assertEqual(True, s == s2) + s4 = ugettext_lazy('Some other string') + self.assertEqual(False, s == s4) ->>> s1 = ugettext_lazy('Add %(name)s') ->>> s == s1 -True ->>> s2 = gettext_lazy('Add %(name)s') ->>> s3 = gettext_lazy('Add %(name)s') ->>> s2 == s3 -True ->>> s == s2 -True ->>> s4 = ugettext_lazy('Some other string') ->>> s == s4 -False + def test_string_concat(self): + """ + unicode(string_concat(...)) should not raise a TypeError - #4796 + """ + import django.utils.translation + self.assertEqual(django.utils.translation, reload(django.utils.translation)) + self.assertEqual(u'django', unicode(django.utils.translation.string_concat("dja", "ngo"))) -unicode(string_concat(...)) should not raise a TypeError - #4796 + def test_safe_status(self): + """ + Translating a string requiring no auto-escaping shouldn't change the "safe" status. + """ + from django.utils.safestring import mark_safe, SafeString, SafeUnicode + s = mark_safe('Password') + self.assertEqual(SafeString, type(s)) + activate('de') + self.assertEqual(SafeUnicode, type(ugettext(s))) + deactivate() + self.assertEqual('aPassword', SafeString('a') + s) + self.assertEqual('Passworda', s + SafeString('a')) + self.assertEqual('Passworda', s + mark_safe('a')) + self.assertEqual('aPassword', mark_safe('a') + s) + self.assertEqual('as', mark_safe('a') + mark_safe('s')) + #self.assertEqual(Password, print s) ->>> import django.utils.translation ->>> reload(django.utils.translation) - ->>> unicode(django.utils.translation.string_concat("dja", "ngo")) -u'django' + def test_maclines(self): + """ + Translations on files with mac or dos end of lines will be converted + to unix eof in .po catalogs, and they have to match when retrieved + """ + from django.utils.translation.trans_real import translation + ca_translation = translation('ca') + ca_translation._catalog[u'Mac\nEOF\n'] = u'Catalan Mac\nEOF\n' + ca_translation._catalog[u'Win\nEOF\n'] = u'Catalan Win\nEOF\n' + activate('ca') + self.assertEqual(u'Catalan Mac\nEOF\n', ugettext(u'Mac\rEOF\r')) + self.assertEqual(u'Catalan Win\nEOF\n', ugettext(u'Win\r\nEOF\r\n')) + deactivate() -Translating a string requiring no auto-escaping shouldn't change the "safe" -status. + def test_dates_and_numbers(self): + """ + Localization of dates and numbers + """ + import datetime + import decimal + from django.conf import settings + from django.utils.formats import get_format, date_format, number_format, localize + from django.utils.numberformat import format + from django import template, forms + from django.forms.extras import SelectDateWidget ->>> from django.utils.safestring import mark_safe, SafeString ->>> s = mark_safe('Password') ->>> type(s) - ->>> activate('de') ->>> type(ugettext(s)) - ->>> deactivate() + old_use_i18n = settings.USE_I18N + old_use_l10n = settings.USE_L10N + old_use_thousand_separator = settings.USE_THOUSAND_SEPARATOR ->>> SafeString('a') + s -'aPassword' ->>> s + SafeString('a') -'Passworda' ->>> s + mark_safe('a') -'Passworda' ->>> mark_safe('a') + s -'aPassword' ->>> mark_safe('a') + mark_safe('s') -'as' ->>> print s -Password -""" + n = decimal.Decimal('66666.666') + f = 99999.999 + d = datetime.date(2009, 12, 31) + dt = datetime.datetime(2009, 12, 31, 20, 50) + ctxt = template.Context({'n': n, 'd': d, 'dt': dt, 'f': f}) -__test__ = { - 'regressions': regressions, - 'misc': misc.tests, -} + # Locale independent + + class I18nForm(forms.Form): + decimal_field = forms.DecimalField() + float_field = forms.FloatField() + date_field = forms.DateField() + datetime_field = forms.DateTimeField() + time_field = forms.TimeField() + + class SelectDateForm(forms.Form): + date_field = forms.DateField(widget=SelectDateWidget) + + settings.USE_L10N = True + settings.USE_THOUSAND_SEPARATOR = False + self.assertEqual(u'66666.66', format(n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) + self.assertEqual(u'66666A6', format(n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) + + settings.USE_THOUSAND_SEPARATOR = True + self.assertEqual(u'66,666.66', format(n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) + self.assertEqual(u'6B6B6B6B6A6', format(n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) + self.assertEqual(u'-66666.6', format(-66666.666, decimal_sep='.', decimal_pos=1)) + self.assertEqual(u'-66666.0', format(int('-66666'), decimal_sep='.', decimal_pos=1)) + + # Catalan locale with format i18n disabled translations will be used, but not formats + + settings.USE_L10N = False + activate('ca') + self.assertEqual('N j, Y', get_format('DATE_FORMAT')) + self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK')) + self.assertEqual('.', get_format('DECIMAL_SEPARATOR')) + self.assertEqual(u'des. 31, 2009', date_format(d)) + self.assertEqual(u'desembre 2009', date_format(d, 'YEAR_MONTH_FORMAT')) + self.assertEqual(u'12/31/2009 8:50 p.m.', date_format(dt, 'SHORT_DATETIME_FORMAT')) + self.assertEqual('No localizable', localize('No localizable')) + self.assertEqual(decimal.Decimal('66666.666'), localize(n)) + self.assertEqual(99999.999, localize(f)) + self.assertEqual(datetime.date(2009, 12, 31), localize(d)) + self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), localize(dt)) + self.assertEqual(u'66666.666', template.Template('{{ n }}').render(ctxt)) + self.assertEqual(u'99999.999', template.Template('{{ f }}').render(ctxt)) + self.assertEqual(u'2009-12-31', template.Template('{{ d }}').render(ctxt)) + self.assertEqual(u'2009-12-31 20:50:00', template.Template('{{ dt }}').render(ctxt)) + self.assertEqual(u'66666.67', template.Template('{{ n|floatformat:2 }}').render(ctxt)) + self.assertEqual(u'100000.0', template.Template('{{ f|floatformat }}').render(ctxt)) + self.assertEqual(u'12/31/2009', template.Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(ctxt)) + self.assertEqual(u'12/31/2009 8:50 p.m.', template.Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(ctxt)) + + form = I18nForm({ + 'decimal_field': u'66666,666', + 'float_field': u'99999,999', + 'date_field': u'31/12/2009', + 'datetime_field': u'31/12/2009 20:50', + 'time_field': u'20:50' + }) + self.assertEqual(False, form.is_valid()) + self.assertEqual([u'Introdu\xefu un n\xfamero.'], form.errors['float_field']) + self.assertEqual([u'Introdu\xefu un n\xfamero.'], form.errors['decimal_field']) + self.assertEqual([u'Introdu\xefu una data v\xe0lida.'], form.errors['date_field']) + self.assertEqual([u'Introdu\xefu una data/hora v\xe0lides.'], form.errors['datetime_field']) + + form2 = SelectDateForm({ + 'date_field_month': u'12', + 'date_field_day': u'31', + 'date_field_year': u'2009' + }) + self.assertEqual(True, form2.is_valid()) + self.assertEqual(datetime.date(2009, 12, 31), form2.cleaned_data['date_field']) + self.assertEqual(u'\n\n', SelectDateWidget().render('mydate', datetime.date(2009, 12, 31))) + deactivate() + + # Catalan locale + + settings.USE_L10N = True + activate('ca') + self.assertEqual('j \de F \de Y', get_format('DATE_FORMAT')) + self.assertEqual(1, get_format('FIRST_DAY_OF_WEEK')) + self.assertEqual(',', get_format('DECIMAL_SEPARATOR')) + self.assertEqual(u'31 de desembre de 2009', date_format(d)) + self.assertEqual(u'desembre del 2009', date_format(d, 'YEAR_MONTH_FORMAT')) + self.assertEqual(u'31/12/2009 20:50', date_format(dt, 'SHORT_DATETIME_FORMAT')) + self.assertEqual('No localizable', localize('No localizable')) + + settings.USE_THOUSAND_SEPARATOR = True + self.assertEqual(u'66.666,666', localize(n)) + self.assertEqual(u'99.999,999', localize(f)) + + settings.USE_THOUSAND_SEPARATOR = False + self.assertEqual(u'66666,666', localize(n)) + self.assertEqual(u'99999,999', localize(f)) + self.assertEqual(u'31 de desembre de 2009', localize(d)) + self.assertEqual(u'31 de desembre de 2009 a les 20:50', localize(dt)) + + settings.USE_THOUSAND_SEPARATOR = True + self.assertEqual(u'66.666,666', template.Template('{{ n }}').render(ctxt)) + self.assertEqual(u'99.999,999', template.Template('{{ f }}').render(ctxt)) + + settings.USE_THOUSAND_SEPARATOR = False + self.assertEqual(u'66666,666', template.Template('{{ n }}').render(ctxt)) + self.assertEqual(u'99999,999', template.Template('{{ f }}').render(ctxt)) + self.assertEqual(u'31 de desembre de 2009', template.Template('{{ d }}').render(ctxt)) + self.assertEqual(u'31 de desembre de 2009 a les 20:50', template.Template('{{ dt }}').render(ctxt)) + self.assertEqual(u'66666,67', template.Template('{{ n|floatformat:2 }}').render(ctxt)) + self.assertEqual(u'100000,0', template.Template('{{ f|floatformat }}').render(ctxt)) + self.assertEqual(u'31/12/2009', template.Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(ctxt)) + self.assertEqual(u'31/12/2009 20:50', template.Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(ctxt)) + + form3 = I18nForm({ + 'decimal_field': u'66666,666', + 'float_field': u'99999,999', + 'date_field': u'31/12/2009', + 'datetime_field': u'31/12/2009 20:50', + 'time_field': u'20:50' + }) + self.assertEqual(True, form3.is_valid()) + self.assertEqual(decimal.Decimal('66666.666'), form3.cleaned_data['decimal_field']) + self.assertEqual(99999.999, form3.cleaned_data['float_field']) + self.assertEqual(datetime.date(2009, 12, 31), form3.cleaned_data['date_field']) + self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form3.cleaned_data['datetime_field']) + self.assertEqual(datetime.time(20, 50), form3.cleaned_data['time_field']) + + form4 = SelectDateForm({ + 'date_field_month': u'12', + 'date_field_day': u'31', + 'date_field_year': u'2009' + }) + self.assertEqual(True, form4.is_valid()) + self.assertEqual(datetime.date(2009, 12, 31), form4.cleaned_data['date_field']) + self.assertEqual(u'\n\n', SelectDateWidget().render('mydate', datetime.date(2009, 12, 31))) + deactivate() + + # English locale + + settings.USE_L10N = True + activate('en') + self.assertEqual('N j, Y', get_format('DATE_FORMAT')) + self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK')) + self.assertEqual('.', get_format('DECIMAL_SEPARATOR')) + self.assertEqual(u'Dec. 31, 2009', date_format(d)) + self.assertEqual(u'December 2009', date_format(d, 'YEAR_MONTH_FORMAT')) + self.assertEqual(u'12/31/2009 8:50 p.m.', date_format(dt, 'SHORT_DATETIME_FORMAT')) + self.assertEqual('No localizable', localize('No localizable')) + + settings.USE_THOUSAND_SEPARATOR = True + self.assertEqual(u'66,666.666', localize(n)) + self.assertEqual(u'99,999.999', localize(f)) + + settings.USE_THOUSAND_SEPARATOR = False + self.assertEqual(u'66666.666', localize(n)) + self.assertEqual(u'99999.999', localize(f)) + self.assertEqual(u'Dec. 31, 2009', localize(d)) + self.assertEqual(u'Dec. 31, 2009, 8:50 p.m.', localize(dt)) + + settings.USE_THOUSAND_SEPARATOR = True + self.assertEqual(u'66,666.666', template.Template('{{ n }}').render(ctxt)) + self.assertEqual(u'99,999.999', template.Template('{{ f }}').render(ctxt)) + + settings.USE_THOUSAND_SEPARATOR = False + self.assertEqual(u'66666.666', template.Template('{{ n }}').render(ctxt)) + self.assertEqual(u'99999.999', template.Template('{{ f }}').render(ctxt)) + self.assertEqual(u'Dec. 31, 2009', template.Template('{{ d }}').render(ctxt)) + self.assertEqual(u'Dec. 31, 2009, 8:50 p.m.', template.Template('{{ dt }}').render(ctxt)) + self.assertEqual(u'66666.67', template.Template('{{ n|floatformat:2 }}').render(ctxt)) + self.assertEqual(u'100000.0', template.Template('{{ f|floatformat }}').render(ctxt)) + self.assertEqual(u'12/31/2009', template.Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(ctxt)) + self.assertEqual(u'12/31/2009 8:50 p.m.', template.Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(ctxt)) + + form5 = I18nForm({ + 'decimal_field': u'66666.666', + 'float_field': u'99999.999', + 'date_field': u'12/31/2009', + 'datetime_field': u'12/31/2009 20:50', + 'time_field': u'20:50' + }) + self.assertEqual(True, form5.is_valid()) + self.assertEqual(decimal.Decimal('66666.666'), form5.cleaned_data['decimal_field']) + self.assertEqual(99999.999, form5.cleaned_data['float_field']) + self.assertEqual(datetime.date(2009, 12, 31), form5.cleaned_data['date_field']) + self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form5.cleaned_data['datetime_field']) + self.assertEqual(datetime.time(20, 50), form5.cleaned_data['time_field']) + + form6 = SelectDateForm({ + 'date_field_month': u'12', + 'date_field_day': u'31', + 'date_field_year': u'2009' + }) + self.assertEqual(True, form6.is_valid()) + self.assertEqual(datetime.date(2009, 12, 31), form6.cleaned_data['date_field']) + self.assertEqual(u'\n\n', SelectDateWidget().render('mydate', datetime.date(2009, 12, 31))) + deactivate() + + # Check if sublocales fall back to the main locale + activate('de-at') + settings.USE_THOUSAND_SEPARATOR = True + self.assertEqual(u'66.666,666', template.Template('{{ n }}').render(ctxt)) + deactivate() + + activate('es-ar') + self.assertEqual(u'31 de Diciembre de 2009', date_format(d)) + deactivate() + + # Restore defaults + settings.USE_I18N = old_use_i18n + settings.USE_L10N = old_use_l10n + settings.USE_THOUSAND_SEPARATOR = old_use_thousand_separator + + +class MiscTests(TestCase): + + def test_parse_spec_http_header(self): + """ + Testing HTTP header parsing. First, we test that we can parse the + values according to the spec (and that we extract all the pieces in + the right order). + """ + from django.utils.translation.trans_real import parse_accept_lang_header + p = parse_accept_lang_header + # Good headers. + self.assertEqual([('de', 1.0)], p('de')) + self.assertEqual([('en-AU', 1.0)], p('en-AU')) + self.assertEqual([('*', 1.0)], p('*;q=1.00')) + self.assertEqual([('en-AU', 0.123)], p('en-AU;q=0.123')) + self.assertEqual([('en-au', 0.10000000000000001)], p('en-au;q=0.1')) + self.assertEqual([('en-au', 1.0)], p('en-au;q=1.0')) + self.assertEqual([('da', 1.0), ('en', 0.5), ('en-gb', 0.25)], p('da, en-gb;q=0.25, en;q=0.5')) + self.assertEqual([('en-au-xx', 1.0)], p('en-au-xx')) + self.assertEqual([('de', 1.0), ('en-au', 0.75), ('en-us', 0.5), ('en', 0.25), ('es', 0.125), ('fa', 0.125)], p('de,en-au;q=0.75,en-us;q=0.5,en;q=0.25,es;q=0.125,fa;q=0.125')) + self.assertEqual([('*', 1.0)], p('*')) + self.assertEqual([('de', 1.0)], p('de;q=0.')) + self.assertEqual([], p('')) + + # Bad headers; should always return []. + self.assertEqual([], p('en-gb;q=1.0000')) + self.assertEqual([], p('en;q=0.1234')) + self.assertEqual([], p('en;q=.2')) + self.assertEqual([], p('abcdefghi-au')) + self.assertEqual([], p('**')) + self.assertEqual([], p('en,,gb')) + self.assertEqual([], p('en-au;q=0.1.0')) + self.assertEqual([], p('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZ,en')) + self.assertEqual([], p('da, en-gb;q=0.8, en;q=0.7,#')) + self.assertEqual([], p('de;q=2.0')) + self.assertEqual([], p('de;q=0.a')) + self.assertEqual([], p('')) + + def test_parse_literal_http_header(self): + """ + Now test that we parse a literal HTTP header correctly. + """ + from django.utils.translation.trans_real import get_language_from_request + g = get_language_from_request + from django.http import HttpRequest + r = HttpRequest + r.COOKIES = {} + r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'} + self.assertEqual('pt-br', g(r)) + + r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt'} + self.assertEqual('pt', g(r)) + + r.META = {'HTTP_ACCEPT_LANGUAGE': 'es,de'} + self.assertEqual('es', g(r)) + + r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'} + self.assertEqual('es-ar', g(r)) + + # Python 2.3 and 2.4 return slightly different results for completely + # bogus locales, so we omit this test for that anything below 2.4. + # It's relatively harmless in any cases (GIGO). This also means this + # won't be executed on Jython currently, but life's like that + # sometimes. (On those platforms, passing in a truly bogus locale + # will get you the default locale back.) + if sys.version_info >= (2, 5): + # This test assumes there won't be a Django translation to a US + # variation of the Spanish language, a safe assumption. When the + # user sets it as the preferred language, the main 'es' + # translation should be selected instead. + r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'} + self.assertEqual(g(r), 'es') + + # This tests the following scenario: there isn't a main language (zh) + # translation of Django but there is a translation to variation (zh_CN) + # the user sets zh-cn as the preferred language, it should be selected + # by Django without falling back nor ignoring it. + r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-cn,de'} + self.assertEqual(g(r), 'zh-cn')