/** 发帖/回复时间统一为相对时间:刚刚 / N分钟前 / N小时前 / N天前 / N个月前 / N年前 */ export function formatRelative(dateStr: string): string { const t = new Date(dateStr).getTime(); const diff = Date.now() - t; const min = 60_000, hour = 60 * min, day = 24 * hour; if (diff < min) return "刚刚"; if (diff < hour) return `${Math.floor(diff / min)}分钟前`; if (diff < day) return `${Math.floor(diff / hour)}小时前`; if (diff < 30 * day) return `${Math.floor(diff / day)}天前`; if (diff < 365 * day) return `${Math.floor(diff / (30 * day))}个月前`; return `${Math.floor(diff / (365 * day))}年前`; } /** 去掉末尾多余的 .0(12.0 → 12,1.25 → 1.3 由 toFixed 保证) */ function trimTenths(v: number): string { return String(Number(v.toFixed(1))); } /** 紧凑数字:999 / 1.2K / 128K / 2.3M(站点数据卡) */ export function formatCompact(n: number): string { if (!Number.isFinite(n)) return "0"; if (n < 1000) return String(Math.round(n)); if (n < 1_000_000) { const v = n / 1000; return `${v >= 100 ? Math.round(v) : trimTenths(v)}K`; } return `${trimTenths(n / 1_000_000)}M`; } function pad2(n: number) { return String(n).padStart(2, "0"); } /** 短日期:今年显示 MM-DD,往年显示 YYYY-MM-DD(右栏公告用) */ export function formatShortDate(dateStr: string): string { const d = new Date(dateStr); const md = `${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`; return d.getFullYear() === new Date().getFullYear() ? md : `${d.getFullYear()}-${md}`; } /** 完整日期 YYYY-MM-DD */ export function formatDate(dateStr: string): string { const d = new Date(dateStr); return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`; } /** 完整日期时间 YYYY-MM-DD HH:mm:ss(本地时区) */ export function formatDateTime(dateStr: string): string { const d = new Date(dateStr); if (Number.isNaN(d.getTime())) return ""; return `${formatDate(dateStr)} ${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`; } /** 评论列表短时间:同年「M月D日 HH:mm」,跨年补年份。悬停用 formatDateTime。 */ export function formatCommentTime(dateStr: string, now = new Date()): string { const d = new Date(dateStr); if (Number.isNaN(d.getTime())) return ""; const hm = `${pad2(d.getHours())}:${pad2(d.getMinutes())}`; const md = `${d.getMonth() + 1}月${d.getDate()}日 ${hm}`; return d.getFullYear() === now.getFullYear() ? md : `${d.getFullYear()}年${md}`; }