From b8928379ded4acc8bfba48e5f37292a99e8bde5f Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Thu, 29 May 2025 14:07:03 +0300 Subject: [PATCH] feat: Fix timezone issues in event creation - Correctly handle timezones when creating events, ensuring that start and end times are accurately represented regardless of the user's timezone. - Add 1-day compensation to event times to handle timezone shifts during conversion to UTC. - Improve default time setting for date-specific events. --- actix_mvc_app/src/views/calendar/index.html | 74 +++++++++++++++++---- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/actix_mvc_app/src/views/calendar/index.html b/actix_mvc_app/src/views/calendar/index.html index d8c0b0c..244c1ba 100644 --- a/actix_mvc_app/src/views/calendar/index.html +++ b/actix_mvc_app/src/views/calendar/index.html @@ -654,10 +654,51 @@ const endTime = document.getElementById('endTime').value; if (startTime) { - formData.set('start_time', new Date(startTime).toISOString()); + // Check if this is a date-specific event (from calendar click) + const modal = document.getElementById('newEventModal'); + const selectedDateStr = modal.getAttribute('data-selected-date'); + + if (selectedDateStr) { + // For date-specific events, ensure the time stays on the selected date + // Parse the datetime-local value and preserve the selected date + const timeValue = startTime; // "2025-05-10T07:00" + const timeParts = timeValue.split('T'); + const selectedDatePart = selectedDateStr; // "2025-05-10" + const timePart = timeParts[1]; // "07:00" + + // Create the datetime string with the selected date and add seconds + const correctedStartTime = selectedDatePart + 'T' + timePart + ':00'; + + // Create date and add one day to compensate for timezone shift + const localDate = new Date(correctedStartTime); + const compensatedDate = new Date(localDate.getTime() + 24 * 60 * 60 * 1000); // Add 1 day + formData.set('start_time', compensatedDate.toISOString()); + } else { + formData.set('start_time', new Date(startTime).toISOString()); + } } if (endTime) { - formData.set('end_time', new Date(endTime).toISOString()); + // Check if this is a date-specific event (from calendar click) + const modal = document.getElementById('newEventModal'); + const selectedDateStr = modal.getAttribute('data-selected-date'); + + if (selectedDateStr) { + // For date-specific events, ensure the time stays on the selected date + const timeValue = endTime; // "2025-05-10T08:00" + const timeParts = timeValue.split('T'); + const selectedDatePart = selectedDateStr; // "2025-05-10" + const timePart = timeParts[1]; // "08:00" + + // Create the datetime string with the selected date and add seconds + const correctedEndTime = selectedDatePart + 'T' + timePart + ':00'; + + // Create date and add one day to compensate for timezone shift + const localDate = new Date(correctedEndTime); + const compensatedDate = new Date(localDate.getTime() + 24 * 60 * 60 * 1000); // Add 1 day + formData.set('end_time', compensatedDate.toISOString()); + } else { + formData.set('end_time', new Date(endTime).toISOString()); + } } } else { // For all-day events, set times to start and end of day @@ -676,12 +717,15 @@ const day = parseInt(dateParts[2]); // Create dates in local timezone at noon to avoid any date boundary issues - // This ensures the date stays consistent regardless of timezone when converted to UTC const startOfDay = new Date(year, month, day, 12, 0, 0); // Noon local time const endOfDay = new Date(year, month, day, 12, 0, 1); // Noon + 1 second local time - formData.set('start_time', startOfDay.toISOString()); - formData.set('end_time', endOfDay.toISOString()); + // Add one day to compensate for timezone shift (same as timed events) + const compensatedStartOfDay = new Date(startOfDay.getTime() + 24 * 60 * 60 * 1000); + const compensatedEndOfDay = new Date(endOfDay.getTime() + 24 * 60 * 60 * 1000); + + formData.set('start_time', compensatedStartOfDay.toISOString()); + formData.set('end_time', compensatedEndOfDay.toISOString()); } else { // Use today's date for general "Create Event" button const today = new Date(); @@ -940,23 +984,25 @@ // Set the date for the selected day const selectedDate = new Date(date.getFullYear(), date.getMonth(), parseInt(day)); - // Set default times for the selected date - const startTime = new Date(selectedDate); - startTime.setHours(9, 0, 0, 0); + // Create datetime-local strings directly to avoid timezone issues + const year = selectedDate.getFullYear(); + const month = String(selectedDate.getMonth() + 1).padStart(2, '0'); + const dayStr = String(selectedDate.getDate()).padStart(2, '0'); - const endTime = new Date(selectedDate); - endTime.setHours(10, 0, 0, 0); + // Format as YYYY-MM-DDTHH:MM for datetime-local input + const startTimeStr = `${year}-${month}-${dayStr}T09:00`; + const endTimeStr = `${year}-${month}-${dayStr}T10:00`; // Update the modal form with the selected date const startTimeInput = document.getElementById('startTime'); const endTimeInput = document.getElementById('endTime'); - startTimeInput.value = startTime.toISOString().slice(0, 16); - endTimeInput.value = endTime.toISOString().slice(0, 16); + startTimeInput.value = startTimeStr; + endTimeInput.value = endTimeStr; // Restrict date changes - set min and max to the selected date - const minDate = selectedDate.toISOString().split('T')[0] + 'T00:00'; - const maxDate = selectedDate.toISOString().split('T')[0] + 'T23:59'; + const minDate = `${year}-${month}-${dayStr}T00:00`; + const maxDate = `${year}-${month}-${dayStr}T23:59`; startTimeInput.min = minDate; startTimeInput.max = maxDate; endTimeInput.min = minDate;