Openstatus
www.openstatus.dev
1import { endOfDay, isSameDay, startOfDay } from "date-fns";
2
3export function formatMilliseconds(ms: number) {
4 if (ms > 1000) {
5 return `${Intl.NumberFormat("en-US", {
6 style: "unit",
7 unit: "second",
8 maximumFractionDigits: 2,
9 }).format(ms / 1000)}`;
10 }
11
12 return `${Intl.NumberFormat("en-US", {
13 style: "unit",
14 unit: "millisecond",
15 }).format(ms)}`;
16}
17
18export function formatMillisecondsRange(min: number, max: number) {
19 if ((min > 1000 && max > 1000) || (min < 1000 && max < 1000)) {
20 return `${formatNumber(min / 1000)} - ${formatMilliseconds(max)}`;
21 }
22
23 return `${formatMilliseconds(min)} - ${formatMilliseconds(max)}`;
24}
25
26export function formatPercentage(value: number) {
27 if (Number.isNaN(value)) return "100%";
28 return `${Intl.NumberFormat("en-US", {
29 style: "percent",
30 minimumFractionDigits: 2,
31 maximumFractionDigits: 2,
32 }).format(value)}`;
33}
34
35export function formatNumber(
36 value: number,
37 options?: Intl.NumberFormatOptions,
38) {
39 return `${Intl.NumberFormat("en-US", options).format(value)}`;
40}
41
42// TODO: think of supporting custom formats
43
44export function formatDate(date: Date, options?: Intl.DateTimeFormatOptions) {
45 return date.toLocaleDateString("en-US", {
46 year: "numeric",
47 month: "long",
48 day: "numeric",
49 ...options,
50 });
51}
52
53export function formatDateTime(date: Date) {
54 return date.toLocaleDateString("en-US", {
55 month: "long",
56 day: "numeric",
57 hour: "numeric",
58 minute: "numeric",
59 });
60}
61
62export function formatTime(date: Date) {
63 return date.toLocaleTimeString("en-US", {
64 hour: "numeric",
65 minute: "numeric",
66 });
67}
68
69export function formatDateRange(from?: Date, to?: Date) {
70 const sameDay = from && to && isSameDay(from, to);
71 const isFromStartDay = from && startOfDay(from).getTime() === from.getTime();
72 const isToEndDay = to && endOfDay(to).getTime() === to.getTime();
73
74 if (sameDay) {
75 if (from.getTime() === to.getTime()) {
76 return formatDateTime(from);
77 }
78 if (from && to) {
79 return `${formatDateTime(from)} - ${formatTime(to)}`;
80 }
81 }
82
83 if (from && to) {
84 if (isFromStartDay && isToEndDay) {
85 return `${formatDate(from)} - ${formatDate(to)}`;
86 }
87 return `${formatDateTime(from)} - ${formatDateTime(to)}`;
88 }
89
90 if (to) {
91 return `Until ${formatDateTime(to)}`;
92 }
93
94 if (from) {
95 return `Since ${formatDateTime(from)}`;
96 }
97
98 return "All time";
99}
100
101export function formatDateForInput(date: Date): string {
102 const year = date.getFullYear();
103 const month = String(date.getMonth() + 1).padStart(2, "0");
104 const day = String(date.getDate()).padStart(2, "0");
105 const hours = String(date.getHours()).padStart(2, "0");
106 const minutes = String(date.getMinutes()).padStart(2, "0");
107
108 return `${year}-${month}-${day}T${hours}:${minutes}`;
109}