Fixed #33879 - Adjusted month duration
Adjusted month duration to be relative to the months between d and now.
This commit is contained in:
parent
6ea0b9383d
commit
bbfc0f946a
|
@ -23,6 +23,8 @@ TIMESINCE_CHUNKS = (
|
|||
(60, "minute"),
|
||||
)
|
||||
|
||||
MONTHS_DAYS = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
|
||||
|
||||
|
||||
def timesince(d, now=None, reversed=False, time_strings=None, depth=2):
|
||||
"""
|
||||
|
@ -69,28 +71,36 @@ def timesince(d, now=None, reversed=False, time_strings=None, depth=2):
|
|||
leapdays += 1
|
||||
delta -= datetime.timedelta(leapdays)
|
||||
|
||||
# fix months duration to be relative to the months between d and now
|
||||
months = now.month - d.month
|
||||
if months > 0:
|
||||
m_days = (sum(MONTHS_DAYS[d.month - 1 : now.month - 1])) / months
|
||||
else:
|
||||
m_days = (365 - sum(MONTHS_DAYS[now.month - 1 : d.month - 1])) / (12 + months)
|
||||
timesince_chunks_adjusted = list(TIMESINCE_CHUNKS)
|
||||
timesince_chunks_adjusted[1] = (int(m_days * 24 * 60 * 60), "month")
|
||||
|
||||
# ignore microseconds
|
||||
since = delta.days * 24 * 60 * 60 + delta.seconds
|
||||
if since <= 0:
|
||||
# d is in the future compared to now, stop processing.
|
||||
return avoid_wrapping(time_strings["minute"] % {"num": 0})
|
||||
for i, (seconds, name) in enumerate(TIMESINCE_CHUNKS):
|
||||
for i, (seconds, name) in enumerate(timesince_chunks_adjusted):
|
||||
count = since // seconds
|
||||
if count != 0:
|
||||
break
|
||||
else:
|
||||
return avoid_wrapping(time_strings["minute"] % {"num": 0})
|
||||
|
||||
result = []
|
||||
current_depth = 0
|
||||
while i < len(TIMESINCE_CHUNKS) and current_depth < depth:
|
||||
seconds, name = TIMESINCE_CHUNKS[i]
|
||||
|
||||
while i < len(timesince_chunks_adjusted) and current_depth < depth:
|
||||
seconds, name = timesince_chunks_adjusted[i]
|
||||
count = since // seconds
|
||||
if count == 0:
|
||||
break
|
||||
result.append(avoid_wrapping(time_strings[name] % {"num": count}))
|
||||
# prevent errors in long intervals
|
||||
if name == "month" and count > 2:
|
||||
seconds += 10 * 60 * 60
|
||||
since -= seconds * count
|
||||
current_depth += 1
|
||||
i += 1
|
||||
|
|
|
@ -506,8 +506,8 @@ class HumanizeTests(SimpleTestCase):
|
|||
# "%(delta)s from now" translations
|
||||
now + datetime.timedelta(days=1),
|
||||
now + datetime.timedelta(days=2),
|
||||
now + datetime.timedelta(days=30),
|
||||
now + datetime.timedelta(days=60),
|
||||
now + datetime.timedelta(days=31),
|
||||
now + datetime.timedelta(days=61),
|
||||
now + datetime.timedelta(days=500),
|
||||
now + datetime.timedelta(days=865),
|
||||
]
|
||||
|
|
|
@ -147,7 +147,7 @@ class TimesinceTests(TimezoneTestCase):
|
|||
)
|
||||
self.assertEqual(output, "1\xa0day")
|
||||
|
||||
# Test for #33879 (wrong results for 11 months + several weeks)
|
||||
# Tests for #33879 (wrong results for 11 months + several weeks)
|
||||
@setup({"timesince19": "{{ earlier|timesince }}"})
|
||||
def test_timesince19(self):
|
||||
output = self.engine.render_to_string(
|
||||
|
@ -155,6 +155,15 @@ class TimesinceTests(TimezoneTestCase):
|
|||
)
|
||||
self.assertEqual(output, "11\xa0months, 3\xa0weeks")
|
||||
|
||||
@setup({"timesince20": "{{ a|timesince:b }}"})
|
||||
def test_timesince20(self):
|
||||
now = datetime(2018, 5, 9)
|
||||
output = self.engine.render_to_string(
|
||||
"timesince20",
|
||||
{"a": now, "b": now + timedelta(days=365) + timedelta(days=364)},
|
||||
)
|
||||
self.assertEqual(output, "1\xa0year, 11\xa0months")
|
||||
|
||||
|
||||
class FunctionTests(SimpleTestCase):
|
||||
def test_since_now(self):
|
||||
|
|
|
@ -16,7 +16,7 @@ class TimesinceTests(TestCase):
|
|||
self.onehour = datetime.timedelta(hours=1)
|
||||
self.oneday = datetime.timedelta(days=1)
|
||||
self.oneweek = datetime.timedelta(days=7)
|
||||
self.onemonth = datetime.timedelta(days=30)
|
||||
self.onemonth = datetime.timedelta(days=31)
|
||||
self.oneyear = datetime.timedelta(days=365)
|
||||
|
||||
def test_equal_datetimes(self):
|
||||
|
|
Loading…
Reference in New Issue