Files
sbd2-frontend/src/utils/format-date.ts
JSC 009780e64c feat: add schedulers feature with task management
- Introduced SchedulersPage for managing scheduled tasks.
- Implemented CreateTaskDialog for creating new scheduled tasks.
- Added SchedulersHeader for filtering and searching tasks.
- Created SchedulersTable to display scheduled tasks with actions.
- Implemented loading and error states with SchedulersLoadingStates.
- Added API service for task management in schedulers.
- Enhanced date formatting utility to handle timezone.
- Updated AppSidebar and AppRoutes to include SchedulersPage.
2025-08-29 00:09:45 +02:00

145 lines
4.1 KiB
TypeScript

import { formatDistanceToNow } from 'date-fns';
/**
* Parse and optionally convert a date string to a Date object with timezone handling
* @param dateString - The date string to parse
* @param isUTC - Whether to convert from UTC to local timezone (default: true)
* @returns Processed Date object or null if invalid
*/
function parseAndConvertDate(dateString: string, isUTC: boolean = true): Date | null {
try {
// If isUTC is true and the date string doesn't have timezone info, treat it as UTC
let dateToProcess = dateString;
if (isUTC && !dateString.endsWith('Z') && !dateString.includes('+') && !dateString.includes('-', 10)) {
dateToProcess = `${dateString}Z`;
}
const date = new Date(dateToProcess);
if (isNaN(date.getTime())) {
return null;
}
if (!isUTC) {
return date;
}
// Get timezone from localStorage, default to Europe/Paris
const timezone = localStorage.getItem('timezone') || 'Europe/Paris';
// Format the date in the target timezone
const formatter = new Intl.DateTimeFormat('fr-FR', {
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
const parts = formatter.formatToParts(date);
const partsObj = parts.reduce((acc, part) => {
acc[part.type] = part.value;
return acc;
}, {} as Record<string, string>);
// Create new date object in the target timezone
return new Date(
parseInt(partsObj.year),
parseInt(partsObj.month) - 1, // Month is 0-indexed
parseInt(partsObj.day),
parseInt(partsObj.hour),
parseInt(partsObj.minute),
parseInt(partsObj.second)
);
} catch (error) {
console.error('Error parsing date:', error);
return null;
}
}
/**
* Format a date string to DD/MM/YYYY HH:MM:SS or DD/MM/YYYY
* @param dateString - The date string to format
* @param withTime - Whether to include time in the output (default: true)
* @param isUTC - Whether to convert from UTC to local timezone (default: true)
* @returns Formatted date string
*/
export function formatDate(
dateString: string,
withTime: boolean = true,
isUTC: boolean = true
): string {
const date = parseAndConvertDate(dateString, isUTC);
if (!date) {
return 'Invalid Date';
}
const day = date.getDate().toString().padStart(2, '0');
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const year = date.getFullYear().toString();
const dateFormatted = `${day}/${month}/${year}`;
if (!withTime) {
return dateFormatted;
}
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return `${dateFormatted} ${hours}:${minutes}:${seconds}`;
}
/**
* Format a date string to show distance to now (e.g., "2 hours ago", "3 days ago")
* @param dateString - The date string to format
* @param isUTC - Whether to convert from UTC to local timezone (default: true)
* @returns Formatted distance string (e.g., "2 hours ago")
*/
export function formatDateDistanceToNow(
dateString: string,
isUTC: boolean = true
): string {
const date = parseAndConvertDate(dateString, isUTC);
if (!date) {
return 'Invalid Date';
}
return formatDistanceToNow(date, { addSuffix: true });
}
/**
* Format a date string with timezone consideration
* @param dateString - The date string to format
* @param timezone - The target timezone (default: 'UTC')
* @returns Formatted date string with timezone
*/
export function formatDateTime(dateString: string, timezone: string = 'UTC'): string {
try {
const date = new Date(dateString)
if (isNaN(date.getTime())) {
return 'Invalid Date'
}
const formatter = new Intl.DateTimeFormat('fr-FR', {
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false,
})
return formatter.format(date)
} catch {
return 'Invalid Date'
}
}