diff --git a/apps/st/src/components/statistics/management/StatisticsInputPeriodDialog.tsx b/apps/st/src/components/statistics/management/StatisticsInputPeriodDialog.tsx index 6ebcfc66e..f560fd717 100644 --- a/apps/st/src/components/statistics/management/StatisticsInputPeriodDialog.tsx +++ b/apps/st/src/components/statistics/management/StatisticsInputPeriodDialog.tsx @@ -19,7 +19,6 @@ import { DialogHeader, DialogTitle, Input, - InputDatePicker, Label, Select, SelectContent, @@ -48,9 +47,32 @@ function normalizeStatsYrInput(raw: string): string { function formatDateToYmd(d: Date | undefined): string | null { if (!d || Number.isNaN(d.getTime())) return null; const y = d.getFullYear(); + if (y < 1000 || y > 9999) return null; const m = String(d.getMonth() + 1).padStart(2, "0"); const day = String(d.getDate()).padStart(2, "0"); - return `${y}${m}${day}`; + return `${String(y).padStart(4, "0")}${m}${day}`; +} + +/** Chrome `type="date"`는 max가 없으면 연도를 6자리까지 받음 */ +const PERIOD_DATE_INPUT_MIN = "1000-01-01"; +const PERIOD_DATE_INPUT_MAX = "9999-12-31"; + +function formatDateToInputValue(d: Date | undefined): string { + if (!d || Number.isNaN(d.getTime())) return ""; + const ymd = formatDateToYmd(d); + if (!ymd) return ""; + return `${ymd.slice(0, 4)}-${ymd.slice(4, 6)}-${ymd.slice(6, 8)}`; +} + +function parseFourDigitYearDate(raw: string): Date | undefined { + const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(raw); + if (!match) return undefined; + const year = Number(match[1]); + const month = Number(match[2]); + const day = Number(match[3]); + const parsed = new Date(year, month - 1, day); + if (Number.isNaN(parsed.getTime()) || parsed.getFullYear() !== year) return undefined; + return parsed; } export interface StatisticsInputPeriodDialogProps { @@ -281,18 +303,26 @@ export function StatisticsInputPeriodDialog({ )}