From 5dd5fec5637ed723f71eb22ae56dc3e02241482f Mon Sep 17 00:00:00 2001 From: "Audric Onockx (auon)" Date: Wed, 26 Oct 2022 08:05:31 +0000 Subject: [PATCH] [FIX] web: format float time correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps: Go to timesheet (grid view). Launch the timer. Got to list view and check the new line. Issue: Few seconds before the minute, the seconds are negative. Fix: Convert hours decimals in milliseconds before calculating minutes and seconds. Also deleted the unnecessary condition for abs(). Also changes some `${...}` to String(...) to reduce noise. closes odoo/odoo#104209 X-original-commit: 9d3e7ab4e903d2ada99693aa23e024d3ff84f5fb Signed-off-by: Géry Debongnie --- addons/web/static/src/views/fields/formatters.js | 14 +++++++------- .../static/tests/views/fields/formatters_tests.js | 6 ++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/addons/web/static/src/views/fields/formatters.js b/addons/web/static/src/views/fields/formatters.js index 8bd27f7cc68..0355212cc98 100644 --- a/addons/web/static/src/views/fields/formatters.js +++ b/addons/web/static/src/views/fields/formatters.js @@ -229,24 +229,24 @@ export function formatFloatTime(value, options = {}) { return ""; } const isNegative = value < 0; - if (isNegative) { - value = Math.abs(value); - } + value = Math.abs(value); + let hour = Math.floor(value); + const milliSecLeft = Math.round(value * 3600000) - hour * 3600000; // Although looking quite overkill, the following line ensures that we do // not have float issues while still considering that 59s is 00:00. - let min = Math.floor((Math.round((value % 1) * 100) / 100) * 60); + let min = Math.floor(milliSecLeft / 60000); if (min === 60) { min = 0; hour = hour + 1; } - min = `${min}`.padStart(2, "0"); + min = String(min).padStart(2, "0"); if (!options.noLeadingZeroHour) { - hour = `${hour}`.padStart(2, "0"); + hour = String(hour).padStart(2, "0"); } let sec = ""; if (options.displaySeconds) { - sec = ":" + `${Math.round((value % 1) * 3600) - min * 60}`.padStart(2, "0"); + sec = ":" + String(Math.floor((milliSecLeft % 60000) / 1000)).padStart(2, "0"); } return `${isNegative ? "-" : ""}${hour}:${min}${sec}`; } diff --git a/addons/web/static/tests/views/fields/formatters_tests.js b/addons/web/static/tests/views/fields/formatters_tests.js index a5104730782..5b3cb8c7e5a 100644 --- a/addons/web/static/tests/views/fields/formatters_tests.js +++ b/addons/web/static/tests/views/fields/formatters_tests.js @@ -167,9 +167,14 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual(formatFloatTime(2), "02:00"); assert.strictEqual(formatFloatTime(3.5), "03:30"); assert.strictEqual(formatFloatTime(0.25), "00:15"); + assert.strictEqual(formatFloatTime(2 / 60, { displaySeconds: true }), "00:02:00"); + assert.strictEqual(formatFloatTime(2 / 60 + 1 / 3600, { displaySeconds: true }), "00:02:01"); + assert.strictEqual(formatFloatTime(2 / 60 + 2 / 3600, { displaySeconds: true }), "00:02:02"); + assert.strictEqual(formatFloatTime(2 / 60 + 3 / 3600, { displaySeconds: true }), "00:02:03"); assert.strictEqual(formatFloatTime(0.25, { displaySeconds: true }), "00:15:00"); assert.strictEqual(formatFloatTime(0.25 + 15 / 3600, { displaySeconds: true }), "00:15:15"); assert.strictEqual(formatFloatTime(0.25 + 45 / 3600, { displaySeconds: true }), "00:15:45"); + assert.strictEqual(formatFloatTime(56 / 3600, { displaySeconds: true }), "00:00:56"); assert.strictEqual(formatFloatTime(-0.5), "-00:30"); const options = { noLeadingZeroHour: true }; @@ -178,6 +183,7 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual(formatFloatTime(3.5, { ...options, displaySeconds: true }), "3:30:00"); assert.strictEqual(formatFloatTime(3.5 + 15 / 3600, { ...options, displaySeconds: true }), "3:30:15"); assert.strictEqual(formatFloatTime(3.5 + 45 / 3600, { ...options, displaySeconds: true }), "3:30:45"); + assert.strictEqual(formatFloatTime(56 / 3600, { ...options, displaySeconds: true }), "0:00:56"); assert.strictEqual(formatFloatTime(-0.5, options), "-0:30"); });