From 9f2db10548a1c0eb8decc2170c67a95fcdac01e9 Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Sun, 2 Nov 2025 15:17:26 +0100 Subject: [PATCH] fix: prevent rounding error show 60s --- .../src/common/utils/__tests__/time.test.ts | 19 ++++++++++++++++++- apps/client/src/common/utils/time.ts | 8 +++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/apps/client/src/common/utils/__tests__/time.test.ts b/apps/client/src/common/utils/__tests__/time.test.ts index b79ce13b9..429300f7d 100644 --- a/apps/client/src/common/utils/__tests__/time.test.ts +++ b/apps/client/src/common/utils/__tests__/time.test.ts @@ -1,4 +1,6 @@ -import { formatTime, nowInMillis } from '../time'; +import { MILLIS_PER_HOUR, MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-utils'; + +import { formatDuration, formatTime, nowInMillis } from '../time'; describe('nowInMillis()', () => { it('should return the current time in milliseconds', () => { @@ -38,3 +40,18 @@ describe('formatTime()', () => { expect(time).toStrictEqual('-01:00'); }); }); + +describe('formatDuration()', () => { + it('formats durations correctly', () => { + expect(formatDuration(0)).toBe('0h 0m'); + expect(formatDuration(-5000)).toBe('0h 0m'); + expect(formatDuration(MILLIS_PER_MINUTE)).toBe('1m'); + expect(formatDuration(6 * MILLIS_PER_MINUTE + 11 * MILLIS_PER_SECOND)).toBe('6m'); + expect(formatDuration(MILLIS_PER_MINUTE * 10)).toBe('10m'); + expect(formatDuration(MILLIS_PER_MINUTE * 10 + 100)).toBe('10m'); + expect(formatDuration(MILLIS_PER_MINUTE * 10 - 100)).toBe('9m'); + expect(formatDuration(2 * MILLIS_PER_HOUR + 6 * MILLIS_PER_MINUTE)).toBe('2h6m'); + expect(formatDuration(2 * MILLIS_PER_HOUR + 6 * MILLIS_PER_MINUTE + 45 * MILLIS_PER_SECOND, false)).toBe('2h6m45s'); + expect(formatDuration(599702, false)).toBe('9m59s'); + }); +}); diff --git a/apps/client/src/common/utils/time.ts b/apps/client/src/common/utils/time.ts index dc45d7244..109436962 100644 --- a/apps/client/src/common/utils/time.ts +++ b/apps/client/src/common/utils/time.ts @@ -117,6 +117,7 @@ export function formatDuration(duration: number, hideSeconds = true): string { const hours = Math.floor(duration / MILLIS_PER_HOUR); const minutes = Math.floor((duration % MILLIS_PER_HOUR) / MILLIS_PER_MINUTE); + let result = ''; if (hours > 0) { result += `${hours}h`; @@ -126,11 +127,16 @@ export function formatDuration(duration: number, hideSeconds = true): string { } if (!hideSeconds) { - const seconds = Math.ceil((duration % MILLIS_PER_MINUTE) / MILLIS_PER_SECOND); + const remainingMs = duration % MILLIS_PER_MINUTE; + const exactSeconds = remainingMs / MILLIS_PER_SECOND; + // cap at 59 to avoid showing 60s + const seconds = Math.min(59, Math.ceil(exactSeconds)); + if (seconds > 0) { result += `${seconds}s`; } } + return result; }