使用方法
- 在「开始日期」选或填 2026-09-01(默认示例值),「结束日期」填 2026-10-01(默认示例值),两个框都只接受
YYYY-MM-DD格式,允许 1900-01-01 ~ 2199-12-31。 - 「跳过周六日」默认勾选,用来算工作日;不勾时结果区会标明工作日口径未启用,而不是悄悄给出 0。
- 点「计算间隔天数」,或直接在任一日期框里按 Enter。结果区一次给出四个数:相隔天数(不含首日)、含首日天数、工作日天数、周与余数。
- 分不清该填哪一头时,点「交换起止」把两个日期对调,再点一次计算即可;结束日早于开始日会得到负数,并在提示里说明方向。
- 点「复制结果」把四行口径一次拿走,或到下方「常见日期区间对照表」里点「导出对照表 CSV」拿到 15 组常用区间的表格文件。
这个日期间隔天数计算器能解决什么问题
一是把"相差多少天"和"一共多少天"分开。这两个数只差 1,却经常被混着用:合同期从 1 月 1 日到 12 月 31 日,说"相隔 364 天"和"共 365 天"都没错,但报销天数、计息天数、请假天数各自认其中一个。这个日期间隔天数计算器把两个数并排给出,避免你事后返工。
二是算工作日而不是自然日。项目排期、交付周期、试用期这些场景只认周一至周五。本页的第三个数会跳过周六日逐个计数,省去拿日历手点一遍。
三是避开夏令时的 23/25 小时陷阱。用本地时间构造日期再相减,遇到夏令时切换那天时长是 23 小时或 25 小时,除以 24 会得到 0.9583 或 1.0417 天这种小数;本页一律按 UTC 零点相减,结果永远是整数天。
四是快速查常见区间。季度、半年、整年、跨年、闰年 2 月末这些固定区间的天数不必每次重算,页面下方的对照表把 15 组常用值先算好了,可以直接复制进表格。
本页不做这些事:不处理中国法定节假日的调休安排(政府每年单独发布,需要按当年公告逐日核对),不把时间部分(时、分、秒)纳入计算——只认日历日;也不做日期加减运算,要"某天往后推 N 天是哪天",请用页面底部的「日期加天数计算器」。
计算原理:为什么必须用 UTC 零点相减
这个日期间隔天数计算器的核心只有两句:先把两个日期各自转成 UTC 时间戳,再相减除以一天的毫秒数。构造时间戳用的是 Date.UTC(2026, 8, 1)(月份从 0 开始,所以 9 月写作 8),它返回的是"1970-01-01T00:00:00Z 起经过的毫秒数",与浏览器的时区设置无关。相减得到毫秒差,再除以 86400000(即 24 × 60 × 60 × 1000)就得到天数。
为什么不能用本地时间构造。如果写 new Date(2026, 2, 8),得到的是本机时区的零点。在实行夏令时的地区(如纽约),2026-03-08 这一天只有 23 小时,2026-03-09 与它相减得到的毫秒数不整除 86400000,商是 0.9583。UTC 没有夏令时,相邻两天的 UTC 零点间隔恒为 86400000 毫秒,所以本页的结果一定是整数,不需要额外的四舍五入兜底。
工作日是怎么数的。取到开始日期的 UTC 时间戳后,每次加 86400000 毫秒前进一天,用 getUTCDay() 取星期(0 是周日、6 是周六),落在 1~5 之间的计数加一,直到抵达结束日期为止,形成半开区间 [开始, 结束)。默认示例里 2026-09-01 到 2026-10-01 共 30 个自然日,落在周一至周五的恰好 22 天——9 月共有 22 个工作日,10 月 1 日当天不计入。
输入校验靠"回读比对"。只判断字符串格式是不够的:2026-02-30 在 Date.UTC 里会被自动进位上溢成 3 月 2 日,不报错也不返回 NaN。本页的做法是构造时间戳后再用 getUTCFullYear()、getUTCMonth()、getUTCDate() 读回来和输入逐项比对,对不上就判定为无效日期并给出提示。
遵循的标准。日期字面量采用 ISO 8601 的 YYYY-MM-DD 扩展格式;闰年判定遵循格里高利历规则——能被 4 整除且不能被 100 整除,或者能被 400 整除。所以 2024 年和 2000 年是闰年(366 天),1900 年和 2100 年是平年(365 天),这与"四年一闰"的直觉并不一致。
完整示例(2026-09-01 到 2026-10-01)
页面打开时的默认条件:开始 2026-09-01(周二)、结束 2026-10-01(周四)、勾选跳过周六日。
- 相隔天数(不含首日)= 30 天,即结束时间戳减开始时间戳;
- 含首日天数(头尾都算)= 31 天,比分隔数多 1;
- 工作日(跳过周六日)= 22 天,10 月 1 日当天按半开区间不计入;
- 周与余数 = 4 周 2 天(30 ÷ 7 = 4 余 2);
- 把日期对调成 10-01 到 09-01,相隔天数变成 -30 天,工作日仍按绝对跨度算 22 天。
同样两个日期,如果换成"含首日但只数工作日",你会得到 22 天加上 10 月 1 日(周四)这 1 天 = 23 天。这就是为什么本页把"是否含首日"和"是否只数工作日"拆成两个独立开关——它们不是同一件事,混在一起就会各说各话。
常见日期区间对照表(含首日与不含首日)
下表固定"跳过周六日"口径,逐行实测。「含首日」列是「相隔天数」加 1。默认展示 12 行,其余 3 行点「加载更多」展开。
| 开始日期 | 结束日期 | 相隔天数 | 含首日 | 工作日 | 周与余数 |
|---|---|---|---|---|---|
| 2026-09-01 | 2026-10-01 | 30 | 31 | 22 | 4 周 2 天 |
| 2026-09-01 | 2026-09-30 | 29 | 30 | 21 | 4 周 1 天 |
| 2026-01-01 | 2026-02-01 | 31 | 32 | 22 | 4 周 3 天 |
| 2026-01-01 | 2026-07-01 | 181 | 182 | 129 | 25 周 6 天 |
| 2026-01-01 | 2026-12-31 | 364 | 365 | 260 | 52 周 0 天 |
| 2026-01-01 | 2027-01-01 | 365 | 366 | 261 | 52 周 1 天 |
| 2026-10-01 | 2026-10-01 | 0 | 1 | 0 | 0 周 0 天 |
| 2026-10-02 | 2026-10-01 | -1 | 0 | 0 | 负向,不换周 |
| 2024-02-28 | 2024-03-01 | 2 | 3 | 2 | 0 周 2 天 |
| 2025-02-28 | 2025-03-01 | 1 | 2 | 1 | 0 周 1 天 |
| 2000-01-01 | 2100-01-01 | 36525 | 36526 | 26089 | 5217 周 6 天 |
| 1970-01-01 | 2026-10-01 | 20727 | 20728 | 14805 | 2961 周 0 天 |
| 2000-01-01 | 2026-01-01 | 9497 | 9498 | 6783 | 1356 周 5 天 |
| 2026-05-01 | 2026-06-15 | 45 | 46 | 31 | 6 周 3 天 |
| 2026-12-25 | 2027-01-05 | 11 | 12 | 7 | 1 周 4 天 |
两组对照最能说明口径差:2024-02-28 到 2024-03-01 是 2 天,而 2025-02-28 到 2025-03-01 只有 1 天——差别全部来自 2 月 29 日这一天,闰年规则在这里体现得最直接。另外 2026-01-01 到 2026-12-31 相隔 364 天、含首日 365 天,正好是平年的天数;跨到 2027-01-01 则变成 365 天。
输入范围、闰年规则与边界
下面这些是刻意划定的边界,知道它们能避免你把这个日期间隔天数计算器用在不该用的地方:
- 日期范围 1900-01-01 ~ 2199-12-31,总跨度 109572 天(约 300.0 年)。超出这个范围会被拒绝,避免历史历法换算和极端值带来的歧义。
- 只接受
YYYY-MM-DD,且必须是真实存在的日期。2026-02-30、2026-13-01、2026-04-31都会被判为无效——不是靠格式正则,而是靠Date.UTC构造后再回读年月日比对。 - 闰年规则:能被 4 整除但不能被 100 整除,或者能被 400 整除。于是 2024 年、2000 年是闰年(366 天),1900 年、2100 年是平年(365 天)。二月因此只有 28 天或 29 天两种可能。
- 工作日只跳过周六日,不含法定节假日与调休。中国的节假日安排由国务院每年单独发布,且存在"调休上班的周六",任何静态规则都无法覆盖,所以本页不假装能算——需要精确工期的,请拿结果再去核当年的放假通知。
- 同一天输入两次会得到 0 天,含首日是 1 天。这两个数都对,只是口径不同;结果区的提示会明确标出当前用的是哪一种。
- 结束日早于开始日会得到负数(例如 -30),并且不参与周数换算——负数除以 7 取余在数学上成立但在业务上没有意义,所以本页对负向区间只报相隔天数与工作日。
- 不含时间部分。
2026-09-01 23:59和2026-09-01 00:00在本页是同一个日期,都按当日零点处理。要算到小时和分钟,请改用时间戳类工具。
常见问题
为什么要给"不含首日"和"含首日"两个数?
因为不同业务认不同的口径。行程、工期、利息通常按"相隔天数"(结束减开始),而住宿、请假、票期常常"头尾都算",同一个 2026-09-01 到 2026-10-01 就分别是 30 天和 31 天。与其争论哪个对,不如两个都列出来,让你按业务规则挑。
为什么同一天输入两次,结果一个是 0 一个是 1?
0 是"相隔天数",指从开始到结束跨过了 0 个整日;1 是"含首日天数",指这一天本身算 1 天。两者并不矛盾,只是问的问题不同。
工作日为什么要单独算,不能直接用自然日减周末?
不能。一周有 2 个周末日,但区间的起止并不一定落在周一或周日,直接用"天数 ÷ 7 × 2"会算错。本页是逐日前进并用 getUTCDay() 判断星期,7 天以内、跨月、跨年的区间都精确。
2000 年是闰年吗?1900 年呢?
2000 年是(366 天),1900 年不是(365 天)。因为闰年规则是"能被 4 整除且不能被 100 整除,或者能被 400 整除":1900 能被 4 和 100 整除但不能被 400 整除,所以是平年;2000 能被 400 整除,所以是闰年。
为什么算出来的工作日和中国节假日日历对不上?
因为本页只按周一至周五判断,不读取任何节假日数据。国内的法定节假日安排每年由国务院办公厅单独发布,还包含把周末调成工作日的"调休",无法用固定规则推出。要精确到节假日,请以当年公告为准。
换一个时区打开,结果会变吗?
不会。日期先被转成 UTC 时间戳再相减,整个过程不读取本机时区,也不受夏令时影响。这也是它比"本地零点相减"更可靠的原因——后者在夏令时切换那天会算出 0.9583 或 1.0417 天。
能不能算两个日期之间有多少个月?
本页只把天数换算成"周与余数",不做自然月换算。因为"一个月"没有固定天数(28~31 天),"相隔 3 个月"这类说法必须先定义按月还是按天进位,容易产生歧义。需要严格的月数推算,请用页面底部的日期计算类工具。
最大能算多远?109572 天是怎么来的?
输入范围是 1900-01-01 到 2199-12-31,两端相减正好 109572 天(约 300.0 年)。这不是 JavaScript 的能力上限——Date.UTC 本身可表示到约 ±1.0 亿天——而是人为收窄,避免用户误用远古或极远未来的日期得到没有业务意义的数字。