140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
/**
|
|
* Unified date formatting utilities for consistent date display across the application
|
|
*/
|
|
|
|
/**
|
|
* Format date string to display format (DD/MM/YYYY HH:mm or DD/MM/YYYY)
|
|
* Handles multiple input formats: ISO, DD-MM-YYYY, YYYY-MM-DD, DD/MM/YYYY
|
|
*/
|
|
export const formatDate = (dateString: string | null | undefined): string => {
|
|
if (!dateString) return "-";
|
|
|
|
try {
|
|
let date: Date;
|
|
|
|
// Check if it's an ISO date string (e.g., "2025-06-09T22:58:47.731Z")
|
|
if (dateString.includes('T') || dateString.includes('Z')) {
|
|
date = new Date(dateString);
|
|
}
|
|
// Handle DD-MM-YYYY format
|
|
else if (dateString.match(/^\d{1,2}-\d{1,2}-\d{4}$/)) {
|
|
const [day, month, year] = dateString.split("-");
|
|
date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
|
}
|
|
// Handle DD/MM/YYYY format
|
|
else if (dateString.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/)) {
|
|
const [day, month, year] = dateString.split("/");
|
|
date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
|
}
|
|
// Handle YYYY-MM-DD format
|
|
else if (dateString.match(/^\d{4}-\d{1,2}-\d{1,2}$/)) {
|
|
date = new Date(dateString);
|
|
}
|
|
// Fallback to direct parsing
|
|
else {
|
|
date = new Date(dateString);
|
|
}
|
|
|
|
// Check if date is valid
|
|
if (isNaN(date.getTime())) {
|
|
console.warn("Invalid date format:", dateString);
|
|
return dateString;
|
|
}
|
|
|
|
// Format date in DD/MM/YYYY HH:mm format
|
|
const day = date.getDate().toString().padStart(2, '0');
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
const year = date.getFullYear();
|
|
const hours = date.getHours().toString().padStart(2, '0');
|
|
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
|
|
// Include time if it's not midnight
|
|
if (hours !== '00' || minutes !== '00') {
|
|
return `${day}/${month}/${year} ${hours}:${minutes}`;
|
|
}
|
|
|
|
return `${day}/${month}/${year}`;
|
|
} catch (error) {
|
|
console.error('Date formatting error:', error, dateString);
|
|
return dateString;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get relative time description (e.g., "2 days ago", "Yesterday", "Today")
|
|
*/
|
|
export const getRelativeTime = (dateString: string | null | undefined): string => {
|
|
if (!dateString) return '';
|
|
|
|
try {
|
|
let date: Date;
|
|
|
|
// Handle DD-MM-YYYY format
|
|
if (dateString.includes('-') && dateString.match(/^\d{1,2}-\d{1,2}-\d{4}$/)) {
|
|
const parts = dateString.split('-');
|
|
if (parts.length === 3) {
|
|
const [day, month, year] = parts;
|
|
date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
|
} else {
|
|
date = new Date(dateString);
|
|
}
|
|
} else {
|
|
date = new Date(dateString);
|
|
}
|
|
|
|
if (isNaN(date.getTime())) return '';
|
|
|
|
const now = new Date();
|
|
const diffTime = Math.abs(now.getTime() - date.getTime());
|
|
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
|
|
|
if (diffDays === 0) return 'Today';
|
|
if (diffDays === 1) return 'Yesterday';
|
|
if (diffDays < 7) return `${diffDays} days ago`;
|
|
if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`;
|
|
if (diffDays < 365) return `${Math.floor(diffDays / 30)} months ago`;
|
|
return `${Math.floor(diffDays / 365)} years ago`;
|
|
} catch (error) {
|
|
console.error('Relative time calculation error:', error, dateString);
|
|
return '';
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Format date for display in US locale (Month DD, YYYY)
|
|
*/
|
|
export const formatDateUS = (dateString: string | null | undefined): string => {
|
|
if (!dateString) return "-";
|
|
|
|
try {
|
|
let date: Date;
|
|
|
|
// Handle DD-MM-YYYY format
|
|
if (dateString.includes('-') && dateString.match(/^\d{1,2}-\d{1,2}-\d{4}$/)) {
|
|
const parts = dateString.split('-');
|
|
if (parts.length === 3) {
|
|
const [day, month, year] = parts;
|
|
date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
|
} else {
|
|
date = new Date(dateString);
|
|
}
|
|
} else {
|
|
date = new Date(dateString);
|
|
}
|
|
|
|
if (isNaN(date.getTime())) {
|
|
console.warn("Invalid date format:", dateString);
|
|
return "-";
|
|
}
|
|
|
|
return date.toLocaleDateString("en-US", {
|
|
year: "numeric",
|
|
month: "short",
|
|
day: "numeric",
|
|
});
|
|
} catch (error) {
|
|
console.error("Error formatting date:", dateString, error);
|
|
return "-";
|
|
}
|
|
};
|