/** * Server-side local-date helpers. * * Bill due dates and payment dates are stored as plain YYYY-MM-DD strings in * the server's local timezone (the client computes "today" the same way in * client/pages/TrackerPage.tsx → localDateString). Never derive a calendar * date from Date.toISOString() — that yields the UTC date, which disagrees * with local time around midnight and month boundaries. */ /** YYYY-MM-DD in local time. */ export function localDateString(date: Date = new Date()): string { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } /** { year, month } (1-based month) in local time. */ export function localYearMonth(date: Date = new Date()): { year: number; month: number } { return { year: date.getFullYear(), month: date.getMonth() + 1 }; } /** YYYY-MM-DD in local time, `days` days before `from`. */ export function localDateStringDaysAgo(days: number, from: Date = new Date()): string { const d = new Date(from); d.setDate(d.getDate() - days); return localDateString(d); } /** Today as YYYY-MM-DD in local time. Alias of localDateString(). */ export function todayLocal(): string { return localDateString(new Date()); } /** YYYY-MM month key in local time (e.g. "2026-06"). */ export function monthKey(date: Date = new Date()): string { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`; }