datatype date fixed

This commit is contained in:
Simon Pocrnjič
2025-10-30 18:21:47 +01:00
parent 20d4907fc5
commit cb7851f91c
4 changed files with 83 additions and 28 deletions
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace App\Services;
class DateNormalizer
{
/**
* Normalize a raw date string to Y-m-d (ISO) or return null if unparseable.
* Accepted examples: 30.10.2025, 30/10/2025, 30-10-2025, 1/2/25, 2025-10-30
*/
public static function toDate(?string $raw): ?string
{
if ($raw === null) {
return null;
}
$raw = trim($raw);
if ($raw === '') {
return null;
}
// Common European and ISO formats first (day-first, then ISO)
$candidates = [
'd.m.Y', 'd.m.y',
'd/m/Y', 'd/m/y',
'd-m-Y', 'd-m-y',
'Y-m-d', 'Y/m/d', 'Y.m.d',
];
foreach ($candidates as $fmt) {
$dt = \DateTime::createFromFormat($fmt, $raw);
if ($dt instanceof \DateTime) {
$errors = \DateTime::getLastErrors();
if ((int) ($errors['warning_count'] ?? 0) === 0 && (int) ($errors['error_count'] ?? 0) === 0) {
// Adjust two-digit years to reasonable century (00-69 => 2000-2069, 70-99 => 1970-1999)
$year = (int) $dt->format('Y');
if ($year < 100) {
$year += ($year <= 69) ? 2000 : 1900;
// Rebuild date with corrected year
$month = (int) $dt->format('m');
$day = (int) $dt->format('d');
return sprintf('%04d-%02d-%02d', $year, $month, $day);
}
return $dt->format('Y-m-d');
}
}
}
// Fallback: strtotime (permissive). If fails, return null.
$ts = @strtotime($raw);
if ($ts === false) {
return null;
}
return date('Y-m-d', $ts);
}
}
+4 -26
View File
@@ -553,7 +553,8 @@ public function process(Import $import, ?Authenticatable $user = null): array
$payload = [
'account_id' => $accountIdForPayment,
'reference' => $p['reference'] ?? null,
'paid_at' => $p['payment_date'] ?? ($p['paid_at'] ?? null),
// Normalize payment date to ISO (Y-m-d) to avoid DB parse errors
'paid_at' => \App\Services\DateNormalizer::toDate((string) (($p['payment_date'] ?? ($p['paid_at'] ?? '')))),
'currency' => $p['currency'] ?? 'EUR',
'created_by' => $user?->getAuthIdentifier(),
];
@@ -1742,31 +1743,8 @@ private function sanitizeHeaderName(string $v): string
*/
private function normalizeDate(?string $raw): ?string
{
if ($raw === null) {
return null;
}
$raw = trim($raw);
if ($raw === '') {
return null;
}
$candidates = ['d.m.Y', 'd.m.y', 'd/m/Y', 'd/m/y', 'Y-m-d'];
foreach ($candidates as $fmt) {
$dt = \DateTime::createFromFormat($fmt, $raw);
if ($dt instanceof \DateTime) {
// Reject invalid (createFromFormat returns false on mismatch; partial matches handled by checking errors)
$errors = \DateTime::getLastErrors();
if (($errors['warning_count'] ?? 0) === 0 && ($errors['error_count'] ?? 0) === 0) {
return $dt->format('Y-m-d');
}
}
}
// Fallback: strtotime (very permissive); if fails return null
$ts = @strtotime($raw);
if ($ts === false) {
return null;
}
return date('Y-m-d', $ts);
// Delegate to shared normalizer for consistency across the app
return \App\Services\DateNormalizer::toDate($raw);
}
private function findSourceColumnFor($mappings, string $targetField): ?string