date-fns:200+ 函数的 JavaScript 日期工具库

date-fns:200+ 函数的 JavaScript 日期工具库

date-fns 在 GitHub 上拿到了 36.5K Star。

JavaScript 的 Date 对象设计反直觉:月份从 0 开始计数,getDay() 返回星期而非日期,时区操作几乎空白。Moment.js 曾是事实标准,但已进入维护模式,官方不再推荐新项目使用。date-fns 是目前接替这个位置的候选之一。

1、解决了什么

两个问题:API 可用性和打包体积。

Moment.js 封装了易用的 API,但整体导入,tree-shaking 对它无效。一个只用了 format 函数的页面,会把整份 Moment.js 都打包进去。date-fns 的做法不同:200 多个函数拆成独立模块,import 哪个就打包哪个,Webpack 和 Rollup 的 tree-shaking 默认生效。

另一个差异是数据不可变。每个函数输入原日期,返回新日期,不修改原始对象。在 React 和 Vue 的状态管理场景里,这个性质直接影响数据流是否可控。举个例子,用原生 Date 的 setDate() 会原地修改对象,而 date-fns 的 setDate 函数返回一个全新实例,旧值不受影响。

正文顶部截图

2、核心设计原则

原生 Date 类型。不包装、不扩展原生对象,传进去的是 Date,拿出来的还是 Date。与浏览器 API 和第三方库的兼容没有额外成本。你可以直接把 date-fns 的返回值传给任何接受 Date 参数的函数。

TypeScript 全覆盖。整个库用 TypeScript 重写,类型定义全部手写,IDE 补全和类型检查的准确度高于自动生成的类型声明。函数的参数签名和返回值都有明确的类型约束,编译阶段就能发现日期类型的使用错误。

国际化按需加载。几十种语言包同样遵循按模块引入的原则,只需要 import { zhCN } from 'date-fns/locale' 就能使用中文格式化,其他语言不会进入最终打包产物。

基本用法:

import { compareAsc, format } from "date-fns";

format(new Date(2014, 1, 11), "yyyy-MM-dd");
//=> '2014-02-11'

const dates = [
  new Date(1995, 6, 2),
  new Date(1987, 1, 11),
  new Date(1989, 6, 10),
];
dates.sort(compareAsc);
//=> 按时间升序排列

常用函数涵盖了日期计算的各个方向:addDayssubMonths 做加减,differenceInDaysdifferenceInHours 算差值,isBeforeisAfterisEqual 做比较,startOfDayendOfMonth 取边界。200 多个函数的覆盖面已经相当完整。

README区域截图

3、主要使用场景

替换 Moment.js。Moment.js 官方列出的替代方案中,date-fns 是迁移路径最短的一个,API 风格接近,学习成本低。Moment.js 的 moment().format('YYYY-MM-DD') 可以对应到 format(new Date(), 'yyyy-MM-dd'),迁移时逐个函数替换即可。

现代前端工程。TypeScript + tree-shaking 的体系下,date-fns 的模块化设计直接匹配这条工具链,不需要额外配置。Next.js、Vite 这类构建工具默认就能做 tree-shaking,最终打包体积只包含实际使用的函数。

服务端日期计算。纯函数、无副作用,在 Node.js 后端中批量处理时间数据时,行为可预测,测试也简单。不依赖浏览器环境,不需要 DOM 或 window 对象,单元测试直接构造 Date 参数即可。

4、v4.0 的时区支持

date-fns v4.0 把时区能力内建到了核心函数中。此前处理时区需要辅助函数和外部数据源,v4.0 直接提供一等公民的时区支持。对于跨国业务、国际化 SaaS、全球用户时区展示这些场景,减少了一层外部依赖。同时 v4.0 保持了 API 的向后兼容,v3 的代码升级到 v4 不需要大规模修改。

安装:

npm install date-fns --save
posted @ 2026-06-14 09:17  cloudnine36  阅读(23)  评论(0)    收藏  举报