feat: validar y normalizar fechas explícitas (YYYY-MM-DD y YY-MM-DD)

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
main
borja 3 weeks ago
parent 414374367d
commit 275f5adfde

@ -58,6 +58,41 @@ export class CommandService {
const todayYMD = ymdFromDateInTZ(new Date()); const todayYMD = ymdFromDateInTZ(new Date());
// Helpers para validar y normalizar fechas explícitas
const isLeap = (y: number) => (y % 4 === 0 && y % 100 !== 0) || (y % 400 === 0);
const daysInMonth = (y: number, m: number) => {
if (m === 2) return isLeap(y) ? 29 : 28;
return [31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][m - 1];
};
const isValidYMD = (ymd: string): boolean => {
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(ymd);
if (!m) return false;
const Y = parseInt(m[1], 10);
const MM = parseInt(m[2], 10);
const DD = parseInt(m[3], 10);
if (MM < 1 || MM > 12) return false;
const dim = daysInMonth(Y, MM);
if (!dim || DD < 1 || DD > dim) return false;
return true;
};
const normalizeDateToken = (t: string): string | null => {
// YYYY-MM-DD
if (/^\d{4}-\d{2}-\d{2}$/.test(t)) {
return isValidYMD(t) ? t : null;
}
// YY-MM-DD -> 20YY-MM-DD
const m = /^(\d{2})-(\d{2})-(\d{2})$/.exec(t);
if (m) {
const yy = parseInt(m[1], 10);
const mm = m[2];
const dd = m[3];
const yyyy = 2000 + yy;
const ymd = `${String(yyyy)}-${mm}-${dd}`;
return isValidYMD(ymd) ? ymd : null;
}
return null;
};
type DateCandidate = { index: number; ymd: string }; type DateCandidate = { index: number; ymd: string };
const dateCandidates: DateCandidate[] = []; const dateCandidates: DateCandidate[] = [];
const dateTokenIndexes = new Set<number>(); const dateTokenIndexes = new Set<number>();
@ -67,11 +102,11 @@ export class CommandService {
const raw = parts[i]; const raw = parts[i];
const low = raw.toLowerCase().replace(/^[([{¿¡"']+/, '').replace(/[.,;:!?)\]}¿¡"'']+$/, ''); const low = raw.toLowerCase().replace(/^[([{¿¡"']+/, '').replace(/[.,;:!?)\]}¿¡"'']+$/, '');
// Fecha explícita YYYY-MM-DD // Fecha explícita en formatos permitidos: YYYY-MM-DD o YY-MM-DD (expandido a 20YY)
if (/^\d{4}-\d{2}-\d{2}$/.test(low)) { {
// Validar rango básico y filtrar pasado según hoy en TZ const norm = normalizeDateToken(low);
if (low >= todayYMD) { if (norm && norm >= todayYMD) {
dateCandidates.push({ index: i, ymd: low }); dateCandidates.push({ index: i, ymd: norm });
dateTokenIndexes.add(i); dateTokenIndexes.add(i);
continue; continue;
} }

Loading…
Cancel
Save