Files
s3-drive-storage-manage/src/lib/format.ts
T

56 lines
1.7 KiB
TypeScript

/**
* Format a number of bytes into a human-readable string (e.g., "8.7 GB", "512 KB").
*/
export function formatBytes(bytes: number | null | undefined, decimals = 1): string {
if (bytes === null || bytes === undefined || Number.isNaN(bytes)) {
return "—"
}
if (bytes === 0) return "0 B"
const k = 1024
const dm = decimals < 0 ? 0 : decimals
const sizes = ["B", "KB", "MB", "GB", "TB", "PB"]
const i = Math.floor(Math.log(bytes) / Math.log(k))
const index = Math.min(i, sizes.length - 1)
const value = bytes / Math.pow(k, index)
return `${new Intl.NumberFormat("en-US", {
minimumFractionDigits: 0,
maximumFractionDigits: dm,
}).format(value)} ${sizes[index]}`
}
/**
* Format an ISO timestamp into a relative time string (e.g., "5 minutes ago", "just now").
*/
export function formatRelativeTime(isoString: string | null | undefined): string {
if (!isoString) return "Never"
const date = new Date(isoString)
if (Number.isNaN(date.getTime())) return "Unknown"
const now = Date.now()
const diffInSeconds = Math.round((date.getTime() - now) / 1000)
if (Math.abs(diffInSeconds) < 10) {
return "just now"
}
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" })
const absSeconds = Math.abs(diffInSeconds)
if (absSeconds < 60) {
return rtf.format(diffInSeconds, "second")
}
const diffInMinutes = Math.round(diffInSeconds / 60)
if (Math.abs(diffInMinutes) < 60) {
return rtf.format(diffInMinutes, "minute")
}
const diffInHours = Math.round(diffInMinutes / 60)
if (Math.abs(diffInHours) < 24) {
return rtf.format(diffInHours, "hour")
}
const diffInDays = Math.round(diffInHours / 24)
return rtf.format(diffInDays, "day")
}