Openstatus
www.openstatus.dev
1/**
2 * Format milliseconds to human-readable duration
3 *
4 * @example
5 * formatDuration(30000) // "30s"
6 * formatDuration(135000) // "2m 15s"
7 * formatDuration(8130000) // "2h 15m 30s"
8 * formatDuration(90000000) // "1d 1h"
9 *
10 * @param durationMs - Duration in milliseconds
11 * @param options - Formatting options
12 * @param options.maxUnits - Max number of units to show (default: 3)
13 * @returns Formatted duration string
14 */
15export function formatDuration(
16 durationMs: number,
17 options?: {
18 maxUnits?: number;
19 },
20): string {
21 const maxUnits = options?.maxUnits ?? 3;
22
23 if (durationMs < 0) {
24 return "0s";
25 }
26
27 const totalSeconds = Math.floor(durationMs / 1000);
28
29 if (totalSeconds === 0) {
30 return "0s";
31 }
32
33 const days = Math.floor(totalSeconds / 86400);
34 const hours = Math.floor((totalSeconds % 86400) / 3600);
35 const minutes = Math.floor((totalSeconds % 3600) / 60);
36 const seconds = totalSeconds % 60;
37
38 const parts: string[] = [];
39
40 if (days > 0) {
41 parts.push(`${days}d`);
42 }
43 if (hours > 0) {
44 parts.push(`${hours}h`);
45 }
46 if (minutes > 0) {
47 parts.push(`${minutes}m`);
48 }
49 if (seconds > 0) {
50 parts.push(`${seconds}s`);
51 }
52
53 // Take only the first maxUnits parts
54 return parts.slice(0, maxUnits).join(" ");
55}
56
57/**
58 * Calculate duration between two timestamps
59 *
60 * @param start - Start date
61 * @param end - End date
62 * @returns Duration in milliseconds
63 */
64export function calculateDuration(start: Date, end: Date): number {
65 return end.getTime() - start.getTime();
66}