diff --git a/rhodecode/lib/utils2.py b/rhodecode/lib/utils2.py --- a/rhodecode/lib/utils2.py +++ b/rhodecode/lib/utils2.py @@ -357,23 +357,27 @@ def age(prevdate): :rtype: unicode :returns: unicode words describing age """ - + now = datetime.datetime.now() + now = now.replace(microsecond=0) order = ['year', 'month', 'day', 'hour', 'minute', 'second'] deltas = {} future = False - # Get date parts deltas - now = datetime.datetime.now() if prevdate > now: now, prevdate = prevdate, now future = True + # Get date parts deltas for part in order: - deltas[part] = getattr(now, part) - getattr(prevdate, part) + if future: + import dateutil + d = dateutil.relativedelta.relativedelta(now, prevdate) + deltas[part] = getattr(d, part + 's') + else: + deltas[part] = getattr(now, part) - getattr(prevdate, part) # Fix negative offsets (there is 1 second between 10:59:59 and 11:00:00, # not 1 hour, -59 minutes and -59 seconds) - for num, length in [(5, 60), (4, 60), (3, 24)]: # seconds, minutes, hours part = order[num] carry_part = order[num - 1] diff --git a/rhodecode/tests/test_libs.py b/rhodecode/tests/test_libs.py --- a/rhodecode/tests/test_libs.py +++ b/rhodecode/tests/test_libs.py @@ -119,39 +119,36 @@ class TestLibs(unittest.TestCase): self.assertEqual(s, extract_mentioned_users(sample)) def test_age(self): - import calendar from rhodecode.lib.utils2 import age + from dateutil import relativedelta n = datetime.datetime.now() - delt = lambda *args, **kwargs: datetime.timedelta(*args, **kwargs) - prev_month = n.month - 1 if n.month != 1 else n.month - 2 + delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs) + self.assertEqual(age(n), u'just now') - self.assertEqual(age(n - delt(seconds=1)), u'1 second ago') - self.assertEqual(age(n - delt(seconds=60 * 2)), u'2 minutes ago') - self.assertEqual(age(n - delt(hours=1)), u'1 hour ago') - self.assertEqual(age(n - delt(hours=24)), u'1 day ago') - self.assertEqual(age(n - delt(hours=24 * 5)), u'5 days ago') - self.assertEqual(age(n - delt(hours=24 * (calendar.mdays[prev_month]))), - u'1 month ago') - self.assertEqual(age(n - delt(hours=24 * (calendar.mdays[prev_month] + 2))), - u'1 month and 2 days ago') - self.assertEqual(age(n - delt(hours=24 * 400)), u'1 year and 1 month ago') + self.assertEqual(age(n + delt(seconds=-1)), u'1 second ago') + self.assertEqual(age(n + delt(seconds=-60 * 2)), u'2 minutes ago') + self.assertEqual(age(n + delt(hours=-1)), u'1 hour ago') + self.assertEqual(age(n + delt(hours=-24)), u'1 day ago') + self.assertEqual(age(n + delt(hours=-24 * 5)), u'5 days ago') + self.assertEqual(age(n + delt(months=-1)), u'1 month ago') + self.assertEqual(age(n + delt(months=-1, days=-2)), u'1 month and 2 days ago') + self.assertEqual(age(n + delt(years=-1, months=-1)), u'1 year and 1 month ago') def test_age_in_future(self): - import calendar from rhodecode.lib.utils2 import age + from dateutil import relativedelta n = datetime.datetime.now() - delt = lambda *args, **kwargs: datetime.timedelta(*args, **kwargs) + delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs) + self.assertEqual(age(n), u'just now') self.assertEqual(age(n + delt(seconds=1)), u'in 1 second') self.assertEqual(age(n + delt(seconds=60 * 2)), u'in 2 minutes') self.assertEqual(age(n + delt(hours=1)), u'in 1 hour') self.assertEqual(age(n + delt(hours=24)), u'in 1 day') self.assertEqual(age(n + delt(hours=24 * 5)), u'in 5 days') - self.assertEqual(age(n + delt(hours=24 * (calendar.mdays[n.month]))), - u'in 1 month') - self.assertEqual(age(n + delt(hours=24 * (calendar.mdays[n.month] + 1))), - u'in 1 month and 1 day') - self.assertEqual(age(n + delt(hours=24 * 400)), u'in 1 year and 1 month') + self.assertEqual(age(n + delt(months=1)), u'in 1 month') + self.assertEqual(age(n + delt(months=1, days=1)), u'in 1 month and 1 day') + self.assertEqual(age(n + delt(years=1, months=1)), u'in 1 year and 1 month') def test_tag_exctrator(self): sample = (