87 lines
2.2 KiB
TypeScript
Raw Normal View History

/**
* Toolkit - Date Formatting
*
* Utilities for formatting dates and times.
*/
export type DateFormatStyle = "short" | "medium" | "long" | "full";
export interface DateFormatOptions {
locale?: string;
dateStyle?: DateFormatStyle;
timeStyle?: DateFormatStyle;
includeTime?: boolean;
timezone?: string;
}
/**
* Format an ISO date string for display
*/
export function formatDate(isoString: string, options: DateFormatOptions = {}): string {
const {
locale = "en-US",
dateStyle = "medium",
timeStyle = "short",
includeTime = false,
timezone,
} = options;
try {
const date = new Date(isoString);
if (isNaN(date.getTime())) {
return isoString; // Return original if invalid
}
const formatOptions: Intl.DateTimeFormatOptions = {
dateStyle,
...(includeTime && { timeStyle }),
...(timezone && { timeZone: timezone }),
};
return new Intl.DateTimeFormat(locale, formatOptions).format(date);
} catch {
return isoString; // Return original on error
}
}
/**
* Format a date relative to now (e.g., "2 days ago", "in 3 hours")
*/
export function formatRelativeDate(isoString: string, options: { locale?: string } = {}): string {
const { locale = "en-US" } = options;
try {
const date = new Date(isoString);
const now = new Date();
const diffMs = date.getTime() - now.getTime();
const diffSeconds = Math.floor(diffMs / 1000);
const diffMinutes = Math.floor(diffSeconds / 60);
const diffHours = Math.floor(diffMinutes / 60);
const diffDays = Math.floor(diffHours / 24);
// Use Intl.RelativeTimeFormat for proper localization
const formatter = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
if (Math.abs(diffDays) > 0) {
return formatter.format(diffDays, "day");
} else if (Math.abs(diffHours) > 0) {
return formatter.format(diffHours, "hour");
} else if (Math.abs(diffMinutes) > 0) {
return formatter.format(diffMinutes, "minute");
} else {
return formatter.format(diffSeconds, "second");
}
} catch {
return isoString;
}
}
/**
* Check if a date string is valid
*/
export function isValidDate(dateString: string): boolean {
const date = new Date(dateString);
return !isNaN(date.getTime());
}