应直接使用 DateTime.IsLeapYear(),它已封装公历全部闰年规则(含1900、2100等例外),比手写逻辑更可靠;需确保年份为1–9999之间的int,避免传入0、负数或超范围值引发ArgumentOutOfRangeException。

直接用 DateTime.IsLeapYear(),别自己写规则
它已经把公历所有闰年逻辑(包括1900、2100这种世纪年份的例外)封装好了,比手写 (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) 更可靠。自己实现容易漏掉边界:比如负数、0、超范围年份(DateTime 只支持 1–9999),而且优先级或括号写错就会出错。
DateTime.IsLeapYear() 的参数和异常要提前防住
它只接受 int 类型年份,不接受 DateTime 对象——想从日期取年份得先确保对象非空、有效,再调用 .Year:
- 传入
0、负数、或大于9999的值,会抛ArgumentOutOfRangeException - 别写
DateTime.IsLeapYear(someDate?.Year ?? 0)这种——?? 0会让非法年份悄悄变成 0,然后崩在方法里 - 正确做法是先校验:
if (year >= 1 && year ,再调用
别用 new DateTime(year, 2, 29) 反推闰年
这是性能差、意图模糊、还容易掩盖真实错误的典型反模式:
- 每次失败都走异常路径,实测 10 万次调用比
IsLeapYear()慢约 8ms - 抛出的都是
ArgumentOutOfRangeException,你分不清是“2 月 29 日不存在”,还是“年份本身非法(比如 -1 或 10000)” - 如果年份来自用户输入或数据库字段,没做前置校验就直接构造,程序可能在不该崩的地方崩掉
农历闰年完全不适用这个方法
DateTime.IsLeapYear() 固定按公历(格里高利历)算,返回 true 只代表“2 月有 29 天”,跟农历有没有闰月毫无关系。比如 2023 年公历不是闰年,但农历有闰二月;2000 年公历是闰年,农历却是平年。业务中若涉及节气、春节排班、合同跨农历年等,必须用 ChineseLunisolarCalendar 或可信第三方库,不能混用。
最容易被忽略的是年份来源——字符串解析、数据库读取、API 返回值,往往带空、超界或格式错误,直接喂给 IsLeapYear() 前不校验,等于把异常留到运行时才暴露。










