summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2016-12-27 15:29:11 +0100
committerTim Graham <timograham@gmail.com>2016-12-27 09:32:23 -0500
commit50830aa1d93a1a703a5c2c546f730c1afb3f4a0a (patch)
treef458b78ce11de03758b71a331cb12abbef51a095
parent7418690bf71da5ce9b6bdab6086515c2763b5820 (diff)
[1.9.x] Fixed #27637 -- Fixed timesince, timeuntil in leap year edge case.
Backport of 3e5c5e6754648590e87725b66d11d283079728e6 from master
-rw-r--r--django/utils/timesince.py9
-rw-r--r--docs/releases/1.9.13.txt13
-rw-r--r--docs/releases/index.txt1
-rw-r--r--tests/utils_tests/test_timesince.py6
4 files changed, 27 insertions, 2 deletions
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.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 a628ee1875..82288e159f 100644
--- a/docs/releases/index.txt
+++ b/docs/releases/index.txt
@@ -25,6 +25,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 ea1064f902..ecd0dfa336 100644
--- a/tests/utils_tests/test_timesince.py
+++ b/tests/utils_tests/test_timesince.py
@@ -123,6 +123,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):
@@ -135,3 +140,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')