ToolAct工具行动

日期加减计算器

从指定日期加减天数、周数、月数、年数,快速推算目标日期

从日期加减时间

什么是日期加减计算器?

日期加减计算器用于从一个起始日期向前或向后推算目标日期,可以按天、周、月、年进行加减。它常用于续费提醒、合同到期、回访安排、保修期限、项目排期和纪念日推算,避免人工翻日历时漏算。日期加减看似简单,难点在于真实日历并不规则:每个月天数不同,闰年会影响 2 月,1 月 31 日加 1 个月也未必存在对应日期。这个工具适合做快速、清晰的日历推算。需要注意,它计算的是自然日历时间,不会自动扣除周末、节假日、调休日或法律条款中的特殊截止规则。

使用方法

使用方法

  1. 输入起始日期
  2. 选择增加(向前)或减少(向后)
  3. 输入数值并选择单位(日/周/月/年)
  4. 点击「计算结果」查看目标日期

日期规则

  • 月和年的计算可能落到较短的月份;请确认业务规则如何处理如1月31日加一个月这类情况。
  • 对于截止日期,请确认是否需要根据周末、节假日或当日截止时间调整最终日期。

使用场景

从已知起始日期计算截止日期选择起始日期,选择加法或减法,应用天、周、月或年,生成保修、续费、跟进或交付估算的单一结果日期。由于月末溢出由浏览器的日期工具处理,1 月 31 日加一个月这类边界情况会解析为 2 月 28 日或 29 日,无需服务端日历查询。
使用快速偏移量覆盖常见规划窗口结果出现后,+7 天、+30 天、+90 天和 +1 月、+3 月、+1 年的快捷按钮让比较常见审核周期变得快捷,无需重新输入值。起始日期和选择的偏移量仅保存在页面内,不会向后端发送请求,因此可以在共享或借用的设备上计算纪念日、试用期、签证申请或医疗随访日期而无需暴露输入内容。
注意日历运算不等于工作日规则工具处理的是日历日期和月/年溢出,基于日期工具计算。不考虑节假日、周末、公司日历或特定司法管辖区的截止日期规则。将起始日期、偏移量和结果日期一起记录,以便日后理解计算过程。
复查月末溢出(如 1 月 31 日加一个月)当起始日超过目标月份的天数时,确认计算器如何处理溢出,避免订阅续费和合同周年日悄然偏移到不同日期。在将结果用于计费或人事系统之前,测试 1 月 31 日加一个月对 2 月实际天数、3 月 31 日减一个月对闰年 31 天的 2 月等边界情况。
为分布式团队的结果附加时区将参考日期与明确的时区或 UTC 偏移量一起记录,因为不附带上下文的截止日期在其他地区的审核人员重新解释时可能会偏移一天。例如,写为 2026-07-15 的合同结束日期对东京和洛杉矶的团队可能意味着完全不同的时刻,因此在日期旁存储偏移量可以防止跨地区交接中常见的静默日期偏移。

技术原理

