如何计算两个日期之间的天数:完整日期计算指南
学习如何计算两日期之间的天数、加减日期以及处理闰年。涵盖手动计算方法、工作日计数、公历历史及编程示例。
简介
日期计算是日常生活中看似简单、实则暗藏陷阱的任务。距离假期还有多少天?90 天质保何时到期?签订合同到交货截止日之间有多少个工作日?
难点在于我们的日历并不是一套整齐划一的体系。各月天数不同(28、29、30 或 31 天),闰年每四年增加一天(还有例外情况),工作日计数要跳过周末和节假日。哪怕差一天,都可能导致错过截止日期、利息计算有误或年龄算错。
本指南将带你全面掌握日期计算所需的一切知识:如何手动计算两日期之间的天数、如何加减日期、闰年的运算规则、工作日与日历日的区别、公历的简要历史、常见日期计算场景,以及如何在编程中处理日期。
使用我们的免费日期计算器,快速计算两日期之间的天数、对日期进行加减运算。
如何计算两日期之间的天数
计算两个日期之间天数的方法有几种。最简单的是逐日累计,但对于相隔较远的日期,更系统化的方法能节省时间、减少出错。
方法一:按月逐段累加
这是最直观的手动方法:
- 计算起始月剩余天数。 用该月总天数减去起始日。
- 加上中间各完整月的天数。 将起始月与结束月之间所有月份的天数相加。
- 加上结束日期的日数。
示例:3 月 15 日到 6 月 10 日
- 3 月剩余天数:31 - 15 = 16 天
- 完整月份:4 月(30 天)+ 5 月(31 天)= 61 天
- 6 月天数:10 天
- 合计:16 + 61 + 10 = 87 天
方法二:年积日编号法
每个日期可以用年积日编号(1 至 365 或 366)来表示。1 月 1 日为第 1 天,2 月 1 日为第 32 天,以此类推。若计算同一年内两个日期之间的天数,直接用年积日编号相减即可。
年积日参考表(非闰年):
| 月份 | 首日编号 | 本月天数 |
|---|---|---|
| 一月 | 1 | 31 |
| 二月 | 32 | 28 |
| 三月 | 60 | 31 |
| 四月 | 91 | 30 |
| 五月 | 121 | 31 |
| 六月 | 152 | 30 |
| 七月 | 182 | 31 |
| 八月 | 213 | 31 |
| 九月 | 244 | 30 |
| 十月 | 274 | 31 |
| 十一月 | 305 | 30 |
| 十二月 | 335 | 31 |
示例:1 月 20 日到 9 月 5 日(非闰年)
- 1 月 20 日 = 第 20 天
- 9 月 5 日 = 第 244 + 5 - 1 = 第 248 天
- 差值:248 - 20 = 228 天
方法三:跨年计算
对于跨越不同年份的日期:
- 计算起始日期到起始年 12 月 31 日的剩余天数。
- 期间每个完整平年加 365 天,每个完整闰年加 366 天。
- 加上结束日期的年积日编号。
示例:2024 年 11 月 10 日到 2026 年 3 月 5 日
- 2024 年剩余天数:11 月有 30 天,剩余 20 天 + 12 月 31 天 = 51 天
- 2025 年全年(平年):365 天
- 2026 年到 3 月 5 日:1 月 31 天 + 2 月 28 天 + 3 月 5 天 = 64 天
- 合计:51 + 365 + 64 = 480 天
日期加减运算
对日期加上或减去若干天,逻辑与上述方法类似,只是方向相反。
给日期加天数
将某日期加上 N 天:
- 将 N 与当前日数相加。
- 若结果超过当前月的天数,减去该月剩余天数,进入下一个月。
- 重复上述步骤,直到所有天数分配完毕。
示例:1 月 20 日加 45 天
- 1 月剩余天数:31 - 20 = 11 天。1 月结束后:45 - 11 = 34 天待分配。
- 整个 2 月(非闰年):28 天。2 月结束后:34 - 28 = 6 天待分配。
- 3 月 6 日。
- 结果:3 月 6 日
给日期减天数
将某日期减去 N 天:
- 从当前日数中减去 N。
- 若结果为零或负数,退回上一个月并加上该月总天数。
- 重复上述步骤,直到减法完成。
示例:4 月 15 日减 50 天
- 从 4 月减:15 天。剩余:50 - 15 = 35 天。回到 3 月底。
- 从 3 月减:31 天。剩余:35 - 31 = 4 天。回到 2 月底。
- 从 2 月(非闰年)减:共 28 天,但只需再减 4 天。
- 2 月 28 日 - 4 = 2 月 24 日。
- 结果:2 月 24 日
加减月份
加减月份相对复杂,因为各月天数不同。标准做法如下:
- 将指定月数加到月份字段上。
- 若结果日期超过新月份的天数,则截断到该月最后一天。
示例:1 月 31 日 + 1 个月 = 2 月 28 日(闰年则为 2 月 29 日)。由于 2 月没有 31 天,日期被截断。
闰年规则及其对计算的影响
闰年是手动日期计算中最容易出错的环节。掌握相关规则至关重要。
三条判断规则
满足以下条件的年份为闰年:
- 能被 4 整除(2024、2028、2032 均为闰年)
- 但不能被 100 整除(1900、2100、2200 均非闰年)
- 但能被 400 整除的例外(2000、2400 均为闰年)
为何存在这些规则
地球绕太阳公转一周约需 365.2422 天。若日历每年严格按 365 天计算,每隔约 4 年就会偏差 1 天。闰年规则正是为了纠正这一偏差:
- 每 4 年加 1 天,平均每年 365.25 天(略长)
- 跳过世纪年,平均每年 365.24 天(略短)
- 但整 400 年重新加回 1 天,平均每年 365.2425 天(非常接近 365.2422)
对日期计算的影响
若计算区间跨越某年 2 月,必须判断该年是否为闰年:
- 1 月 1 日到 12 月 31 日: 平年 364 天,闰年 365 天
- 2 月 28 日到 3 月 1 日: 平年 1 天,闰年 2 天
- 跨越多年: 区间内每个闰年额外增加 1 天
一个常见错误是将所有能被 4 整除的年份都当作闰年。1900 年并非闰年,2100 年同样不是。
工作日与日历日
在法律、金融和商业场景中,工作日与日历日的区分至关重要。
什么是工作日?
工作日是指周一至周五中不属于法定节假日的任何一天。以下时间不计入工作日:
- 周六和周日(周末)
- 法定节假日(因国家乃至地区而异)
工作日计数方法
计算两个日期之间的工作日:
- 计算两日期之间的日历日总天数。
- 计算完整周数(除以 7),乘以 5 得出完整周内的工作日数。
- 计算不足一周的剩余部分中的工作日数。
- 减去区间内落在工作日的法定节假日数量。
示例:3 月 2 日(周一)到 3 月 13 日(周五)
- 日历日总天数:11 天
- 完整周数:1 周(7 天 = 5 个工作日)
- 剩余 4 天:周二至周五 = 4 个工作日
- 工作日合计:5 + 4 = 9 天(假设无节假日)
一年中的工作日数
一个标准年有 52 周零 1 天,共计 260 个工作日。但需注意:
- 额外的 1 天(闰年为 2 天)可能是工作日,也可能不是
- 美国有 11 个联邦假日,实际工作日通常约为 249—251 天
- 其他国家的节假日数量各有不同
常见工作日截止期限
许多法律和金融流程以工作日为单位计时:
- 3 个工作日: 证券交易结算的典型时限(目前标准为 T+2,历史上曾为 T+3)
- 5 个工作日: 商业往来回复的常见截止期限
- 10 个工作日: 许多政府申请的标准处理时限
- 30 个工作日: 合同条款及监管申报中的常见约定
公历
了解我们的日历体系如何运作,有助于解释日期计算中的各种规律。
儒略历
公元前 46 年,尤利乌斯·恺撒引入儒略历,取代了混乱的罗马历法。儒略历每年 365 天,每 4 年设一个闰年,平均年长为 365.25 天。这是一次重大改进,但每年仍比太阳年多估约 11 分 14 秒。
问题所在
数百年累积下来,这一微小误差不断扩大。到 16 世纪,日历已比天文季节偏移约 10 天。春分原本应在 3 月 20—21 日前后,却提前至 3 月 11 日左右。这对天主教会极为重要,因为复活节的日期取决于春分。
格里高利十三世的修正
1582 年,教皇格里高利十三世引入公历,做出两项关键修改:
- 删除 10 天: 1582 年 10 月 4 日之后直接跳至 10 月 15 日,使日历重新与季节对齐。
- 修改闰年规则: 整百年不再设为闰年,除非能被 400 整除。这将平均年长从 365.25 天修正为 365.2425 天,更接近实际值 365.2422 天。
采用时间线
各国采用公历的时间并不统一:
- 1582 年: 天主教国家(意大利、西班牙、葡萄牙、波兰)
- 1752 年: 英国及其殖民地(包括后来的美国)跳过了 11 天
- 1918 年: 俄国在十月革命后采用公历
- 1923 年: 希腊是最后几个完成转换的欧洲国家之一
由于各国采用时间不同,跨国的历史日期计算可能相当复杂。同一个日期,用"旧历"(儒略历)和"新历"(公历)表示,可能相差 10—13 天,具体取决于所处的世纪。
消失天数之谜
1752 年英国采用公历时,9 月 2 日之后直接跳至 9 月 14 日——整整 11 天从日历上凭空消失。民间传说人们走上街头,高呼"还我们十一天!"这场骚乱是否真实发生至今仍有争议,但日历变更确实引发了实际混乱:租金何时到期?法定年龄如何计算?合同何时失效?
俄国同样经历了类似困惑。1917 年的"十月革命"按公历实际上发生在 11 月——彼时儒略历与公历相差 13 天,儒略历的 10 月 25 日对应公历的 11 月 7 日。
现实场景中的日期计算
法律与合同截止期限
法律体系对期限天数有具体的计算规则:
- "30 天内" 通常指触发事件次日起的 30 个日历日。若合同于 3 月 1 日签署,"30 天内"通常意味着须在 3 月 31 日前完成。
- "10 个工作日" 排除周末,通常也排除联邦假日。具体哪些节假日计入,取决于所在司法管辖区。
- 落在周末或节假日的申请截止日,在美国大多数法院通常顺延至下一个工作日。
- 诉讼时效从权利受侵害之日起计算,哪怕差一天也可能决定一项主张是否有效。
医疗与健康计算
日期计算在医学领域至关重要:
- 预产期按末次月经第一天起推算 280 天(40 周),采用内格勒法则(减 3 个月,加 7 天)
- 用药方案通常采用"每隔 X 天"或"每隔 X 小时"的时间间隔,必须精确计算
- 隔离期限从接触日起按日历日计算
- 疫苗接种时间表规定了各剂次之间必须满足的最短间隔,以确保效果
金融计算
银行和金融机构采用不同的计息惯例:
- 实际天数/365(Actual/365): 以实际天数除以 365(适用于美国国债)
- 实际天数/360(Actual/360): 以实际天数除以 360(适用于货币市场工具和众多贷款)
- 30/360: 假定每月 30 天、每年 360 天(适用于公司债券和部分抵押贷款)
这些惯例会影响利息计算。采用实际天数/360 的贷款比采用实际天数/365 的贷款应计利息略多,因为除以 360 会得到更高的日利率。
常见日期计算搜索问题
以下是人们最常搜索的日期计算问题及快速解答:
距今多少天?
| 情景 | 典型计算方式 |
|---|---|
| 今天起 30 天后 | 在今天日期上加 30 天 |
| 今天起 60 天后 | 在今天日期上加 60 天 |
| 今天起 90 天后 | 加 90 天(约 3 个月) |
| 今天起 180 天后 | 加 180 天(约 6 个月) |
| 今天起 1 年后 | 加 365 天(若跨越闰年 2 月 29 日则加 366 天) |
常见时间段的天数
| 时间段 | 天数 |
|---|---|
| 1 周 | 7 |
| 2 周 | 14 |
| 1 个月 | 28—31(不固定) |
| 1 个季度 | 90—92 |
| 1 个学期 | 约 120 |
| 6 个月 | 181—184 |
| 1 年 | 365 或 366 |
| 1 个十年 | 3,652 或 3,653 |
年龄计算
计算某人的精确年龄:
- 用当前年份减去出生年份。
- 若当前月日早于出生月日,则减去 1(本年生日尚未到来)。
- 进一步计算月份和天数的剩余差值。
编程中的日期计算
现代编程语言提供了完善的日期库,能处理日历、闰年和时区的各种复杂情况。
JavaScript
// 计算两日期之间的天数
const start = new Date('2026-01-15');
const end = new Date('2026-06-30');
const diffMs = end - start;
const diffDays = Math.round(diffMs / (1000 * 60 * 60 * 24));
console.log(diffDays); // 166
// 给某日期加 90 天
const date = new Date('2026-03-01');
date.setDate(date.getDate() + 90);
console.log(date.toISOString().split('T')[0]); // 2026-05-30
// 判断是否为闰年
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
}
console.log(isLeapYear(2024)); // true
console.log(isLeapYear(1900)); // false
console.log(isLeapYear(2000)); // true
Python
from datetime import date, timedelta
# 计算两日期之间的天数
start = date(2026, 1, 15)
end = date(2026, 6, 30)
diff = (end - start).days
print(diff) # 166
# 给某日期加 90 天
result = date(2026, 3, 1) + timedelta(days=90)
print(result) # 2026-05-30
# 判断是否为闰年
import calendar
print(calendar.isleap(2024)) # True
print(calendar.isleap(1900)) # False
print(calendar.isleap(2000)) # True
# 计算工作日(排除周末)
import numpy as np
busdays = np.busday_count('2026-03-02', '2026-03-13')
print(busdays) # 9
Excel 与 Google 表格
电子表格无需编程即可实现日期计算:
=DATEDIF(A1, B1, "D") -- 两日期之间的天数
=DATEDIF(A1, B1, "M") -- 两日期之间的月数
=DATEDIF(A1, B1, "Y") -- 两日期之间的年数
=A1 + 90 -- 给某日期加 90 天
=NETWORKDAYS(A1, B1) -- 两日期之间的工作日数
=NETWORKDAYS(A1, B1, holidays) -- 工作日数(扣除节假日)
=EDATE(A1, 3) -- 给某日期加 3 个月
=EOMONTH(A1, 0) -- 当月最后一天
NETWORKDAYS 函数尤为实用,它会自动排除周末,还可以传入一个可选的节假日日期区间一并排除。
编程常见陷阱
-
时区问题: 在 JavaScript 中创建 Date 对象时,默认使用本地时区。两个看似相差 1 天的日期,在不同时区和夏令时转换的影响下,实际可能相差 0 天或 2 天。
-
夏令时问题: 时钟拨快时,某天可能只有 23 小时;时钟拨回时,某天可能有 25 小时。在夏令时切换前后使用毫秒差值可能产生差一天的错误。
-
月份索引: JavaScript 的月份从 0 开始(一月 = 0),而 Python 的月份从 1 开始(一月 = 1)。这是一个高频 bug 来源。
-
可变性: JavaScript 的
Date.setDate()会直接修改原始对象。若需保留原始日期,请务必先创建一个新的 Date 对象。 -
月末边界情况: 在 JavaScript 中,给 1 月 31 日加一个月会得到 3 月 3 日(因为"2 月 31 日"溢出)。不同语言的处理方式不同——有的会截断到月末,有的会溢出到下一个月。
-
2038 年问题: 以 32 位 Unix 时间戳存储日期的系统将在 2038 年 1 月 19 日发生溢出。大多数现代系统已采用 64 位时间戳,可用至公元 292,277,026,596 年。
常见问题解答
如何计算包含起始日期的两日期之间的天数?
标准日期差计算不含起始日,只含结束日(例如,1 月 1 日到 1 月 3 日 = 2 天)。若需同时包含起始日和结束日,只需将结果加 1。这种方式有时称为"含端点计数",在某些法律和医疗场景中会用到。
为什么有些月有 30 天,有些有 31 天?
这一规律可追溯至罗马历法。七月(以尤利乌斯·恺撒命名)和八月(以奥古斯都·恺撒命名)都有 31 天——据传奥古斯都不肯让自己的月份天数少于恺撒的。其余月份则在 30 天和 31 天之间交替,唯独二月例外——它在最初的罗马历法中是最后一个月,因此分到的天数最少。
公历的精度如何?
公历的平均年长为 365.2425 天,而实际太阳年约为 365.2422 天。每年偏差为 0.0003 天,即每 3,236 年偏移 1 天。在需要进行任何修正之前,还有数千年的时间。
什么是儒略日数?
儒略日数(JDN)是从儒略周期起始日(公元前 4713 年 1 月 1 日)起连续计数的天数。天文学家使用它来规避不同历法体系带来的复杂性。例如,2026 年 1 月 1 日的儒略日数为 2,461,042。要计算两个日期之间的天数,只需将它们的儒略日数相减即可。
如何处理跨时区的日期计算?
对于仅涉及日期(不含时间)的计算,建议使用 UTC 日期以避免时区问题。若需进行包含时间的计算,应先将两个日期转换到同一时区,再计算差值。大多数编程语言都提供了时区转换的相关库。
什么是 ISO 8601?它对日期处理有何意义?
ISO 8601 是表示日期和时间的国际标准。格式为 YYYY-MM-DD(如 2026-03-19)。采用该格式可消除欧洲常用的 DD/MM/YYYY 与美国常用的 MM/DD/YYYY 之间的歧义。大多数编程语言和数据库均原生支持 ISO 8601。
不用计算器如何手动计算两日期之间的工作日数?
先计算两日期之间的完整周数,乘以 5 得出完整周内的工作日数。再统计起止两端不足一周部分中的工作日数。例如,从周三到下一个周二,共 1 整周(5 个工作日)加上剩余的几天。最后减去区间内落在工作日的节假日数量。
能计算公历采用之前的日期吗?
可以,但有一些注意事项。1582 年 10 月 15 日之前(或其他国家的相应时间之前)的日期,通常以儒略历表示。若计算跨越公历采用节点,必须考虑被跳过的 10—13 天。许多日期计算器采用"前推公历"(proleptic Gregorian calendar)方案,即将公历规则向前延伸,适用于公历正式采用之前的日期。