Day.js - 日期时间处理
Day.js 是一个轻量级的 JavaScript 日期库,仅 2KB 大小,API 设计与 Moment.js 相同,但更加轻量和现代化。
安装
bash
npm install dayjsbash
pnpm add dayjsbash
yarn add dayjsbash
bun add dayjs基础使用
引入和初始化
javascript
import dayjs from 'dayjs'
// 当前时间
const now = dayjs()
// 指定日期
const date = dayjs('2024-11-28')
// 时间戳
const fromTimestamp = dayjs(1701158400000)
// Date 对象
const fromDate = dayjs(new Date())常用 API
格式化
javascript
import dayjs from 'dayjs'
const date = dayjs('2024-11-28 15:30:00')
// 常用格式
date.format('YYYY-MM-DD') // 2024-11-28
date.format('YYYY-MM-DD HH:mm:ss') // 2024-11-28 15:30:00
date.format('YYYY年MM月DD日') // 2024年11月28日
date.format('MM/DD/YYYY') // 11/28/2024
date.format('HH:mm:ss') // 15:30:00
// 格式化标记
// YYYY - 四位年份
// MM - 两位月份
// DD - 两位日期
// HH - 24小时制小时
// mm - 分钟
// ss - 秒
// SSS - 毫秒获取时间信息
javascript
const date = dayjs('2024-11-28 15:30:45')
date.year() // 2024
date.month() // 10 (0-11,0代表1月)
date.date() // 28
date.day() // 4 (0-6,0代表周日)
date.hour() // 15
date.minute() // 30
date.second() // 45
date.millisecond() // 0
// 获取时间戳
date.valueOf() // 1701158445000
date.unix() // 1701158445 (秒级时间戳)设置时间
javascript
const date = dayjs('2024-11-28')
// 设置年份
date.year(2025)
// 设置月份 (0-11)
date.month(0) // 1月
// 设置日期
date.date(15)
// 设置小时
date.hour(10)
// 设置分钟
date.minute(30)
// 链式调用
dayjs().year(2025).month(0).date(1).hour(0).minute(0).second(0)时间操作
javascript
const date = dayjs('2024-11-28')
// 增加时间
date.add(1, 'day') // 增加1天
date.add(1, 'month') // 增加1个月
date.add(1, 'year') // 增加1年
date.add(2, 'hour') // 增加2小时
date.add(30, 'minute') // 增加30分钟
// 减少时间
date.subtract(1, 'day') // 减少1天
date.subtract(1, 'month') // 减少1个月
date.subtract(1, 'year') // 减少1年
// 支持的单位
// year, month, week, day, hour, minute, second, millisecond开始和结束时间
javascript
const date = dayjs('2024-11-28 15:30:45')
// 一天的开始
date.startOf('day') // 2024-11-28 00:00:00
// 一天的结束
date.endOf('day') // 2024-11-28 23:59:59
// 月初
date.startOf('month') // 2024-11-01 00:00:00
// 月末
date.endOf('month') // 2024-11-30 23:59:59
// 年初
date.startOf('year') // 2024-01-01 00:00:00
// 年末
date.endOf('year') // 2024-12-31 23:59:59
// 周初 (周日)
date.startOf('week') // 2024-11-24 00:00:00
// 周末 (周六)
date.endOf('week') // 2024-11-30 23:59:59时间比较
javascript
const date1 = dayjs('2024-11-28')
const date2 = dayjs('2024-11-30')
// 是否之前
date1.isBefore(date2) // true
// 是否之后
date1.isAfter(date2) // false
// 是否相同
date1.isSame(date2) // false
// 指定粒度比较
date1.isSame(date2, 'month') // true
date1.isSame(date2, 'year') // true
date1.isSame(date2, 'day') // false时间差
javascript
const date1 = dayjs('2024-11-28')
const date2 = dayjs('2024-12-01')
// 相差天数
date2.diff(date1, 'day') // 3
// 相差小时
date2.diff(date1, 'hour') // 72
// 相差分钟
date2.diff(date1, 'minute') // 4320
// 相差月份
date2.diff(date1, 'month') // 0
// 支持小数
date2.diff(date1, 'month', true) // 0.1常用插件
相对时间 (RelativeTime)
javascript
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import 'dayjs/locale/zh-cn'
dayjs.extend(relativeTime)
dayjs.locale('zh-cn')
const date = dayjs('2024-11-25')
dayjs().to(date) // 3天前
dayjs().from(date) // 3天后
date.fromNow() // 3天前
date.toNow() // 3天后自定义解析格式 (CustomParseFormat)
javascript
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
dayjs.extend(customParseFormat)
// 解析自定义格式
dayjs('12-25-2024', 'MM-DD-YYYY')
dayjs('2024/11/28', 'YYYY/MM/DD')是否为闰年 (IsLeapYear)
javascript
import dayjs from 'dayjs'
import isLeapYear from 'dayjs/plugin/isLeapYear'
dayjs.extend(isLeapYear)
dayjs('2024-01-01').isLeapYear() // true
dayjs('2023-01-01').isLeapYear() // false周数 (WeekOfYear)
javascript
import dayjs from 'dayjs'
import weekOfYear from 'dayjs/plugin/weekOfYear'
dayjs.extend(weekOfYear)
dayjs('2024-11-28').week() // 48 (一年中的第48周)季度 (QuarterOfYear)
javascript
import dayjs from 'dayjs'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'
dayjs.extend(quarterOfYear)
dayjs('2024-11-28').quarter() // 4 (第四季度)实际应用场景
场景1: 显示友好的时间格式
javascript
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import 'dayjs/locale/zh-cn'
dayjs.extend(relativeTime)
dayjs.locale('zh-cn')
function formatTime(timestamp) {
const date = dayjs(timestamp)
const now = dayjs()
const diff = now.diff(date, 'day')
if (diff === 0) {
return date.format('HH:mm') // 今天显示时间
} else if (diff === 1) {
return '昨天 ' + date.format('HH:mm')
} else if (diff < 7) {
return date.fromNow() // 一周内显示相对时间
} else {
return date.format('YYYY-MM-DD') // 更早显示日期
}
}
// 使用
formatTime(Date.now()) // 15:30
formatTime(Date.now() - 86400000) // 昨天 15:30
formatTime(Date.now() - 172800000) // 2天前场景2: 计算年龄
javascript
function calculateAge(birthday) {
const birth = dayjs(birthday)
const now = dayjs()
return now.diff(birth, 'year')
}
calculateAge('1990-05-15') // 34场景3: 判断是否为工作日
javascript
function isWorkday(date) {
const day = dayjs(date).day()
return day !== 0 && day !== 6 // 0是周日,6是周六
}
isWorkday('2024-11-28') // true (周四)
isWorkday('2024-11-30') // false (周六)场景4: 获取本月日期范围
javascript
function getMonthRange() {
const start = dayjs().startOf('month')
const end = dayjs().endOf('month')
return {
start: start.format('YYYY-MM-DD'),
end: end.format('YYYY-MM-DD'),
days: end.date() // 本月天数
}
}
getMonthRange()
// { start: '2024-11-01', end: '2024-11-30', days: 30 }场景5: 倒计时
javascript
function countdown(targetDate) {
const target = dayjs(targetDate)
const now = dayjs()
const days = target.diff(now, 'day')
const hours = target.diff(now, 'hour') % 24
const minutes = target.diff(now, 'minute') % 60
const seconds = target.diff(now, 'second') % 60
return {
days,
hours,
minutes,
seconds,
total: target.diff(now, 'millisecond')
}
}
countdown('2024-12-31 23:59:59')
// { days: 33, hours: 8, minutes: 29, seconds: 14, total: 2880554000 }场景6: 日期范围选择器
javascript
function getDateRangePresets() {
return {
'今天': [
dayjs().startOf('day'),
dayjs().endOf('day')
],
'昨天': [
dayjs().subtract(1, 'day').startOf('day'),
dayjs().subtract(1, 'day').endOf('day')
],
'最近7天': [
dayjs().subtract(6, 'day').startOf('day'),
dayjs().endOf('day')
],
'最近30天': [
dayjs().subtract(29, 'day').startOf('day'),
dayjs().endOf('day')
],
'本月': [
dayjs().startOf('month'),
dayjs().endOf('month')
],
'上月': [
dayjs().subtract(1, 'month').startOf('month'),
dayjs().subtract(1, 'month').endOf('month')
]
}
}场景7: 生成日历数据
javascript
function generateCalendar(year, month) {
const firstDay = dayjs(`${year}-${month}-01`)
const lastDay = firstDay.endOf('month')
const daysInMonth = lastDay.date()
const calendar = []
for (let i = 1; i <= daysInMonth; i++) {
const date = dayjs(`${year}-${month}-${i}`)
calendar.push({
date: i,
day: date.day(),
isWeekend: date.day() === 0 || date.day() === 6,
isToday: date.isSame(dayjs(), 'day'),
fullDate: date.format('YYYY-MM-DD')
})
}
return calendar
}
generateCalendar(2024, 11)场景8: 时区转换
javascript
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
dayjs.extend(utc)
dayjs.extend(timezone)
// 转换到指定时区
const date = dayjs('2024-11-28 15:30:00')
date.tz('America/New_York').format('YYYY-MM-DD HH:mm:ss')
date.tz('Asia/Tokyo').format('YYYY-MM-DD HH:mm:ss')
date.tz('Europe/London').format('YYYY-MM-DD HH:mm:ss')与 Moment.js 对比
| 特性 | Day.js | Moment.js |
|---|---|---|
| 大小 | 2KB | 67KB |
| API | 兼容 Moment.js | - |
| 不可变 | 是 | 否 |
| 维护状态 | 活跃 | 停止维护 |
| 性能 | 更快 | 较慢 |
最佳实践
- 按需引入插件: 只引入需要的插件,保持包体积最小
- 使用不可变操作: Day.js 默认不可变,每次操作返回新实例
- 统一时区处理: 在应用中统一使用 UTC 或指定时区
- 格式化缓存: 对于频繁使用的格式,可以提前定义常量
- 类型安全: 配合 TypeScript 使用,获得更好的类型提示