Skip to content

Commit 8936517

Browse files
fix(ta): seconds to duration function (#3891)
1 parent 4d54c6a commit 8936517

File tree

2 files changed

+47
-17
lines changed

2 files changed

+47
-17
lines changed

src/shared/utils/dates.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,24 @@ describe('formatTimeFromSeconds', () => {
3434
it('returns the correct time format when totalSeconds is greater than 0', () => {
3535
expect(formatTimeFromSeconds(3661)).toBe('1h 1m 1s')
3636
})
37+
38+
it('returns the correct time format when totalSeconds is a float', () => {
39+
expect(formatTimeFromSeconds(12901948.144373389)).toBe('149d 7h 52m 28s')
40+
})
41+
42+
it('returns the correct time format when totalSeconds is less than 1', () => {
43+
expect(formatTimeFromSeconds(0.5)).toBe('<1s')
44+
})
45+
46+
it('returns "N/A" when totalSeconds is negative', () => {
47+
expect(formatTimeFromSeconds(-1)).toBe('N/A')
48+
})
49+
50+
it('returns only minutes when totalSeconds is an exact number of minutes', () => {
51+
expect(formatTimeFromSeconds(120)).toBe('2m')
52+
})
53+
54+
it('handles float values that round down', () => {
55+
expect(formatTimeFromSeconds(59.999)).toBe('59s')
56+
})
3757
})

src/shared/utils/dates.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import {
2-
formatDistanceToNow,
3-
fromUnixTime,
4-
intervalToDuration,
5-
parseISO,
6-
} from 'date-fns'
1+
import { formatDistanceToNow, fromUnixTime, parseISO } from 'date-fns'
2+
3+
const SECONDS_PER_DAY = 86400
4+
const SECONDS_PER_HOUR = 3600
5+
const SECONDS_PER_MINUTE = 60
76

87
export function formatTimeToNow(date?: string | number | null) {
98
if (!date) return null
@@ -16,19 +15,30 @@ export function formatTimeToNow(date?: string | number | null) {
1615
}
1716

1817
export const formatTimeFromSeconds = (totalSeconds?: number | null) => {
18+
if (totalSeconds == null || totalSeconds < 0) return 'N/A'
1919
if (totalSeconds === 0) return '0s'
20-
if (!totalSeconds) return 'N/A'
20+
if (totalSeconds < 1) return '<1s'
2121

22-
const duration = intervalToDuration({ start: 0, end: totalSeconds * 1000 })
22+
const days = Math.floor(totalSeconds / SECONDS_PER_DAY)
23+
const hours = Math.floor((totalSeconds % SECONDS_PER_DAY) / SECONDS_PER_HOUR)
24+
const minutes = Math.floor(
25+
(totalSeconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE
26+
)
27+
const seconds = Math.floor(totalSeconds % SECONDS_PER_MINUTE)
2328

24-
const { days, hours, minutes, seconds } = duration
29+
const timeParts = []
30+
if (days > 0) {
31+
timeParts.push(`${days}d`)
32+
}
33+
if (hours > 0) {
34+
timeParts.push(`${hours}h`)
35+
}
36+
if (minutes > 0) {
37+
timeParts.push(`${minutes}m`)
38+
}
39+
if (seconds > 0) {
40+
timeParts.push(`${seconds}s`)
41+
}
2542

26-
return [
27-
days ? `${days}d` : '',
28-
hours ? `${hours}h` : '',
29-
minutes ? `${minutes}m` : '',
30-
seconds ? `${seconds}s` : '',
31-
]
32-
.filter(Boolean)
33-
.join(' ')
43+
return timeParts.join(' ')
3444
}

0 commit comments

Comments
 (0)