[FIX] web: format float time correctly

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 <ged@odoo.com>
This commit is contained in:
Audric Onockx (auon)
2022-10-27 07:15:47 +02:00
committed by Laurent Stukkens (LTU)
parent 2b80646ccb
commit 5dd5fec563
2 changed files with 13 additions and 7 deletions
@@ -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}`;
}
@@ -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");
});