diff --git a/services/dataProcessor.ts b/services/dataProcessor.ts index c529371..246be48 100644 --- a/services/dataProcessor.ts +++ b/services/dataProcessor.ts @@ -195,21 +195,25 @@ const normalizeMonth = (rawMonth: string): string => { // 2. Handle numeric months "01", "1", "01-2023" // If it's a full date string like "2023-04-01", "01/04/2023", or "23/2/26" (DD/M/YY) if (m.includes('/') || m.includes('-')) { - // Handle DD/M/YY or DD/MM/YY (European day-first format, e.g. "23/2/26" = 23 Feb 2026) - const parts = m.split(m.includes('/') ? '/' : '-'); + // Handle date strings with 3 parts separated by '/' or '-' + const sep = m.includes('/') ? '/' : '-'; + const parts = m.split(sep); if (parts.length === 3) { const [a, b, c] = parts.map(p => parseInt(p, 10)); if (!isNaN(a) && !isNaN(b) && !isNaN(c)) { - // If first part > 12: definitely day-first → DD/MM/YY - if (a > 12 && b >= 1 && b <= 12) { - const yearShort = c < 100 ? String(c).padStart(2, '0') : String(c).slice(2); + // YYYY-MM-DD or YYYY/MM/DD (ISO-like, year is 4 digits in first position) + if (a > 31 && b >= 1 && b <= 12) { + const yearShort = String(a).slice(2); const result = `${MONTH_ORDER[b - 1]}-${yearShort}`; monthCache[rawMonth] = result; return result; } - // YYYY/MM/DD or YYYY-MM-DD (ISO-like, year is 4 digits in first position) - if (a > 31 && b >= 1 && b <= 12) { - const yearShort = String(a).slice(2); + // DD/M/YY European format (e.g. "5/1/26"=5 Jan 2026, "23/2/26"=23 Feb 2026). + // When last part is a 2-digit year and middle part is a valid month, always + // treat as day-first (Spanish/EU convention). Covers ambiguous cases like + // "5/1/26" where day <= 12, avoiding JS Date's US MM/DD/YY misparse. + if (c < 100 && b >= 1 && b <= 12 && a >= 1 && a <= 31) { + const yearShort = String(c).padStart(2, '0'); const result = `${MONTH_ORDER[b - 1]}-${yearShort}`; monthCache[rawMonth] = result; return result;