Fix timezone conversion bug for events displaying on wrong day

- Preserve original local dates when converting times to UTC for storage
- Prevent events created late in day from appearing on next day due to timezone offset
- Remove hacky bandaid logic in week view that tried to handle timezone shifts
- Use stored event date directly instead of calculating from UTC conversion
- Ensure events always display on intended day regardless of timezone

Fixes issue where events created within last 4 hours of day would show on wrong day
after UTC conversion caused date component to shift to next day.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-09-13 18:27:09 -04:00
parent b307be7eb1
commit fdea5cd646
2 changed files with 11 additions and 11 deletions

View File

@@ -164,17 +164,20 @@ impl EventCreationData {
self.end_time.format("%H:%M").to_string(), self.end_time.format("%H:%M").to_string(),
) )
} else { } else {
// Convert local date/time to UTC // Convert local date/time to UTC, but preserve original local dates
let start_local = Local.from_local_datetime(&self.start_date.and_time(self.start_time)).single(); let start_local = Local.from_local_datetime(&self.start_date.and_time(self.start_time)).single();
let end_local = Local.from_local_datetime(&self.end_date.and_time(self.end_time)).single(); let end_local = Local.from_local_datetime(&self.end_date.and_time(self.end_time)).single();
if let (Some(start_dt), Some(end_dt)) = (start_local, end_local) { if let (Some(start_dt), Some(end_dt)) = (start_local, end_local) {
let start_utc = start_dt.with_timezone(&chrono::Utc); let start_utc = start_dt.with_timezone(&chrono::Utc);
let end_utc = end_dt.with_timezone(&chrono::Utc); let end_utc = end_dt.with_timezone(&chrono::Utc);
// IMPORTANT: Use original local dates, not UTC dates!
// This ensures events display on the correct day regardless of timezone conversion
( (
start_utc.format("%Y-%m-%d").to_string(), self.start_date.format("%Y-%m-%d").to_string(),
start_utc.format("%H:%M").to_string(), start_utc.format("%H:%M").to_string(),
end_utc.format("%Y-%m-%d").to_string(), self.end_date.format("%Y-%m-%d").to_string(),
end_utc.format("%H:%M").to_string(), end_utc.format("%H:%M").to_string(),
) )
} else { } else {

View File

@@ -1229,15 +1229,12 @@ fn pixels_to_time(pixels: f64, time_increment: u32) -> NaiveTime {
fn calculate_event_position(event: &VEvent, date: NaiveDate, time_increment: u32, print_pixels_per_hour: Option<f64>, print_start_hour: Option<u32>) -> (f32, f32, bool) { fn calculate_event_position(event: &VEvent, date: NaiveDate, time_increment: u32, print_pixels_per_hour: Option<f64>, print_start_hour: Option<u32>) -> (f32, f32, bool) {
// Convert UTC times to local time for display // Convert UTC times to local time for display
let local_start = event.dtstart.with_timezone(&Local); let local_start = event.dtstart.with_timezone(&Local);
let event_date = local_start.date_naive();
// Position events based on when they appear in local time, not their original date // Events should display based on their stored date (which now preserves the original local date)
// For timezone issues: an event created at 10 PM Sunday might be stored as Monday UTC // not the calculated local date from UTC conversion, since we fixed the creation logic
// but should still display on Sunday's column since that's when the user sees it let event_date = event.dtstart.date_naive(); // Use the stored date, not the converted local date
let should_display_here = event_date == date ||
(event_date == date - chrono::Duration::days(1) && local_start.hour() >= 20);
if !should_display_here { if event_date != date {
return (0.0, 0.0, false); // Event not on this date return (0.0, 0.0, false); // Event not on this date
} }