You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将UTC字符串解析为std::chrono::utc_clock::time_point?

UTC字符串解析为std::chrono::utc_clock::time_point的问题与解决方法

问题场景

给定UTC格式的字符串(如"2023-12-02 01:22:36.675349139 +00:00:00"),尝试解析为std::chrono::utc_clock::time_point时,结果总是出现时区偏移(本地时区为+9h,结果偏移-9h),使用的代码如下:

// 给定的字符串始终为UTC格式
//"2023-12-02 01:22:36.675349139 +00:00:00"

std::istringstream ss(j.get<std::string>());
std::tm t = {};
ss >> std::get_time(&t, "%Y-%m-%d %H:%M:%S");

// 转换为time_point
long timeSinceEpoch = std::mktime(&t);
auto duration = std::chrono::seconds(timeSinceEpoch);
time_point = std::chrono::utc_clock::time_point(duration);
std::cout << "time_point: " << time_point << std::endl;

偏移原因

偏移出在std::mktime函数上:

  • std::get_time只是按格式把字符串解析到std::tm结构体里,不会处理时区,此时tm存储的就是UTC时间的各个字段。
  • 但std::mktime的设计逻辑是把传入的std::tm当作本地时间,它会自动将这个"本地时间"转换为UTC时间戳。相当于你输入的UTC时间被当成了本地时间,再转一次UTC,自然会出现和本地时区相反的偏移。

简便可靠的解决方法

C++20及以上版本(优先推荐)

C++20的<chrono>库原生支持UTC时间字符串解析,不用手动处理时区,代码简洁且无歧义:

#include <chrono>
#include <string>
#include <iostream>

int main() {
    std::string utc_str = "2023-12-02 01:22:36.675349139 +00:00:00";
    // 直接解析为utc_clock的time_point,支持纳秒精度
    auto tp = std::chrono::parse("%Y-%m-%d %H:%M:%S.%f %z", utc_str, std::chrono::utc_clock::time_point{});
    std::cout << "time_point: " << tp << std::endl;
    return 0;
}
  • %z格式符专门用来解析时区偏移(示例中的+00:00:00),std::chrono::parse会自动根据时区信息调整到正确的UTC时间点。
  • 原生支持高精度时间(比如示例里的纳秒部分),不需要额外处理。

C++20以下版本

如果无法升级到C++20,有两种替代方案:

方案1:用timegm替代mktime

timegm是POSIX标准函数(部分编译器支持),它的逻辑是把std::tm当作UTC时间直接转换为epoch时间戳,完美匹配需求:

std::istringstream ss(j.get<std::string>());
std::tm t = {};
ss >> std::get_time(&t, "%Y-%m-%d %H:%M:%S");
// timegm将tm视为UTC时间,直接生成正确的epoch时间戳
long timeSinceEpoch = timegm(&t);
auto duration = std::chrono::seconds(timeSinceEpoch);
auto time_point = std::chrono::utc_clock::time_point(duration);
std::cout << "time_point: " << time_point << std::endl;

方案2:手动修正时区偏移

如果不能用timegm,可以先计算本地时区与UTC的偏移量,再修正mktime的结果:

std::istringstream ss(j.get<std::string>());
std::tm t = {};
ss >> std::get_time(&t, "%Y-%m-%d %H:%M:%S");

// 计算本地时区与UTC的偏移量
std::tm local_tm = t;
time_t local_epoch = mktime(&local_tm);
std::tm utc_tm = *gmtime(&local_epoch);
long offset = mktime(&local_tm) - mktime(&utc_tm);

// 修正时间戳得到正确的UTC epoch值
long timeSinceEpoch = mktime(&t) - offset;
auto duration = std::chrono::seconds(timeSinceEpoch);
auto time_point = std::chrono::utc_clock::time_point(duration);
std::cout << "time_point: " << time_point << std::endl;

内容的提问来源于stack exchange,提问作者Nathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:27:12