使用方法
- 在「判断年份」填 4 位公历年份(示例
2026)。也可以填 3 位(如996)或 1 位(4),取模规则对正整数一致生效。 - 点「判断是否闰年」或直接在输入框按 Enter,立刻得到闰年/平年结论、2 月天数、全年天数与 1 月 1 日的星期。
- 想看两个年份之间隔了多久,把「对照基准年」也填上(示例
2024),页面会给出相差多少年、其中有几个闰年、2 月 29 日出现过几次。 - 点「复制结果」把结论拿走;点「重置」回到
2026与2024这组示例。
这个闰年判断工具能解决什么问题
闰年规则只有一句话,但世纪年是绝大多数人算错的地方:被 4 整除不够,还得看它是不是 100 的倍数、是不是 400 的倍数。闰年判断工具把这三个余数直接摆出来,遇到 1900、2100 这类年份时不用在脑子里绕。
三个真实场景:一是算 2 月最后一天——做账、对账、算季度报表时,2 月 28 日和 29 日差一天,金额与工时都会差;二是校验表单里的出生日期——用户填 1900-02-29 时要能当场告诉他「1900 年 2 月没有 29 日」,而不是存进去后由数据库报错;三是预排两年后的排班表——2028 年 2 月有 29 天,2 月底的班次数量和 2027 年不同。
本页只判公历(格里高利历)闰年,不涉及农历闰月(农历的闰月规则完全不同,由 astronomical 计算确定)、也不涉及犹太历等其它历法。要在公历与农历之间换算请用农历公历转换;要查某个月的天数请用天月计算器;本页一次给你 2 月天数与全年天数,但重点是年份本身的判定。
原理与规则说明:三个取模与它们的历史来源
- 判定式:
(y % 4 === 0 && y % 100 !== 0) || y % 400 === 0。三个条件用||与&&组合,短路求值:先看能不能被 4 整除,不能就直接判平年,省掉后两次取模。 - 为什么 4 是起点:地球绕太阳一圈的实际时长约 365.2422 天,比 365 天多出约 0.2422 天。一年多出 0.2422 天,累积 4 年就是 0.9688 天——不到 1 天,所以每 4 年补一天最省事。这条「4 年一闰」就是儒略历的做法,公元前 45 年由儒略大帝确立,是格里高利历的直接前身。
- 为什么加 100 条例外:按 4 年一闰,一百年会多补 25 天,而实际需要补的只有约 24.22 天,多出来约 0.78 天。误差在 128 年累积成整天之后,日历上的季节就漂了。格里高利十三世 1582 年 2 月 24 日颁布
Inter gravissimas训令,把「100 的倍数不闰」写进正题。 - 为什么 400 年又补回来:砍掉 100 的倍数后,一百年只补 24 天,又少补了约 0.22 天,四百年累积约 0.88 天,仍接近 1 天。所以再加一条:400 的倍数照样闰。这条把平均年长精确锁定在
365 + 97/400 = 365.2425天,实测 400 年总长 146097 天,与太阳年误差不到 1 天。 - 遵循的标准:格里高利历规则由 ISO 8601《日期和时间》以及各国历法标准采纳;公历在中国对应 GB/T 7408—2005《数据元和交换格式 信息交换 日期和时间表示法》。这套规则在 1582 年 10 月 15 日正式生效——10 月 4 日的第二天直接是 10 月 15 日,中间 10 天被跳过。
- 400 年周期的实际后果:实测 2000 至 2399 这 400 年里闰年 97 个(100 个 4 的倍数,剔除 4 个 100 的倍数,补回 1 个 400 的倍数)。而 146097 天恰好是 20871 整周,所以 400 年后同一个日期的星期完全不变——这是400 年日历能循环复用的数学基础。
- 不能用 Date 构造来判闰年:这是实测出来的坑。
new Date(Date.UTC(1900, 1, 29))不会报错,而是静默归一化成1900-03-01,因为 1900 年 2 月只有 28 天,多出来的 1 天被推到 3 月。所以正确写法是自己取模,或者反过来校验——构造后回读getUTCDate()是否仍等于 29,不等就说明那天不存在。
完整示例(数值仅作演示)
示例条件与工具默认值一致:判断年份 2026,对照基准年 2024。
2026 % 4 = 2,不为 0,第一个条件就不成立 → 平年。后两次取模分别是2026 % 100 = 26、2026 % 400 = 26,第二条件也不成立。- 平年 2 月 28 天,全年 365 天。365 = 52 × 7 + 1,所以 2026 年 1 月 1 日是周四。
- 对照基准年 2024:
2024 % 4 = 0且2024 % 100 = 24(不为 0)→ 闰年,2 月 29 天,全年 366 天。 - 两年相差 2 年,其中闰年 1 个(2024),2 月 29 日出现 1 次。这正是排班、账期这类跨年计算要看的数。
- 换成 2025 对比:
2025 % 4 = 1→ 平年。从 2024 到 2025 同一个日期星期要 +2(因为 2024 是 366 天),从 2025 到 2026 只需 +1。
星期与天数为公历确定性推算结果,不含任何节假日或调休信息。
输入范围与对照表
输入范围:年份 1 ~ 9999 的正整数,min="1" max="9999" step="1"。0 年在格里高利历中不存在(ISO 8601 从 1 起算),不作为合法输入。下表是 2024 至 2047 年的逐年判定,前 12 行直接显示。
| 年份 | 余数 %4 | 余数 %100 | 余数 %400 | 结论 | 2 月天数 | 全年天数 | 1 月 1 日 |
|---|---|---|---|---|---|---|---|
| 2024 | 0 | 24 | 24 | 闰年 | 29 | 366 | 周一 |
| 2025 | 1 | 25 | 25 | 平年 | 28 | 365 | 周三 |
| 2026 | 2 | 26 | 26 | 平年 | 28 | 365 | 周四 |
| 2027 | 3 | 27 | 27 | 平年 | 28 | 365 | 周五 |
| 2028 | 0 | 28 | 28 | 闰年 | 29 | 366 | 周六 |
| 2029 | 1 | 29 | 29 | 平年 | 28 | 365 | 周一 |
| 2030 | 2 | 30 | 30 | 平年 | 28 | 365 | 周二 |
| 2031 | 3 | 31 | 31 | 平年 | 28 | 365 | 周三 |
| 2032 | 0 | 32 | 32 | 闰年 | 29 | 366 | 周四 |
| 2033 | 1 | 33 | 33 | 平年 | 28 | 365 | 周六 |
| 2034 | 2 | 34 | 34 | 平年 | 28 | 365 | 周日 |
| 2035 | 3 | 35 | 35 | 平年 | 28 | 365 | 周一 |
| 2036 | 0 | 36 | 36 | 闰年 | 29 | 366 | 周二 |
| 2037 | 1 | 37 | 37 | 平年 | 28 | 365 | 周四 |
| 2038 | 2 | 38 | 38 | 平年 | 28 | 365 | 周五 |
| 2039 | 3 | 39 | 39 | 平年 | 28 | 365 | 周六 |
| 2040 | 0 | 40 | 40 | 闰年 | 29 | 366 | 周日 |
| 2041 | 1 | 41 | 41 | 平年 | 28 | 365 | 周二 |
| 2042 | 2 | 42 | 42 | 平年 | 28 | 365 | 周三 |
| 2043 | 3 | 43 | 43 | 平年 | 28 | 365 | 周四 |
| 2044 | 0 | 44 | 44 | 闰年 | 29 | 366 | 周五 |
| 2045 | 1 | 45 | 45 | 平年 | 28 | 365 | 周日 |
| 2046 | 2 | 46 | 46 | 平年 | 28 | 365 | 周一 |
| 2047 | 3 | 47 | 47 | 平年 | 28 | 365 | 周二 |
四个世纪年的具体判定——这四个是「4 年一闰」直觉最容易出错的地方:
| 年份 | 被 4 整除 | 被 100 整除 | 被 400 整除 | 结论 | 2 月 29 日 | 儒略历结论 |
|---|---|---|---|---|---|---|
| 1900 | 是 | 是 | 否 | 平年 | 不存在 | 闰年(差 13 天) |
| 2000 | 是 | 是 | 是 | 闰年 | 存在 | 闰年 |
| 2100 | 是 | 是 | 否 | 平年 | 不存在 | 闰年(差 14 天) |
| 2400 | 是 | 是 | 是 | 闰年 | 存在 | 闰年 |
「差 13 天 / 14 天」指该年公历与儒略历的日期偏移量,按 floor(y/100) − floor(y/400) − 2 估算,是解释「为什么旧历书上的日期对不上现代日历」的依据。
边界与精度
- 输入硬边界 1 ~ 9999:填 0、负数、小数或非数字时,页面会指出是「判断年份」还是「对照基准年」超界、允许范围是多少,不会静默当成 0 处理。0 年在格里高利历中不存在,ISO 8601 明确从 1 起算,所以下界取 1 而不是 0。
- 2 月天数的取法:不做
new Date(y, 1, 29)这类构造(会静默溢出到 3 月),而是用Date.UTC(y, 2, 1) − Date.UTC(y, 1, 1)直接算 2 月实际天数,再由结果反推 28 或 29。闰年 2 月 29 天,平年 28 天,差 1 天 = 24 小时。 - 星期的计算口径:用
Date.UTC(y, 0, 1).getUTCDay()取 1 月 1 日的星期,索引 0 是周日。必须用getUTCDay()而非getDay()——后者按浏览器所在时区算,跨时区访问同一页面会得到不同结果。这是本页所有日期计算统一用 UTC 的原因。 - 1 月 1 日星期的年差规律:平年 365 = 52 × 7 + 1,同一日期下一年 +1 天;闰年 366 = 52 × 7 + 2,+2 天。实测 2024 年 1 月 1 日是周一,2025 年是周三(+2),2026 年是周四(+1)——这也解释了为什么闰年会让全年星期整体错开一格。
- 400 年循环的精确性:400 年 146097 天 = 20871 整周,闰年 97 个,因此格里高利历在 400 年后与太阳年的总偏差可以忽略。这也是为什么 2 月 29 日的存在与否在 400 年周期内完全可预测,而历法软件可以直接内建一张 400 年闰年表,不必每次重算。
- 不覆盖的范围:本页不处理 1582 年 10 月 5 日至 14 日这 10 天(格里高利历推行时跳过,历史上并不存在这 10 个日期),也不处理格里高利历推行之前(1582 年 10 月 4 日及更早)的日期——那段时间各地实际使用的是儒略历或其它历法,日期与公历无法直接对应。输入 1 ~ 1582 的年份时,页面按公历规则给出结论,但那是「推算」而非「历史实况」。
常见问题
1900 年和 2000 年都被 4 和 100 整除,为什么一个平一个闰?
因为差别在 400 这条。1900 ÷ 400 = 4.75,不整除,所以按 100 的倍数排除,是平年;2000 ÷ 400 = 5,整除,补回闰年。规则是「被 100 整除时,还要再看能不能被 400 整除」,不是简单的一刀切。1900 年 2 月 28 日的第二天按公历直接是 3 月 1 日。
2100 年闰不闰?2100 年 2 月有 29 日吗?
平年,2 月只有 28 天,没有 2 月 29 日。2100 % 4 = 0、2100 % 100 = 0、2100 % 400 = 100,三个余数里前两个把它归入「100 的倍数」,第三个又不整除,所以被排除。整个 21 世纪只有 2000 一个闰年,2100 是本世纪最后一个需要特别当心的年份。
为什么会有 100 和 400 两条例外,直接 4 年一闰不行吗?
不行的。按 4 年一闰,一百年会多补 25 天,而实际只需要补约 24.22 天;多出的 0.78 天累积 128 年就成整天,季节会明显漂移。加 100 条例外后一百年只补 24 天,又少补约 0.22 天,所以再用 400 条例外补回来,最终平均年长锁定在 365.2425 天。这套修正是格里高利十三世在 1582 年训令里定的,两条例外各修掉一半误差,缺任何一条都不准。
用 JavaScript 的 new Date(2025, 1, 29) 判断闰年可以吗?
不可以,这是实测出来的静默错误。new Date(Date.UTC(1900, 1, 29)) 与 new Date(Date.UTC(2025, 1, 29)) 都不报错,而是直接返回 3 月 1 日——多余的天被归一化推走了。如果你的代码用「构造 2 月 29 日再读月份是不是 2」来判闰年,平年会被误判成闰年。正确做法是取模,或者构造后回读 getUTCDate() 确认还是 29。
闰年会影响一年 52 周还是 53 周吗?
会。ISO 8601 定义 week-based year 时,一周从星期一开始,属于同一周年的只有前 4 天含 1 月 4 日的那一周。这种定义下 53 周的年份数量是 71 个而不是 74 个,闰年不能简单对应「多一天就多一周」。本页给的是「1 月 1 日是星期几」这个基础事实,需要按周次排期请用周数字计算器。
农历也有闰月,规则和公历一样吗?
完全不一样。农历的闰月由朔望月与回归年的差决定,一个回归年约 12.368 个朔望月,累积到第 7 个闰月时插入一次,19 年内插入 7 个闰月。这不是「按 4 或 400 整除」的规则,没有取模可套。闰年判断工具只管公历,农历闰月查询请用农历公历转换。
格里高利历和儒略历差在哪天?我手上的老日历该怎么对?
差值按 floor(y/100) − floor(y/400) − 2 估算:1600 年差 10 天、1700 年差 11 天、1800 年差 12 天、1900 年差 13 天、2000 年差 13 天、2100 年差 14 天。所以 1900 年以前的公历日期,在 1582 年 10 月 15 日之后与当时实际使用的儒略历日期并不对应。查具体某天的历法换算请用农历公历转换。
这个工具免费吗?输入的年份会上传吗?
免费,无需注册。判定用的是三个取模运算,星期与天数用 Date.UTC() 在浏览器本地算完,页面不发任何网络请求,可以在开发者工具的 Network 面板里连点几次「判断是否闰年」确认请求列表始终为空。年份不写 Cookie、不写本地存储,刷新即清空。