Fix all-day event date display bug: events created 9/4-9/6 now show correctly instead of 9/3-9/5
All checks were successful
Build and Push Docker Image / docker (push) Successful in 1m9s

- Backend: Store all-day events at noon UTC instead of midnight to avoid timezone boundary issues
- Backend: Remove local timezone conversion for all-day events in series handler
- Frontend: Skip timezone conversion when extracting dates from all-day events for display
- Frontend: Extract dates directly from UTC for all-day events in event_spans_date function

The issue was that timezone conversion of UTC midnight could shift dates backward in western timezones.
Now all-day events use noon UTC storage and pure date extraction without timezone conversion.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-09-03 17:35:29 -04:00
parent 089f4ce105
commit 289284a532
3 changed files with 26 additions and 19 deletions

View File

@@ -852,10 +852,11 @@ fn parse_event_datetime(
.map_err(|_| format!("Invalid date format: {}. Expected YYYY-MM-DD", date_str))?;
if all_day {
// For all-day events, use midnight UTC
// For all-day events, use noon UTC to avoid timezone boundary issues
// This ensures the date remains correct when converted to any local timezone
let datetime = date
.and_hms_opt(0, 0, 0)
.ok_or_else(|| "Failed to create midnight datetime".to_string())?;
.and_hms_opt(12, 0, 0)
.ok_or_else(|| "Failed to create noon datetime".to_string())?;
Ok(Utc.from_utc_datetime(&datetime))
} else {
// Parse the time

View File

@@ -397,8 +397,9 @@ pub async fn update_event_series(
};
let (start_datetime, end_datetime) = if request.all_day {
// For all-day events, use noon UTC to avoid timezone boundary issues
let start_dt = start_date
.and_hms_opt(0, 0, 0)
.and_hms_opt(12, 0, 0)
.ok_or_else(|| ApiError::BadRequest("Invalid start date".to_string()))?;
// For all-day events, also preserve the original date pattern
@@ -414,20 +415,13 @@ pub async fn update_event_series(
};
let end_dt = end_date
.and_hms_opt(23, 59, 59)
.and_hms_opt(12, 0, 0)
.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()))?;
// For all-day events, use UTC directly (no local conversion needed)
(
start_local.with_timezone(&chrono::Utc),
end_local.with_timezone(&chrono::Utc),
chrono::Utc.from_utc_datetime(&start_dt),
chrono::Utc.from_utc_datetime(&end_dt),
)
} else {
let start_time = if !request.start_time.is_empty() {