直接用 std::chrono::floor 获取当前时间到今天午夜的秒数最稳妥:先取 now(),再 floor 截断到当日零点,最后用 tomorrow 减 now 得 seconds;避免 localtime/mktime 因 dst 和闰秒导致错误。

如何用 std::chrono 获取当前到今天午夜的秒数
直接用 std::chrono 算最稳妥,不依赖 C 风格时间函数,也避开时区和夏令时陷阱。核心思路是:取当前时间点 → 截断到当天零点 → 相减得到 std::chrono::seconds。
注意别用 std::time(nullptr) 加手动计算,容易在跨月/闰秒/本地时区偏移上出错。
- 用
std::chrono::system_clock::now()获取当前时间点 - 用
std::chrono::floor<:chrono::days>(tp)</:chrono::days>截断到当日 00:00:00(UTC 时间语义,但对“今天午夜”在本地时区下仍可用,因system_clock通常对应本地 wall clock) - 相减后调用
.count()得到整型秒数
为什么不能直接用 localtime + 手动算小时分钟
看似简单,实则埋雷:比如 localtime 返回的 tm 结构里 tm_sec/tm_min/tm_hour 是“已归一化”的,但你得自己处理 tm_hour == 0 时是否真代表午夜(可能刚过 midnight,也可能还没到),而且 mktime 可能修正输入、引入歧义。
更麻烦的是 DST 切换日——比如凌晨 2:00 跳到 3:00,或回拨到 1:00,这时“今天午夜”可能根本不存在或重复,mktime 行为不可靠。
-
localtime+mktime组合在 DST 边界日可能返回 -1 或错误时间点 - 手动算
(24 - tm_hour) * 3600 - tm_min * 60 - tm_sec忽略了tm_sec可能为 60(闰秒),且没考虑tm_isdst对午夜定义的影响 - 所有基于
time_t的算术都隐含 UTC 偏移假设,而time_t本身不带时区信息
std::chrono::floor<:chrono::days></:chrono::days> 的实际行为
这个操作不是“四舍五入”,而是向下取整到最近的完整日期起点(即当天 00:00:00)。它作用于 system_clock::time_point,结果仍是 time_point,只是精度被截断。
关键点:它不转换时区,也不做任何本地化;system_clock 在大多数实现中对应 Unix epoch(UTC),但用户感知的“今天”是本地日历日。只要你的程序按本地时间理解“今天”,这个截断就符合直觉——因为 system_clock::now() 返回的时间点,在本地显示就是“现在”,而 floor<days></days> 就是把它掰回到本地日历的零点。
- 若需严格按 UTC 午夜算,应先转成
utc_clock(C++20),再 floor - 若程序部署在多个时区,且逻辑依赖“服务器本地今天”,保持用
system_clock即可 -
floor<days></days>比duration_cast<days></days>更安全:后者会丢精度,前者保留纳秒级剩余部分(只是归零)
一个可靠、可移植的 C++20 实现
下面这段代码在 GCC 11+、Clang 14+、MSVC 19.30+ 上都能跑,不需要第三方库:
auto now = std::chrono::system_clock::now();
auto today = std::chrono::floor<:chrono::days>(now);
auto until_midnight = today + std::chrono::days{1} - now;
std::cout <p>注意:这里用 <code>today + days{1}</code> 而不是 <code>today</code> 本身,是因为“到今天午夜”指的其实是“到**下一个**午夜”,也就是今天结束时刻。如果当前是 14:00,你要的是 10 小时后的秒数,不是倒退到今天 00:00。</p>
<p>如果你真要“距今天 00:00 过去了多少秒”,那就把最后一行改成 <code>now - today</code> —— 但标题明确是“到今天午夜”,所以是正向剩余时间。</p>
<p>真正容易被忽略的,是“午夜”这个词在业务逻辑里到底指哪一刻:是 00:00:00,还是 24:00:00?前者是日开始,后者是日结束。上面代码算的是到 24:00:00(即明天 00:00:00)的秒数,这也是绝大多数场景的真实需求。</p></:chrono::days>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











