import { formatAppMinuteOfDay } from '@/lib/i18n/format'; /** Normalize to local midnight; invalid input falls back to today. */ export function startOfLocalDay(d: Date): Date { if (Number.isNaN(d.getTime())) { const t = new Date(); return new Date(t.getFullYear(), t.getMonth(), t.getDate(), 0, 0, 0, 0); } return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0); } /** Local calendar bounds for a date (browser timezone). */ export function getLocalDayIsoRange(day: Date): { from: string; to: string } { const start = startOfLocalDay(day); const end = new Date(start.getFullYear(), start.getMonth(), start.getDate() + 1, 0, 0, 0, 0); return { from: start.toISOString(), to: end.toISOString() }; } export function toDateInputValue(d: Date): string { const y = d.getFullYear(); const m = String(d.getMonth() + 1).padStart(2, '0'); const day = String(d.getDate()).padStart(2, '0'); return `${y}-${m}-${day}`; } export function parseDateInput(value: string): Date { const [y, m, d] = value.split('-').map(Number); return new Date(y, m - 1, d, 0, 0, 0, 0); } export function combineLocalDateAndTime(day: Date, timeHHmm: string): Date { const [h, min] = timeHHmm.split(':').map(Number); return new Date(day.getFullYear(), day.getMonth(), day.getDate(), h, min, 0, 0); } export function formatTimeForInput(d: Date): string { const h = String(d.getHours()).padStart(2, '0'); const m = String(d.getMinutes()).padStart(2, '0'); return `${h}:${m}`; } export function isSameLocalCalendarDay(a: Date, b: Date): boolean { return ( a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate() ); } export function formatHourLabel(hour: number, locale: string): string { return formatAppMinuteOfDay(hour * 60, locale); } /** Local midnight + delta calendar days. */ export function addCalendarDays(day: Date, delta: number): Date { return new Date(day.getFullYear(), day.getMonth(), day.getDate() + delta, 0, 0, 0, 0); } /** Compare two calendar days at local midnight (ordering by date only). */ export function compareLocalDayStart(a: Date, b: Date): number { const ta = new Date(a.getFullYear(), a.getMonth(), a.getDate()).getTime(); const tb = new Date(b.getFullYear(), b.getMonth(), b.getDate()).getTime(); return ta - tb; } export function parseTimeInputToMinutes(time: string): number { const [h, m] = time.split(':').map(Number); if (!Number.isFinite(h) || !Number.isFinite(m)) { return 0; } return h * 60 + m; } export function minutesToTimeInput(minutes: number): string { const clamped = Math.max(0, Math.min(24 * 60 - 1, minutes)); const h = Math.floor(clamped / 60); const m = clamped % 60; return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`; } export function adjustTimeInput(time: string, deltaMinutes: number): string { return minutesToTimeInput(parseTimeInputToMinutes(time) + deltaMinutes); }