aslan-h5/src/utils/utcFormat.js
2025-08-21 18:27:25 +08:00

203 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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
}