如何用年、月、日设置std::chrono::system_clock的time_point
UTC日期转std::chrono::time_point的正确实现
问题原因
你直接用years(y-1970) + months(m-1) + days(d-1)构造system_clock::time_point的方式错误。system_clock的时间点基于物理时长(从1970-01-01 UTC起的秒数/纳秒数),而years、months这类是日历时长,它们的实际长度随日期变化(比如闰年多一天、不同月份天数不同)。将日历时长直接转换为物理时长时会采用近似值,长期累加后就会出现你看到的时间偏差。
正确代码实现
要准确构造指定UTC日期的system_clock::time_point,需借助C++20的日历类型先构建准确的日期对象,再转换为系统时钟时间点:
#include <chrono> #include <format> #include <cstdio> using namespace std::chrono; void DisplayDate(int y, int m, int d) { // 构造UTC的年-月-日对象,确保日期有效性 year_month_day ymd{year(y), month(m), day(d)}; if (!ymd.ok()) { // 处理无效日期(比如2月30日) wprintf(L"Invalid date\n"); return; } // 转换为system_clock对应的UTC 00:00:00时间点 system_clock::time_point tp = sys_days{ymd}; // 输出UTC时间:使用utc_zone()确保显示UTC标准时间 std::wstring s = std::format(L"{:%Y-%m-%d %H:%M:%S}", zoned_time{utc_zone(), tp}); // 若需要输出本地时区时间,替换为zoned_time{current_zone(), tp} wprintf(s.c_str()); }
调用DisplayDate(2024,11,22)后,会输出2024-11-22 00:00:00,完全符合预期。
关键细节说明
year_month_day:C++20引入的强类型日历对象,能准确表示公历日期,自动处理闰年、月份天数等规则。sys_days:system_clock::time_point的别名,专门用于表示UTC日期对应的0点时间,是连接日历类型与系统时钟时间点的桥梁。- 时区处理:如果需要输出UTC时间,必须使用
utc_zone();若要输出本地时区的对应时间,保留current_zone()即可,但此时显示的是UTC 22日0点对应的本地时间。
内容的提问来源于stack exchange,提问作者Dominik Weber
相关产品推荐
相关产品推荐

