Day.js
第一章:初识
一、简介
Day.js 是一个极简的 JavaScript 库,可以为现代浏览器解析、验证、操作和显示日期和时间。
在以前可能大多数使用的是 Moment.js 库,但目前官方也推荐最好不要在新项目中使用。进入维护模式,不在添加新功能。

二、手写精简版 Day.js
;(function(g){
// browser -> window 全局对象 node -> global 全局对象
// globalThis -> ES11
// 检查 globalThis 是否存在, 如果存在 → 使用 globalThis, 如果不存在 → 使用 g || self
g = typeof globalThis !== 'undefined' ? globalThis : g || self
// 构造函数
function Dayjs() {
var date = new Date()
this.$Y = date.getFullYear()
this.$M = date.getMonth()
this.$D = date.getDate()
}
// 原型上的方法
Dayjs.prototype.format = function() {
return `${this.$Y}-${ (this.$M + 1) }-${this.$D}`
}
// 学习原型的上的方法
// ......原型的方法......
// 工厂函数
function dayjs() {
return new Dayjs()
}
// 统一导出
g.dayjs = dayjs
})(this)手写精简版 Day.js 之后,我们就知道了接下来主要学习 Day.js 原型上的方法。
三、初体验
dayjs().format() // 默认返回的是 ISO8601 格式字符串 '2020-04-02T08:02:17+08:00'第二章:常用方法
调用 Day.js 的每个方法都返回一个新的 Day.js 实例。官方介绍这个特性为沙盒,有助于防止错误和避免长时间的调试会话。我们理解就是支持链式编程。
一、实例
1. 直接调用
直接调用 dayjs() 将返回一个包含当前日期和时间的 Day.js 对象。
var now = dayjs()2. ISO 8601
解析传入的 ISO 8601 格式的字符串并返回一个 Day.js 对象实例。
dayjs('2018-04-04T16:00:00.000Z')3. Unix 时间戳 (毫秒)
解析传入的一个 Unix 时间戳 (13 位数字,从1970年1月1日 UTC 午夜开始所经过的毫秒数) 创建一个 Day.js 对象。
dayjs(1318781876406)4. Unix 时间戳 (秒)
解析传入的一个 Unix 时间戳 (10 位数字,从1970年1月1日 UTC 午夜开始所经过的秒数) 创建一个 Day.js 对象。
dayjs.unix(1318781876)5. Date 对象
使用原生 Javascript Date 对象创建一个 Day.js 对象。
var d = new Date(2018, 8, 18)
var day = dayjs(d)二、取值 / 赋值
1. 特定方法
// 获取或设置年份
dayjs().year()
dayjs().year(2000)
// 获取或设置月份
// 传入0到11的 number (1月是0) 。如果超出这个范围,它会进位到年份。
dayjs().month()
dayjs().month(0) // 返回一个新对象
// 获取或设置月份里的日期 (Date of Month)
// 接受1到31的数字。如果超出这个范围,它会进位到月份。
dayjs().date()
dayjs().date(1)
// 获取或设置小时
// 传入0到23的数字。如果超出这个范围,它会进位到天数。
dayjs().hour()
dayjs().hour(12)
// 获取或设置分钟
// 传入0到59的数字。如果超出这个范围,它会进位到小时。
dayjs().minute()
dayjs().minute(59)
// 获取或设置秒
// 传入0到59的数字。如果超出这个范围,它会进位到分钟。
dayjs().second()
dayjs().second(1)
// 获取或设置毫秒
// 传入0到999的数字。如果超出这个范围,它会进位到秒。
dayjs().millisecond()
dayjs().millisecond(1)
// 获取或设置星期几 (Day of Week)
// 传入number从0(星期天)到6(星期六)。如果超出这个范围,它会进位到其他周。
dayjs().day()
dayjs().day(0)2. 统一方法
Get & Set
dayjs().get(unit) // 从 Day.js 对象中获取相应信息的 getter
dayjs().set(unit, value) // 通用的 setter,两个参数分别是要更新的单位和数值,调用后会返回一个修改后的新实例unit 支持的关键字。
| 单位 | 缩写 | 描述 |
|---|---|---|
| year | y | 年 |
| month | M | 月份 (0-11) |
| date | D | 月份里的日期 |
| hour | h | 小时 |
| minute | m | 分钟 |
| second | s | 秒 |
| millisecond | ms | 毫秒 |
| day | d | 星期 (星期日0,星期六6) |
缩写区分大小写,单位的全名不区分大小写。
三、操作
1. 增加 & 减去
// 增加
dayjs().add(7, 'day')
dayjs().add(-7, 'day') // 等价于 dayjs().subtract(7, 'day')
// 减去
dayjs().subtract(7, 'day')支持的单位列表:
| 单位 | 缩写 | 描述 |
|---|---|---|
| year | y | 年 |
| month | M | 月份 (0-11) |
| day | d | 日 |
| hour | h | 小时 |
| minute | m | 分钟 |
| second | s | 秒 |
| millisecond | ms | 毫秒 |
| week | w | 周 |
缩写区分大小写,单位的全名不区分大小写。
2. 时间的开始与结束
// 时间的开始
dayjs().startOf('year')
// 时间的结束
dayjs().endOf('month')支持的单位列表:
| 单位 | 缩写 | 描述 |
|---|---|---|
| year | y | 今年一月1日上午 00:00 |
| month | M | 本月1日上午 00:00 |
| date | D | 当天 00:00 |
| day | d | 当天 00:00 |
| hour | h | 当前时间,0 分、0 秒、0 毫秒 |
| minute | m | 当前时间,0 秒、0 毫秒 |
| second | s | 当前时间,0 毫秒 |
| week | w | 本周的第一天上午 00:00 |
缩写区分大小写,单位的全名不区分大小写。
四、显示
1. 格式化
dayjs('2019-01-25').format('DD/MM/YYYY') // '25/01/2019'支持的格式化占位符列表:
| 标识 | 示例 | 描述 |
|---|---|---|
| YY | 18 | 年,两位数 |
| YYYY | 2018 | 年,四位数 |
| M | 1-12 | 月,从1开始 |
| MM | 01-12 | 月,两位数 |
| MMM | Jan-Dec | 月,英文缩写 |
| MMMM | January-December | 月,英文全称 |
| D | 1-31 | 日 |
| DD | 01-31 | 日,两位数 |
| d | 0-6 | 一周中的一天,星期天是 0 |
| dd | Su-Sa | 最简写的星期几 |
| ddd | Sun-Sat | 简写的星期几 |
| dddd | Sunday-Saturday | 星期几,英文全称 |
| H | 0-23 | 小时 |
| HH | 00-23 | 小时,两位数 |
| h | 1-12 | 小时, 12 小时制 |
| hh | 01-12 | 小时, 12 小时制, 两位数 |
| m | 0-59 | 分钟 |
| mm | 00-59 | 分钟,两位数 |
| s | 0-59 | 秒 |
| ss | 00-59 | 秒,两位数 |
| S | 0-9 | 毫秒(十),一位数 |
| SS | 00-99 | 毫秒(百),两位数 |
| SSS | 000-999 | 毫秒,三位数 |
| Z | -05:00 | UTC 的偏移量,±HH:mm |
| ZZ | -0500 | UTC 的偏移量,±HHmm |
| A | AM / PM | 上/下午,大写 |
| a | am / pm | 上/下午,小写 |
还支持其他格式化占位符,但需要依赖插件。
2. 差异 (Difference)
返回指定单位下两个日期时间之间的差异。
const date1 = dayjs('2019-01-25')
const date2 = dayjs('2018-06-05')
// 默认单位是毫秒, 等价于 date1.diff(date2, 'millisecond')
date1.diff(date2) // 20217600000
date2.diff(date1) // -20217600000要获取其他单位下的差异,则在第二个参数传入相应的单位。
const date1 = dayjs('2019-01-25')
date1.diff('2018-06-05', 'month') // 7默认情况下 dayjs#diff 会将结果截去小数部分,返回一个整数。 如果要得到一个浮点数,将 true 作为第三个参数传入。
const date1 = dayjs('2019-01-25')
date1.diff('2018-06-05', 'month', true) // 7.645161290322581支持的单位列表:
| 单位 | 缩写 | 描述 |
|---|---|---|
| year | y | 年 |
| month | M | 月份 (一月 0, 十二月 11) |
| day | d | 日 |
| week | w | 周(Week of Year) |
| hour | h | 小时 |
| minute | m | 分钟 |
| second | s | 秒 |
| millisecond | ms | 毫秒(默认) |
缩写区分大小写,单位的全名不区分大小写。
例子
获取某个时间点到今天间隔几天(距今多少天)
dayjs().diff(dayjs(1718258944185), 'day')3. Unix 时间戳 (毫秒)
返回当前实例的 UNIX 时间戳,13位数字,毫秒。
dayjs('2019-01-25').valueOf() // 1548381600000
+dayjs(1548381600000) // 15483816000004. Unix 时间戳 (秒)
返回当前实例的 UNIX 时间戳,10位数字,秒。
dayjs('2019-01-25').unix() // 1548381600 (根据本地时区返回 Unix 时间戳)此值不包含毫秒信息,会进位到秒。
5. 获取月天数
获取当前月份包含的天数。
dayjs('2019-01-25').daysInMonth() // 31五、转换
1. 转 Date
调用 dayjs#toDate 从 Day.js 对象中获取原生的 Date 对象。
dayjs('2019-01-25').toDate()2. 转字符串
返回包含时间信息的 string 。
dayjs('2019-01-25').toString() // 'Fri, 25 Jan 2019 02:00:00 GMT'3. 转 JSON
序列化为 ISO 8601 格式的字符串。
dayjs('2019-01-25').toJSON() // '2019-01-25T02:00:00.000Z'4. 转 ISO 8601 字符串
返回一个 ISO 8601 格式的字符串。
dayjs('2019-01-25').toISOString() // '2019-01-25T02:00:00.000Z'第三章:高级
一、插件
1. 使用步骤
以在浏览器中使用插件为例,不演示如何在 Node.js 中如何使用。
1️⃣ 下载插件文件,使用 script 标签引入到 HTML 中。
2️⃣ 使用 dayjs.extend(XXX); 注册插件。其中 XXX 为插件注入到 window 的变量。
3️⃣ 插件会在 dayjs 原型上注入方法。
4️⃣ 使用插件提供的方法。
Node.js 中加载插件可以参考官方文档:加载插件 (NodeJS) · Day.js
2. 常用插件
1)RelativeTime
[1] 使用说明
RelativeTime 增加了 from、to、fromNow、toNow 这 4 个 API 来展示相对的时间 (例如:3 小时以前) 。
如果传入 true,则可以获得不带后缀的值。
var relativeTime = require('dayjs/plugin/relativeTime')
dayjs.extend(relativeTime)
dayjs().from(dayjs('1990-01-01')) // 31 年后
dayjs().from(dayjs('1990-01-01'), true) // 31 年
dayjs().fromNow()
dayjs().to(dayjs('1990-01-01')) // 31 年前
dayjs().toNow()| 需求 | 方法 | 返回值 |
|---|---|---|
| Time from now | .fromNow(withoutSuffix?: boolean) | 返回现在到当前实例的相对时间。 |
| Time from X | .from(compared: Dayjs, withoutSuffix?: boolean) | 返回 X 到当前实例的相对时间。 |
| Time to now | .toNow(withoutSuffix?: boolean) | 返回当前实例到现在的相对时间。 |
| Time to X | .to(compared: Dayjs, withoutSuffix?: boolean) | 返回当前实例到 X 的相对时间。 |
from - "从...开始算"
- 方向:从目标时间 → 当前时间对象
- 语义:当前时间相对于目标时间是"多久之前"或"多久之后"
to - "到...为止"
- 方向:从当前时间对象 → 目标时间
- 语义:从当前时间到目标时间需要"多久"
技巧:from 以后面时间为基准,to 以前面时间为基准。
[2] 例子
/*
假设现在时间 (now) 是 2023/09/25 10:00
*/
const dayjs = require('dayjs');
const relativeTime = require('dayjs/plugin/relativeTime');
dayjs.extend(relativeTime);
// 1. 距离现在的相对时间
const pastTime = dayjs('2023-09-24 10:00');
console.log(pastTime.fromNow()); // 输出: "1天前"
const futureTime = dayjs('2023-09-26 15:00');
console.log(futureTime.fromNow()); // 输出: "1天后"
// 2. 距离 X 的相对时间
const date1 = dayjs('2023-09-20');
const date2 = dayjs('2023-10-05');
console.log(date1.from(date2)); // 输出: "15天前"
console.log(date2.from(date1)); // 输出: "15天后"
// 3. 到现在的相对时间
const futureEvent = dayjs('2023-12-25');
console.log(futureEvent.toNow()); // 输出: "3个月后"
const pastEvent = dayjs('2023-08-01');
console.log(pastEvent.toNow()); // 输出: "2个月前"
// 4. 到 X 的相对时间
const startDate = dayjs('2023-09-25');
const endDate = dayjs('2024-03-01');
console.log(startDate.to(endDate)); // 输出: "5个月后"
const birthday = dayjs('2023-11-15');
console.log(dayjs().to(birthday)); // 输出: "2个月后"二、国际化
1. 使用步骤
<!-- 1. 导入语言支持文件 -->
<script src="https://unpkg.com/dayjs@1.8.21/locale/zh-cn.js"></script>
<!-- 2. 设置 dayjs 目标语言 -->
<script>
dayjs.locale('zh-cn')
</script>