/** * 将用户粘贴的中文日期时间(如「2026年6月22日12时18分」)解析为系统标准格式。 */ export type ChineseDatetimeFormat = 'date' | 'datetime' | 'datetime-minute' /** 将日期时间规范为 `YYYY-MM-DD HH:mm`(去掉秒,兼容历史带秒数据) */ export function formatDatetimeToMinute(val: string): string { const s = String(val || '').trim() if (!s) return '' const parsed = parseChineseDatetimeText(s, 'datetime-minute') return parsed || s } export function parseChineseDatetimeText( text: string, format: ChineseDatetimeFormat ): string | null { const raw = text.trim() if (!raw) return null if (/^\d{4}-\d{2}-\d{2}$/.test(raw)) { return raw } if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(:\d{2})?$/.test(raw)) { const normalized = raw.replace('T', ' ') if (format === 'date') return normalized.slice(0, 10) const parts = normalized.split(' ') const time = parts[1] || '00:00:00' const timeParts = time.split(':') const hh = timeParts[0]?.padStart(2, '0') ?? '00' const mm = timeParts[1]?.padStart(2, '0') ?? '00' if (format === 'datetime-minute') { return `${parts[0]} ${hh}:${mm}` } const ss = timeParts[2]?.padStart(2, '0') ?? '00' return `${parts[0]} ${hh}:${mm}:${ss}` } const cnMatch = raw.match( /^(\d{4})年(\d{1,2})月(\d{1,2})日(?:\s*(\d{1,2})[时点::](\d{1,2})(?:[分::](\d{1,2})[秒]?)?)?/ ) if (!cnMatch) return null const y = cnMatch[1] const mo = String(Number(cnMatch[2])).padStart(2, '0') const d = String(Number(cnMatch[3])).padStart(2, '0') const dateStr = `${y}-${mo}-${d}` if (format === 'date') return dateStr const h = String(Number(cnMatch[4] || 0)).padStart(2, '0') const mi = String(Number(cnMatch[5] || 0)).padStart(2, '0') if (format === 'datetime-minute') { return `${dateStr} ${h}:${mi}` } const s = String(Number(cnMatch[6] || 0)).padStart(2, '0') return `${dateStr} ${h}:${mi}:${s}` } export function handleChineseDatetimePaste( e: ClipboardEvent, format: ChineseDatetimeFormat, setter: (val: string) => void ) { const text = e.clipboardData?.getData('text')?.trim() if (!text) return const parsed = parseChineseDatetimeText(text, format) if (!parsed) return e.preventDefault() e.stopPropagation() setter(parsed) }