Loading django/contrib/humanize/templatetags/humanize.py +6 −2 Original line number Diff line number Diff line from __future__ import unicode_literals import re from datetime import date, datetime, timedelta from datetime import date, datetime from django import template from django.conf import settings Loading Loading @@ -143,7 +143,9 @@ def apnumber(value): return value return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1] @register.filter # Perform the comparison in the default time zone when USE_TZ = True # (unless a specific time zone has been applied with the |timezone filter). @register.filter(expects_localtime=True) def naturalday(value, arg=None): """ For date values that are tomorrow, today or yesterday compared to Loading @@ -169,6 +171,8 @@ def naturalday(value, arg=None): return _('yesterday') return defaultfilters.date(value, arg) # This filter doesn't require expects_localtime=True because it deals properly # with both naive and aware datetimes. Therefore avoid the cost of conversion. @register.filter def naturaltime(value): """ Loading django/contrib/humanize/tests.py +47 −25 Original line number Diff line number Diff line from __future__ import unicode_literals import datetime import new from django.contrib.humanize.templatetags import humanize from django.template import Template, Context, defaultfilters from django.test import TestCase from django.utils import translation, tzinfo from django.utils.translation import ugettext as _ from django.test.utils import override_settings from django.utils.html import escape from django.utils.timezone import utc from django.utils import translation from django.utils.translation import ugettext as _ from django.utils import tzinfo # Mock out datetime in some tests so they don't fail occasionally when they # run too slow. Use a fixed datetime for datetime.now(). DST change in # America/Chicago (the default time zone) happened on March 11th in 2012. now = datetime.datetime(2012, 3, 9, 22, 30) class MockDateTime(datetime.datetime): @classmethod def now(self, tz=None): if tz is None or tz.utcoffset(now) is None: return now else: # equals now.replace(tzinfo=utc) return now.replace(tzinfo=tz) + tz.utcoffset(now) class HumanizeTests(TestCase): Loading Loading @@ -109,28 +127,36 @@ class HumanizeTests(TestCase): self.humanize_tester(test_list, result_list, 'naturalday') def test_naturalday_tz(self): from django.contrib.humanize.templatetags.humanize import naturalday today = datetime.date.today() tz_one = tzinfo.FixedOffset(datetime.timedelta(hours=-12)) tz_two = tzinfo.FixedOffset(datetime.timedelta(hours=12)) # Can be today or yesterday date_one = datetime.datetime(today.year, today.month, today.day, tzinfo=tz_one) naturalday_one = naturalday(date_one) naturalday_one = humanize.naturalday(date_one) # Can be today or tomorrow date_two = datetime.datetime(today.year, today.month, today.day, tzinfo=tz_two) naturalday_two = naturalday(date_two) naturalday_two = humanize.naturalday(date_two) # As 24h of difference they will never be the same self.assertNotEqual(naturalday_one, naturalday_two) def test_naturalday_uses_localtime(self): # Regression for #18504 # This is 2012-03-08HT19:30:00-06:00 in Ameria/Chicago dt = datetime.datetime(2012, 3, 9, 1, 30, tzinfo=utc) orig_humanize_datetime, humanize.datetime = humanize.datetime, MockDateTime try: with override_settings(USE_TZ=True): self.humanize_tester([dt], ['yesterday'], 'naturalday') finally: humanize.datetime = orig_humanize_datetime def test_naturaltime(self): class naive(datetime.tzinfo): def utcoffset(self, dt): return None # we're going to mock datetime.datetime, so use a fixed datetime now = datetime.datetime(2011, 8, 15, 1, 23) test_list = [ now, now - datetime.timedelta(seconds=1), Loading @@ -148,6 +174,7 @@ class HumanizeTests(TestCase): now + datetime.timedelta(hours=1, minutes=30, seconds=30), now + datetime.timedelta(hours=23, minutes=50, seconds=50), now + datetime.timedelta(days=1), now + datetime.timedelta(days=2, hours=6), now + datetime.timedelta(days=500), now.replace(tzinfo=naive()), now.replace(tzinfo=utc), Loading @@ -169,27 +196,22 @@ class HumanizeTests(TestCase): 'an hour from now', '23 hours from now', '1 day from now', '2 days, 6 hours from now', '1 year, 4 months from now', 'now', 'now', ] # mock out datetime so these tests don't fail occasionally when the # test runs too slow class MockDateTime(datetime.datetime): @classmethod def now(self, tz=None): if tz is None or tz.utcoffset(now) is None: return now else: # equals now.replace(tzinfo=utc) return now.replace(tzinfo=tz) + tz.utcoffset(now) from django.contrib.humanize.templatetags import humanize orig_humanize_datetime = humanize.datetime humanize.datetime = MockDateTime # Because of the DST change, 2 days and 6 hours after the chosen # date in naive arithmetic is only 2 days and 5 hours after in # aware arithmetic. result_list_with_tz_support = result_list[:] assert result_list_with_tz_support[-4] == '2 days, 6 hours from now' result_list_with_tz_support[-4] == '2 days, 5 hours from now' orig_humanize_datetime, humanize.datetime = humanize.datetime, MockDateTime try: self.humanize_tester(test_list, result_list, 'naturaltime') with override_settings(USE_TZ=True): self.humanize_tester(test_list, result_list_with_tz_support, 'naturaltime') finally: humanize.datetime = orig_humanize_datetime Loading
django/contrib/humanize/templatetags/humanize.py +6 −2 Original line number Diff line number Diff line from __future__ import unicode_literals import re from datetime import date, datetime, timedelta from datetime import date, datetime from django import template from django.conf import settings Loading Loading @@ -143,7 +143,9 @@ def apnumber(value): return value return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1] @register.filter # Perform the comparison in the default time zone when USE_TZ = True # (unless a specific time zone has been applied with the |timezone filter). @register.filter(expects_localtime=True) def naturalday(value, arg=None): """ For date values that are tomorrow, today or yesterday compared to Loading @@ -169,6 +171,8 @@ def naturalday(value, arg=None): return _('yesterday') return defaultfilters.date(value, arg) # This filter doesn't require expects_localtime=True because it deals properly # with both naive and aware datetimes. Therefore avoid the cost of conversion. @register.filter def naturaltime(value): """ Loading
django/contrib/humanize/tests.py +47 −25 Original line number Diff line number Diff line from __future__ import unicode_literals import datetime import new from django.contrib.humanize.templatetags import humanize from django.template import Template, Context, defaultfilters from django.test import TestCase from django.utils import translation, tzinfo from django.utils.translation import ugettext as _ from django.test.utils import override_settings from django.utils.html import escape from django.utils.timezone import utc from django.utils import translation from django.utils.translation import ugettext as _ from django.utils import tzinfo # Mock out datetime in some tests so they don't fail occasionally when they # run too slow. Use a fixed datetime for datetime.now(). DST change in # America/Chicago (the default time zone) happened on March 11th in 2012. now = datetime.datetime(2012, 3, 9, 22, 30) class MockDateTime(datetime.datetime): @classmethod def now(self, tz=None): if tz is None or tz.utcoffset(now) is None: return now else: # equals now.replace(tzinfo=utc) return now.replace(tzinfo=tz) + tz.utcoffset(now) class HumanizeTests(TestCase): Loading Loading @@ -109,28 +127,36 @@ class HumanizeTests(TestCase): self.humanize_tester(test_list, result_list, 'naturalday') def test_naturalday_tz(self): from django.contrib.humanize.templatetags.humanize import naturalday today = datetime.date.today() tz_one = tzinfo.FixedOffset(datetime.timedelta(hours=-12)) tz_two = tzinfo.FixedOffset(datetime.timedelta(hours=12)) # Can be today or yesterday date_one = datetime.datetime(today.year, today.month, today.day, tzinfo=tz_one) naturalday_one = naturalday(date_one) naturalday_one = humanize.naturalday(date_one) # Can be today or tomorrow date_two = datetime.datetime(today.year, today.month, today.day, tzinfo=tz_two) naturalday_two = naturalday(date_two) naturalday_two = humanize.naturalday(date_two) # As 24h of difference they will never be the same self.assertNotEqual(naturalday_one, naturalday_two) def test_naturalday_uses_localtime(self): # Regression for #18504 # This is 2012-03-08HT19:30:00-06:00 in Ameria/Chicago dt = datetime.datetime(2012, 3, 9, 1, 30, tzinfo=utc) orig_humanize_datetime, humanize.datetime = humanize.datetime, MockDateTime try: with override_settings(USE_TZ=True): self.humanize_tester([dt], ['yesterday'], 'naturalday') finally: humanize.datetime = orig_humanize_datetime def test_naturaltime(self): class naive(datetime.tzinfo): def utcoffset(self, dt): return None # we're going to mock datetime.datetime, so use a fixed datetime now = datetime.datetime(2011, 8, 15, 1, 23) test_list = [ now, now - datetime.timedelta(seconds=1), Loading @@ -148,6 +174,7 @@ class HumanizeTests(TestCase): now + datetime.timedelta(hours=1, minutes=30, seconds=30), now + datetime.timedelta(hours=23, minutes=50, seconds=50), now + datetime.timedelta(days=1), now + datetime.timedelta(days=2, hours=6), now + datetime.timedelta(days=500), now.replace(tzinfo=naive()), now.replace(tzinfo=utc), Loading @@ -169,27 +196,22 @@ class HumanizeTests(TestCase): 'an hour from now', '23 hours from now', '1 day from now', '2 days, 6 hours from now', '1 year, 4 months from now', 'now', 'now', ] # mock out datetime so these tests don't fail occasionally when the # test runs too slow class MockDateTime(datetime.datetime): @classmethod def now(self, tz=None): if tz is None or tz.utcoffset(now) is None: return now else: # equals now.replace(tzinfo=utc) return now.replace(tzinfo=tz) + tz.utcoffset(now) from django.contrib.humanize.templatetags import humanize orig_humanize_datetime = humanize.datetime humanize.datetime = MockDateTime # Because of the DST change, 2 days and 6 hours after the chosen # date in naive arithmetic is only 2 days and 5 hours after in # aware arithmetic. result_list_with_tz_support = result_list[:] assert result_list_with_tz_support[-4] == '2 days, 6 hours from now' result_list_with_tz_support[-4] == '2 days, 5 hours from now' orig_humanize_datetime, humanize.datetime = humanize.datetime, MockDateTime try: self.humanize_tester(test_list, result_list, 'naturaltime') with override_settings(USE_TZ=True): self.humanize_tester(test_list, result_list_with_tz_support, 'naturaltime') finally: humanize.datetime = orig_humanize_datetime