/** * 格式化工具函数 * * 统一管理各种格式化逻辑(日期、时间、数字等) * 包括:日期时间格式化、文件大小格式化、数字格式化、百分比格式化等 * 确保整个应用的格式化一致性 * * @created 2025-01-XX(从各组件提取) * @utils */ import { format } from 'date-fns' /** * 格式化日期时间(完整格式) * @param date - 日期对象或时间戳字符串 * @param formatStr - 格式化字符串,默认为 'yyyy-MM-dd HH:mm:ss' * @returns 格式化后的日期时间字符串 */ export function formatDateTime(date: Date | string | number, formatStr: string = 'yyyy-MM-dd HH:mm:ss'): string { try { const dateObj = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date if (isNaN(dateObj.getTime())) { return '无效日期' } return format(dateObj, formatStr) } catch (error) { console.error('Date formatting error:', error) return '无效日期' } } /** * 格式化日期(仅日期部分) * @param date - 日期对象或时间戳字符串 * @returns 格式化后的日期字符串(yyyy-MM-dd) */ export function formatDate(date: Date | string | number): string { return formatDateTime(date, 'yyyy-MM-dd') } /** * 格式化时间(仅时间部分) * @param date - 日期对象或时间戳字符串 * @returns 格式化后的时间字符串(HH:mm:ss) */ export function formatTime(date: Date | string | number): string { return formatDateTime(date, 'HH:mm:ss') } /** * 格式化日期时间(简短格式,不含秒) * @param date - 日期对象或时间戳字符串 * @returns 格式化后的日期时间字符串(yyyy-MM-dd HH:mm) */ export function formatDateTimeShort(date: Date | string | number): string { return formatDateTime(date, 'yyyy-MM-dd HH:mm') } /** * 使用本地化格式格式化日期时间 * @param date - 日期对象或时间戳字符串 * @param locale - 语言环境,默认为 'zh-CN' * @param options - Intl.DateTimeFormat 选项 * @returns 格式化后的日期时间字符串 */ export function formatDateTimeLocale( date: Date | string | number, locale: string = 'zh-CN', options?: Intl.DateTimeFormatOptions ): string { try { const dateObj = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date if (isNaN(dateObj.getTime())) { return '无效日期' } const defaultOptions: Intl.DateTimeFormatOptions = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, } return new Intl.DateTimeFormat(locale, options || defaultOptions).format(dateObj) } catch (error) { console.error('Date formatting error:', error) return '无效日期' } } /** * 格式化相对时间(如:2小时前、3天前) * @param date - 日期对象或时间戳字符串 * @returns 相对时间字符串 */ export function formatRelativeTime(date: Date | string | number): string { try { const dateObj = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date if (isNaN(dateObj.getTime())) { return '无效日期' } const now = new Date() const diffMs = now.getTime() - dateObj.getTime() const diffSeconds = Math.floor(diffMs / 1000) const diffMinutes = Math.floor(diffSeconds / 60) const diffHours = Math.floor(diffMinutes / 60) const diffDays = Math.floor(diffHours / 24) if (diffSeconds < 60) { return '刚刚' } else if (diffMinutes < 60) { return `${diffMinutes}分钟前` } else if (diffHours < 24) { return `${diffHours}小时前` } else if (diffDays < 7) { return `${diffDays}天前` } else { return formatDateTimeShort(dateObj) } } catch (error) { console.error('Relative time formatting error:', error) return '无效日期' } } /** * 格式化文件大小 * @param bytes - 字节数 * @param decimals - 小数位数,默认为 2 * @returns 格式化后的文件大小字符串 */ export function formatFileSize(bytes: number, decimals: number = 2): string { if (bytes === 0) return '0 Bytes' const k = 1024 const dm = decimals < 0 ? 0 : decimals const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] const i = Math.floor(Math.log(bytes) / Math.log(k)) return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i] } /** * 格式化数字(添加千位分隔符) * @param num - 数字 * @param decimals - 小数位数,默认为 0 * @returns 格式化后的数字字符串 */ export function formatNumber(num: number, decimals: number = 0): string { try { return num.toLocaleString('zh-CN', { minimumFractionDigits: decimals, maximumFractionDigits: decimals, }) } catch (error) { console.error('Number formatting error:', error) return String(num) } } /** * 格式化百分比 * @param value - 数值(0-1 或 0-100) * @param isDecimal - 是否为小数格式(0-1),默认为 false(0-100) * @param decimals - 小数位数,默认为 1 * @returns 格式化后的百分比字符串 */ export function formatPercent(value: number, isDecimal: boolean = false, decimals: number = 1): string { try { const percent = isDecimal ? value * 100 : value return `${percent.toFixed(decimals)}%` } catch (error) { console.error('Percent formatting error:', error) return '0%' } }