From c103a517c8169e2ce546c302f30138fe089ca6b6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Nov 2025 11:06:21 +0000 Subject: [PATCH] =?UTF-8?q?Fix:=20Correction=20compl=C3=A8te=20du=20d?= =?UTF-8?q?=C3=A9calage=20horaire=20d'1=20heure=20dans=20le=20calendrier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problèmes corrigés: - Ajout de fonctions utilitaires toLocalDateTimeString() et toParisISO() pour gérer correctement les conversions de timezone Europe/Paris - Correction des valeurs par défaut des champs datetime-local lors de la création d'événements (utilisaient toISOString().slice() incorrectement) - Correction des valeurs par défaut lors de l'édition d'événements - Correction de la soumission des formulaires (création et édition) pour envoyer les dates ISO correctes avec timezone Europe/Paris Les dates sont désormais: 1. Affichées correctement en heure Europe/Paris dans les formulaires 2. Converties correctement lors de l'envoi au backend 3. Stockées et récupérées sans décalage horaire Fichiers modifiés: - src/pages/Index.tsx: Ajout des fonctions utilitaires et correction de toutes les conversions de dates pour les événements du calendrier --- src/pages/Index.tsx | 86 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 8 deletions(-) diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index dd7c7ba..0621f4d 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -32,6 +32,76 @@ import { ConfirmModal } from "@/components/modals/ConfirmModal"; import { InputModal } from "@/components/modals/InputModal"; import { AddUserModal } from "@/components/modals/AddUserModal"; +// ===== FONCTIONS UTILITAIRES TIMEZONE EUROPE/PARIS ===== + +/** + * Convertit une date ISO/UTC en format datetime-local pour Europe/Paris + * @param date - Date ISO string ou Date object + * @returns String au format "YYYY-MM-DDTHH:mm" en heure Europe/Paris + */ +function toLocalDateTimeString(date: string | Date): string { + const d = typeof date === 'string' ? new Date(date) : date; + + // Formater en heure Europe/Paris + const formatter = new Intl.DateTimeFormat('fr-FR', { + timeZone: 'Europe/Paris', + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + hour12: false + }); + + const parts = formatter.formatToParts(d); + const year = parts.find(p => p.type === 'year')?.value; + const month = parts.find(p => p.type === 'month')?.value; + const day = parts.find(p => p.type === 'day')?.value; + const hour = parts.find(p => p.type === 'hour')?.value; + const minute = parts.find(p => p.type === 'minute')?.value; + + return `${year}-${month}-${day}T${hour}:${minute}`; +} + +/** + * Convertit une valeur datetime-local en ISO string pour Europe/Paris + * @param localDateTimeString - String au format "YYYY-MM-DDTHH:mm" (sans timezone) + * @returns ISO string représentant cette heure en Europe/Paris + */ +function toParisISO(localDateTimeString: string): string { + // Le champ datetime-local renvoie une string locale (ex: "2024-11-16T14:30") + // On doit l'interpréter comme étant en Europe/Paris, puis convertir en ISO + + // Parser les composants de la date + const [datePart, timePart] = localDateTimeString.split('T'); + const [year, month, day] = datePart.split('-').map(Number); + const [hour, minute] = timePart.split(':').map(Number); + + // Créer une date "fictive" en UTC avec ces valeurs + const utcDate = new Date(Date.UTC(year, month - 1, day, hour, minute, 0)); + + // Formater cette date en tant que date Paris + const parisTime = utcDate.toLocaleString('en-US', { + timeZone: 'Europe/Paris', + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false + }); + + // Calculer la différence entre l'heure voulue et l'heure obtenue + const parisDate = new Date(parisTime); + const diff = utcDate.getTime() - parisDate.getTime(); + + // Créer la date finale en ajustant + const finalDate = new Date(utcDate.getTime() - diff); + + return finalDate.toISOString(); +} + interface UserType { id: number; username: string; @@ -2061,8 +2131,8 @@ const Index = () => { const eventData = { title: formData.get('title') as string, description: formData.get('description') as string || undefined, - startDateTime: new Date(formData.get('startDateTime') as string).toISOString(), - endDateTime: new Date(formData.get('endDateTime') as string).toISOString(), + startDateTime: toParisISO(formData.get('startDateTime') as string), + endDateTime: toParisISO(formData.get('endDateTime') as string), location: formData.get('location') as string || undefined, attendees: (formData.get('attendees') as string || '').split(',').map(e => e.trim()).filter(e => e), reminders: reminderMinutes && reminderMinutes !== '0' ? [ @@ -2105,7 +2175,7 @@ const Index = () => { name="startDateTime" type="datetime-local" required - defaultValue={new Date(Date.now() + 60*60*1000).toISOString().slice(0, 16)} + defaultValue={toLocalDateTimeString(new Date(Date.now() + 60*60*1000))} />
@@ -2115,7 +2185,7 @@ const Index = () => { name="endDateTime" type="datetime-local" required - defaultValue={new Date(Date.now() + 2*60*60*1000).toISOString().slice(0, 16)} + defaultValue={toLocalDateTimeString(new Date(Date.now() + 2*60*60*1000))} />
@@ -2239,8 +2309,8 @@ const Index = () => { const eventData = { title: formData.get('title') as string, description: formData.get('description') as string || undefined, - startDateTime: new Date(formData.get('startDateTime') as string).toISOString(), - endDateTime: new Date(formData.get('endDateTime') as string).toISOString(), + startDateTime: toParisISO(formData.get('startDateTime') as string), + endDateTime: toParisISO(formData.get('endDateTime') as string), location: formData.get('location') as string || undefined, attendees: (formData.get('attendees') as string || '').split(',').map(e => e.trim()).filter(e => e), reminders: reminderMinutes && reminderMinutes !== '0' ? [ @@ -2282,7 +2352,7 @@ const Index = () => { name="startDateTime" type="datetime-local" required - defaultValue={editEventModal.event ? new Date(editEventModal.event.start_time).toISOString().slice(0, 16) : ''} + defaultValue={editEventModal.event ? toLocalDateTimeString(editEventModal.event.start_time) : ''} />
@@ -2292,7 +2362,7 @@ const Index = () => { name="endDateTime" type="datetime-local" required - defaultValue={editEventModal.event ? new Date(editEventModal.event.end_time).toISOString().slice(0, 16) : ''} + defaultValue={editEventModal.event ? toLocalDateTimeString(editEventModal.event.end_time) : ''} />