111 lines
2.8 KiB
TypeScript
111 lines
2.8 KiB
TypeScript
import type { TZDate } from "@date-fns/tz";
|
|
import { format, isSameYear } from "date-fns";
|
|
|
|
export function formatSize(bytes: number): string {
|
|
const units = ["byte", "kilobyte", "megabyte", "gigabyte", "terabyte"];
|
|
|
|
const unitIndex = Math.max(
|
|
0,
|
|
Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1),
|
|
);
|
|
|
|
return Intl.NumberFormat("en-US", {
|
|
style: "unit",
|
|
unit: units[unitIndex],
|
|
}).format(+Math.round(bytes / 1024 ** unitIndex));
|
|
}
|
|
|
|
export function formatHoursMinutes(seconds: number) {
|
|
const hours = Math.floor(seconds / 3600);
|
|
const minutes = Math.floor((seconds % 3600) / 60);
|
|
|
|
if (hours && minutes) {
|
|
return `${hours}h ${minutes}m`;
|
|
}
|
|
|
|
if (hours) {
|
|
return `${hours}h`;
|
|
}
|
|
|
|
if (minutes) {
|
|
return `${minutes}m`;
|
|
}
|
|
|
|
return "0m";
|
|
}
|
|
|
|
export function formatDate(date: string, dateFormat?: string | null, checkYear = true) {
|
|
if (checkYear && isSameYear(new Date(), new Date(date))) {
|
|
return format(new Date(date), "MMM d");
|
|
}
|
|
|
|
return format(new Date(date), dateFormat ?? "P");
|
|
}
|
|
|
|
export function formatNumber(value: number | undefined): string {
|
|
return Intl.NumberFormat("en-US").format(value ?? 0);
|
|
}
|
|
|
|
export function getInitials(value: string) {
|
|
const formatted = value.toUpperCase().replace(/[\s.-]/g, "");
|
|
|
|
if (formatted.split(" ").length > 1) {
|
|
return `${formatted.charAt(0)}${formatted.charAt(1)}`;
|
|
}
|
|
|
|
if (value.length > 1) {
|
|
return formatted.charAt(0) + formatted.charAt(1);
|
|
}
|
|
|
|
return formatted.charAt(0);
|
|
}
|
|
|
|
export function formatDateRange(dates: TZDate[]): string {
|
|
if (!dates.length) return "";
|
|
|
|
const formatFullDate = (date: TZDate) => format(date, "MMM d");
|
|
const formatDay = (date: TZDate) => format(date, "d");
|
|
|
|
const startDate = dates[0];
|
|
const endDate = dates[1];
|
|
|
|
if (!startDate) return "";
|
|
|
|
if (dates.length === 1 || !endDate || startDate.getTime() === endDate.getTime()) {
|
|
return formatFullDate(startDate);
|
|
}
|
|
|
|
if (startDate.getMonth() === endDate.getMonth()) {
|
|
// Same month
|
|
return `${format(startDate, "MMM")} ${formatDay(startDate)} - ${formatDay(endDate)}`;
|
|
}
|
|
// Different months
|
|
return `${formatFullDate(startDate)} - ${formatFullDate(endDate)}`;
|
|
}
|
|
|
|
export function formatRelativeTime(date: Date): string {
|
|
const now = new Date();
|
|
const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
|
|
|
|
if (diffInSeconds < 60) {
|
|
return "just now";
|
|
}
|
|
|
|
const intervals = [
|
|
{ label: "y", seconds: 31536000 },
|
|
{ label: "mo", seconds: 2592000 },
|
|
{ label: "d", seconds: 86400 },
|
|
{ label: "h", seconds: 3600 },
|
|
{ label: "m", seconds: 60 },
|
|
] as const;
|
|
|
|
for (const interval of intervals) {
|
|
const count = Math.floor(diffInSeconds / interval.seconds);
|
|
if (count > 0) {
|
|
return `${count}${interval.label} ago`;
|
|
}
|
|
}
|
|
|
|
return "just now";
|
|
}
|