判断闰年需满足(能被4整除且不能被100整除)或能被400整除,如2000是闰年、1900不是;获取月份天数时2月须动态计算,其余月份用静态数组,并严格校验month范围1–12及year≥1。

判断闰年的正确逻辑不能只看能被4整除
很多人写 isLeapYear 时直接用 year % 4 == 0,结果2100年、1900年出错。公历闰年规则是:能被4整除但**不能被100整除**,或者**能被400整除**。漏掉后半条,世纪年份全算错。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 写成
(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0),别合并或简化 - 测试必须包含:2000(是闰年)、1900(不是)、2024(是)、2100(不是)
- 注意
year类型——用int足够,但避免传入负数或0(ISO日历无公元0年)
月份天数要单独处理2月,别硬套数组索引
常见错误是定义一个12元素的 daysInMonth 数组,然后直接 arr[month-1] 返回,却忘了2月得根据闰年动态算。数组只能存非2月的固定值。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 非2月:用静态数组
static const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - 2月:先调
isLeapYear(year),返回28或29 - 务必检查
month范围:1–12,越界直接返回-1或抛异常,别静默返回0
封装成函数时,输入校验比计算逻辑更重要
用户传 getDaysInMonth(2023, 13) 或 getDaysInMonth(-1, 5),函数不该返回31或崩溃,而应明确拒绝。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 开头立刻检查:
if (month 12) return -1; - 年份下限建议设为1(对应公元1年),上限可设9999(ISO 8601支持)
- 返回类型用
int即可,无需size_t——负数用于表示错误更直观 - 示例实现片段:
int getDaysInMonth(int year, int month) {
if (month < 1 || month > 12) return -1;
static const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month != 2) return days[month - 1];
return isLeapYear(year) ? 29 : 28;
}注意时区和日历系统带来的隐性陷阱
这个函数算的是**公历(格里高利历)** 天数,不适用于儒略历、农历或ISO周历。比如1752年英国改历那年9月有缺失日期,但普通业务场景无需处理——除非你在写历史天文软件。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 文档里明确写死“仅支持公历,1582年10月15日后有效”(格里高利历起始日)
- 不要试图兼容儒略历——那需要额外参数和复杂分支
- 如果项目需处理历史日期(如1700年前欧洲),直接用
boost::date_time或 C++20<chrono>的日历设施,别手写
实际用的时候,最常被忽略的是输入校验和世纪年份测试。写完立刻跑四个年份:2000、1900、2024、2100,再加一个 month=13,基本就稳了。


















