From f24d5466ec00977c0c77c31c56ee5731319afe50 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 15 Jan 2020 11:57:46 +0100 Subject: [PATCH] templatetags: add add_days and add_hours filters (#36943) --- combo/public/templatetags/combo.py | 37 +++++++++++++++++++++++++++++- tests/test_public_templatetags.py | 21 +++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/combo/public/templatetags/combo.py b/combo/public/templatetags/combo.py index b9f6ac6..401aec8 100644 --- a/combo/public/templatetags/combo.py +++ b/combo/public/templatetags/combo.py @@ -27,7 +27,7 @@ from django.core.exceptions import PermissionDenied from django.template import VariableDoesNotExist from django.template.base import TOKEN_BLOCK, TOKEN_VAR, TOKEN_COMMENT from django.template.defaultfilters import stringfilter -from django.utils import dateparse +from django.utils import dateparse, six from django.utils.encoding import force_text from combo.data.models import Page, Placeholder @@ -269,3 +269,38 @@ def get_page(page_slug): @register.filter def startswith(string, substring): return string and force_text(string).startswith(force_text(substring)) + +def parse_float(value): + if isinstance(value, six.string_types): + # replace , by . for French users comfort + value = value.replace(',', '.') + try: + return float(value) + except (ValueError, TypeError): + return '' + +@register.filter(expects_localtime=True, is_safe=False) +def add_days(value, arg): + try: + value = parse_datetime(value).date() # consider only date, not hours + except AttributeError: # parse_datetime returned None + value = parse_date(value) + if not value: + return '' + arg = parse_float(arg) + if not arg: + return value + result = value + datetime.timedelta(days=float(arg)) + return result + +@register.filter(expects_localtime=True, is_safe=False) +def add_hours(value, arg): + value = parse_datetime(value) or parse_date(value) + if not value: + return '' + if not isinstance(value, datetime.datetime): + value = datetime.datetime(year=value.year, month=value.month, day=value.day) + arg = parse_float(arg) + if not arg: + return value + return value + datetime.timedelta(hours=float(arg)) diff --git a/tests/test_public_templatetags.py b/tests/test_public_templatetags.py index d5efd57..9d2b816 100644 --- a/tests/test_public_templatetags.py +++ b/tests/test_public_templatetags.py @@ -201,3 +201,24 @@ def test_startswith(): assert t.render(context) == '' context = Context({'foo': 'bar'}) assert t.render(context) == 'ok' + +def test_date_maths(): + tmpl = Template('{{ plop|add_days:4 }}') + assert tmpl.render(Context({'plop': '2017-12-21'})) == 'Dec. 25, 2017' + assert tmpl.render(Context({'plop': '2017-12-21 18:00'})) == 'Dec. 25, 2017' + tmpl = Template('{{ plop|add_days:"-1" }}') + assert tmpl.render(Context({'plop': '2017-12-21'})) == 'Dec. 20, 2017' + assert tmpl.render(Context({'plop': '2017-12-21 18:00'})) == 'Dec. 20, 2017' + tmpl = Template('{{ plop|add_days:1.5 }}') + assert tmpl.render(Context({'plop': '2017-12-21'})) == 'Dec. 22, 2017' + assert tmpl.render(Context({'plop': '2017-12-21 18:00'})) == 'Dec. 22, 2017' + tmpl = Template('{{ plop|add_days:"1.5" }}') + assert tmpl.render(Context({'plop': '2017-12-21'})) == 'Dec. 22, 2017' + assert tmpl.render(Context({'plop': '2017-12-21 18:00'})) == 'Dec. 22, 2017' + + tmpl = Template('{{ plop|add_hours:24 }}') + assert tmpl.render(Context({'plop': '2017-12-21'})) == 'Dec. 22, 2017, midnight' + assert tmpl.render(Context({'plop': '2017-12-21 18:00'})) == 'Dec. 22, 2017, 6 p.m.' + tmpl = Template('{{ plop|add_hours:"12.5" }}') + assert tmpl.render(Context({'plop': '2017-12-21'})) == 'Dec. 21, 2017, 12:30 p.m.' + assert tmpl.render(Context({'plop': '2017-12-21 18:00'})) == 'Dec. 22, 2017, 6:30 a.m.' -- 2.20.1