Merge pull request #335 from Amith211/333-en-gb-datetimeformat

Add en-gb datetime overrides
This commit is contained in:
Christopher Charbonneau Wells 2021-12-13 16:19:45 -05:00 committed by GitHub
commit 2ad48940c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 160 additions and 12 deletions

View File

@ -5,6 +5,7 @@ import pytz
from django.conf import settings
from django.utils import timezone, translation
from django.conf.locale.en import formats as formats_en_us
from django.conf.locale.en_GB import formats as formats_en_gb
def update_en_us_date_formats():
@ -38,6 +39,30 @@ def update_en_us_date_formats():
custom_input_formats + formats_en_us.DATETIME_INPUT_FORMATS
def update_en_gb_date_formats():
if settings.USE_24_HOUR_TIME_FORMAT:
# 25 October 2006 14:30:00
formats_en_gb.DATETIME_FORMAT = 'j F Y H:i:s'
custom_input_formats = [
'%d/%m/%Y %H:%M:%S', # '25/10/2006 14:30:59'
'%d/%m/%Y %H:%M', # '25/10/2006 14:30'
]
formats_en_gb.SHORT_DATETIME_FORMAT = 'd/m/Y H:i'
formats_en_gb.TIME_FORMAT = 'H:i'
else:
formats_en_gb.DATETIME_FORMAT = 'j F Y f a' # 25 October 2006 2:30 p.m
# These formats are added to support the locale style of Baby Buddy's
# frontend library, which uses momentjs.
custom_input_formats = [
'%d/%m/%Y %I:%M:%S %p', # '25/10/2006 2:30:59 PM'
'%d/%m/%Y %I:%M %p', # '25/10/2006 2:30 PM'
]
# Append all other input formats from the base locale.
formats_en_gb.DATETIME_INPUT_FORMATS = \
custom_input_formats + formats_en_gb.DATETIME_INPUT_FORMATS
class UserLanguageMiddleware:
"""
Customizes settings based on user language setting.
@ -57,6 +82,8 @@ class UserLanguageMiddleware:
if language:
if language == 'en-US':
update_en_us_date_formats()
elif language == 'en-GB':
update_en_gb_date_formats()
# Set the language before generating the response.
translation.activate(language)

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
import datetime
from django.core.exceptions import ValidationError
from django.forms.fields import DateTimeField
from django.test import TestCase, override_settings # , tag
from django.utils.formats import date_format, time_format
from babybuddy.middleware import update_en_gb_date_formats
class GbFormatsTestCase(TestCase):
@override_settings(LANGUAGE_CODE='en-GB')
def test_datetime_input_formats(self):
update_en_gb_date_formats()
field = DateTimeField()
supported_custom_examples = [
'20/01/2020',
'20/01/2020 9:30 AM',
'20/01/2020 9:30:03 AM',
'01/10/2020 11:30 PM',
'01/10/2020 11:30:03 AM',
]
for example in supported_custom_examples:
try:
result = field.to_python(example)
self.assertIsInstance(result, datetime.datetime)
except ValidationError:
self.fail('Format of "{}" not recognized!'.format(example))
with self.assertRaises(ValidationError):
field.to_python('invalid date string!')
# @tag('isolate')
@override_settings(LANGUAGE_CODE='en-GB', USE_24_HOUR_TIME_FORMAT=True)
def test_use_24_hour_time_format(self):
update_en_gb_date_formats()
field = DateTimeField()
supported_custom_examples = [
'25/10/2006 2:30:59',
'25/10/2006 2:30',
'25/10/2006 14:30:59',
'25/10/2006 14:30',
]
for example in supported_custom_examples:
try:
result = field.to_python(example)
self.assertIsInstance(result, datetime.datetime)
except ValidationError:
self.fail('Format of "{}" not recognized!'.format(example))
with self.assertRaises(ValidationError):
field.to_python('invalid date string!')
dt = datetime.datetime(year=2011, month=11, day=4, hour=23, minute=5,
second=59)
self.assertEqual(
date_format(dt, 'DATETIME_FORMAT'), '4 November 2011 23:05:59')
dt = datetime.datetime(year=2011, month=11, day=4, hour=2, minute=5,
second=59)
self.assertEqual(
date_format(dt, 'SHORT_DATETIME_FORMAT'), '04/11/2011 02:05')
t = datetime.time(hour=16, minute=2, second=25)
self.assertEqual(time_format(t), '16:02')
# def test_short_month_day_format(self):
# update_en_gb_date_formats()
# dt = datetime.datetime(year=2021, month=7, day=31, hour=5, minute=5,
# second=5)
# self.assertEqual(date_format(dt, 'SHORT_MONTH_DAY_FORMAT'), '31 Jul')

View File

@ -7,19 +7,37 @@ from django.utils.translation import gettext_lazy as _
register = template.Library()
@register.simple_tag()
def datetimepicker_format(format_string='L LT'):
@register.simple_tag(takes_context=True)
def datetimepicker_format(context, format_string='L LT'):
"""
Return a datetime format string for momentjs, with support for 24 hour time
override setting.
:param context: caller context data
:param format_string: the default format string (locale based)
:return: the format string to use, as 24 hour time if configured.
"""
try:
user = context['request'].user
if hasattr(user, 'settings') and user.settings.language:
language = user.settings.language
else:
language = settings.LANGUAGE_CODE
except KeyError:
language = None
if settings.USE_24_HOUR_TIME_FORMAT:
if format_string == 'L LT':
return 'L HH:mm'
format_string = 'L HH:mm'
elif format_string == 'L LTS':
return 'L HH:mm:ss'
format_string = 'L HH:mm:ss'
elif language and language == 'en-GB':
# Force 12-hour format if 24 hour format is not configured for en-GB
# (Django default is 12H, momentjs default is 24H).
if format_string == 'L LT':
format_string = 'L h:mm a'
elif format_string == 'L LTS':
format_string = 'L h:mm:ss a'
return format_string

View File

@ -1,12 +1,17 @@
# -*- coding: utf-8 -*-
from django.contrib.auth.models import User
from django.test import TestCase
from django.test import TestCase, override_settings
from django.utils import timezone, formats
from core.models import Child, Timer
from core.templatetags import bootstrap, datetime, duration, timers
class MockUserRequest:
def __init__(self, user):
self.user = user
class TemplateTagsTestCase(TestCase):
def test_bootstrap_bool_icon(self):
self.assertEqual(
@ -72,17 +77,41 @@ class TemplateTagsTestCase(TestCase):
timer.id, child.slug))
def test_datetimepicker_format(self):
self.assertEqual(datetime.datetimepicker_format(), 'L LT')
self.assertEqual(datetime.datetimepicker_format('L LT'), 'L LT')
request = MockUserRequest(User.objects.first())
request.user.settings.dashboard_hide_empty = True
context = {'request': request}
with self.settings(USE_24_HOUR_TIME_FORMAT=False):
self.assertEqual(datetime.datetimepicker_format(context), 'L LT')
self.assertEqual(
datetime.datetimepicker_format('L LTS'), 'L LTS')
datetime.datetimepicker_format(context, 'L LT'), 'L LT')
self.assertEqual(
datetime.datetimepicker_format(context, 'L LTS'), 'L LTS')
with self.settings(USE_24_HOUR_TIME_FORMAT=True):
self.assertEqual(datetime.datetimepicker_format(), 'L HH:mm')
self.assertEqual(
datetime.datetimepicker_format('L LT'), 'L HH:mm')
datetime.datetimepicker_format(context), 'L HH:mm')
self.assertEqual(
datetime.datetimepicker_format('L LTS'), 'L HH:mm:ss')
datetime.datetimepicker_format(context, 'L LT'), 'L HH:mm')
self.assertEqual(
datetime.datetimepicker_format(context, 'L LTS'), 'L HH:mm:ss')
@override_settings(USE_24_HOUR_TIME_FORMAT=False)
def test_datetimepicker_format_en_gb(self):
user = User.objects.first()
user.settings.language = 'en-GB'
user.save()
request = MockUserRequest(user)
request.user.settings.dashboard_hide_empty = True
context = {'request': request}
self.assertEqual(
datetime.datetimepicker_format(context), 'L h:mm a')
self.assertEqual(
datetime.datetimepicker_format(context, 'L LT'), 'L h:mm a')
self.assertEqual(
datetime.datetimepicker_format(context, 'L LTS'), 'L h:mm:ss a')
def test_datetime_short(self):
date = timezone.localtime()