fix: round decimal unit values instead of truncating in integer path

Multiplying a decimal quantity by its unit multiplier in binary floating
point can land just below the exact integer (float('2.05') * 60 ==
122.999...), so int() truncated 2.05m to 122 seconds instead of 123.
Round the sub-second unit contribution before adding whole seconds.
This commit is contained in:
dualfroz committed 2026-09-04 09:22:40 +02:00
1 parent 546a3e846e
commit 7b055c8116
3 files changed
+91 -3

No files matched your search

+7 -3
View File
@@ -172,10 +172,14 @@ def timeparse(sval, granularity='seconds'):
elif ('secs' not in mdict or
mdict['secs'] is None or
mdict['secs'].isdigit()):
# we will return an integer
# we will return an integer. Round (not truncate) the
# sub-second unit contribution: multiplying a decimal
# quantity such as 2.05 minutes by 60 yields a binary
# float slightly below the exact value (122.999...), and
# int() would truncate it to 122 instead of 123.
return (
sign * int(sum([MULTIPLIERS[k] * float(v) for (k, v) in
list(mdict.items()) if k != 'secs' and v is not None])) +
sign * int(round(sum([MULTIPLIERS[k] * float(v) for (k, v) in
list(mdict.items()) if k != 'secs' and v is not None]))) +
(int(mdict['secs'], 10) if mdict['secs'] else 0))
else:
# SECS is a float, we will return a float