Day.js 是一个轻量级的 JavaScript 日期处理库,其设计目标是为现代 Web 开发提供简单、快速且功能强大的日期时间处理工具。作为一个仅约 2KB 的极简库,它在保持微小体积的同时提供了与 Moment.js 高度兼容的 API 设计,使得开发者能够以极低的学习成本进行迁移和使用。
核心特性与设计理念
Day.js 的核心优势体现在多个方面。其极简体积是现代前端开发中的重要特点,2KB 的大小相较于 Moment.js 的 70KB 左右具有显著优势,这意味着更快的加载速度、解析时间和执行效率。API 兼容性是另一个关键优势,Day.js 刻意保持了与 Moment.js 相似的 API 设计,这使得已有 Moment.js 经验的开发者能够几乎无缝地切换到 Day.js,大大降低了迁移成本和学习曲线。
不可变数据结构是 Day.js 的另一个重要特性。所有对 Day.js 对象的操作都会返回新的实例,而不是修改原始对象。这种设计避免了副作用,使代码更易于理解和调试,同时也更符合函数式编程的原则。链式调用支持允许开发者通过流畅的接口连续执行多个操作,提高了代码的可读性和编写效率。
国际化支持方面,Day.js 提供了多语言环境支持,开发者可以按需加载所需的语言包,而不是将所有语言包都打包到最终应用中。插件系统进一步扩展了 Day.js 的功能边界,通过各种官方和社区插件,开发者可以添加时区支持、相对时间显示、周数计算等高级功能。
安装与基础用法
安装 Day.js 有多种方式,最常见的是通过 npm 或 yarn 这样的包管理工具:
npm install dayjs
或者
yarn add dayjs
对于不想使用包管理工具的开发者,也可以直接在 HTML 中通过 CDN 引入:
<script src="https://unpkg.com/dayjs"></script>
基本使用方式非常简单,首先需要引入库,然后就可以创建日期对象并进行各种操作:
import dayjs from 'dayjs';
// 创建当前时间实例
const now = dayjs();
// 格式化输出
console.log(now.format('YYYY-MM-DD HH:mm:ss'));
// 日期操作
const tomorrow = dayjs().add(1, 'day');
const lastMonth = dayjs().subtract(1, 'month');
// 日期比较
const isBefore = dayjs('2020-01-01').isBefore('2020-01-02');
日期解析与格式化
Day.js 支持多种日期解析方式,提供了极大的灵活性。它可以解析 ISO 8601 格式的字符串、Unix 时间戳(毫秒)、JavaScript Date 对象以及各种常见的日期时间字符串格式。
// 多种解析方式示例
const date1 = dayjs(); // 当前时间
const date2 = dayjs('2023-05-20'); // ISO 8601 格式
const date3 = dayjs(1684569600000); // Unix 时间戳(毫秒)
const date4 = dayjs(new Date(2023, 4, 20)); // JavaScript Date 对象
格式化是日期处理中最常用的功能之一,Day.js 提供了丰富的格式化选项:
// 常见格式化示例
console.log(dayjs().format('YYYY年MM月DD日')); // 2023年05月20日
console.log(dayjs().format('hh:mm:ss A')); // 03:45:30 PM
console.log(dayjs().format('YYYY-MM-DD[T]HH:mm:ssZ[Z]')); // 2023-05-20T15:45:30+08:00Z
// 格式参数详解
// Y - 年, M - 月, D - 日, H - 时(24制), h - 时(12制), m - 分, s - 秒, A - 上午/下午
日期操作与查询
Day.js 提供了丰富的日期操作方法,包括加减操作、设置特定单位、获取时间段的开始/结束等:
// 加减操作
console.log(dayjs().add(7, 'day').format('YYYY-MM-DD')); // 加7天
console.log(dayjs().subtract(1, 'year').format('YYYY-MM-DD')); // 减1年
// 设置特定单位
console.log(dayjs().set('month', 5).format('YYYY-MM-DD')); // 设置为6月(0-11)
console.log(dayjs().set('date', 15).format('YYYY-MM-DD')); // 设置为当月15日
// 获取时间段的开始/结束
console.log(dayjs().startOf('week').format('YYYY-MM-DD HH:mm:ss')); // 本周开始(周日)
console.log(dayjs().endOf('month').format('YYYY-MM-DD HH:mm:ss')); // 本月最后一天23:59:59
日期查询和比较是另一个重要功能,Day.js 提供了多种方法:
// 比较日期
const dateA = dayjs('2023-01-01');
const dateB = dayjs('2023-01-02');
console.log(dateA.isBefore(dateB)); // true
console.log(dateA.isAfter(dateB)); // false
console.log(dateA.isSame(dateB, 'month')); // true (同月)
// 获取日期差异
console.log(dayjs('2023-12-31').diff(dayjs(), 'day')); // 距离年底还有多少天
// 验证日期有效性
console.log(dayjs('2023-02-30').isValid()); // false (2月没有30日)
国际化与本地化支持
Day.js 的国际化支持设计得非常灵活,开发者可以全局设置语言,也可以在特定实例中使用不同语言:
// 加载语言包
import 'dayjs/locale/zh-cn';
import 'dayjs/locale/es';
// 全局设置语言
dayjs.locale('zh-cn');
// 或者在特定实例中使用不同语言
console.log(dayjs().locale('es').format('MMMM')); // mayo (西班牙语五月)
// 中文环境下的格式化示例
console.log(dayjs().format('YYYY年MM月DD日 dddd')); // 2023年01月01日 星期日
插件系统与功能扩展
Day.js 通过插件机制扩展功能,一些常用的插件包括:
- AdvancedFormat:扩展格式化选项
- RelativeTime:相对时间显示(如
2天前) - WeekOfYear:获取一年中的周数
- TimeZone:时区支持
- Calendar:日历式时间显示
- Duration:日期持续时间处理
// 插件使用示例
import advancedFormat from 'dayjs/plugin/advancedFormat';
import relativeTime from 'dayjs/plugin/relativeTime';
import weekOfYear from 'dayjs/plugin/weekOfYear';
// 扩展插件功能
dayjs.extend(advancedFormat);
dayjs.extend(relativeTime);
dayjs.extend(weekOfYear);
// 使用扩展功能
console.log(dayjs().format('Qo [季度]')); // "2nd 季度"
console.log(dayjs('2023-05-01').fromNow()); // "3周前"
console.log(dayjs().week()); // 获取当前是第几周
实际应用示例
在实际开发中,Day.js 可以应用于各种场景,以下是一些常见示例:
格式化日期显示函数:
const formatDate = (date) => {
return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
};
计算剩余时间:
const getRemainingTime = (endDate) => {
const end = dayjs(endDate);
const now = dayjs();
const days = end.diff(now, 'day');
const hours = end.diff(now, 'hour') % 24;
const minutes = end.diff(now, 'minute') % 60;
return `${days}天${hours}小时${minutes}分钟`;
};
获取日期范围:
const getDateRange = (start, end) => {
const dates = [];
let current = dayjs(start);
while (current.isBefore(end) || current.isSame(end)) {
dates.push(current.format('YYYY-MM-DD'));
current = current.add(1, 'day');
}
return dates;
};
判断是否是工作日:
const isWorkday = (date) => {
const day = dayjs(date).day();
return day !== 0 && day !== 6; // 0是周日,6是周六
};
获取月份天数:
const getDaysInMonth = (date) => {
return dayjs(date).daysInMonth();
};
性能优化与最佳实践
为了确保 Day.js 的最佳性能,可以考虑以下优化建议:
按需加载语言包,避免将所有的语言包都打包到最终应用中,只加载项目实际需要的语言包。
按需使用插件,只引入必要的插件,避免不必要的功能增加包体积。
复用实例,避免频繁创建新实例,尤其是在循环或高性能要求的场景中。
缓存格式化结果,对于重复使用的格式化结果进行缓存,避免重复计算。
在大型应用中,考虑将 Day.js 实例管理集中化,避免散落在代码库的各个角落。
对于频繁的日期操作,考虑使用原生 Date 对象进行中间计算,仅在最终需要结果时使用 Day.js。
在 React 等框架中,可以将 Day.js 实例存储在状态中,但要注意不可变特性。
对于服务端渲染,注意时区处理,确保服务器和客户端之间的时间一致性。
与 Moment.js 的对比与迁移
Day.js 与 Moment.js 的对比可以从多个维度进行:
| 特性 | Day.js | Moment.js |
|---|---|---|
| 体积 | ~2KB | ~70KB |
| 不可变性 | 支持 | 不支持 |
| API 兼容性 | 高度兼容 | - |
| 性能 | 更优 | 一般 |
| 插件系统 | 支持 | 有限支持 |
从 Moment.js 迁移到 Day.js 的过程相对简单:
安装 Day.js:
npm uninstall moment
npm install dayjs
替换导入语句:
// 将
import moment from 'moment';
// 替换为
import dayjs from 'dayjs';
替换 API 调用(大多数情况下只需简单替换):
// Moment.js
const date = moment('2023-10-01');
console.log(date.format('YYYY-MM-DD'));
// Day.js
const date = dayjs('2023-10-01');
console.log(date.format('YYYY-MM-DD'));
处理可能的行为差异,如 diff 方法的返回值:
// Moment.js
const diff = moment('2023-10-02').diff('2023-10-01', 'days'); // 1
// Day.js
const diff = dayjs('2023-10-02').diff('2023-10-01', 'day'); // 1
引入必要的插件以支持高级功能:
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
dayjs.extend(utc);
dayjs.extend(timezone);
const date = dayjs().tz('America/New_York');
console.log(date.format('YYYY-MM-DD HH:mm:ss'));
在不同技术栈中的使用
Day.js 可以在各种 JavaScript 技术栈中使用,包括 Vue.js、React 和 Node.js。
在 Vue.js 中使用:
<template>
<div>
<p>当前日期:{{ formattedDate }}</p>
<p>一周后的日期:{{ nextWeekDate }}</p>
</div>
</template>
<script>
import dayjs from 'dayjs';
export default {
data() {
return {
currentDate: dayjs(), // 获取当前日期
};
},
computed: {
// 格式化当前日期
formattedDate() {
return this.currentDate.format('YYYY-MM-DD');
},
// 计算一周后的日期
nextWeekDate() {
return this.currentDate.add(1, 'week').format('YYYY-MM-DD');
},
},
};
</script>
在 React 中使用:
import React from 'react';
import dayjs from 'dayjs';
const DateComponent = ({ date }) => {
const formattedDate = dayjs(date).format('MMMM D, YYYY');
return <div>{formattedDate}</div>;
};
export default DateComponent;
在 Node.js 中使用:
const dayjs = require('dayjs');
const now = dayjs();
console.log(now.format('YYYY-MM-DD')); // 输出当前日期
Day.js 作为一个轻量级且功能强大的日期处理库,适用于大多数常见的日期和时间操作场景。它的 API 与 Moment.js 高度相似,使得从 Moment.js 迁移到 Day.js 非常容易。尽管 Day.js 的功能相对 Moment.js 较少,但其体积小、性能高,非常适合现代 Web 开发。
对于需要处理日期和时间的 JavaScript 项目,Day.js 提供了一个优秀的解决方案,它平衡了功能丰富性和体积小巧性,是现代前端开发中日期处理的理想选择。无论是简单的日期格式化还是复杂的日期计算,Day.js 都能提供优雅的解决方案。
















