前端开发【工具函数】基于dayjs 封装的DateUtils工具函数,可以直接拿着使用

前端开发中,日期处理是高频需求,以下按「格式化、差值计算、范围判断、特殊日期、时区 / 时间戳转换」5 类核心场景,整理可直接复用的 JS 工具函数,覆盖绝大多数日期处理需求:

bash 复制代码
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 0
    const 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 false
    return dayjs(time).isSame(dayjs(), 'day')
  },

  /**
   * 判断日期是否为昨天
   * @param {Number|String|Date} time - 输入时间
   * @returns {Boolean} 是否为昨天
   */
  isYesterday(time) {
    if (!time) return false
    return dayjs(time).isSame(dayjs().subtract(1, 'day'), 'day')
  },

  /**
   * 判断日期是否为周末(周六/周日)
   * @param {Number|String|Date} time - 输入时间
   * @returns {Boolean} 是否为周末
   */
  isWeekend(time) {
    if (!time) return false
    const 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 false
    const 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 : numTs
    return 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 0
    const target = dayjs(time)
    return unit === 'second' ? target.unix() : target.valueOf() // unix()返回10位,valueOf()返回13位
  },
}

这些工具函数基于 dayjs 的强大能力,覆盖了前端系统开发中「表单校验、报表筛选、状态显示、后端对接」等核心场景,可直接复制到项目中使用,也可根据业务需求扩展(如添加「农历转换」「节假日判断」等函数,需配合 dayjs 对应的扩展插件)

相关推荐
郑清3 小时前
Spring AI Alibaba 10分钟快速入门
java·人工智能·后端·ai·1024程序员节·springaialibaba
枫叶丹43 小时前
破局政务数字化核心难题:金仓数据库以国产化方案引领电子证照系统升级之路
数据库·政务·1024程序员节·金仓
jingling5553 小时前
CSS进阶 | 不用一行JS!用纯CSS打造会动的现代化单页应用(3D翻转卡片)
前端·javascript·css
你的电影很有趣3 小时前
lesson76:Vue.js 核心特性详解:事件处理、计算属性与侦听器
javascript·vue·1024程序员节
belldeep3 小时前
python:怎样用 Django 开发电子商务程序
django·电子商务·1024程序员节
Neil今天也要学习3 小时前
永磁同步电机无速度算法--基于相位超前校正的LESO
算法·1024程序员节
消失的旧时光-19433 小时前
Kotlin × Gson:为什么遍历 JsonObject 要用 entrySet()
android·kotlin·数据处理·1024程序员节
360智汇云3 小时前
从0到1理解智能体模式
1024程序员节
旷野说3 小时前
Spring Boot 1.x、2.x 3.x区别汇总
java·spring·tomcat·1024程序员节