Fix timezone bug in event creation
Events were appearing 4 hours earlier than selected time due to incorrect timezone handling in backend. The issue was treating frontend local time as if it was already in UTC. - Fix parse_event_datetime() in events.rs to properly convert local time to UTC - Fix all datetime conversions in series.rs to use Local timezone conversion - Replace Utc.from_utc_datetime() with proper Local.from_local_datetime() - Add timezone conversion using with_timezone(&Utc) for accurate UTC storage Now when user selects 5:00 AM, it correctly stores as UTC equivalent and displays back at 5:00 AM local time. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -845,7 +845,7 @@ fn parse_event_datetime(
|
|||||||
time_str: &str,
|
time_str: &str,
|
||||||
all_day: bool,
|
all_day: bool,
|
||||||
) -> Result<chrono::DateTime<chrono::Utc>, String> {
|
) -> Result<chrono::DateTime<chrono::Utc>, String> {
|
||||||
use chrono::{NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
|
use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
|
||||||
|
|
||||||
// Parse the date
|
// Parse the date
|
||||||
let date = NaiveDate::parse_from_str(date_str, "%Y-%m-%d")
|
let date = NaiveDate::parse_from_str(date_str, "%Y-%m-%d")
|
||||||
@@ -865,7 +865,11 @@ fn parse_event_datetime(
|
|||||||
// Combine date and time
|
// Combine date and time
|
||||||
let datetime = NaiveDateTime::new(date, time);
|
let datetime = NaiveDateTime::new(date, time);
|
||||||
|
|
||||||
// Assume local time and convert to UTC (in a real app, you'd want timezone support)
|
// Treat the datetime as local time and convert to UTC
|
||||||
Ok(Utc.from_utc_datetime(&datetime))
|
let local_datetime = Local.from_local_datetime(&datetime)
|
||||||
|
.single()
|
||||||
|
.ok_or_else(|| "Ambiguous local datetime".to_string())?;
|
||||||
|
|
||||||
|
Ok(local_datetime.with_timezone(&Utc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,9 +130,17 @@ pub async fn create_event_series(
|
|||||||
.and_hms_opt(23, 59, 59)
|
.and_hms_opt(23, 59, 59)
|
||||||
.ok_or_else(|| ApiError::BadRequest("Invalid end date".to_string()))?;
|
.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()))?;
|
||||||
|
|
||||||
(
|
(
|
||||||
chrono::Utc.from_utc_datetime(&start_dt),
|
start_local.with_timezone(&chrono::Utc),
|
||||||
chrono::Utc.from_utc_datetime(&end_dt),
|
end_local.with_timezone(&chrono::Utc),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// Parse times for timed events
|
// Parse times for timed events
|
||||||
@@ -163,9 +171,17 @@ pub async fn create_event_series(
|
|||||||
start_date.and_time(end_time)
|
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()))?;
|
||||||
|
|
||||||
(
|
(
|
||||||
chrono::Utc.from_utc_datetime(&start_dt),
|
start_local.with_timezone(&chrono::Utc),
|
||||||
chrono::Utc.from_utc_datetime(&end_dt),
|
end_local.with_timezone(&chrono::Utc),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -401,9 +417,17 @@ pub async fn update_event_series(
|
|||||||
.and_hms_opt(23, 59, 59)
|
.and_hms_opt(23, 59, 59)
|
||||||
.ok_or_else(|| ApiError::BadRequest("Invalid end date".to_string()))?;
|
.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()))?;
|
||||||
|
|
||||||
(
|
(
|
||||||
chrono::Utc.from_utc_datetime(&start_dt),
|
start_local.with_timezone(&chrono::Utc),
|
||||||
chrono::Utc.from_utc_datetime(&end_dt),
|
end_local.with_timezone(&chrono::Utc),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let start_time = if !request.start_time.is_empty() {
|
let start_time = if !request.start_time.is_empty() {
|
||||||
@@ -438,9 +462,17 @@ pub async fn update_event_series(
|
|||||||
(chrono::Utc.from_utc_datetime(&start_dt) + original_duration).naive_utc()
|
(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()))?;
|
||||||
|
|
||||||
(
|
(
|
||||||
chrono::Utc.from_utc_datetime(&start_dt),
|
start_local.with_timezone(&chrono::Utc),
|
||||||
chrono::Utc.from_utc_datetime(&end_dt),
|
end_local.with_timezone(&chrono::Utc),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user