停止在 JavaScript 中错误计算年龄:闰年、2 月 29 日和 1 月 31 日陷阱

发布: (2026年2月9日 GMT+8 09:18)
3 分钟阅读
原文: Dev.to

Source: Dev.to

大多数年龄计算器都算错了

  • 它们只做 nowYear - dobYear,却忘记检查生日是否已经过去。
  • 它们把所有月份都当成同等长度。
  • 它们在 2 月 29 日生日上崩溃。
  • 它们会遇到 JavaScript 的 “1 月 31 日 + 1 个月 = 3 月” 的意外。

如果你需要一个可以直接使用的年龄计算器,就必须正确处理这些边缘情况。

我们真正想要计算的内容

给定

  • dob – 出生日期
  • asOf – 你想要测量年龄的日期(默认是今天)

我们想要

  • years – 已经完整度过的生日数
  • months – 自上一次生日起完整的月份数
  • days – 自该月份锚点起剩余的天数

如果 asOf = dob);

// ---- Years ----
let years = asOf.getFullYear() - dob.getFullYear();
const bdayThisYear = birthdayInYear(dob, asOf.getFullYear(), "FEB_28");
if (asOf  {
  it("handles birthday not yet happened this year", () => {
    const dob = new Date("2000-10-20");
    const asOf = new Date("2026-02-09");
    const r = calculateAge(dob, asOf);
    expect(r.years).toBe(25);
  });

  it("handles month‑end clamping (Jan 31)", () => {
    const dob = new Date("2000-01-31");
    const asOf = new Date("2000-03-01");
    const r = calculateAge(dob, asOf);
    // If your month add is buggy, this often breaks.
    expect(r.years).toBe(0);
    expect(r.months).toBeGreaterThanOrEqual(1);
  });

  it("handles Feb 29 birthdays with FEB_28 rule", () => {
    const dob = new Date("2004-02-29");
    const asOf = new Date("2025-02-28");
    const r = calculateAge(dob, asOf);
    // Under FEB_28 policy, birthday is considered reached on Feb 28.
    expect(r.years).toBe(21);
  });

  it("rejects asOf before dob", () => {
    const dob = new Date("2020-01-01");
    const asOf = new Date("2019-12-31");
    expect(() => calculateAge(dob, asOf)).toThrow();
  });
});

你可以添加的其他边缘案例

  • dob = 1999-12-31, asOf = 2000-01-01
  • dob = 2000-02-28, asOf = 2001-02-28
  • dob = 2000-03-31, asOf = 2000-04-30

关键要点

要得到正确的年龄输出:

  1. 规范化 为仅日期(午夜)。
  2. 定义 一个统一的 2 月 29 日政策。
  3. 在跨月时 对月末进行夹取(clamp)。
  4. 编写 覆盖这些奇怪日期的测试。

就这么简单——不需要外部库。

演示(可选):

0 浏览
Back to Blog

相关文章

阅读更多 »

解锁笔记本电脑 GPU 的隐藏力量

概述:大多数现代笔记本电脑都配备了强大的 GPU,但往往未被充分利用。无论你是运行本地 LLM 的软件工程师,还是数据科学家……