c++20中获取今天日期最轻量可靠的方式是用std::chrono::system_clock::now()获取时间点,floor截断到当日零点,再用year_month_day拆解年月日。

用 std::chrono::system_clock 获取今天日期(年月日)
直接取当前时间点再转换成本地日历日期,是 C++20 最轻量、最可靠的方式。别用 time() + localtime(),那套老接口不保证线程安全,且无法直接对接 std::chrono 类型。
关键步骤:先用 std::chrono::system_clock::now() 拿时间点,再通过 std::chrono::floor<:chrono::days></:chrono::days> 截断到当日零点,最后用 std::chrono::year_month_day 拆解:
#include <chrono>
#include <iostream>
int main() {
using namespace std::chrono;
auto now = system_clock::now();
auto today = year_month_day{floor<days>(now)};
std::cout (today.month()) (today.day())
<ul>
<li>
<code>floor<days>(now)</days></code> 是必须的——它把毫秒级时间点“归零”到当天 00:00:00,否则 <code>year_month_day</code> 构造可能跨天(比如系统时钟刚好在 23:59:59.999 时取值)</li>
<li>
<code>month()</code> 和 <code>day()</code> 返回的是 <code>month</code> / <code>day</code> 类型,不能直接流输出,得转成 <code>unsigned</code>
</li>
<li>这个结果是 UTC 时间对应的日历日期;若需本地时区,得先用 <code>std::chrono::current_zone()</code> 转换(见下节)</li>
</ul>
<h3>获取本地时区下的“今天”要额外转换</h3>
<p><code>system_clock</code> 的时间点本质是 UTC,<code>year_month_day</code> 默认按 UTC 解析。想得到你所在时区的“今天”,不能只靠 <code>std::chrono::current_zone()</code> —— 它返回的是运行时默认时区对象,但必须手动把时间点从 UTC 映射过去:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill2659" title="C++"><img
src="https://img.php.cn/upload/skill/000/000/081/178927213426672.jpg" alt="C++" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill2659" title="C++" class="overflowclass">C++</a>
<p class="overflowclass">"空空如也"</p>
</div>
<a rel="nofollow" href="/xiazai/skill2659" title="C++" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<pre class="brush:php;toolbar:false;">auto now = system_clock::now();
auto zoned = current_zone()->to_local(now);
auto today_local = year_month_day{floor<days>(zoned)};</days>
- 漏掉
to_local()直接对now取floor<days></days>,结果仍是 UTC 日期,不是你电脑设置的本地日期 -
current_zone()可能返回nullptr(如时区数据库未加载),生产环境应判空 - Windows 上需链接
tzdb库(CMake 中加target_link_libraries(... PRIVATE tzdb)),否则current_zone()恒为nullptr
格式化成字符串推荐用 std::format(C++20)
手拼 year()/month()/day() 容易出错,尤其补零问题。C++20 原生支持 std::format,简洁又安全:
auto today = year_month_day{floor<days>(system_clock::now())};
std::string s = std::format("{:%Y-%m-%d}", today); // 输出如 "2024-06-12"</days>
-
{:%Y-%m-%d}是标准 strftime 格式,%Y四位年,%m补零月,%d补零日 - 注意:MSVC 2022 17.5+、GCC 13+、Clang 15+ 才完整支持
std::format;旧编译器会编译失败 - 如果不用
std::format,就老实用std::ostringstream+std::setfill('0'),别自己写 sprintf 风格拼接
别踩 std::chrono::utc_clock 的坑
看到 “UTC” 就以为能直接拿今天日期?错。UTC 时间点和日历日期是两回事:utc_clock 的时间点仍需 floor 到 days 单位才能转 year_month_day,而且它的 epoch 和 system_clock 不同,直接混用会出错。
- 除非你在做高精度天文或金融时间计算,否则一律用
system_clock—— 它是 C++ 标准规定的“系统实时时钟”,语义清晰 -
utc_clock主要用于协调世界时与闰秒同步,日常业务完全不需要 - 所有示例里出现的
floor<days>(...)</days>都不可省略,这是从时间点到日历日期的必要转换,不是可选项
真正麻烦的从来不是怎么写,而是搞清“今天”到底指哪个时区、要不要考虑夏令时、以及 floor 操作是否被遗漏——这几个点卡住,代码跑出来永远差一天。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










