From a30f2778fd3e0afe7b9ed2106b73043398e3e200 Mon Sep 17 00:00:00 2001 From: Dennis Nemec Date: Sat, 11 Jul 2026 00:10:53 +0200 Subject: [PATCH] fix(tours): Tagesumschlag nach Ortszeit statt UTC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'Heute' wurde per Utc::now().date_naive() bestimmt. Bei CEST (UTC+2) wechselte der Tag dadurch erst um 02:00 Ortszeit — der Fahrer sah nach Mitternacht noch die Touren von gestern. Umgestellt auf Local::now() in list_my_tours_today sowie den Import-/Resync-Defaults und dem Scheduler-Catch-up. Co-Authored-By: Claude Opus 4.8 --- crates/api/src/main.rs | 4 ++-- crates/api/src/routes/admin.rs | 2 +- crates/api/src/routes/dev.rs | 2 +- crates/application/src/usecases/list_my_tours_today.rs | 9 +++++++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/crates/api/src/main.rs b/crates/api/src/main.rs index 9bc6e22..244d964 100644 --- a/crates/api/src/main.rs +++ b/crates/api/src/main.rs @@ -559,7 +559,7 @@ pub(crate) async fn run_app( let job = Job::new_async(cfg.import.cron.as_str(), move |_uuid, _lock| { let import = import.clone(); Box::pin(async move { - let date = (chrono::Utc::now() + chrono::Duration::days(offset)).date_naive(); + let date = (chrono::Local::now() + chrono::Duration::days(offset)).date_naive(); match import.execute_with(date, SyncTrigger::Scheduler).await { Ok(summary) => tracing::info!( date = %summary.date, @@ -592,7 +592,7 @@ pub(crate) async fn run_app( let sync_runs = sync_run_repository.clone(); let offset = cfg.import.date_offset_days; tokio::spawn(async move { - let date = (chrono::Utc::now() + chrono::Duration::days(offset)).date_naive(); + let date = (chrono::Local::now() + chrono::Duration::days(offset)).date_naive(); match sync_runs.has_successful_run_for(date).await { Ok(true) => tracing::info!( %date, diff --git a/crates/api/src/routes/admin.rs b/crates/api/src/routes/admin.rs index 2804346..cb60e45 100644 --- a/crates/api/src/routes/admin.rs +++ b/crates/api/src/routes/admin.rs @@ -82,7 +82,7 @@ pub async fn import_erp( "ungültiges Datum '{s}' (erwartet YYYY-MM-DD): {e}" ))) })?, - None => chrono::Utc::now().date_naive(), + None => chrono::Local::now().date_naive(), }; tracing::info!(%date, "admin.import_erp"); let summary = state.import_erp_tours.execute(date).await?; diff --git a/crates/api/src/routes/dev.rs b/crates/api/src/routes/dev.rs index 94a7c39..e6ecf6c 100644 --- a/crates/api/src/routes/dev.rs +++ b/crates/api/src/routes/dev.rs @@ -50,7 +50,7 @@ pub async fn dev_resync( "ungültiges Datum '{s}' (erwartet YYYY-MM-DD): {e}" ))) })?, - None => chrono::Utc::now().date_naive(), + None => chrono::Local::now().date_naive(), }; tracing::warn!(%date, "dev.resync: Postgres wird überschrieben + neu importiert"); let summary = state.dev_resync_tours.execute(date).await?; diff --git a/crates/application/src/usecases/list_my_tours_today.rs b/crates/application/src/usecases/list_my_tours_today.rs index 29f8900..4999383 100644 --- a/crates/application/src/usecases/list_my_tours_today.rs +++ b/crates/application/src/usecases/list_my_tours_today.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use chrono::{NaiveDate, Utc}; +use chrono::{Local, NaiveDate}; use crate::dto::TourSummary; use crate::error::ApplicationError; @@ -27,9 +27,14 @@ impl ListMyToursTodayUseCase { } pub async fn execute(&self, personalnummer: i64) -> Result, ApplicationError> { + // Bewusst Local statt Utc: der Tagesumschlag muss sich nach der + // Ortszeit des Fahrers richten. Mit Utc wechselt "heute" erst um + // 02:00 Ortszeit (CEST = UTC+2) — bis dahin sähe der Fahrer nach + // Mitternacht noch die Touren von gestern. Der Server läuft in + // Europe/Vienna, daher ist Local hier korrekt. let today = self .today_override - .unwrap_or_else(|| Utc::now().date_naive()); + .unwrap_or_else(|| Local::now().date_naive()); self.repository .find_today_for_driver(personalnummer, today) .await