diff --git a/lang/es.json b/lang/es.json
index aabf9dba..df18dfbf 100644
--- a/lang/es.json
+++ b/lang/es.json
@@ -1696,6 +1696,7 @@
"Works everywhere": "Funciona en todas partes",
"Would you like to add more accounts or continue to the dashboard?": "¿Quieres agregar más cuentas o continuar al panel?",
"YYYY-MM-DD (e.g., 2024-12-31)": "YYYY-MM-DD (ej., 2024-12-31)",
+ "YYYYMMDD (e.g., 20241231)": "YYYYMMDD (ej., 20241231)",
"Year": "Año",
"Yearly": "Anual",
"Yearly code": "Código anual",
diff --git a/resources/js/components/accounts/import-balances/import-balance-step-mapping.tsx b/resources/js/components/accounts/import-balances/import-balance-step-mapping.tsx
index 2a336af4..a28a1e1d 100644
--- a/resources/js/components/accounts/import-balances/import-balance-step-mapping.tsx
+++ b/resources/js/components/accounts/import-balances/import-balance-step-mapping.tsx
@@ -282,6 +282,19 @@ export function ImportBalanceStepMapping({
{__('DD-MM-YYYY (e.g., 31-12-2024)')}
+
+
+
+
+
)}
diff --git a/resources/js/components/transactions/import-step-mapping.tsx b/resources/js/components/transactions/import-step-mapping.tsx
index 1bb1143e..c52a27ad 100644
--- a/resources/js/components/transactions/import-step-mapping.tsx
+++ b/resources/js/components/transactions/import-step-mapping.tsx
@@ -593,6 +593,19 @@ export function ImportStepMapping({
{__('DD-MM-YYYY (e.g., 31-12-2024)')}
+
+
+
+
+
)}
diff --git a/resources/js/lib/file-parser.test.ts b/resources/js/lib/file-parser.test.ts
index dd45e206..1123e3d8 100644
--- a/resources/js/lib/file-parser.test.ts
+++ b/resources/js/lib/file-parser.test.ts
@@ -72,6 +72,30 @@ describe('convertRowsToTransactions', () => {
process.env.TZ = originalTimezone;
}
});
+
+ it('parses YYYYMMDD compact dates', () => {
+ const transactions = convertRowsToTransactions(
+ [
+ {
+ date: '20241231',
+ description: 'New Year Eve',
+ amount: '10.00',
+ },
+ ],
+ {
+ transaction_date: 'date',
+ description: 'description',
+ amount: 'amount',
+ balance: null,
+ creditor_name: null,
+ debtor_name: null,
+ },
+ DateFormat.YearMonthDayCompact,
+ );
+
+ expect(transactions).toHaveLength(1);
+ expect(transactions[0].transaction_date).toBe('2024-12-31');
+ });
});
describe('convertRowsToTransactions balance column', () => {
@@ -279,6 +303,17 @@ describe('autoDetectDateFormat', () => {
DateFormat.DayMonthYear,
);
});
+
+ it('detects YYYYMMDD compact format unambiguously', () => {
+ const data = [
+ { date: '20240115' },
+ { date: '20240220' },
+ { date: '20240325' },
+ ];
+ expect(autoDetectDateFormat(data, 'date')).toBe(
+ DateFormat.YearMonthDayCompact,
+ );
+ });
});
describe('getLatestTransactionDate', () => {
diff --git a/resources/js/lib/file-parser.ts b/resources/js/lib/file-parser.ts
index 6b500bff..74369496 100644
--- a/resources/js/lib/file-parser.ts
+++ b/resources/js/lib/file-parser.ts
@@ -224,12 +224,14 @@ export function autoDetectDateFormat(
DateFormat.YearMonthDay,
DateFormat.DayMonthYear,
DateFormat.MonthDayYear,
+ DateFormat.YearMonthDayCompact,
];
const sampleSize = Math.min(10, data.length);
const scores: Record = {
[DateFormat.YearMonthDay]: 0,
[DateFormat.DayMonthYear]: 0,
[DateFormat.MonthDayYear]: 0,
+ [DateFormat.YearMonthDayCompact]: 0,
};
for (let i = 0; i < sampleSize; i++) {
@@ -427,7 +429,14 @@ export function parseDate(
month: number | undefined,
day: number | undefined;
- if (str.length === 5) {
+ if (format === DateFormat.YearMonthDayCompact) {
+ const compactArray = /^(\d{4})(\d{2})(\d{2})$/.exec(str);
+ if (compactArray) {
+ year = Number(compactArray[1]);
+ month = Number(compactArray[2]);
+ day = Number(compactArray[3]);
+ }
+ } else if (str.length === 5) {
const dateRegex = /^(\d{1,2})-(\d{1,2})$/;
const dateArray = dateRegex.exec(str);
if (dateArray) {
diff --git a/resources/js/types/import.ts b/resources/js/types/import.ts
index c309b8eb..719fb9f9 100644
--- a/resources/js/types/import.ts
+++ b/resources/js/types/import.ts
@@ -11,6 +11,7 @@ export enum DateFormat {
YearMonthDay = 'YYYY-MM-DD',
MonthDayYear = 'MM-DD-YYYY',
DayMonthYear = 'DD-MM-YYYY',
+ YearMonthDayCompact = 'YYYYMMDD',
}
export interface ColumnMapping {