diff --git a/addons/web/static/src/views/fields/formatters.js b/addons/web/static/src/views/fields/formatters.js index 8e6ef42e827..0235776d7b1 100644 --- a/addons/web/static/src/views/fields/formatters.js +++ b/addons/web/static/src/views/fields/formatters.js @@ -185,8 +185,8 @@ export function formatFloatFactor(value, options = {}) { * * @param {number | false} value * @param {Object} [options] - * @param {boolean} [options.noLeadingZeroHour] if true, format like 1:30 - * otherwise, format like 01:30 + * @param {boolean} [options.noLeadingZeroHour] if true, format like 1:30 otherwise, format like 01:30 + * @param {boolean} [options.displaySeconds] if true, format like ?1:30:00 otherwise, format like ?1:30 * @returns {string} */ export function formatFloatTime(value, options = {}) { @@ -198,7 +198,8 @@ export function formatFloatTime(value, options = {}) { value = Math.abs(value); } let hour = Math.floor(value); - let min = Math.round((value % 1) * 60); + // This 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); if (min === 60) { min = 0; hour = hour + 1; @@ -207,7 +208,11 @@ export function formatFloatTime(value, options = {}) { if (!options.noLeadingZeroHour) { hour = `${hour}`.padStart(2, "0"); } - return `${isNegative ? "-" : ""}${hour}:${min}`; + let sec = ""; + if (options.displaySeconds) { + sec = ":" + `${(Math.round((value % 1) * 3600) - min * 60)}`.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 164c0f80bfb..a5104730782 100644 --- a/addons/web/static/tests/views/fields/formatters_tests.js +++ b/addons/web/static/tests/views/fields/formatters_tests.js @@ -167,12 +167,17 @@ 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(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(-0.5), "-00:30"); const options = { noLeadingZeroHour: true }; assert.strictEqual(formatFloatTime(2, options), "2:00"); assert.strictEqual(formatFloatTime(3.5, options), "3:30"); + 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(-0.5, options), "-0:30"); });