Opened 2 years ago
Last modified 23 months ago
#33879 closed Cleanup/optimization
timesince - wrong results for 11 months + several weeks — at Version 1
Reported by: | אורי | Owned by: | nobody |
---|---|---|---|
Component: | Utilities | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Hi,
I'm using timesince
to format how much time passed since the user last visited my website. The code is:
_("On {date} ({timesince} ago)").format( date=formats.date_format(value=last_visit_date), timesince=timesince(d=last_visit_date, now=today) )
Now I created a test to test these times, and I noticed that for a year minus a week, the result is "(11\u00A0months, 4\u00A0weeks ago)" (why the "\u00A0" and not a space?), and for a year minus 2 weeks, the result is "(11\u00A0months, 3\u00A0weeks ago)":
user_18 = ActiveUserFactory() user_18.profile.last_visit -= (relativedelta(years=1) - relativedelta(weeks=1)) user_18.save_user_and_profile() self.assertIs(expr1={'en': "(11\u00A0months, 4\u00A0weeks ago)", 'he': "(לפני 11\u00A0חודשים, 4\u00A0שבועות)"}[self.language_code] in user_18.profile.last_visit_str, expr2=True) user_19 = ActiveUserFactory() user_19.profile.last_visit -= (relativedelta(years=1) - relativedelta(weeks=2)) user_19.save_user_and_profile() self.assertIs(expr1={'en': "(11\u00A0months, 3\u00A0weeks ago)", 'he': "(לפני 11\u00A0חודשים, 3\u00A0שבועות)"}[self.language_code] in user_19.profile.last_visit_str, expr2=True)
Now, a year is 365 days, a year minus one week is 358 days, which is 11 months and 3 weeks. I think the problem is because each month is considered as 30 days, so 11 months are 330 days. But 11 months are about 334 days actually, so we receive a result of 11 months and 4 weeks, instead of 11 months and 3 weeks.
A fix would be to change the number of days in a month to 30.4 (the average), optionally only for more than 2 months (because it makes sense to calculate exactly 30 days for the first 2 months).
Also, it's important to calculate the number of days in 11 (or any number) of months as an integer, so that the result will not display hours and minutes (if depth
is big enough).