diff --git a/src/shared/utils/dates.test.ts b/src/shared/utils/dates.test.ts index 0ab5d9564e..063ec3428d 100644 --- a/src/shared/utils/dates.test.ts +++ b/src/shared/utils/dates.test.ts @@ -34,4 +34,24 @@ describe('formatTimeFromSeconds', () => { it('returns the correct time format when totalSeconds is greater than 0', () => { expect(formatTimeFromSeconds(3661)).toBe('1h 1m 1s') }) + + it('returns the correct time format when totalSeconds is a float', () => { + expect(formatTimeFromSeconds(12901948.144373389)).toBe('149d 7h 52m 28s') + }) + + it('returns the correct time format when totalSeconds is less than 1', () => { + expect(formatTimeFromSeconds(0.5)).toBe('<1s') + }) + + it('returns "N/A" when totalSeconds is negative', () => { + expect(formatTimeFromSeconds(-1)).toBe('N/A') + }) + + it('returns only minutes when totalSeconds is an exact number of minutes', () => { + expect(formatTimeFromSeconds(120)).toBe('2m') + }) + + it('handles float values that round down', () => { + expect(formatTimeFromSeconds(59.999)).toBe('59s') + }) }) diff --git a/src/shared/utils/dates.ts b/src/shared/utils/dates.ts index 538588c782..c3793a11f5 100644 --- a/src/shared/utils/dates.ts +++ b/src/shared/utils/dates.ts @@ -1,9 +1,8 @@ -import { - formatDistanceToNow, - fromUnixTime, - intervalToDuration, - parseISO, -} from 'date-fns' +import { formatDistanceToNow, fromUnixTime, parseISO } from 'date-fns' + +const SECONDS_PER_DAY = 86400 +const SECONDS_PER_HOUR = 3600 +const SECONDS_PER_MINUTE = 60 export function formatTimeToNow(date?: string | number | null) { if (!date) return null @@ -16,19 +15,30 @@ export function formatTimeToNow(date?: string | number | null) { } export const formatTimeFromSeconds = (totalSeconds?: number | null) => { + if (totalSeconds == null || totalSeconds < 0) return 'N/A' if (totalSeconds === 0) return '0s' - if (!totalSeconds) return 'N/A' + if (totalSeconds < 1) return '<1s' - const duration = intervalToDuration({ start: 0, end: totalSeconds * 1000 }) + const days = Math.floor(totalSeconds / SECONDS_PER_DAY) + const hours = Math.floor((totalSeconds % SECONDS_PER_DAY) / SECONDS_PER_HOUR) + const minutes = Math.floor( + (totalSeconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE + ) + const seconds = Math.floor(totalSeconds % SECONDS_PER_MINUTE) - const { days, hours, minutes, seconds } = duration + const timeParts = [] + if (days > 0) { + timeParts.push(`${days}d`) + } + if (hours > 0) { + timeParts.push(`${hours}h`) + } + if (minutes > 0) { + timeParts.push(`${minutes}m`) + } + if (seconds > 0) { + timeParts.push(`${seconds}s`) + } - return [ - days ? `${days}d` : '', - hours ? `${hours}h` : '', - minutes ? `${minutes}m` : '', - seconds ? `${seconds}s` : '', - ] - .filter(Boolean) - .join(' ') + return timeParts.join(' ') }