diff --git a/django/utils/timesince.py b/django/utils/timesince.py index 06accab2e0..1bf24809d4 100644 --- a/django/utils/timesince.py +++ b/django/utils/timesince.py @@ -40,10 +40,15 @@ def timesince(d, now=None, reversed=False): if not now: now = datetime.datetime.now(utc if is_aware(d) else None) - delta = (d - now) if reversed else (now - d) + if reversed: + d, now = now, d + delta = now - d # Deal with leapyears by subtracing the number of leapdays - delta -= datetime.timedelta(calendar.leapdays(d.year, now.year)) + leapdays = calendar.leapdays(d.year, now.year) + if leapdays != 0 and calendar.isleap(d.year): + leapdays -= 1 + delta -= datetime.timedelta(leapdays) # ignore microseconds since = delta.days * 24 * 60 * 60 + delta.seconds diff --git a/docs/releases/1.10.5.txt b/docs/releases/1.10.5.txt index 381f956bc8..0c70fc04b5 100644 --- a/docs/releases/1.10.5.txt +++ b/docs/releases/1.10.5.txt @@ -14,3 +14,6 @@ Bugfixes * Fixed occasional missing plural forms in ``JavaScriptCatalog`` (:ticket:`27418`). + +* Fixed a regression in the ``timesince`` and ``timeuntil`` filters that caused + incorrect results for dates in a leap year. diff --git a/docs/releases/1.9.13.txt b/docs/releases/1.9.13.txt new file mode 100644 index 0000000000..093b40f057 --- /dev/null +++ b/docs/releases/1.9.13.txt @@ -0,0 +1,13 @@ +=========================== +Django 1.9.13 release notes +=========================== + +*Under development* + +Django 1.9.13 fixes a bug in 1.9.12. + +Bugfixes +======== + +* Fixed a regression in the ``timesince`` and ``timeuntil`` filters that caused + incorrect results for dates in a leap year. diff --git a/docs/releases/index.txt b/docs/releases/index.txt index 6b0157502c..c3734f6e58 100644 --- a/docs/releases/index.txt +++ b/docs/releases/index.txt @@ -45,6 +45,7 @@ versions of the documentation contain the release notes for any later releases. .. toctree:: :maxdepth: 1 + 1.9.13 1.9.12 1.9.11 1.9.10 diff --git a/tests/utils_tests/test_timesince.py b/tests/utils_tests/test_timesince.py index a410032acf..08c9bc2950 100644 --- a/tests/utils_tests/test_timesince.py +++ b/tests/utils_tests/test_timesince.py @@ -105,6 +105,11 @@ class TimesinceTests(unittest.TestCase): self.assertEqual(timeuntil(today - self.oneday, today), '0\xa0minutes') self.assertEqual(timeuntil(today + self.oneweek, today), '1\xa0week') + def test_leap_year(self): + start_date = datetime.date(2016, 12, 25) + self.assertEqual(timeuntil(start_date + self.oneweek, start_date), '1\xa0week') + self.assertEqual(timesince(start_date, start_date + self.oneweek), '1\xa0week') + def test_naive_datetime_with_tzinfo_attribute(self): class naive(datetime.tzinfo): def utcoffset(self, dt): @@ -117,3 +122,4 @@ class TimesinceTests(unittest.TestCase): def test_thousand_years_ago(self): t = datetime.datetime(1007, 8, 14, 13, 46, 0) self.assertEqual(timesince(t, self.t), '1000\xa0years') + self.assertEqual(timeuntil(self.t, t), '1000\xa0years')