From 899525a75cb560df6ac98ca7a11d5e526abdc12a Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Tue, 28 Apr 2026 15:36:48 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20#59:=20Legacy-Format-Schutz=20f=C3=BCr=20?= =?UTF-8?q?Instant-Parsing=20in=20ProcessingAttempt-Repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Haiku 4.5 --- ...iteProcessingAttemptRepositoryAdapter.java | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/pdf-umbenenner-adapter-out/src/main/java/de/gecheckt/pdf/umbenenner/adapter/out/sqlite/SqliteProcessingAttemptRepositoryAdapter.java b/pdf-umbenenner-adapter-out/src/main/java/de/gecheckt/pdf/umbenenner/adapter/out/sqlite/SqliteProcessingAttemptRepositoryAdapter.java index 5c2698f..98e8e89 100644 --- a/pdf-umbenenner-adapter-out/src/main/java/de/gecheckt/pdf/umbenenner/adapter/out/sqlite/SqliteProcessingAttemptRepositoryAdapter.java +++ b/pdf-umbenenner-adapter-out/src/main/java/de/gecheckt/pdf/umbenenner/adapter/out/sqlite/SqliteProcessingAttemptRepositoryAdapter.java @@ -7,8 +7,11 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; +import java.time.DateTimeFormatter; import java.time.Instant; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -308,8 +311,8 @@ public class SqliteProcessingAttemptRepositoryAdapter implements ProcessingAttem new DocumentFingerprint(rs.getString("fingerprint")), new RunId(rs.getString("run_id")), rs.getInt("attempt_number"), - Instant.parse(rs.getString("started_at")), - Instant.parse(rs.getString("ended_at")), + stringToInstant(rs.getString("started_at")), + stringToInstant(rs.getString("ended_at")), ProcessingStatus.valueOf(rs.getString("status")), rs.getString("failure_class"), rs.getString("failure_message"), @@ -328,6 +331,35 @@ public class SqliteProcessingAttemptRepositoryAdapter implements ProcessingAttem ); } + /** + * Versucht, einen Instant aus einer String-Darstellung zu parsen. + * Unterstützt sowohl modernes ISO-8601-Format als auch Legacy-Format. + * + * @param stringValue die String-Darstellung des Datums, kann null sein + * @return das geparste Instant, oder null wenn stringValue null oder leer ist + */ + private Instant stringToInstant(String stringValue) { + if (stringValue == null || stringValue.isBlank()) { + return null; + } + + // Versuch mit ISO-8601 Format (moderner Standard) + try { + return Instant.parse(stringValue); + } catch (Exception e) { + // Fallback auf älteres Format "yyyy-MM-dd HH:mm:ss" (als UTC) + try { + LocalDateTime dateTime = LocalDateTime.parse(stringValue, + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + return dateTime.atZone(ZoneId.of("UTC")).toInstant(); + } catch (Exception fallbackException) { + logger.warn("Fehler beim Parsen der Instant-String '{}' in beiden Formaten (ISO-8601 und Legacy-Format)", + stringValue, fallbackException); + return null; + } + } + } + // ------------------------------------------------------------------------- // JDBC nullable helpers // -------------------------------------------------------------------------