(
date: Date | string | null,
options: FormatTimeUntilOptions = {},
)
| 49 | * formatTimeUntil(pastDate, { fallback: '0h' }) // "0h" |
| 50 | */ |
| 51 | export const formatTimeUntil = ( |
| 52 | date: Date | string | null, |
| 53 | options: FormatTimeUntilOptions = {}, |
| 54 | ): string => { |
| 55 | const { fallback = 'now', includeSubUnit = true } = options |
| 56 | |
| 57 | if (!date) return fallback |
| 58 | |
| 59 | const target = typeof date === 'string' ? new Date(date) : date |
| 60 | const diffMs = target.getTime() - Date.now() |
| 61 | |
| 62 | if (isNaN(diffMs) || diffMs <= 0) return fallback |
| 63 | |
| 64 | const diffMins = Math.floor(diffMs / (1000 * 60)) |
| 65 | const diffHours = Math.floor(diffMins / 60) |
| 66 | const diffDays = Math.floor(diffHours / 24) |
| 67 | const remainingHours = diffHours % 24 |
| 68 | const remainingMins = diffMins % 60 |
| 69 | |
| 70 | if (diffDays > 0) { |
| 71 | return includeSubUnit && remainingHours > 0 |
| 72 | ? `${diffDays}d ${remainingHours}h` |
| 73 | : `${diffDays}d` |
| 74 | } |
| 75 | if (diffHours > 0) { |
| 76 | return includeSubUnit && remainingMins > 0 |
| 77 | ? `${diffHours}h ${remainingMins}m` |
| 78 | : `${diffHours}h` |
| 79 | } |
| 80 | return `${diffMins}m` |
| 81 | } |
no outgoing calls
no test coverage detected