Files
2026-06-02 15:28:25 +08:00

249 lines
6.7 KiB
JavaScript

/**
* 公共函数库
* 包含日期时间、工具函数等
*/
/**
* 数字补零
* @param {number} num - 数字
* @param {number} len - 目标长度,默认2
* @returns {string} 补零后的字符串
* @example padZero(5) => '05'
*/
export function padZero(num, len = 2) {
let str = String(num)
while (str.length < len) {
str = '0' + str
}
return str
}
/**
* 获取日期字符串 yyyy-MM-dd
* @param {Date|string|number} [date] - 日期,默认当前日期
* @param {string} [separator='-'] - 分隔符
* @returns {string} 日期字符串
* @example getDate() => '2026-05-21'
*/
export function getDate(date, separator = '-') {
const d = date ? new Date(date) : new Date()
const y = d.getFullYear()
const m = padZero(d.getMonth() + 1)
const day = padZero(d.getDate())
return `${y}${separator}${m}${separator}${day}`
}
/**
* 获取时间字符串 HH:mm:ss
* @param {Date|string|number} [date] - 日期,默认当前时间
* @param {string} [separator=':'] - 分隔符
* @returns {string} 时间字符串
* @example getTime() => '14:30:45'
*/
export function getTime(date, separator = ':') {
const d = date ? new Date(date) : new Date()
const h = padZero(d.getHours())
const m = padZero(d.getMinutes())
const s = padZero(d.getSeconds())
return `${h}${separator}${m}${separator}${s}`
}
/**
* 获取日期时间字符串 yyyy-MM-dd HH:mm:ss
* @param {Date|string|number} [date] - 日期,默认当前
* @param {string} [dateSep='-'] - 日期分隔符
* @param {string} [timeSep=':'] - 时间分隔符
* @param {string} [dtSep=' '] - 日期和时间之间的分隔符
* @returns {string} 日期时间字符串
* @example getDateTime() => '2026-05-21 14:30:45'
*/
export function getDateTime(date, dateSep = '-', timeSep = ':', dtSep = ' ') {
return `${getDate(date, dateSep)}${dtSep}${getTime(date, timeSep)}`
}
/**
* 自定义格式化日期
* @param {Date|string|number} date - 日期
* @param {string} format - 格式字符串,支持 YYYY MM DD HH mm ss 占位符
* @returns {string} 格式化后的日期字符串
* @example formatDate(new Date(), 'YYYY/MM/DD HH:mm') => '2026/05/21 14:30'
*/
export function formatDate(date, format = 'YYYY-MM-DD HH:mm:ss') {
const d = new Date(date)
const map = {
YYYY: d.getFullYear(),
MM: padZero(d.getMonth() + 1),
DD: padZero(d.getDate()),
HH: padZero(d.getHours()),
mm: padZero(d.getMinutes()),
ss: padZero(d.getSeconds())
}
return format.replace(/YYYY|MM|DD|HH|mm|ss/g, (match) => map[match])
}
/**
* 获取相对日期
* @param {number} days - 天数偏移,正数为之后,负数为之前
* @param {Date|string|number} [baseDate] - 基准日期,默认今天
* @returns {string} 日期字符串 yyyy-MM-dd
* @example getRelativeDate(-7) => 7天前的日期
* @example getRelativeDate(3) => 3天后的日期
*/
export function getRelativeDate(days, baseDate) {
const d = baseDate ? new Date(baseDate) : new Date()
d.setDate(d.getDate() + days)
return getDate(d)
}
/**
* 获取本周一的日期
* @param {Date|string|number} [date] - 日期,默认今天
* @returns {string} yyyy-MM-dd
* @example getWeekStartDate() => '2026-05-18'
*/
export function getWeekStartDate(date) {
const d = date ? new Date(date) : new Date()
const day = d.getDay()
const diff = day === 0 ? -6 : 1 - day
d.setDate(d.getDate() + diff)
return getDate(d)
}
/**
* 获取本月1号的日期
* @param {Date|string|number} [date] - 日期,默认今天
* @returns {string} yyyy-MM-dd
*/
export function getMonthStartDate(date) {
const d = date ? new Date(date) : new Date()
d.setDate(1)
return getDate(d)
}
/**
* 时间戳转日期字符串
* @param {number} timestamp - 时间戳(毫秒)
* @param {string} [format='YYYY-MM-DD HH:mm:ss'] - 格式
* @returns {string} 日期字符串
* @example timestampToDate(1716268800000) => '2024-05-21 14:40:00'
*/
export function timestampToDate(timestamp, format = 'YYYY-MM-DD HH:mm:ss') {
return formatDate(new Date(timestamp), format)
}
/**
* 日期字符串转时间戳
* @param {string} dateStr - 日期字符串,如 '2026-05-21' 或 '2026-05-21 14:30:45'
* @returns {number} 时间戳(毫秒)
*/
export function dateToTimestamp(dateStr) {
return new Date(dateStr.replace(/-/g, '/')).getTime()
}
/**
* 计算两个日期之间的天数差
* @param {Date|string|number} date1
* @param {Date|string|number} date2
* @returns {number} date1 - date2 的天数差
* @example daysBetween('2026-05-25', '2026-05-21') => 4
*/
export function daysBetween(date1, date2) {
const d1 = new Date(date1)
const d2 = new Date(date2)
const diff = d1.getTime() - d2.getTime()
return Math.round(diff / (1000 * 60 * 60 * 24))
}
/**
* 判断是否为今天
* @param {Date|string|number} date
* @returns {boolean}
*/
export function isToday(date) {
const d = new Date(date)
const today = new Date()
return d.getFullYear() === today.getFullYear() &&
d.getMonth() === today.getMonth() &&
d.getDate() === today.getDate()
}
/**
* 生成唯一ID
* @param {string} [prefix=''] - 前缀
* @returns {string}
* @example generateId('DEV_') => 'DEV_lrx8a2b3c'
*/
export function generateId(prefix = '') {
return prefix + Date.now().toString(36) + Math.random().toString(36).slice(2, 8)
}
/**
* 深拷贝
* @param {*} obj - 要拷贝的对象
* @returns {*} 拷贝后的新对象
*/
export function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj
if (obj instanceof Date) return new Date(obj.getTime())
if (Array.isArray(obj)) return obj.map(item => deepClone(item))
const cloned = {}
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
cloned[key] = deepClone(obj[key])
}
}
return cloned
}
/**
* 防抖函数
* @param {Function} fn - 要防抖的函数
* @param {number} [delay=300] - 延迟时间(毫秒)
* @returns {Function}
*/
export function debounce(fn, delay = 300) {
let timer = null
return function (...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
/**
* 节流函数
* @param {Function} fn - 要节流的函数
* @param {number} [interval=300] - 间隔时间(毫秒)
* @returns {Function}
*/
export function throttle(fn, interval = 300) {
let lastTime = 0
return function (...args) {
const now = Date.now()
if (now - lastTime >= interval) {
lastTime = now
fn.apply(this, args)
}
}
}
export default {
padZero,
getDate,
getTime,
getDateTime,
formatDate,
getRelativeDate,
getWeekStartDate,
getMonthStartDate,
timestampToDate,
dateToTimestamp,
daysBetween,
isToday,
generateId,
deepClone,
debounce,
throttle
}