不能直接用==、<、memcmp或逐字段比较std::tm,因其内存布局不保证连续、未初始化字段值不可靠、tm_wday/tm_yday未调用mktime()前无效,且忽略夏令时、闰年、月份天数等隐含规则;正确做法是先用mktime()将两个std::tm转为time_t再比较,注意处理返回-1的非法时间、避免原结构被修改、显式初始化所有字段并设tm_isdst = -1。

不能直接用 == 或 < 比较两个 std::tm 结构体——它们是普通 POD 结构,字段顺序和填充不确定,且 tm_wday、tm_yday 等字段由系统自动填充,未初始化时值不可靠。
为什么不能 memcmp 或逐字段比较 std::tm
std::tm 是 C 风格结构体,不保证内存布局连续;tm_isdst 为负时表示“未知”,不同实现可能填不同值;tm_wday 和 tm_yday 在未调用 mktime() 前是无效的(即使你手动设了 tm_year/tm_mon)。直接比较字段会漏掉夏令时逻辑、闰年校验、月份天数差异等隐含规则。
正确做法:先转成 time_t 再比较
唯一可移植、语义正确的比较方式是把两个 std::tm 都喂给 mktime(),得到对应的 time_t 值,再比较这两个整数:
-
mktime()会标准化输入(比如把tm_mon = 13自动进位到下一年)、填充tm_wday/tm_yday、根据本地时区和夏令时规则计算真实秒数 - 若某个
std::tm时间非法(如 2026-02-30),mktime()返回-1,需检查返回值避免误判 - 注意:
mktime()会就地修改传入的std::tm*,如果原结构要复用,先拷贝一份
常见错误场景与修复
容易忽略的点:
立即学习“C++免费学习笔记(深入)”;
- 没设
tm_isdst = -1:导致mktime()使用过时的夏令时假设,跨 DST 切换日比较结果出错 - 混用本地时间和 UTC 时间:一个用
localtime()解析,另一个用gmtime(),却都喂给mktime()——mktime()总是按本地时区解释,UTC 时间会被错误偏移 - 忘记清零未用字段:比如只设了
tm_hour/tm_min,但tm_sec是垃圾值,mktime()会把它当真实秒数参与计算
最稳妥的起点是:所有字段显式初始化为 0,再设置你需要的年月日时分秒,最后设 tm_isdst = -1,再调 mktime()。否则哪怕只是比个“今天 9 点”和“今天 10 点”,也可能因 tm_sec 随机值而错判。


