本工具的日期运算基于 ECMAScript Date 对象实现的格里高利历外推规则。JavaScript 中月份从 0 开始索引(一月为 0,十二月为 11),这是日期代码中差一错误的最大来源。加天数很简单:new Date(d.getTime() + n * 86_400_000)。加月数则更复杂,因为月份有 28、29、30 或 31 天:标准写法 date.setMonth(date.getMonth() + n) 在结果月份比源日期短时会产生溢出,所以 1 月 31 日加 1 个月会得到 3 月 3 日而非 2 月 28 日(引擎将多余的 3 天顺延到 3 月)。本工具通过比较 setMonth 后的 date.getMonth() 来检测溢出,并在需要时将日期限制在目标月份的最后一天,与 moment.js、date-fns 和 Temporal 的 Plain Date.add() 行为一致。 闰年遵循标准格里高利规则:年份能被 4 整除即为闰年,但世纪年还必须能被 400 整除。因此 1900 年和 2100 年是平年,而 2000 年是闰年,2024 年也是。当计算跨越 2 月 29 日时这点很重要:2023 年 1 月 29 日加 1 个月再加 1 个月得到 3 月 29 日,但在 2024 年翻转会经过 2 月 29 日(有效日期)再到 3 月 29 日,无需限制。1582 年从儒略历切换到格里高利历的分界点在此被忽略,因为外推格里高利历将规则无限期向后延伸;1582 年 10 月 15 日之前的日期在技术上是时代错位的,但对于现代用途仍然计算正确。 时区处理是一个独立维度:Date 内部存储 UTC 时间点,仅在调用 .getDate()、.getMonth() 或 .toLocaleString() 时应用宿主系统的 IANA 时区(如 America/New_York、Asia/Shanghai)。由此产生两个陷阱:(1) 从不带 Z 后缀的 ISO 字符串("2026-06-10")构造的日期按 UTC 午夜解析,但不带 Z 的 "2026-06-10T00:00:00" 按本地时间午夜解析,同一个 date.getDate() 可能返回 9 或 10,取决于用户的偏移量;(2) 春季夏令时跳过 02:00-03:00,秋季重复 01:00-02:00,这使得某些算术变得模糊,因此 "+24 小时" 的加法可能落在相差 23 或 25 小时的挂钟时间上。对于工作日、仅限工作日或考虑节假日的算术,此处的日历结果必须针对特定地区的节假日列表进行后处理(例如通过 date-holidays npm 包或自定义日历),而不是依赖简单的翻转。

  • JS Date 月份从 0 开始索引:一月 = 0,十二月 = 11;差一错误是最常见的错误。
  • setMonth 溢出:1 月 31 日加 1 个月得到 3 月 3 日而非 2 月 28 日;工具通过比较 setMonth 后的 getMonth() 来限制到月末。
  • 闰年:能被 4 整除,但世纪年还必须能被 400 整除(所以 1900 年不是,2000 年是,2024 年是)。
  • 不带 Z 的 ISO 8601("2026-06-10T00:00:00")按本地时间解析;带 Z 的按 UTC 解析——getDate() 可能返回不同的日期。
  • 夏令时转换造成 23 小时和 25 小时的一天;加 24 小时并不总是等于加 1 个日历天。
  • 天级别的计算通过 getTime() + n * 86_400_000 精确完成;更长的单位通过 setMonth/setFullYear 级联处理并进行限制。
  • 工作日和节假日感知的算术必须通过特定地区的日历表在引擎之上分层实现——不在引擎本身中。

示例

起始日期加 90 天(试用期 / OKR 复盘)

起始日期: 2026-01-15(周四)
操作    : + 90 天
结果    : 2026-04-15(周三)
使用场景: 90 天试用期到期、Q1 OKR 复盘

从今天减去 6 个月

起始日期: 2026-06-11
操作    : - 6 个月
结果    : 2025-12-11
使用场景: 回看半年前的数据用于续费或流失分析

加 2 年 3 个月 5 天(签证到期)

起始日期: 2026-01-15
步骤 1 : + 2 年    -> 2028-01-15
步骤 2 : + 3 个月  -> 2028-04-15
步骤 3 : + 5 天    -> 2028-04-20
结果    : 2028-04-20

月末进位:1 月 31 日 + 1 个月

起始日期: 2026-01-31
操作    : + 1 个月
结果    : 2026-02-28(2026 年 2 月有 28 天)

闰年验证:
起始日期: 2028-01-31
操作    : + 1 个月
结果    : 2028-02-29(2028 年是闰年)

减 14 天用于账单提醒

订阅续费日: 2026-07-01
操作      : - 14 天
提醒发送日: 2026-06-17

常见问题

对月末日期加月份是怎么处理的?

由于各月天数不同,给 1 月 31 日加 1 个月并不唯一确定。计算器遵循通行约定:截断到目标月的最后一天——1 月 31 日 + 1 月 = 2 月 28 日(闰年为 29 日)。这与 Excel 的 EDATE 函数一致。

周末和节假日会被计入吗?

默认计入——「加 5 天」即加 5 个自然日。如果要计算工作日(跳过周末以及可选节假日),请使用专门的「工作日计算器」工具;本页只做纯日历运算。

可以同时加年、月、周、日吗?

可以。计算时按「年 → 月 → 周 → 日」的顺序应用,这是包括 JavaScript Temporal 提案在内的大多数日期库采用的约定。顺序很重要:从 1 月 1 日加「1 个月零 30 天」与「30 天零 1 个月」结果不同。

如何处理夏令时?

本页的运算基于日历日期而非绝对时间,因此跨夏令时切换加「一天」后,本地时区的时刻保持不变。如果需要精确到 24 小时的运算,请将单位换成小时而不是天。

支持的日期范围是多少?

JavaScript Date 支持以 1970 年为基准前后各 100,000,000 天,约对应公元前 271,821 年至公元 275,760 年。该范围内的任意历史或未来日期均可处理。需要注意的是,1582 年格里高利历改革之前的日期与各地民用历法不一定一致。

两个日期相减为什么和加上负数天数不同?

其实是相同的——减去 N 天等同于加上 -N。如果你想求两个日期之间的差值,请使用「日期差值」工具。本页只做单向运算:起始日期加上或减去一段时长。

我的数据会被上传吗?

不会。计算在浏览器中完成,刷新页面后输入即被清除。