前端开发【工具函数】基于dayjs 封装的DateUtils工具函数,可以直接拿着使用
前端开发中,日期处理是高频需求,以下按「格式化、差值计算、范围判断、特殊日期、时区 / 时间戳转换」5 类核心场景,整理可直接复用的 JS 工具函数,覆盖绝大多数日期处理需求:
import dayjs from 'dayjs'/*** 日期相关工具函数(基于 dayjs 库)*/
export const DateUtils = {/*** 通用日期格式化(支持多种输入类型,自定义输出格式)* @param {Number|String|Date} time - 输入时间(时间戳/字符串/Date对象)* @param {String} format - 输出格式(默认:YYYY-MM-DD HH:mm:ss)* @returns {String} 格式化后的日期*/formatDate(time, format = 'YYYY-MM-DD HH:mm:ss') {if (!time) return '' // 空值返回空字符串,避免报错return dayjs(time).format(format)},/*** 快捷格式化:仅显示日期(YYYY-MM-DD)* @param {Number|String|Date} time - 输入时间* @returns {String} 格式化后的日期*/formatDateOnly(time) {return this.formatDate(time, 'YYYY-MM-DD')},/*** 快捷格式化:仅显示时间(HH:mm:ss)* @param {Number|String|Date} time - 输入时间* @returns {String} 格式化后的时间*/formatTimeOnly(time) {return this.formatDate(time, 'HH:mm:ss')},/*** 相对时间格式化(如“1小时前”“3天后”)* @param {Number|String|Date} time - 输入时间(与当前时间对比)* @returns {String} 相对时间描述*/formatRelativeTime(time) {if (!time) return ''// 配置相对时间语言(中文)dayjs.locale('zh-cn')return dayjs(time).fromNow()},/*** 计算两个日期的差值(支持多种单位)* @param {Number|String|Date} start - 开始时间* @param {Number|String|Date} end - 结束时间(默认当前时间)* @param {String} unit - 差值单位(year/month/day/hour/minute/second,默认day)* @returns {Number} 差值(整数,向下取整)*/getDateDiff(start, end = dayjs(), unit = 'day') {if (!start) return 0const startDay = dayjs(start)const endDay = dayjs(end)// dayjs.diff 返回整数,单位由 unit 指定return endDay.diff(startDay, unit)},/*** 计算年龄(精确到年)* @param {Number|String|Date} birthday - 出生日期* @returns {Number} 年龄*/calculateAge(birthday) {if (!birthday) return 0// 计算当前日期与生日的年差,自动处理“未到生日”的情况return dayjs().diff(dayjs(birthday), 'year')},/*** 计算两个时间的时长(格式:HH:mm:ss)* @param {Number|String|Date} start - 开始时间* @param {Number|String|Date} end - 结束时间* @returns {String} 时长(如“02:30:15”)*/calculateDuration(start, end) {if (!start || !end) return '00:00:00'const diffMs = dayjs(end).diff(dayjs(start)) // 差值(毫秒)// 转换为小时、分钟、秒const hours = Math.floor(diffMs / (3600 * 1000)).toString().padStart(2, '0')const minutes = Math.floor((diffMs % (3600 * 1000)) / (60 * 1000)).toString().padStart(2, '0')const seconds = Math.floor((diffMs % (60 * 1000)) / 1000).toString().padStart(2, '0')return `${hours}:${minutes}:${seconds}`},/*** 获取指定日期的当天范围(00:00:00 ~ 23:59:59)* @param {Number|String|Date} time - 输入时间(默认当前时间)* @returns {Object} 当天范围(start-开始时间,end-结束时间,均为YYYY-MM-DD HH:mm:ss格式)*/getDayRange(time = dayjs()) {const targetDay = dayjs(time)return {start: targetDay.startOf('day').format('YYYY-MM-DD HH:mm:ss'), // 当天0点end: targetDay.endOf('day').format('YYYY-MM-DD HH:mm:ss'), // 当天23点59分59秒}},/*** 获取近N天的日期范围(如近7天:今天 ~ 7天前)* @param {Number} days - 天数(默认7天)* @returns {Object} 近N天范围(start-开始时间,end-结束时间)*/getRecentDaysRange(days = 7) {const todayEnd = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')const recentStart = dayjs().subtract(days - 1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')return {start: recentStart,end: todayEnd,}},/*** 获取指定日期的当月范围(月初 ~ 月末)* @param {Number|String|Date} time - 输入时间(默认当前时间)* @returns {Object} 当月范围(start-月初,end-月末)*/getMonthRange(time = dayjs()) {const targetMonth = dayjs(time)return {start: targetMonth.startOf('month').format('YYYY-MM-DD HH:mm:ss'), // 月初0点end: targetMonth.endOf('month').format('YYYY-MM-DD HH:mm:ss'), // 月末23点59分59秒}},/*** 获取指定日期的上月范围(上月初 ~ 上月末)* @param {Number|String|Date} time - 输入时间(默认当前时间)* @returns {Object} 上月范围(start-上月初,end-上月末)*/getLastMonthRange(time = dayjs()) {const lastMonth = dayjs(time).subtract(1, 'month')return {start: lastMonth.startOf('month').format('YYYY-MM-DD HH:mm:ss'),end: lastMonth.endOf('month').format('YYYY-MM-DD HH:mm:ss'),}},/*** 判断日期是否为今天* @param {Number|String|Date} time - 输入时间* @returns {Boolean} 是否为今天*/isToday(time) {if (!time) return falsereturn dayjs(time).isSame(dayjs(), 'day')},/*** 判断日期是否为昨天* @param {Number|String|Date} time - 输入时间* @returns {Boolean} 是否为昨天*/isYesterday(time) {if (!time) return falsereturn dayjs(time).isSame(dayjs().subtract(1, 'day'), 'day')},/*** 判断日期是否为周末(周六/周日)* @param {Number|String|Date} time - 输入时间* @returns {Boolean} 是否为周末*/isWeekend(time) {if (!time) return falseconst day = dayjs(time).day() // day() 返回0(周日)~6(周六)return day === 0 || day === 6},/*** 判断日期是否在指定范围内(包含边界)* @param {Number|String|Date} time - 目标日期* @param {Number|String|Date} start - 范围开始时间* @param {Number|String|Date} end - 范围结束时间* @returns {Boolean} 是否在范围内*/isInDateRange(time, start, end) {if (!time || !start || !end) return falseconst target = dayjs(time)// isSameOrAfter:目标 >= 开始;isSameOrBefore:目标 <= 结束return target.isSameOrAfter(start, 'second') && target.isSameOrBefore(end, 'second')},/*** UTC时间转指定时区时间(默认北京时间)* @param {Number|String|Date} utcTime - UTC时间(如2025-09-16T02:54:15Z)* @param {String} timezone - 目标时区(默认Asia/Shanghai,即北京时间)* @param {String} format - 输出格式(默认YYYY-MM-DD HH:mm:ss)* @returns {String} 转换后的时间*/utcToTimezone(utcTime, timezone = 'Asia/Shanghai', format = 'YYYY-MM-DD HH:mm:ss') {if (!utcTime) return ''// 先解析为UTC时间,再转为目标时区return dayjs.utc(utcTime).tz(timezone).format(format)},/*** 时间戳转日期(支持10位/13位时间戳)* @param {Number|String} timestamp - 时间戳(10位秒级/13位毫秒级)* @param {String} format - 输出格式(默认YYYY-MM-DD HH:mm:ss)* @returns {String} 格式化后的日期*/timestampToDate(timestamp, format = 'YYYY-MM-DD HH:mm:ss') {if (!timestamp) return ''const numTs = Number(timestamp)// 10位时间戳(秒)转13位(毫秒)const msTs = numTs.toString().length === 10 ? numTs * 1000 : numTsreturn dayjs(msTs).format(format)},/*** 日期转时间戳(支持指定单位)* @param {Number|String|Date} time - 输入时间* @param {String} unit - 时间戳单位(second-10位,millisecond-13位,默认millisecond)* @returns {Number} 时间戳*/dateToTimestamp(time, unit = 'millisecond') {if (!time) return 0const target = dayjs(time)return unit === 'second' ? target.unix() : target.valueOf() // unix()返回10位,valueOf()返回13位},
}
这些工具函数基于 dayjs 的强大能力,覆盖了前端系统开发中「表单校验、报表筛选、状态显示、后端对接」等核心场景,可直接复制到项目中使用,也可根据业务需求扩展(如添加「农历转换」「节假日判断」等函数,需配合 dayjs 对应的扩展插件)
