封装时间格式组件
时间:2025-12-2 17:37 作者:suxiaojun 分类: 无
// utils/formatDate.ts
/**
* 按指定格式格式化时间戳
* @param timestamp 时间戳(number | string),可为毫秒数或可被 new Date() 解析的字符串
* @param format 输出格式,默认 YYYY-MM-DD hh:mm:ss
* - YYYY: 4 位年份
* - YY: 2 位年份
* - MM/M: 月(两位/一位)
* - DD/D: 日(两位/一位)
* - HH/H: 24 小时制(两位/一位)
* - hh/h: 12 小时制(两位/一位)
* - mm/m: 分钟(两位/一位)
* - ss/s: 秒(两位/一位)
* - A: AM / PM
*/
export function formatDate(timestamp: number | string, format = 'YYYY-MM-DD hh:mm:ss'): string {
// 若传入空值,返回空字符串
if (!timestamp) return ''
let ts: any = null
// 如果 timestamp 不是数字,则直接作为日期字符串处理
// 否则转为数字(时间戳)
if (isNaN(Number(timestamp))) {
ts = timestamp
} else {
ts = Number(timestamp)
}
const date = new Date(ts)
// new Date 无法解析时,返回 Invalid Date
if (isNaN(date.getTime())) return 'Invalid Date'
// 基本日期结构
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hours24 = date.getHours()
const minutes = date.getMinutes()
const seconds = date.getSeconds()
// 处理 12 小时制 AM/PM
const ampm = hours24 >= 12 ? 'PM' : 'AM'
const hours12 = hours24 % 12 || 12 // 0 点转换成 12 点
// 格式中是否出现 A(表示使用 12 小时制)
const use12Hour = format.includes('A')
/**
* 占位符映射表
* 不同的 key 会对应不同的日期组件内容
*/
const map: Record<string, string> = {
YYYY: String(year),
YY: String(year).slice(-2),
MM: String(month).padStart(2, '0'),
M: String(month),
DD: String(day).padStart(2, '0'),
D: String(day),
hh: String(hours12).padStart(2, '0'),
h: String(hours12),
HH: String(hours24).padStart(2, '0'),
H: String(hours24),
mm: String(minutes).padStart(2, '0'),
m: String(minutes),
ss: String(seconds).padStart(2, '0'),
s: String(seconds),
A: ampm, // AM/PM
}
// 如果格式包含 A,则 hh/h 应使用 12 小时制
if (use12Hour) {
map.hh = String(hours12).padStart(2, '0')
map.h = String(hours12)
} else {
// 未使用 A,则 hh/h 默认等同于 24 小时制(HH/H)
map.hh = map.HH
map.h = map.H
}
// 遍历所有占位符并进行替换
let formatted = format
for (const key in map) {
formatted = formatted.replace(new RegExp(key, 'g'), map[key])
}
return formatted
}