refactor: date utils and all calls

This commit is contained in:
Julien Froidefond
2025-09-21 11:41:17 +02:00
parent 799a21df5c
commit 557cdebc13
23 changed files with 300 additions and 117 deletions

View File

@@ -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
View 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)}`;
}