/** * 日期工具(纯函数,零依赖)。 * * 从 `pages/matches/ui.tsx` 抽出 —— 它们原本与 UI 组件混在一个文件里, * 但并不是组件,而是可独立测试的纯函数。 */ /** 日期 key 辅助:YYYY-MM-DD(本地时区) */ function dateKey(d: Date): string { return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}` } /** 未来第 n 天的日期 key */ function addDays(d: Date, n: number): string { const x = new Date(d) x.setFullYear(x.getFullYear(), x.getMonth(), x.getDate() + n) return dateKey(x) } /** UTC ISO → 本地日期 YYYY-MM-DD(用于分组) */ export function toLocalDateKey(iso: string): string { const d = new Date(iso) return dateKey(d) } /** 日期分组头显示:今日/明日/周几 · 年月日 */ export function formatDateHeader(dateKeyStr: string): string { if (!dateKeyStr) return '未开赛' const d = new Date(dateKeyStr + 'T00:00:00') if (isNaN(d.getTime())) return dateKeyStr const today = new Date() const todayKey = dateKey(today) const tmr = new Date(today) tmr.setDate(tmr.getDate() + 1) const tmrKey = dateKey(tmr) const weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][d.getDay()] if (dateKeyStr === todayKey) return `今日 ${weekday}` if (dateKeyStr === tmrKey) return `明日 ${weekday}` return `${d.getMonth() + 1}月${d.getDate()}日 ${weekday}` } /** * 按本地日期分组(非 UTC),保持时间序。 * * 泛型约束 `{ match_date: string }` 而非具体业务类型 —— 使本工具 * 与 Matches 页面解耦,任何带日期字段的列表都能复用。 */ export function groupByDate(list: T[]): Array<[string, T[]]> { const map = new Map() for (const m of list) { const key = toLocalDateKey(m.match_date) const arr = map.get(key) if (arr) arr.push(m) else map.set(key, [m]) } return [...map.entries()] } /** 比赛是否在未来 3 天内(用于默认视图过滤):今天 00:00 → 第 3 天 00:00 */ export function withinNext3Days(matchDate: string): boolean { const key = toLocalDateKey(matchDate) return key >= dateKey(new Date()) && key < addDays(new Date(), 3) }