diff --git a/backend/src/handlers/events.rs b/backend/src/handlers/events.rs index b80c91f..8257131 100644 --- a/backend/src/handlers/events.rs +++ b/backend/src/handlers/events.rs @@ -845,7 +845,7 @@ fn parse_event_datetime( time_str: &str, all_day: bool, ) -> Result, String> { - use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc}; + use chrono::{NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc}; // Parse the date let date = NaiveDate::parse_from_str(date_str, "%Y-%m-%d") @@ -866,11 +866,7 @@ fn parse_event_datetime( // Combine date and time let datetime = NaiveDateTime::new(date, time); - // Treat the datetime as local time and convert to UTC - let local_datetime = Local.from_local_datetime(&datetime) - .single() - .ok_or_else(|| "Ambiguous local datetime".to_string())?; - - Ok(local_datetime.with_timezone(&Utc)) + // Frontend now sends UTC times, so treat as UTC directly + Ok(Utc.from_utc_datetime(&datetime)) } } diff --git a/backend/src/handlers/series.rs b/backend/src/handlers/series.rs index ed1d0a8..f1b8584 100644 --- a/backend/src/handlers/series.rs +++ b/backend/src/handlers/series.rs @@ -130,13 +130,9 @@ pub async fn create_event_series( .and_hms_opt(23, 59, 59) .ok_or_else(|| ApiError::BadRequest("Invalid end date".to_string()))?; - // Convert from local time to UTC - let start_local = chrono::Local.from_local_datetime(&start_dt) - .single() - .ok_or_else(|| ApiError::BadRequest("Ambiguous start datetime".to_string()))?; - let end_local = chrono::Local.from_local_datetime(&end_dt) - .single() - .ok_or_else(|| ApiError::BadRequest("Ambiguous end datetime".to_string()))?; + // Frontend now sends UTC times, so treat as UTC directly + let start_local = chrono::Utc.from_utc_datetime(&start_dt); + let end_local = chrono::Utc.from_utc_datetime(&end_dt); ( start_local.with_timezone(&chrono::Utc), @@ -171,13 +167,9 @@ pub async fn create_event_series( start_date.and_time(end_time) }; - // Convert from local time to UTC - let start_local = chrono::Local.from_local_datetime(&start_dt) - .single() - .ok_or_else(|| ApiError::BadRequest("Ambiguous start datetime".to_string()))?; - let end_local = chrono::Local.from_local_datetime(&end_dt) - .single() - .ok_or_else(|| ApiError::BadRequest("Ambiguous end datetime".to_string()))?; + // Frontend now sends UTC times, so treat as UTC directly + let start_local = chrono::Utc.from_utc_datetime(&start_dt); + let end_local = chrono::Utc.from_utc_datetime(&end_dt); ( start_local.with_timezone(&chrono::Utc), @@ -456,13 +448,9 @@ pub async fn update_event_series( (chrono::Utc.from_utc_datetime(&start_dt) + original_duration).naive_utc() }; - // Convert from local time to UTC - let start_local = chrono::Local.from_local_datetime(&start_dt) - .single() - .ok_or_else(|| ApiError::BadRequest("Ambiguous start datetime".to_string()))?; - let end_local = chrono::Local.from_local_datetime(&end_dt) - .single() - .ok_or_else(|| ApiError::BadRequest("Ambiguous end datetime".to_string()))?; + // Frontend now sends UTC times, so treat as UTC directly + let start_local = chrono::Utc.from_utc_datetime(&start_dt); + let end_local = chrono::Utc.from_utc_datetime(&end_dt); ( start_local.with_timezone(&chrono::Utc), diff --git a/frontend/src/app.rs b/frontend/src/app.rs index e003453..edbf1f2 100644 --- a/frontend/src/app.rs +++ b/frontend/src/app.rs @@ -761,11 +761,30 @@ pub fn App() -> Html { String::new() }; - // Send local time directly to backend (backend will handle UTC conversion) - let start_date = new_start.format("%Y-%m-%d").to_string(); - let start_time = new_start.format("%H:%M").to_string(); - let end_date = new_end.format("%Y-%m-%d").to_string(); - let end_time = new_end.format("%H:%M").to_string(); + // Convert local naive datetime to UTC before sending to backend + use chrono::TimeZone; + let local_tz = chrono::Local; + + let start_utc = local_tz.from_local_datetime(&new_start) + .single() + .unwrap_or_else(|| { + // Fallback for ambiguous times (DST transitions) + local_tz.from_local_datetime(&new_start).earliest().unwrap() + }) + .with_timezone(&chrono::Utc); + + let end_utc = local_tz.from_local_datetime(&new_end) + .single() + .unwrap_or_else(|| { + // Fallback for ambiguous times (DST transitions) + local_tz.from_local_datetime(&new_end).earliest().unwrap() + }) + .with_timezone(&chrono::Utc); + + let start_date = start_utc.format("%Y-%m-%d").to_string(); + let start_time = start_utc.format("%H:%M").to_string(); + let end_date = end_utc.format("%Y-%m-%d").to_string(); + let end_time = end_utc.format("%H:%M").to_string(); // Convert existing event data to string formats for the API let status_str = match original_event.status {