refactor: date utils and all calls
This commit is contained in:
@@ -3,6 +3,7 @@ import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import path from 'path';
|
||||
import { createHash } from 'crypto';
|
||||
import { formatDateForDisplay, getToday } from './date-utils';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -184,7 +185,7 @@ export class BackupUtils {
|
||||
extra?: { hash?: string; size?: number; previousHash?: string }
|
||||
): Promise<void> {
|
||||
try {
|
||||
const date = new Date().toLocaleString('fr-FR');
|
||||
const date = formatDateForDisplay(getToday(), 'DISPLAY_LONG');
|
||||
|
||||
let logEntry = `[${date}] ${type.toUpperCase()} BACKUP ${action.toUpperCase()}: ${details}`;
|
||||
|
||||
|
||||
206
src/lib/date-utils.ts
Normal file
206
src/lib/date-utils.ts
Normal file
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* Utilitaires centralisés pour la gestion des dates
|
||||
* Regroupe toutes les fonctions de formatage, manipulation et validation de dates
|
||||
*/
|
||||
|
||||
import { format, startOfDay, endOfDay, isValid } from 'date-fns';
|
||||
import { fr } from 'date-fns/locale';
|
||||
|
||||
// Re-export des utilitaires workday existants
|
||||
export { getPreviousWorkday, getNextWorkday, isWorkday, getDayName } from './workday-utils';
|
||||
|
||||
/**
|
||||
* Formats de dates standardisés
|
||||
*/
|
||||
export const DATE_FORMATS = {
|
||||
API: 'yyyy-MM-dd', // Format API (YYYY-MM-DD)
|
||||
DISPLAY_SHORT: 'dd/MM/yy', // Format court (01/12/25)
|
||||
DISPLAY_LONG: 'EEEE d MMMM yyyy', // Format long (lundi 1 décembre 2025)
|
||||
DISPLAY_MEDIUM: 'dd/MM/yyyy', // Format moyen (01/12/2025)
|
||||
ISO: "yyyy-MM-dd'T'HH:mm:ss.SSSxxx" // Format ISO complet
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Normalise une date au début de la journée (00:00:00.000)
|
||||
*/
|
||||
export function normalizeDate(date: Date): Date {
|
||||
const normalized = new Date(date);
|
||||
normalized.setHours(0, 0, 0, 0);
|
||||
return normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une date pour l'API (évite les décalages timezone)
|
||||
* @param date - Date à formater
|
||||
* @returns Format YYYY-MM-DD
|
||||
*/
|
||||
export function formatDateForAPI(date: Date): string {
|
||||
if (!isValid(date)) {
|
||||
throw new Error('Date invalide fournie à formatDateForAPI');
|
||||
}
|
||||
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une date pour l'affichage en français
|
||||
*/
|
||||
export function formatDateForDisplay(date: Date, formatType: keyof typeof DATE_FORMATS = 'DISPLAY_MEDIUM'): string {
|
||||
if (!isValid(date)) {
|
||||
throw new Error('Date invalide fournie à formatDateForDisplay');
|
||||
}
|
||||
|
||||
return format(date, DATE_FORMATS[formatType], { locale: fr });
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une date courte pour l'affichage (dd/MM/yy)
|
||||
*/
|
||||
export function formatDateShort(date: Date): string {
|
||||
return formatDateForDisplay(date, 'DISPLAY_SHORT');
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une date longue pour l'affichage (lundi 1 décembre 2025)
|
||||
*/
|
||||
export function formatDateLong(date: Date): string {
|
||||
return formatDateForDisplay(date, 'DISPLAY_LONG');
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si une date est aujourd'hui
|
||||
*/
|
||||
export function isToday(date: Date): boolean {
|
||||
const today = new Date();
|
||||
return normalizeDate(date).getTime() === normalizeDate(today).getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si une date est hier
|
||||
*/
|
||||
export function isYesterday(date: Date): boolean {
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
return normalizeDate(date).getTime() === normalizeDate(yesterday).getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare deux dates (sans tenir compte de l'heure)
|
||||
*/
|
||||
export function isSameDay(date1: Date, date2: Date): boolean {
|
||||
return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtient la date d'aujourd'hui normalisée
|
||||
*/
|
||||
export function getToday(): Date {
|
||||
return normalizeDate(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtient la date d'hier normalisée
|
||||
*/
|
||||
export function getYesterday(): Date {
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
return normalizeDate(yesterday);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée une nouvelle date à partir d'une date existante
|
||||
*/
|
||||
export function createDate(date: Date): Date {
|
||||
return new Date(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute des jours à une date
|
||||
*/
|
||||
export function addDays(date: Date, days: number): Date {
|
||||
const result = createDate(date);
|
||||
result.setDate(result.getDate() + days);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Soustrait des jours à une date
|
||||
*/
|
||||
export function subtractDays(date: Date, days: number): Date {
|
||||
return addDays(date, -days);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse une date depuis une string avec validation
|
||||
*/
|
||||
export function parseDate(dateString: string): Date {
|
||||
const parsed = new Date(dateString);
|
||||
if (!isValid(parsed)) {
|
||||
throw new Error(`Date invalide: ${dateString}`);
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valide qu'une string est une date valide au format API (YYYY-MM-DD)
|
||||
*/
|
||||
export function isValidAPIDate(dateString: string): boolean {
|
||||
const regex = /^\d{4}-\d{2}-\d{2}$/;
|
||||
if (!regex.test(dateString)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const date = parseDate(dateString);
|
||||
return formatDateForAPI(date) === dateString;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtient le début de la journée pour une date
|
||||
*/
|
||||
export function getStartOfDay(date: Date): Date {
|
||||
return startOfDay(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtient la fin de la journée pour une date
|
||||
*/
|
||||
export function getEndOfDay(date: Date): Date {
|
||||
return endOfDay(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une date pour l'affichage avec gestion des cas spéciaux (aujourd'hui, hier)
|
||||
*/
|
||||
export function formatDateSmart(date: Date): string {
|
||||
if (isToday(date)) {
|
||||
return "Aujourd'hui";
|
||||
}
|
||||
|
||||
if (isYesterday(date)) {
|
||||
return "Hier";
|
||||
}
|
||||
|
||||
return formatDateForDisplay(date, 'DISPLAY_MEDIUM');
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère un titre intelligent pour une date (avec emojis)
|
||||
*/
|
||||
export function generateDateTitle(date: Date, emoji: string = '📅'): string {
|
||||
if (isToday(date)) {
|
||||
return `${emoji} Aujourd'hui`;
|
||||
}
|
||||
|
||||
if (isYesterday(date)) {
|
||||
return `${emoji} Hier`;
|
||||
}
|
||||
|
||||
return `${emoji} ${formatDateShort(date)}`;
|
||||
}
|
||||
Reference in New Issue
Block a user