Opened 21 months ago
Closed 20 months ago
#34483 closed Bug (fixed)
Negative result of django.utils.timesince.timesince
Reported by: | Lorenzo Peña | Owned by: | Natalia Bidart |
---|---|---|---|
Component: | Utilities | Version: | 4.2 |
Severity: | Release blocker | Keywords: | timesince |
Cc: | GianpaoloBranca, Natalia Bidart | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Reproducible example:
import zoneinfo import datetime as _dt from django.utils.timesince import timesince import django.utils.timezone as _timezone timesince(_timezone.now().astimezone(zoneinfo.ZoneInfo(key='Europe/Berlin'))-_dt.timedelta(seconds=1)) >>> '-1\xa0Year, 11\xa0Months'
Change History (17)
comment:1 by , 21 months ago
Cc: | added |
---|---|
Severity: | Normal → Release blocker |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 21 months ago
Cc: | added |
---|
comment:3 by , 21 months ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:5 by , 21 months ago
Needs tests: | set |
---|---|
Patch needs improvement: | set |
comment:6 by , 21 months ago
Needs tests: | unset |
---|---|
Patch needs improvement: | unset |
Triage Stage: | Accepted → Ready for checkin |
comment:9 by , 20 months ago
Has patch: | unset |
---|---|
Resolution: | fixed |
Status: | closed → new |
Triage Stage: | Ready for checkin → Accepted |
It seems that there is still an issue when a time difference is less than 1 day but days are different, see logs.
comment:10 by , 20 months ago
Status: | new → assigned |
---|
comment:12 by , 20 months ago
It seems that now
must be in the same time zone (as you suggested at the beginning), however we also have to change time zone when now
is passed, e.g.
-
django/utils/timesince.py
diff --git a/django/utils/timesince.py b/django/utils/timesince.py index 94ba24d48a..9b9dd45af9 100644
a b def timesince(d, now=None, reversed=False, time_strings=None, depth=2): 63 63 if now and not isinstance(now, datetime.datetime): 64 64 now = datetime.datetime(now.year, now.month, now.day) 65 65 66 now = now or datetime.datetime.now(datetime.timezone.utc if is_aware(d) else None) 66 if is_aware(d): 67 now = now.astimezone(d.tzinfo) if now else datetime.datetime.now(tz=d.tzinfo) 68 else: 69 now = now or datetime.datetime.now() 67 70 68 71 if reversed: 69 72 d, now = now, d … … def timesince(d, now=None, reversed=False, time_strings=None, depth=2): 77 80 78 81 # Get years and months. 79 82 total_months = (now.year - d.year) * 12 + (now.month - d.month) 80 time_delta = delta - datetime.timedelta(days=delta.days) 81 if d.day > now.day or (d.day == now.day and time_delta.total_seconds() < 0): 83 if d.day > now.day or (d.day == now.day and d.time() > now.time()): 82 84 total_months -= 1 83 85 years, months = divmod(total_months, 12) 84 86
see a regression test:
-
tests/utils_tests/test_timesince.py
diff --git a/tests/utils_tests/test_timesince.py b/tests/utils_tests/test_timesince.py index d54fce2be6..e023e95148 100644
a b class TimesinceTests(TestCase): 258 258 with self.subTest(value): 259 259 self.assertEqual(timesince(value), expected) 260 260 261 @requires_tz_support 262 def test_less_than_a_day_cross_day_with_zoneinfo(self): 263 now_with_zoneinfo = timezone.make_aware( 264 datetime.datetime(2023, 4, 14, 1, 30, 30), 265 zoneinfo.ZoneInfo(key="Asia/Kathmandu") # UTC+05:45 266 ) 267 now_utc = now_with_zoneinfo.astimezone(datetime.timezone.utc) 268 tests = [ 269 (now_with_zoneinfo, "0\xa0minutes"), 270 (now_with_zoneinfo - self.onemicrosecond, "0\xa0minutes"), 271 (now_with_zoneinfo - self.onesecond, "0\xa0minutes"), 272 (now_with_zoneinfo - self.oneminute, "1\xa0minute"), 273 (now_with_zoneinfo - self.onehour, "1\xa0hour"), 274 ] 275 for value, expected in tests: 276 with self.subTest(value): 277 self.assertEqual(timesince(value, now_utc), expected) 278 261 279 262 280 @requires_tz_support 263 281 @override_settings(USE_TZ=True)
What do you think?
comment:14 by , 20 months ago
Has patch: | set |
---|
comment:17 by , 20 months ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Note:
See TracTickets
for help on using tickets.
Thanks for the report.
Regression in 8d67e16493c903adc9d049141028bc0fff43f8c8.
Reproduced at 3b4728310a7a64f8fcc548163b0aa5f98a5c78f5.