date-fns logo

date-fns

现代 JavaScript 函数式日期工具库,提供 250+ 个纯函数,支持 tree-shaking 和一等时区支持。

精选工具日期时间JavaScript函数式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/
GitHubhttps://github.com/date-fns/date-fns
LicenseMIT
最新版本v4.1.0(稳定线)/ v5(2025-2026 发布,体积优化)
主要维护者Sasha Koss(kossnocorp)及 date-fns 团队
npm 周下载量~3,500 万+
GitHub Stars35,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:提供 TZDateTZDateMini
  • @date-fns/utc:提供 UTCDateUTCDateMini
  • 所有 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/utcUTC 处理(UTCDate、UTCDateMini)239B ~ 504B
@date-fns/tz/mini轻量时区处理761B

核心函数分类

  • 格式化formatformatDistanceformatRelativeformatDistanceToNow
  • 解析parseparseISOfromUnixTime
  • 计算addDaysaddMonthsaddHourssubDayssetMonth
  • 比较isBeforeisAfterisEqualisTodayisFuture
  • 差异differenceInDaysdifferenceInHoursdifferenceInMonths
  • 范围eachDayOfIntervaleachMonthOfIntervalisWithinInterval
  • 校验isValidisDate

社区生态

  • 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 &#123; format &#125; from 'date-fns',避免 import * as
  • 时区显式化:在跨时区场景中,始终使用 TZDatein 属性明确指定时区
  • 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-fnsDay.jsLuxonMoment.js
包大小(tree-shaken)~1-2KB/函数~2KB + 插件~53KB~72KB
API 风格纯函数链式链式/方法链式
Tree-shaking✅ 原生支持❌ 插件不支持✅ 部分
TypeScript✅ 一等支持
时区✅ 一等支持(v4+)插件✅ 内置插件
不可变
函数数量250+~80(含插件)~100~150
Locale60+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 默认使用英语,需要显式传入 &#123; locale: zhCN &#125;
  • 混淆 Date 和 TZDate:普通 Date 对象在跨时区场景下可能产生预期外结果

技术局限与边界

  • API 风格不同:从 Moment.js/Day.js 迁移需要重写所有调用,没有兼容层
  • 无链式调用:纯函数风格不支持 .add().subtract().format() 链式写法,需要嵌套调用
  • 函数数量多:250+ 函数增加了学习成本,需要查阅文档确定使用哪个函数
  • 时区支持需额外包:v4+ 的时区支持需要安装额外的 @date-fns/tz,增加了依赖管理复杂度
  • 社区生态不如 Moment.js:第三方插件和扩展相对较少
  • 非浏览器环境兼容性:部分函数在旧版 Node.js 中可能需要额外配置

学习资源

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 支持最好的选择