diff --git a/backend/src/handlers/events.rs b/backend/src/handlers/events.rs index a12ed2d..af413eb 100644 --- a/backend/src/handlers/events.rs +++ b/backend/src/handlers/events.rs @@ -456,14 +456,11 @@ pub async fn create_event( parse_event_datetime_local(&request.start_date, &request.start_time, request.all_day) .map_err(|e| ApiError::BadRequest(format!("Invalid start date/time: {}", e)))?; - let mut end_datetime = parse_event_datetime_local(&request.end_date, &request.end_time, request.all_day) + let end_datetime = parse_event_datetime_local(&request.end_date, &request.end_time, request.all_day) .map_err(|e| ApiError::BadRequest(format!("Invalid end date/time: {}", e)))?; - // For all-day events, add one day to end date for RFC-5545 compliance - // RFC-5545 uses exclusive end dates for all-day events - if request.all_day { - end_datetime = end_datetime + chrono::Duration::days(1); - } + // Note: Frontend already converts inclusive UI dates to exclusive dates for all-day events + // No additional conversion needed here // Validate that end is after start (allow equal times for all-day events) if request.all_day { @@ -766,14 +763,11 @@ pub async fn update_event( parse_event_datetime_local(&request.start_date, &request.start_time, request.all_day) .map_err(|e| ApiError::BadRequest(format!("Invalid start date/time: {}", e)))?; - let mut end_datetime = parse_event_datetime_local(&request.end_date, &request.end_time, request.all_day) + let end_datetime = parse_event_datetime_local(&request.end_date, &request.end_time, request.all_day) .map_err(|e| ApiError::BadRequest(format!("Invalid end date/time: {}", e)))?; - // For all-day events, add one day to end date for RFC-5545 compliance - // RFC-5545 uses exclusive end dates for all-day events - if request.all_day { - end_datetime = end_datetime + chrono::Duration::days(1); - } + // Note: Frontend already converts inclusive UI dates to exclusive dates for all-day events + // No additional conversion needed here // Validate that end is after start (allow equal times for all-day events) if request.all_day { diff --git a/backend/src/handlers/series.rs b/backend/src/handlers/series.rs index a05251b..b065f24 100644 --- a/backend/src/handlers/series.rs +++ b/backend/src/handlers/series.rs @@ -137,13 +137,11 @@ pub async fn create_event_series( let start_datetime = parse_event_datetime_local(&request.start_date, &request.start_time, request.all_day) .map_err(|e| ApiError::BadRequest(format!("Invalid start date/time: {}", e)))?; - let mut end_datetime = parse_event_datetime_local(&request.end_date, &request.end_time, request.all_day) + let end_datetime = parse_event_datetime_local(&request.end_date, &request.end_time, request.all_day) .map_err(|e| ApiError::BadRequest(format!("Invalid end date/time: {}", e)))?; - // For all-day events, add one day to end date for RFC-5545 compliance - if request.all_day { - end_datetime = end_datetime + chrono::Duration::days(1); - } + // Note: Frontend already converts inclusive UI dates to exclusive dates for all-day events + // No additional conversion needed here // Generate a unique UID for the series let uid = format!("series-{}", uuid::Uuid::new_v4().to_string()); diff --git a/frontend/src/components/create_event_modal.rs b/frontend/src/components/create_event_modal.rs index 0230615..8b4b44a 100644 --- a/frontend/src/components/create_event_modal.rs +++ b/frontend/src/components/create_event_modal.rs @@ -257,7 +257,13 @@ fn vevent_to_creation_data(event: &crate::models::ical::VEvent, available_calend // Timing start_date: start_local.date(), - end_date: end_local.date(), + end_date: if event.all_day { + // For all-day events, subtract one day to convert from exclusive to inclusive end date + // (UI expects inclusive dates, but iCalendar stores exclusive end dates) + end_local.date() - chrono::Duration::days(1) + } else { + end_local.date() + }, start_time: start_local.time(), end_time: end_local.time(), diff --git a/frontend/src/components/event_form/types.rs b/frontend/src/components/event_form/types.rs index 79beced..68efc3b 100644 --- a/frontend/src/components/event_form/types.rs +++ b/frontend/src/components/event_form/types.rs @@ -156,8 +156,9 @@ impl EventCreationData { ) { // Use local date/times and timezone - no UTC conversion - let effective_end_date = if self.end_time == NaiveTime::from_hms_opt(0, 0, 0).unwrap() { - // If end time is midnight (00:00), treat it as beginning of next day + let effective_end_date = if self.all_day { + // For all-day events, add one day to convert from inclusive to exclusive end date + // (iCalendar spec requires exclusive end dates for all-day events) self.end_date + chrono::Duration::days(1) } else { self.end_date