1/**
2 * Format a date to French style (e.g., "22/02/2023 à 23h17")
3 * @param date - The date to format
4 * @returns The formatted date string
5 */
6export function formatFrenchDateTime(date: Date): string {
7 console.debug('Formatting date to French style:', date);
8 return date
9 .toLocaleDateString('fr-FR', {
10 day: '2-digit',
11 month: '2-digit',
12 year: 'numeric',
13 hour: '2-digit',
14 minute: '2-digit',
15 hour12: false
16 })
17 .replace(' à ', ' à '); // Ensure proper spacing around 'à'
18}
19
20/**
21 * Format a date to French style with only time (e.g., "23h17")
22 * @param date - The date to format
23 * @returns The formatted time string
24 */
25export function formatFrenchTime(date: Date): string {
26 console.debug('Formatting time to French style:', date);
27 return date
28 .toLocaleTimeString('fr-FR', {
29 hour: '2-digit',
30 minute: '2-digit',
31 hour12: false
32 })
33 .replace(':', 'h');
34}
35
36/**
37 * Format a date to French style with only date (e.g., "22/02/2023")
38 * @param date - The date to format
39 * @returns The formatted date string
40 */
41export function formatFrenchDate(date: Date): string {
42 console.debug('Formatting date to French style:', date);
43 return date.toLocaleDateString('fr-FR', {
44 day: '2-digit',
45 month: '2-digit',
46 year: 'numeric'
47 });
48}
49
50/**
51 * Format a relative time in French (e.g., "il y a 5 minutes", "il y a 2 heures")
52 * @param date - The date to format relative to now
53 * @returns The formatted relative time string
54 */
55export function formatFrenchRelativeTime(date: Date): string {
56 console.debug('Formatting relative time to French style:', date);
57 const now = new Date();
58 const diff = now.getTime() - date.getTime();
59 const seconds = Math.floor(diff / 1000);
60 const minutes = Math.floor(seconds / 60);
61 const hours = Math.floor(minutes / 60);
62 const days = Math.floor(hours / 24);
63 const months = Math.floor(days / 30);
64 const years = Math.floor(days / 365);
65
66 if (seconds < 60) {
67 return "à l'instant";
68 }
69
70 if (minutes < 60) {
71 return `il y a ${minutes} ${minutes === 1 ? 'minute' : 'minutes'}`;
72 }
73
74 if (hours < 24) {
75 return `il y a ${hours} ${hours === 1 ? 'heure' : 'heures'}`;
76 }
77
78 if (days < 30) {
79 return `il y a ${days} ${days === 1 ? 'jour' : 'jours'}`;
80 }
81
82 if (months < 12) {
83 return `il y a ${months} ${months === 1 ? 'mois' : 'mois'}`;
84 }
85
86 return `il y a ${years} ${years === 1 ? 'an' : 'ans'}`;
87}
88
89/**
90 * Format a relative time in French with more precision (e.g., "il y a 5 minutes et 30 secondes")
91 * @param date - The date to format relative to now
92 * @param withSeconds - Whether to include seconds in the output
93 * @returns The formatted relative time string with more detail
94 */
95export function formatFrenchRelativeTimeDetailed(date: Date, withSeconds = false): string {
96 console.debug('Formatting detailed relative time to French style:', date);
97 const now = new Date();
98 const diff = now.getTime() - date.getTime();
99 const seconds = Math.floor(diff / 1000);
100 const minutes = Math.floor(seconds / 60);
101 const hours = Math.floor(minutes / 60);
102
103 if (seconds < 60) {
104 return withSeconds
105 ? `il y a ${seconds} ${seconds === 1 ? 'seconde' : 'secondes'}`
106 : "à l'instant";
107 }
108
109 if (minutes < 60) {
110 const remainingSeconds = seconds % 60;
111 if (withSeconds && remainingSeconds > 0) {
112 return `il y a ${minutes} ${minutes === 1 ? 'minute' : 'minutes'} et ${remainingSeconds} ${remainingSeconds === 1 ? 'seconde' : 'secondes'}`;
113 }
114 return `il y a ${minutes} ${minutes === 1 ? 'minute' : 'minutes'}`;
115 }
116
117 if (hours < 24) {
118 const remainingMinutes = minutes % 60;
119 if (remainingMinutes > 0) {
120 return `il y a ${hours} ${hours === 1 ? 'heure' : 'heures'} et ${remainingMinutes} ${remainingMinutes === 1 ? 'minute' : 'minutes'}`;
121 }
122 return `il y a ${hours} ${hours === 1 ? 'heure' : 'heures'}`;
123 }
124
125 // For anything longer than 24 hours, use the simple format
126 return formatFrenchRelativeTime(date);
127}
128
129/**
130 * Safely format a timestamp (number), Date, or null/undefined value to a relative time string in French
131 * @param timestamp - The timestamp (in ms), Date object, or null/undefined
132 * @returns The formatted relative time string or a fallback message
133 */
134export function formatFrenchRelativeTimeSafe(timestamp: number | Date | null | undefined): string {
135 console.debug('Formatting safe relative time to French style:', timestamp);
136 if (!timestamp) {
137 return 'jamais';
138 }
139
140 const date = timestamp instanceof Date ? timestamp : new Date(timestamp);
141
142 // Check if the date is valid
143 if (isNaN(date.getTime())) {
144 return 'date invalide';
145 }
146
147 return formatFrenchRelativeTime(date);
148}