判断某天是否为今年1月1日需同时校验年、月、日,仅month==1 && day==1不充分;C++20可用std::chrono::year_month_day,传统方式用struct tm注意tm_year+1900和tm_mon+1。

怎么用 C++ 判断某天是不是今年的 1 月 1 日
直接比对年份和月份日期即可,无需复杂计算。C++ 标准库 std::chrono(C++20 起)或传统 struct tm 都能快速提取年、月、日字段。
常见错误是只判断 month == 1 && day == 1,却忽略年份是否匹配当前年——比如传入 2023-01-01 但想判断“是否为 *2024 年* 的起始日”,必须显式校验年份。
- 用
std::chrono::year_month_day(C++20):先转成sys_days,再用floor<days></days>得到当天零点,然后 extracty.year()和ymd.month()/ymd.day() - 用
localtime+tm:注意tm_year是从 1900 开始的偏移,需加 1900;tm_mon是 0-based,所以 1 月对应0 - 若输入是字符串(如
"2024-01-01"),建议先用std::get_time或strptime解析,避免手撕字符串出错
怎么判断是否为本季度第一天(如 1/1、4/1、7/1、10/1)
季度起始日固定为每年的 1 月 1 日、4 月 1 日、7 月 1 日、10 月 1 日。核心是判断 month 是否属于 {1, 4, 7, 10},且 day == 1,同时年份与目标年一致。
容易踩的坑:把“本季度”误解为“当前系统时间所在季度的起始日”。例如系统时间是 2024-05-15,那么“本季度”指 2024-Q2 → 起始日是 2024-04-01;但如果函数参数是 2023-07-01,它确实是 Q3 起始日,但不是“2024 年本季度”的起始日——语义必须明确。
立即学习“C++免费学习笔记(深入)”;
- 推荐写一个辅助函数:
bool is_quarter_start(int y, int m, int d),内部用(m == 1 || m == 4 || m == 7 || m == 10) && d == 1 - 不要依赖
month / 3计算季度——整除在 1~3 月会得 0,需额外 +1,反而易错 - 注意时区:如果输入时间带时区信息(如 UTC 时间戳),转换为本地
tm前可能跨日,导致月/日错位
用 C++20 calendar 库做季度判断更安全吗
是的,std::chrono::year_month_day + std::chrono::year_month_weekday 可规避手动算月、处理闰年等低级错误,但要注意编译器支持度(GCC 12+、Clang 14+、MSVC 19.30+)。
典型误用:直接对 year_month_day 对象调用 .month() 返回的是 month 类型,不能直接和整数字面量比较,必须用 .month().operator int() 或 static_cast<int>(ymd.month())</int>。
- 正确写法:
int m = static_cast<int>(ymd.month());</int>,再判断m - 季度起始日可预定义为
std::array<:pair int>, 4>{{ {1,1}, {4,1}, {7,1}, {10,1} }}</:pair>,遍历比对 - 性能上无明显差异,但可读性和类型安全更好;若项目还停留在 C++17,别硬套 calendar,老老实实用
tm更稳
为什么不能只靠 mktime 返回值是否为 -1 来判断日期有效性
mktime 主要用于时间归一化(如把 2024-02-30 转成 2024-03-01),不是校验工具。它对无效日期(如 2024-13-01)可能仍返回合法时间戳,只是结果不可预测。
例如:tm.tm_mon = 12; tm.tm_mday = 1;(13 月 1 日)经 mktime 后变成 2025-01-01,但你原本想检测“这不是合法日期”,这就漏判了。
- 真正需要校验日期合法性时,应手动检查:
1 - 月份必须是 1–12;日必须在该年该月的有效范围内(考虑闰年)
- 若已用
mktime归一化过,再反向用localtime提取tm_mon/tm_mday,对比原始输入——不一致说明原输入非法
季度和年度起始日本身都是合法日期,但校验逻辑一旦泛化(比如封装成通用日期验证函数),这点就很容易被忽略。


















