From 72273a3f1c4e7e2d0d156cc2d486af26d2adc654 Mon Sep 17 00:00:00 2001 From: Connor Johnstone Date: Thu, 4 Sep 2025 16:26:05 -0400 Subject: [PATCH] Fix event creation timezone handling to prevent time offset issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Convert local datetime to UTC before sending to backend for non-all-day events - Keep all-day events unchanged (no timezone conversion needed) - Add proper timezone conversion using chrono::Local and chrono::Utc - Include fallback handling if timezone conversion fails - Add debug logging for timezone conversion issues This resolves the issue where events appeared 4 hours earlier than expected due to frontend sending local time but backend treating it as UTC time. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- frontend/src/components/event_form/types.rs | 45 +++++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/event_form/types.rs b/frontend/src/components/event_form/types.rs index 9c85849..ada91f1 100644 --- a/frontend/src/components/event_form/types.rs +++ b/frontend/src/components/event_form/types.rs @@ -152,13 +152,50 @@ impl EventCreationData { Option, // recurrence_count Option, // recurrence_until ) { + use chrono::{Local, TimeZone}; + + // Convert local date/time to UTC for backend + let (utc_start_date, utc_start_time, utc_end_date, utc_end_time) = if self.all_day { + // For all-day events, just use the dates as-is (no time conversion needed) + ( + self.start_date.format("%Y-%m-%d").to_string(), + self.start_time.format("%H:%M").to_string(), + self.end_date.format("%Y-%m-%d").to_string(), + self.end_time.format("%H:%M").to_string(), + ) + } else { + // Convert local date/time to UTC + let start_local = Local.from_local_datetime(&self.start_date.and_time(self.start_time)).single(); + let end_local = Local.from_local_datetime(&self.end_date.and_time(self.end_time)).single(); + + if let (Some(start_dt), Some(end_dt)) = (start_local, end_local) { + let start_utc = start_dt.with_timezone(&chrono::Utc); + let end_utc = end_dt.with_timezone(&chrono::Utc); + ( + start_utc.format("%Y-%m-%d").to_string(), + start_utc.format("%H:%M").to_string(), + end_utc.format("%Y-%m-%d").to_string(), + end_utc.format("%H:%M").to_string(), + ) + } else { + // Fallback if timezone conversion fails - use local time as-is + web_sys::console::warn_1(&"⚠️ Failed to convert local time to UTC, using local time".into()); + ( + self.start_date.format("%Y-%m-%d").to_string(), + self.start_time.format("%H:%M").to_string(), + self.end_date.format("%Y-%m-%d").to_string(), + self.end_time.format("%H:%M").to_string(), + ) + } + }; + ( self.title.clone(), self.description.clone(), - self.start_date.format("%Y-%m-%d").to_string(), - self.start_time.format("%H:%M").to_string(), - self.end_date.format("%Y-%m-%d").to_string(), - self.end_time.format("%H:%M").to_string(), + utc_start_date, + utc_start_time, + utc_end_date, + utc_end_time, self.location.clone(), self.all_day, format!("{:?}", self.status).to_uppercase(),