Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/shared/utils/dates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Comment on lines +37 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test case for float values is good, but the specific large float value 12901948.144373389 seems arbitrary. Consider using a more readable test case or adding a comment explaining why this specific value was chosen. Also, consider adding more edge cases for floats, such as values between 0 and 1.

Suggested change
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 a float', () => {
// Test large float value
expect(formatTimeFromSeconds(12901948.144373389)).toBe('149d 7h 52m 28s')
})
it('returns "0s" when totalSeconds is a small float less than 1', () => {
expect(formatTimeFromSeconds(0.5)).toBe('0s')
})

})

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')
})
})
44 changes: 27 additions & 17 deletions src/shared/utils/dates.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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(' ')
}