mirror of
https://github.com/R0m1k3/noteflow.git
synced 2026-10-11 17:29:37 +02:00
Fix: Correction complète du décalage horaire d'1 heure dans le calendrier
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
This commit is contained in:
1 file changed
+78
-8
+78
-8
@@ -32,6 +32,76 @@ import { ConfirmModal } from "@/components/modals/ConfirmModal";
|
|||||||
import { InputModal } from "@/components/modals/InputModal";
|
import { InputModal } from "@/components/modals/InputModal";
|
||||||
import { AddUserModal } from "@/components/modals/AddUserModal";
|
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 {
|
interface UserType {
|
||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
@@ -2061,8 +2131,8 @@ const Index = () => {
|
|||||||
const eventData = {
|
const eventData = {
|
||||||
title: formData.get('title') as string,
|
title: formData.get('title') as string,
|
||||||
description: formData.get('description') as string || undefined,
|
description: formData.get('description') as string || undefined,
|
||||||
startDateTime: new Date(formData.get('startDateTime') as string).toISOString(),
|
startDateTime: toParisISO(formData.get('startDateTime') as string),
|
||||||
endDateTime: new Date(formData.get('endDateTime') as string).toISOString(),
|
endDateTime: toParisISO(formData.get('endDateTime') as string),
|
||||||
location: formData.get('location') as string || undefined,
|
location: formData.get('location') as string || undefined,
|
||||||
attendees: (formData.get('attendees') as string || '').split(',').map(e => e.trim()).filter(e => e),
|
attendees: (formData.get('attendees') as string || '').split(',').map(e => e.trim()).filter(e => e),
|
||||||
reminders: reminderMinutes && reminderMinutes !== '0' ? [
|
reminders: reminderMinutes && reminderMinutes !== '0' ? [
|
||||||
@@ -2105,7 +2175,7 @@ const Index = () => {
|
|||||||
name="startDateTime"
|
name="startDateTime"
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
required
|
required
|
||||||
defaultValue={new Date(Date.now() + 60*60*1000).toISOString().slice(0, 16)}
|
defaultValue={toLocalDateTimeString(new Date(Date.now() + 60*60*1000))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@@ -2115,7 +2185,7 @@ const Index = () => {
|
|||||||
name="endDateTime"
|
name="endDateTime"
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
required
|
required
|
||||||
defaultValue={new Date(Date.now() + 2*60*60*1000).toISOString().slice(0, 16)}
|
defaultValue={toLocalDateTimeString(new Date(Date.now() + 2*60*60*1000))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -2239,8 +2309,8 @@ const Index = () => {
|
|||||||
const eventData = {
|
const eventData = {
|
||||||
title: formData.get('title') as string,
|
title: formData.get('title') as string,
|
||||||
description: formData.get('description') as string || undefined,
|
description: formData.get('description') as string || undefined,
|
||||||
startDateTime: new Date(formData.get('startDateTime') as string).toISOString(),
|
startDateTime: toParisISO(formData.get('startDateTime') as string),
|
||||||
endDateTime: new Date(formData.get('endDateTime') as string).toISOString(),
|
endDateTime: toParisISO(formData.get('endDateTime') as string),
|
||||||
location: formData.get('location') as string || undefined,
|
location: formData.get('location') as string || undefined,
|
||||||
attendees: (formData.get('attendees') as string || '').split(',').map(e => e.trim()).filter(e => e),
|
attendees: (formData.get('attendees') as string || '').split(',').map(e => e.trim()).filter(e => e),
|
||||||
reminders: reminderMinutes && reminderMinutes !== '0' ? [
|
reminders: reminderMinutes && reminderMinutes !== '0' ? [
|
||||||
@@ -2282,7 +2352,7 @@ const Index = () => {
|
|||||||
name="startDateTime"
|
name="startDateTime"
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
required
|
required
|
||||||
defaultValue={editEventModal.event ? new Date(editEventModal.event.start_time).toISOString().slice(0, 16) : ''}
|
defaultValue={editEventModal.event ? toLocalDateTimeString(editEventModal.event.start_time) : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@@ -2292,7 +2362,7 @@ const Index = () => {
|
|||||||
name="endDateTime"
|
name="endDateTime"
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
required
|
required
|
||||||
defaultValue={editEventModal.event ? new Date(editEventModal.event.end_time).toISOString().slice(0, 16) : ''}
|
defaultValue={editEventModal.event ? toLocalDateTimeString(editEventModal.event.end_time) : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in new issue
Block a user