date-fns
现代 JavaScript 函数式日期工具库,提供 250+ 个纯函数,支持 tree-shaking 和一等时区支持。
date-fns 是模块化、函数式的 JavaScript 日期工具库,提供 250+ 个独立日期操作函数。纯函数设计天然支持 tree-shaking,v4+ 引入一等时区支持,npm 周下载量超 3500 万,是四大日期库中下载量最高的。
date-fns
现代 JavaScript 函数式日期工具库,提供 250+ 个纯函数,支持 tree-shaking 和一等时区支持。
技术简介说明
date-fns 是一个模块化、函数式的 JavaScript 日期工具库,提供了超过 250 个独立的日期操作函数。与 Moment.js 和 Day.js 的链式 OOP 风格不同,date-fns 采用纯函数设计——每个函数接收日期参数并返回新值,没有共享的全局状态或可变对象。
date-fns 的架构使得每个函数都是独立的可导入模块,天然支持 tree-shaking。这意味着只有你实际使用的函数才会被打包到最终产物中,从而实现极致的按需加载。
从 v4.0 开始,date-fns 引入了"一等时区支持"(First-class time zone support),通过外部包 @date-fns/tz 和 @date-fns/utc 提供精确的时区处理能力。v5 进一步将压缩包体积从 5.83MB 降至 2.89MB,减少了约 50%。
基本信息
| 项目 | 详情 |
|---|---|
| 官网 | https://date-fns.org/ |
| GitHub | https://github.com/date-fns/date-fns |
| License | MIT |
| 最新版本 | v4.1.0(稳定线)/ v5(2025-2026 发布,体积优化) |
| 主要维护者 | Sasha Koss(kossnocorp)及 date-fns 团队 |
| npm 周下载量 | ~3,500 万+ |
| GitHub Stars | 35,000+ |
快速上手
安装
# npm
npm install date-fns
# yarn
yarn add date-fns
# pnpm
pnpm add date-fns
# 时区支持(v4+)
npm install @date-fns/tz @date-fns/utc基础配置
// date-fns 无需全局配置,按需导入函数即可
import { format, addDays, differenceInDays } from 'date-fns'
import { zhCN } from 'date-fns/locale'
// 时区配置(v4+)
import { TZDate } from '@date-fns/tz'最小示例
import { format, addDays, isBefore, differenceInHours } from 'date-fns'
import { zhCN } from 'date-fns/locale'
const today = new Date()
// 格式化
console.log(format(today, 'yyyy-MM-dd HH:mm:ss')) // '2026-07-07 14:30:00'
// 中文格式化
console.log(format(today, 'yyyy年MM月dd日', { locale: zhCN }))
// 日期计算
const tomorrow = addDays(today, 1)
// 比较
console.log(isBefore(tomorrow, today)) // false
// 时间差
console.log(differenceInHours(tomorrow, today)) // 24核心概念与架构
纯函数设计
date-fns 的核心设计哲学是函数式编程。每个函数都是独立的、无状态的纯函数:
import { addDays, format } from 'date-fns'
// 每次调用都返回新值,不修改原始日期
const original = new Date(2026, 0, 1)
const result = addDays(original, 10)
console.log(original.getDate()) // 1(未变)
console.log(result.getDate()) // 11模块化按需加载
每个函数都是独立的模块,构建工具可以精确 tree-shaking:
// ✅ 只有 format 和 addDays 被打包
import { format, addDays } from 'date-fns'
// ❌ 避免全量导入
import * as dateFns from 'date-fns'一等时区支持(v4+)
从 v4.0 开始,date-fns 通过外部包实现时区支持:
@date-fns/tz:提供TZDate和TZDateMini类@date-fns/utc:提供UTCDate和UTCDateMini类- 所有 250+ 核心函数自动适配时区输入
in上下文属性可显式指定计算时区
核心特性
- 250+ 纯函数:覆盖解析、格式化、计算、比较、范围等所有日期操作
- 完美 Tree-shaking:每个函数独立模块,只打包用到的函数
- 一等时区支持:v4+ 通过
@date-fns/tz提供精确时区处理 - 不可变设计:所有函数返回新值,不修改输入参数
- TypeScript 优先:完整的类型定义,类型推导准确
- Locale 支持:60+ 种语言的本地化格式化
- 零依赖:核心库无任何外部依赖
- DST 安全:正确处理夏令时边界情况
- UTC 支持:
@date-fns/utc提供轻量 UTC 处理 - 子包体积可控:核心包 17.5KB,单个函数通常 < 1KB
生态图
官方子包
| 包名 | 功能 | 体积 |
|---|---|---|
date-fns | 核心函数库 | ~17.5KB(核心) |
@date-fns/tz | 时区支持(TZDate、TZDateMini) | 761B ~ 1KB |
@date-fns/utc | UTC 处理(UTCDate、UTCDateMini) | 239B ~ 504B |
@date-fns/tz/mini | 轻量时区处理 | 761B |
核心函数分类
- 格式化:
format、formatDistance、formatRelative、formatDistanceToNow - 解析:
parse、parseISO、fromUnixTime - 计算:
addDays、addMonths、addHours、subDays、setMonth - 比较:
isBefore、isAfter、isEqual、isToday、isFuture - 差异:
differenceInDays、differenceInHours、differenceInMonths - 范围:
eachDayOfInterval、eachMonthOfInterval、isWithinInterval - 校验:
isValid、isDate
社区生态
- date-fns-tz(v4 前社区时区方案,已被
@date-fns/tz取代) - angular-date-fns:Angular 集成
- react-date-fns-hooks:React hooks 封装
关键依赖
date-fns 核心零依赖。时区包 @date-fns/tz 独立运行,不依赖核心库也可使用。
适用场景
- 现代前端框架(React/Vue/Svelte):纯函数设计与 React Hooks、Vue Composition API 天然契合
- 对 bundle size 敏感的项目:tree-shaking 特性确保只打包用到的函数
- 需要精确时区处理的国际化应用:v4+ 一等时区支持
- TypeScript 项目:完善的类型推导,减少运行时错误
- 数据密集型日期计算:如排班系统、日历应用、数据分析报表
- Node.js 后端:服务端日期处理、数据格式化
- 函数式编程风格团队:与 fp-ts、Ramda 等函数式库风格一致
开发与工程化
项目构建
git clone https://github.com/date-fns/date-fns.git
cd date-fns
pnpm install
# 运行测试
pnpm test
# 构建
pnpm build
# 类型检查
pnpm typecheck开发最佳实践
- 精确导入:始终使用具名导入
import { format } from 'date-fns',避免import * as - 时区显式化:在跨时区场景中,始终使用
TZDate和in属性明确指定时区 - Locale 按需引入:只导入项目实际使用的 locale
- 统一时间上下文:使用
in参数统一日期计算的时区上下文
CI/CD 集成
# GitHub Actions 示例
- name: Run date-fns related tests
run: pnpm test -- --filter="date"性能与安全
性能特点
- 解析速度:在大量日期处理场景下,性能顺序为:原生 Date > Day.js > date-fns > Luxon(差异微小)
- Bundle 优化:tree-shaking 后实际打包体积远小于核心包大小
- 内存效率:纯函数设计,无全局状态,内存使用可预测
v4/v5 性能改进
- v4 修改了几乎所有核心函数以支持时区,但核心包仅增加 300 字节
- v5 将压缩包体积减少约 50%(5.83MB → 2.89MB)
安全注意事项
- date-fns 纯计算库,不涉及网络请求或 DOM 操作
- 用户输入的日期字符串应通过
isValid进行校验 - 定期更新至最新版本
技术对比
| 特性 | date-fns | Day.js | Luxon | Moment.js |
|---|---|---|---|---|
| 包大小(tree-shaken) | ~1-2KB/函数 | ~2KB + 插件 | ~53KB | ~72KB |
| API 风格 | 纯函数 | 链式 | 链式/方法 | 链式 |
| Tree-shaking | ✅ 原生支持 | ❌ 插件不支持 | ✅ 部分 | ❌ |
| TypeScript | ✅ 一等支持 | ✅ | ✅ | ❌ |
| 时区 | ✅ 一等支持(v4+) | 插件 | ✅ 内置 | 插件 |
| 不可变 | ✅ | ✅ | ✅ | ❌ |
| 函数数量 | 250+ | ~80(含插件) | ~100 | ~150 |
| Locale | 60+ | 160+ | Intl 驱动 | 130+ |
| 学习曲线 | 中等 | 低 | 中等 | 低 |
| 维护状态 | ✅ 活跃 | ✅ 活跃 | ✅ 活跃 | ⚠️ 维护模式 |
何时选择 date-fns
- 需要精确控制 bundle size,每个函数按需导入
- 偏好函数式编程风格
- TypeScript 项目,需要强类型推导
- 需要精确的时区处理(v4+)
- 与 React/Vue 等现代框架深度集成
最佳实践
推荐模式
// ✅ 统一创建带时区的日期工厂函数
import { TZDate } from '@date-fns/tz'
import { format, addDays, startOfMonth } from 'date-fns'
const createInShanghai = (date) => new TZDate(date, 'Asia/Shanghai')
// ✅ 使用 in 上下文参数统一时区
import { differenceInBusinessDays } from 'date-fns'
const days = differenceInBusinessDays(dateA, dateB, {
in: tz('Asia/Shanghai')
})
// ✅ 统一日期工具模块
// utils/date.ts
export { format, addDays, subDays, startOfMonth, endOfMonth } from 'date-fns'
export { TZDate } from '@date-fns/tz'
export { zhCN, enUS } from 'date-fns/locale'常见陷阱
- 忘记导入函数:date-fns 没有全局挂载,每个函数需要单独 import
- 时区参数顺序敏感:不指定
in时,计算结果默认使用第一个参数的时区,交换参数顺序可能导致结果不同 - Locale 未生效:
format默认使用英语,需要显式传入{ locale: zhCN } - 混淆 Date 和 TZDate:普通
Date对象在跨时区场景下可能产生预期外结果
技术局限与边界
- API 风格不同:从 Moment.js/Day.js 迁移需要重写所有调用,没有兼容层
- 无链式调用:纯函数风格不支持
.add().subtract().format()链式写法,需要嵌套调用 - 函数数量多:250+ 函数增加了学习成本,需要查阅文档确定使用哪个函数
- 时区支持需额外包:v4+ 的时区支持需要安装额外的
@date-fns/tz,增加了依赖管理复杂度 - 社区生态不如 Moment.js:第三方插件和扩展相对较少
- 非浏览器环境兼容性:部分函数在旧版 Node.js 中可能需要额外配置
学习资源
- 官方文档:https://date-fns.org/docs/Getting-Started
- 官方博客:https://blog.date-fns.org/
- GitHub 仓库:https://github.com/date-fns/date-fns
- v4 时区支持公告:https://blog.date-fns.org/v40-with-time-zone-support/
- Envato 教程:https://code.tutsplus.com/using-date-fns-for-easy-date-manipulation--cms-107620t
- npm 包:https://www.npmjs.com/package/date-fns
2026 年现状
当前版本
- v4.1.0:v4 稳定线,包含一等时区支持
- v5:2025-2026 发布,压缩包体积减少约 50%(5.83MB → 2.89MB)
社区活跃度
- npm 周下载量 3,500 万+,是四大日期库中下载量最高的
- GitHub Stars 35,000+,社区活跃度高
- 版本发布节奏积极,持续迭代优化
发展趋势
- date-fns 在 2026 年继续保持函数式日期库的领先地位
- v5 的体积优化进一步巩固了其在 bundle size 敏感场景的竞争力
- 一等时区支持使 date-fns 在国际化应用中的竞争力显著提升
- 随着 Temporal API 浏览器原生支持的推进,date-fns 可能会逐步适配或提供 Temporal 互操作层
- 在四大日期库中,date-fns 是 npm 下载量最高、tree-shaking 支持最好的选择