Defect #40914
openRounding error in my/page -> timelog
0%
Description
On the page my/page
, if the timelog is displayed, the total is shown at the top of the table. The summing is not correctly implemented, leading to rounding errors.
Reproduction and Example:
- Add time entries for one day, one issue:
- 0:10
- 0:40
- 0:10 - Navigate to
my/page
- Add the 'timelog' widget if it is not already present.
- The time entries should be shown. The total displayed is 1:01.
Implementation and Easy Fix:
Current implementation (app/views/my/blocks/_timelog.html.erb:45
):
html_hours(format_hours(entries_by_day[day].sum(&:hours)))
Summing hours introduces rounding errors. To fix this, convert to minutes first:
html_hours(format_hours(entries_by_day[day].map{|t| (t.hours * 60).to_i}.sum / 60))
Files
Related issues
Updated by Boris Brodski 5 days ago
In the same way the <h3>..</h3>
tag should be fixed:
Current implementation (app/views/my/blocks/_timelog.html.erb:7
):
l_hours_short entries.sum(&:hours)
Fix:
l_hours_short(entries.map{|t| (t.hours * 60).to_i}.sum / 60)
Updated by Go MAEDA about 1 hour ago
Here is another solution. This patch will likely also fix the issue reported in #36897.
diff --git a/lib/redmine/i18n.rb b/lib/redmine/i18n.rb
index 83ecb05eb..52221029f 100644
--- a/lib/redmine/i18n.rb
+++ b/lib/redmine/i18n.rb
@@ -93,8 +93,9 @@ module Redmine
return "" if hours.blank?
if Setting.timespan_format == 'minutes'
- h = hours.floor
- m = ((hours - h) * 60).round
+ rational_hours = hours.rationalize(Rational('1/60'))
+ h = rational_hours.truncate
+ m = ((rational_hours - h) * 60).round
"%d:%02d" % [h, m]
else
number_with_delimiter(sprintf('%.2f', hours.to_f), delimiter: nil)
Updated by Go MAEDA 23 minutes ago
Go MAEDA wrote in #note-3:
Here is another solution. This patch will likely also fix the issue reported in #36897.
[...]
Sorry, using rationalize(Rational('1/60'))
(approximation in minutes) breaks some tests. rationalize(Rational('1/3600'))
(approximation in seconds) works fine.
Failure: TimelogReportTest#test_report_all_time_by_day [test/functional/timelog_report_test.rb:87]: Expected: "162:54" Actual: "162:53". Expected 0 to be >= 1. bin/rails test test/functional/timelog_report_test.rb:84
diff --git a/lib/redmine/i18n.rb b/lib/redmine/i18n.rb
index 83ecb05eb..40b991f8a 100644
--- a/lib/redmine/i18n.rb
+++ b/lib/redmine/i18n.rb
@@ -93,8 +93,9 @@ module Redmine
return "" if hours.blank?
if Setting.timespan_format == 'minutes'
- h = hours.floor
- m = ((hours - h) * 60).round
+ rational_hours = hours.rationalize(Rational('1/3600'))
+ h = rational_hours.truncate
+ m = ((rational_hours - h) * 60).round
"%d:%02d" % [h, m]
else
number_with_delimiter(sprintf('%.2f', hours.to_f), delimiter: nil)
Updated by Go MAEDA 19 minutes ago
- Related to Defect #36897: Wrong formatting of date in Time Entries added