Ticket #22355: timedelta_templatetag_with_tests_and_docs.diff
File timedelta_templatetag_with_tests_and_docs.diff, 8.4 KB (added by , 10 years ago) |
---|
-
django/template/defaultfilters.py
diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index 76c0121..589bdd9 100644
a b from django.utils.http import urlquote 18 18 from django.utils.text import Truncator, wrap, phone2numeric 19 19 from django.utils.safestring import mark_safe, SafeData, mark_for_escaping 20 20 from django.utils import six 21 from django.utils.timesince import timesince, timeuntil 21 from django.utils.timesince import timesince, timeuntil, delta 22 22 from django.utils.translation import ugettext, ungettext 23 23 from django.utils.text import normalize_newlines 24 24 … … def timeuntil_filter(value, arg=None): 743 743 except (ValueError, TypeError): 744 744 return '' 745 745 746 @register.filter("delta", is_safe=False) 747 def delta_filter(value): 748 """Humanizes a timedelta object on template (i.e. "2 months, 2 weeks").""" 749 if not value: 750 return '' 751 try: 752 return delta(value) 753 except (ValueError, TypeError): 754 return '' 755 746 756 ################### 747 757 # LOGIC # 748 758 ################### -
django/utils/timesince.py
diff --git a/django/utils/timesince.py b/django/utils/timesince.py index 8fb0f64..0c57544 100644
a b from django.utils.html import avoid_wrapping 6 6 from django.utils.timezone import is_aware, utc 7 7 from django.utils.translation import ugettext, ungettext_lazy 8 8 9 def time since(d, now=None, reversed=False):9 def time_to_text(time_delta): 10 10 """ 11 Takes two datetime objects and returns the time between d and now 12 as a nicely formatted string, e.g. "10 minutes". If d occurs after now, 13 then "0 minutes" is returned. 14 15 Units used are years, months, weeks, days, hours, and minutes. 16 Seconds and microseconds are ignored. Up to two adjacent units will be 17 displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are 18 possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not. 19 20 Adapted from 21 http://web.archive.org/web/20060617175230/http://blog.natbat.co.uk/archive/2003/Jun/14/time_since 11 Converts a datetime.timedelta object into a nicely formatted 12 humanized string. Used by timesince, timeuntil and delta utils functions 22 13 """ 23 14 chunks = ( 24 15 (60 * 60 * 24 * 365, ungettext_lazy('%d year', '%d years')), … … def timesince(d, now=None, reversed=False): 28 19 (60 * 60, ungettext_lazy('%d hour', '%d hours')), 29 20 (60, ungettext_lazy('%d minute', '%d minutes')) 30 21 ) 31 # Convert datetime.date to datetime.datetime for comparison.32 if not isinstance(d, datetime.datetime):33 d = datetime.datetime(d.year, d.month, d.day)34 if now and not isinstance(now, datetime.datetime):35 now = datetime.datetime(now.year, now.month, now.day)36 37 if not now:38 now = datetime.datetime.now(utc if is_aware(d) else None)39 40 delta = (d - now) if reversed else (now - d)41 22 # ignore microseconds 42 23 since = delta.days * 24 * 60 * 60 + delta.seconds 43 24 if since <= 0: … … def timesince(d, now=None, reversed=False): 56 37 result += ugettext(', ') + avoid_wrapping(name2 % count2) 57 38 return result 58 39 40 def timesince(d, now=None, reversed=False): 41 """ 42 Takes two datetime objects and returns the time between d and now 43 as a nicely formatted string, e.g. "10 minutes". If d occurs after now, 44 then "0 minutes" is returned. 45 46 Units used are years, months, weeks, days, hours, and minutes. 47 Seconds and microseconds are ignored. Up to two adjacent units will be 48 displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are 49 possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not. 50 51 Adapted from 52 http://web.archive.org/web/20060617175230/http://blog.natbat.co.uk/archive/2003/Jun/14/time_since 53 """ 54 55 if isinstance(d, datetime.timedelta): 56 time_delta = d 57 else: 58 # Convert datetime.date to datetime.datetime for comparison. 59 if not isinstance(d, datetime.datetime): 60 d = datetime.datetime(d.year, d.month, d.day) 61 if now and not isinstance(now, datetime.datetime): 62 now = datetime.datetime(now.year, now.month, now.day) 63 if not now: 64 now = datetime.datetime.now(utc if is_aware(d) else None) 65 time_delta = (d - now) if reversed else (now - d) 66 result = time_to_text(time_delta) 67 return result 68 59 69 def timeuntil(d, now=None): 60 70 """ 61 71 Like timesince, but returns a string measuring the time until 62 72 the given time. 63 73 """ 64 74 return timesince(d, now, reversed=True) 75 76 def delta(time_delta): 77 """ 78 Returns seconds duration as weeks, days, hours, minutes, seconds 79 Similar to timesince/timeuntil, but works with datetime.timedelta 80 """ 81 return timesince(time_delta) 82 No newline at end of file -
docs/ref/templates/builtins.txt
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 9d096e4..15ea5c6 100644
a b Comparing offset-naive and offset-aware datetimes will return an empty string. 2088 2088 Minutes is the smallest unit used, and "0 minutes" will be returned for any 2089 2089 date that is in the past relative to the comparison point. 2090 2090 2091 .. templatefilter:: delta 2092 2093 delta 2094 ^^^^^^^^^ 2095 2096 Similar to ``timesince`` and ``timeuntil``, except that it can take timedelta 2097 as argument. For example, if user has been working on a task for a timespan, 2098 and``working_time`` is a timedelta instance holding 2099 ``datetime.timedelta(1, 43199, 999989)``, then ``{{ working_time|delta }}`` 2100 will return "1 day, 11 hours". 2101 2102 2103 As like ``timesince`` and ``timeuntil``, minutes is the smallest unit used, 2104 and "0 minutes" will be returned for any date that is in the past relative 2105 to the comparison point. 2106 2091 2107 .. templatefilter:: title 2092 2108 2093 2109 title -
tests/defaultfilters/tests.py
diff --git a/tests/defaultfilters/tests.py b/tests/defaultfilters/tests.py index 6f84c14..af1dab7 100644
a b class DefaultFiltersTests(TestCase): 552 552 datetime.datetime(2005, 12, 29)), 553 553 '1\xa0day') 554 554 555 def test_delta(self): 556 self.assertEqual( 557 delta_filter(datetime.timedelta(29, 64788)), 558 '4\xa0weeks, 1\xa0day') 559 555 560 def test_default(self): 556 561 self.assertEqual(default("val", "default"), 'val') 557 562 self.assertEqual(default(None, "default"), 'default') -
tests/template_tests/filters.py
diff --git a/tests/template_tests/filters.py b/tests/template_tests/filters.py index 142f56f..73f98da 100644
a b def get_filter_tests(): 90 90 'filter-timeuntil12' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today}, '0\xa0minutes'), 91 91 'filter-timeuntil13' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today - timedelta(hours=24)}, '1\xa0day'), 92 92 93 # Compare to a given parameter 94 'filter-delta01' : ('{{ a|delta }}', {'a': timedelta(29, 64788)}, u'4\xa0weeks, 1\xa0day'), 95 'filter-delta02' : ('{{ a|delta }}', {'a': now - (datetime.now() - timedelta(hours=36))}, '1\xa0day, 11\xa0hours'), 96 93 97 'filter-addslash01': ("{% autoescape off %}{{ a|addslashes }} {{ b|addslashes }}{% endautoescape %}", {"a": "<a>'", "b": mark_safe("<a>'")}, r"<a>\' <a>\'"), 94 98 'filter-addslash02': ("{{ a|addslashes }} {{ b|addslashes }}", {"a": "<a>'", "b": mark_safe("<a>'")}, r"<a>\' <a>\'"), 95 99 -
tests/utils_tests/test_timesince.py
diff --git a/tests/utils_tests/test_timesince.py b/tests/utils_tests/test_timesince.py index cdb95e6..2cadd1d 100644
a b from __future__ import unicode_literals 3 3 import datetime 4 4 import unittest 5 5 6 from django.utils.timesince import timesince, timeuntil 6 from django.utils.timesince import timesince, timeuntil, delta 7 7 from django.utils.tzinfo import LocalTimezone, FixedOffset 8 8 9 9 class TimesinceTests(unittest.TestCase): … … class TimesinceTests(unittest.TestCase): 123 123 self.assertEqual(timesince(future), '0\xa0minutes') 124 124 past = datetime.datetime(1980, 1, 1, tzinfo=naive()) 125 125 self.assertEqual(timeuntil(past), '0\xa0minutes') 126 127 def test_delta_with_timedelta_objects(self): 128 time_delta = datetime.timedelta(1, 43199, 999989) 129 self.assertEqual(delta(time_delta), '1\xa0day, 11\xa0hours') 130