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