我厌倦了 JavaScript 的 Date API,于是我修复了它

发布: (2025年12月10日 GMT+8 01:39)
5 min read
原文: Dev.to

Source: Dev.to

进入 WristWatch

WristWatch 是我对 JavaScript 日期问题的答案。它是一个体积小(不到 10 KB)且零依赖的库,以一种实际上有意义的方式(至少对我而言)包装了原生 Date API。

我不想构建像 Moment.js 那样的大型框架。我只想要一个能让我:

  • 在不每次都查文档的情况下格式化日期
  • 在不哭泣的情况下进行日期运算
  • 在不需要 JavaScript 考古学博士学位的情况下记住函数名称
  • 不会意外地修改日期导致一切崩溃

有趣的部分

合理的月份

原生 Date.getMonth() 返回 0‑11。在 WristWatch 中,月份是 1‑12,正如普通人所期望的那样:

const date = new WristWatch('2025-12-05');
date.getMonth(); // 12 (December, not 11!)

不烂的格式化

想要格式化日期?只要告诉它你想要的格式:

const now = WristWatch.now();
now.format('YYYY-MM-DD');      // "2025-12-06"
now.format('MMMM D, YYYY');    // "December 6, 2025"
now.toRelative();             // "just now"

不再需要把十几种方法串在一起,也不必引入整个格式化库。

实际可用的日期运算

给日期加天数应该很简单。在 WristWatch 中,确实如此:

const today = WristWatch.now();
const tomorrow = today.add(1, 'day');
const nextWeek = today.add(1, 'week');
const nextMonth = today.add(1, 'month');

所有操作都是不可变的,所以不会意外弄坏原始日期。它还能处理诸如“把一个月加到 1 月 31 日会怎样?”这类边缘情况(答案是得到 2 月 28 日,而不是 3 月 3 日)。

不需要思考的比较

需要检查某个日期是否在另一个日期之前?直接写:

if (tomorrow.isAfter(today)) {
  console.log('Tomorrow is in the future!');
}

if (date.isBetween(start, end)) {
  console.log('Date is in range!');
}

不需要时间戳相减,不用动脑算,只需直接比较。

技术细节

零依赖

WristWatch 完全没有依赖。它是对原生 Date API 的轻量包装,这意味着它快速、可靠,并且不会因为某个随机依赖被废弃而崩溃。

完全类型化

从头到尾使用 TypeScript 编写。每个函数、每个参数、所有内容都有类型。

可摇树优化

只导入你需要的部分。

// 方法链式风格
import { WristWatch } from '@lukelowers/wrist-watch';
const ww = WristWatch.now();
ww.add(1, 'day').format('YYYY-MM-DD');

// 函数式风格
import { now, format, add } from '@lukelowers/wrist-watch';
const date = now();
format(add(date.getDate(), 1, 'day'), 'YYYY-MM-DD');

与原始方案紧密相关

我并不想重新造轮子,而是想在其基础上迭代。WristWatch 是一个包装器,仍然让人想起旧的实现方式,但不会与更大的库竞争。

实际经过测试

使用 fast-check 的基于属性的测试确保一切正常。数百个随机测试用例会跑遍每个函数,代码对任何想进一步测试的人都是开放的。

实话实说

大家都会劝你别自己写日期库。“直接用 Moment!”他们说。“直接用 date‑fns!”他们说。

Moment 已经不再维护。date‑fns 很棒,但体积庞大。有时你只想要一个简单的、恰好满足需求且不必引入半个 npm 的东西。

WristWatch 并不想成为面面俱到的库。它想成为我希望存在的库:小巧、专注、使用起来真的愉快。

想试试吗?

npm install @lukelowers/wrist-watch

GitHub 仓库 包含完整文档和示例。如果发现问题或想添加功能,欢迎提交 PR。

Back to Blog

相关文章

阅读更多 »

Reatom:随你成长的状态管理

碎片化问题 现代前端开发有一个常见的模式: - 从简单的 useState hook 开始 - 需要共享状态?添加 Context - Context re‑...