Fix drag-and-drop timezone bug between dev and production environments
All checks were successful
Build and Push Docker Image / docker (push) Successful in 1m12s
All checks were successful
Build and Push Docker Image / docker (push) Successful in 1m12s
The root cause was that drag operations sent naive local time to the backend, which the backend interpreted using the SERVER's local timezone rather than the USER's timezone. This caused different behavior between development and production servers in different timezones. **Frontend Changes:** - Convert naive datetime from drag operations to UTC before sending to backend - Use client-side Local timezone to properly convert user's intended times - Handle DST transition edge cases with fallback logic **Backend Changes:** - Update parse_event_datetime to treat incoming times as UTC (no server timezone conversion) - Update series handlers to expect UTC times from frontend - Remove server-side Local timezone dependency for event parsing **Result:** - Consistent behavior across all server environments regardless of server timezone - Drag operations now correctly preserve user's intended local times - Fixes "4 hours too early" issue in production drag-and-drop operations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user