96 lines
2.9 KiB
TypeScript
96 lines
2.9 KiB
TypeScript
/**
|
|
* Global Date Formatting Utility
|
|
* Formats dates to relative time strings (today, yesterday, etc.)
|
|
* Usage: formatRelativeDate('2025-01-15') or formatRelativeDate(new Date())
|
|
*/
|
|
|
|
export function formatRelativeDate(dateString: string | Date): string {
|
|
if (!dateString) {
|
|
return 'Today';
|
|
}
|
|
|
|
const date = typeof dateString === 'string' ? new Date(dateString) : dateString;
|
|
|
|
// Check if date is valid
|
|
if (isNaN(date.getTime())) {
|
|
return 'Today';
|
|
}
|
|
|
|
const now = new Date();
|
|
|
|
// Set time to midnight for both dates to compare days only
|
|
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
|
|
const diffTime = today.getTime() - dateOnly.getTime();
|
|
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
|
|
|
if (diffDays === 0) {
|
|
return 'Today';
|
|
} else if (diffDays === 1) {
|
|
return 'Yesterday';
|
|
} else if (diffDays < 30) {
|
|
return `${diffDays} days ago`;
|
|
} else if (diffDays < 365) {
|
|
const months = Math.floor(diffDays / 30);
|
|
const remainingDays = diffDays % 30;
|
|
if (remainingDays === 0) {
|
|
return `${months} month${months > 1 ? 's' : ''} ago`;
|
|
} else {
|
|
return `${months} month${months > 1 ? 's' : ''} ${remainingDays} day${remainingDays > 1 ? 's' : ''} ago`;
|
|
}
|
|
} else {
|
|
const years = Math.floor(diffDays / 365);
|
|
const remainingMonths = Math.floor((diffDays % 365) / 30);
|
|
if (remainingMonths === 0) {
|
|
return `${years} year${years > 1 ? 's' : ''} ago`;
|
|
} else {
|
|
return `${years} year${years > 1 ? 's' : ''} ${remainingMonths} month${remainingMonths > 1 ? 's' : ''} ago`;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format date to a standard display format
|
|
* @param dateString - ISO date string or Date object
|
|
* @param options - Intl.DateTimeFormat options
|
|
* @returns Formatted date string (e.g., "Jan 7, 2026")
|
|
*/
|
|
export function formatDate(
|
|
dateString: string | Date | null | undefined,
|
|
options: Intl.DateTimeFormatOptions = { month: 'short', day: 'numeric', year: 'numeric' }
|
|
): string {
|
|
if (!dateString) return '-';
|
|
|
|
const date = typeof dateString === 'string' ? new Date(dateString) : dateString;
|
|
|
|
if (isNaN(date.getTime())) return '-';
|
|
|
|
return date.toLocaleDateString('en-US', options);
|
|
}
|
|
|
|
/**
|
|
* Format date and time to a standard display format
|
|
* @param dateString - ISO date string or Date object
|
|
* @returns Formatted date and time string (e.g., "Jan 7, 2026, 3:30 PM")
|
|
*/
|
|
export function formatDateTime(
|
|
dateString: string | Date | null | undefined
|
|
): string {
|
|
if (!dateString) return '-';
|
|
|
|
const date = typeof dateString === 'string' ? new Date(dateString) : dateString;
|
|
|
|
if (isNaN(date.getTime())) return '-';
|
|
|
|
return date.toLocaleDateString('en-US', {
|
|
month: 'short',
|
|
day: 'numeric',
|
|
year: 'numeric',
|
|
hour: 'numeric',
|
|
minute: '2-digit',
|
|
hour12: true
|
|
});
|
|
}
|
|
|