-
-
Notifications
You must be signed in to change notification settings - Fork 70
Precisedelta rounding #254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #254 +/- ##
==========================================
+ Coverage 99.49% 99.51% +0.01%
==========================================
Files 11 11
Lines 794 820 +26
==========================================
+ Hits 790 816 +26
Misses 4 4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
29d5ae3
to
036417f
Compare
%d and %0.0f do not produce the same values. So we will first apply the required formatting and turn the formatted string back into a float or int. YEARS needs to be treated slightly differently as it needs to be formatted with `intcomma`. We first check if the resulting value does not have any fractional part and if not, we turn it into an int, so that it string output is what a human would expect. Added several unittests to highlight some of the differences between using %d and %.0f as a format in precisedelta.
036417f
to
191f093
Compare
We only try to round the value based on the format provided if we are dealing with the minimum_unit.
I need a bit more time. I think I can even fix #30 with this PR. |
I added one more commit to address #30 issue. Unittests hopefully describe what is the expected behaviour. I had to make some decisions for corner cases. I'm happy to discuss if there is a disagreement on any of this. |
3bf9f15
to
3ae5e73
Compare
The logic about rounding due to formatting has been moved to _quotient_and_remainder because this is where we have all the logic regarding the minimum unit and suppress units. Also removed _carry function. Instead use the same logic than was used for calculating the `secs` based on the remaining amount of days. It is done now also for `usecs` based on the `secs` remaining. Add another block of logic to check after rounding if any units should be promoted to a higher unit, in case of a rounding up.
3ae5e73
to
efa5e60
Compare
src/humanize/time.py
Outdated
def _rounding_by_fmt(format: str, value: float) -> float | int: | ||
"""Round a number according to the string format provided. | ||
|
||
The string format is the old printf-style String Formatting. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string format is the old printf-style String Formatting. | |
The string format is the old printf-style string formatting. |
tests/test_time.py
Outdated
(dt.timedelta(days=31), "seconds", "1 month and 12 hours"), | ||
(dt.timedelta(days=32), "seconds", "1 month, 1 day and 12 hours"), | ||
(dt.timedelta(days=62), "seconds", "2 months and 1 day"), | ||
(dt.timedelta(days=92), "seconds", "3 months and 12 hours"), | ||
(dt.timedelta(days=31), "days", "1 month and 0.50 days"), | ||
(dt.timedelta(days=32), "days", "1 month and 1.50 days"), | ||
(dt.timedelta(days=62), "days", "2 months and 1 day"), | ||
(dt.timedelta(days=92), "days", "3 months and 0.50 days"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
I know we use 30.5 days = month for some approximations but I think this extra 12 hours may be unexpected?
import datetime as dt
from humanize.time import precisedelta
for days in (30, 31, 32):
print(f"{days} -> {precisedelta(dt.timedelta(days=days))}")
Before:
30 -> 30 days
31 -> 1 month and 0 days
32 -> 1 month and 1 days
After:
30 -> 30 days
31 -> 1 month and 12 hours
32 -> 1 month, 1 day and 12 hours
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you mean and I understand it's indeed confusing. I took it a bit too literally that one month is 30.5 days.
I pushed a new commit where we only consider months to be 30.5 days on average. We round down any remainder when we try to determine the number of months. This means that 31 days is 1 month and 61 days is 2 months.
Although 1 month is 30.5 days on average, we want 31 days to be one month, and not remainder of 0.5 days which would not be intuitive.
32d399b
to
1687b7d
Compare
Fixes #14
Fixes #20
Fixes #30
Based on PR #39 .
Changes proposed in this pull request:
main
and resolve the conflicts.format
in favour of a new helper function which will evaluate the rounding based on the format provided%d
format and%.0f
.