/** * UTC 时间格式化工具 * 提供各种 UTC 时间格式化功能,避免浏览器本地时区影响 */ /** * 格式化时间戳为 UTC 时间字符串 * @param {number|string} timestamp - 时间戳(毫秒) * @param {Object} options - 格式化选项 * @param {boolean} options.showSeconds - 是否显示秒,默认 true * @param {boolean} options.showUTC - 是否显示 UTC 标识,默认 true * @param {string} options.dateSeparator - 日期分隔符,默认 '-' * @param {string} options.timeSeparator - 时间分隔符,默认 ':' * @param {string} options.dateTimeSeparator - 日期时间分隔符,默认 ' ' * @returns {string} 格式化后的时间字符串 */ export const formatUTCTime = (timestamp, options = {}) => { const { showSeconds = true, showUTC = true, dateSeparator = '-', timeSeparator = ':', dateTimeSeparator = ' ' } = options if (!timestamp) return 'Unknown time' const date = new Date(timestamp) // 检查日期是否有效 if (isNaN(date.getTime())) return 'Invalid time' // 获取 UTC 时间组件 const year = date.getUTCFullYear() const month = String(date.getUTCMonth() + 1).padStart(2, '0') const day = String(date.getUTCDate()).padStart(2, '0') const hours = String(date.getUTCHours()).padStart(2, '0') const minutes = String(date.getUTCMinutes()).padStart(2, '0') const seconds = String(date.getUTCSeconds()).padStart(2, '0') // 构建日期部分 const datePart = `${year}${dateSeparator}${month}${dateSeparator}${day}` // 构建时间部分 let timePart = `${hours}${timeSeparator}${minutes}` if (showSeconds) { timePart += `${timeSeparator}${seconds}` } // 构建完整时间字符串 let result = `${datePart}${dateTimeSeparator}${timePart}` if (showUTC) { result += ' UTC' } return result } /** * 格式化时间戳为简短的 UTC 时间字符串(不显示秒) * @param {number|string} timestamp - 时间戳(毫秒) * @returns {string} 格式化后的时间字符串,如: 2025-08-21 15:30 UTC */ export const formatUTCTimeShort = (timestamp) => { return formatUTCTime(timestamp, { showSeconds: false }) } /** * 格式化时间戳为不带 UTC 标识的时间字符串 * @param {number|string} timestamp - 时间戳(毫秒) * @returns {string} 格式化后的时间字符串,如: 2025-08-21 15:30:45 */ export const formatUTCTimeClean = (timestamp) => { return formatUTCTime(timestamp, { showUTC: false }) } /** * 格式化时间戳为日期字符串(仅日期部分) * @param {number|string} timestamp - 时间戳(毫秒) * @param {string} separator - 分隔符,默认 '-' * @returns {string} 格式化后的日期字符串,如: 2025-08-21 */ export const formatUTCDate = (timestamp, separator = '-') => { if (!timestamp) return 'Unknown date' const date = new Date(timestamp) if (isNaN(date.getTime())) return 'Invalid date' const year = date.getUTCFullYear() const month = String(date.getUTCMonth() + 1).padStart(2, '0') const day = String(date.getUTCDate()).padStart(2, '0') return `${year}${separator}${month}${separator}${day}` } /** * 格式化时间戳为时间字符串(仅时间部分) * @param {number|string} timestamp - 时间戳(毫秒) * @param {Object} options - 格式化选项 * @param {boolean} options.showSeconds - 是否显示秒,默认 true * @param {string} options.separator - 分隔符,默认 ':' * @returns {string} 格式化后的时间字符串,如: 15:30:45 */ export const formatUTCTimeOnly = (timestamp, options = {}) => { const { showSeconds = true, separator = ':' } = options if (!timestamp) return 'Unknown time' const date = new Date(timestamp) if (isNaN(date.getTime())) return 'Invalid time' const hours = String(date.getUTCHours()).padStart(2, '0') const minutes = String(date.getUTCMinutes()).padStart(2, '0') const seconds = String(date.getUTCSeconds()).padStart(2, '0') let result = `${hours}${separator}${minutes}` if (showSeconds) { result += `${separator}${seconds}` } return result } /** * 格式化时间戳为相对时间(如:2小时前) * @param {number|string} timestamp - 时间戳(毫秒) * @param {string} lang - 语言,'en' 或 'zh',默认 'en' * @returns {string} 相对时间字符串 */ export const formatRelativeTime = (timestamp, lang = 'en') => { if (!timestamp) return lang === 'zh' ? '未知时间' : 'Unknown time' const date = new Date(timestamp) if (isNaN(date.getTime())) return lang === 'zh' ? '无效时间' : 'Invalid time' const now = new Date() const diffMs = now.getTime() - date.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 (lang === 'zh') { if (diffSeconds < 60) return '刚刚' if (diffMinutes < 60) return `${diffMinutes}分钟前` if (diffHours < 24) return `${diffHours}小时前` if (diffDays < 30) return `${diffDays}天前` return formatUTCDate(timestamp) } else { if (diffSeconds < 60) return 'Just now' if (diffMinutes < 60) return `${diffMinutes} minute${diffMinutes > 1 ? 's' : ''} ago` if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago` if (diffDays < 30) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago` return formatUTCDate(timestamp) } } /** * 自定义格式化时间戳 * @param {number|string} timestamp - 时间戳(毫秒) * @param {string} format - 格式字符串,支持以下占位符: * YYYY - 四位年份 * MM - 两位月份 * DD - 两位日期 * HH - 两位小时 * mm - 两位分钟 * ss - 两位秒钟 * @returns {string} 格式化后的时间字符串 */ export const formatUTCCustom = (timestamp, format = 'YYYY-MM-DD HH:mm:ss') => { if (!timestamp) return 'Unknown time' const date = new Date(timestamp) if (isNaN(date.getTime())) return 'Invalid time' const year = date.getUTCFullYear() const month = String(date.getUTCMonth() + 1).padStart(2, '0') const day = String(date.getUTCDate()).padStart(2, '0') const hours = String(date.getUTCHours()).padStart(2, '0') const minutes = String(date.getUTCMinutes()).padStart(2, '0') const seconds = String(date.getUTCSeconds()).padStart(2, '0') return format .replace('YYYY', year) .replace('MM', month) .replace('DD', day) .replace('HH', hours) .replace('mm', minutes) .replace('ss', seconds) } // 导出常用的预设格式 export const UTC_FORMATS = { FULL: 'YYYY-MM-DD HH:mm:ss UTC', // 2025-08-21 15:30:45 UTC SHORT: 'YYYY-MM-DD HH:mm UTC', // 2025-08-21 15:30 UTC CLEAN: 'YYYY-MM-DD HH:mm:ss', // 2025-08-21 15:30:45 DATE_ONLY: 'YYYY-MM-DD', // 2025-08-21 TIME_ONLY: 'HH:mm:ss', // 15:30:45 ISO_LIKE: 'YYYY-MM-DDTHH:mm:ss', // 2025-08-21T15:30:45 }