fix(dataProcessor): parse DD/M/YY correctly when day <= 12

The previous fix only handled the unambiguous case (day > 12). Dates like
"5/1/26" or "12/1/26" (Jan 5 / Jan 12, 2026) were falling through to
JS's new Date() which parsed them as US format MM/DD/YY, assigning them
to May and December instead of January.

Now any 3-part slash date with a 2-digit year in position 3 and a valid
month in position 2 is treated as DD/M/YY (Spanish/EU convention),
fixing weeks 2-3 of January (days 5-18) showing zero sell-out.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Vidal Wolf
2026-03-03 13:14:30 +01:00
co-authored by Claude Sonnet 4.6
parent 2eed94b94b
commit 37f9ffac2f
+12 -8
View File
@@ -195,21 +195,25 @@ const normalizeMonth = (rawMonth: string): string => {
// 2. Handle numeric months "01", "1", "01-2023" // 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 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('-')) { 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) // Handle date strings with 3 parts separated by '/' or '-'
const parts = m.split(m.includes('/') ? '/' : '-'); const sep = m.includes('/') ? '/' : '-';
const parts = m.split(sep);
if (parts.length === 3) { if (parts.length === 3) {
const [a, b, c] = parts.map(p => parseInt(p, 10)); const [a, b, c] = parts.map(p => parseInt(p, 10));
if (!isNaN(a) && !isNaN(b) && !isNaN(c)) { if (!isNaN(a) && !isNaN(b) && !isNaN(c)) {
// If first part > 12: definitely day-first → DD/MM/YY // YYYY-MM-DD or YYYY/MM/DD (ISO-like, year is 4 digits in first position)
if (a > 12 && b >= 1 && b <= 12) { if (a > 31 && b >= 1 && b <= 12) {
const yearShort = c < 100 ? String(c).padStart(2, '0') : String(c).slice(2); const yearShort = String(a).slice(2);
const result = `${MONTH_ORDER[b - 1]}-${yearShort}`; const result = `${MONTH_ORDER[b - 1]}-${yearShort}`;
monthCache[rawMonth] = result; monthCache[rawMonth] = result;
return result; return result;
} }
// YYYY/MM/DD or YYYY-MM-DD (ISO-like, year is 4 digits in first position) // DD/M/YY European format (e.g. "5/1/26"=5 Jan 2026, "23/2/26"=23 Feb 2026).
if (a > 31 && b >= 1 && b <= 12) { // When last part is a 2-digit year and middle part is a valid month, always
const yearShort = String(a).slice(2); // 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}`; const result = `${MONTH_ORDER[b - 1]}-${yearShort}`;
monthCache[rawMonth] = result; monthCache[rawMonth] = result;
return result; return result;