From 196a3675891d47b7270b5e42b5e60488f299e58d Mon Sep 17 00:00:00 2001 From: tianfeng <769204422@qq.com> Date: Thu, 21 Aug 2025 18:27:25 +0800 Subject: [PATCH] =?UTF-8?q?utfFormat=20=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/utcFormat.js | 202 ++++++++++++++++++++++++++++++++++++++ src/views/MessageView.vue | 3 +- 2 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/utils/utcFormat.js diff --git a/src/utils/utcFormat.js b/src/utils/utcFormat.js new file mode 100644 index 0000000..e3c6356 --- /dev/null +++ b/src/utils/utcFormat.js @@ -0,0 +1,202 @@ +/** + * 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 +} diff --git a/src/views/MessageView.vue b/src/views/MessageView.vue index 23b70d2..dd1cd17 100644 --- a/src/views/MessageView.vue +++ b/src/views/MessageView.vue @@ -25,7 +25,7 @@
{{ message.countryName }} ({{ message.countryCode }})
-{{ new Date(message.createTime).toLocaleString() }}
+{{ formatUTCTime(message.createTime) }}