如何通过strptime()获取std::time_t?C++ UTC时间转Epoch秒
将UTC时间字符串转换为Epoch秒(time_t)
你遇到的核心问题是:strptime解析出的UTC时间tm结构,不能直接用mktime转换(因为mktime默认把tm当作本地时间处理),而gmtime是反向操作(从time_t转UTC的tm)。下面是两种可行的解决方案:
方法一:使用timegm(推荐,多数类Unix系统支持)
timegm是gmtime的逆函数,它直接把UTC时区的tm结构转换为time_t(即自Epoch以来的UTC秒数),完全忽略本地时区设置。
示例代码:
#include <iostream> #include <string> #include <ctime> int main() { std::string my_time_str("2022-08-24 11:09:24"); struct tm tim = {}; // 初始化所有字段为0 // 解析UTC时间字符串到tm结构 if (!strptime(my_time_str.c_str(), "%Y-%m-%d %H:%M:%S", &tim)) { std::cerr << "时间解析失败" << std::endl; return 1; } // 将UTC的tm转换为time_t(Epoch秒) time_t epoch_sec = timegm(&tim); if (epoch_sec == -1) { std::cerr << "转换time_t失败" << std::endl; return 1; } std::cout << "Epoch秒: " << epoch_sec << std::endl; return 0; }
注意:timegm是GNU扩展,不属于C标准,但Linux、BSD、macOS等多数类Unix系统都支持。
方法二:临时修改时区(标准C兼容,适用于所有系统)
如果你的环境不支持timegm(比如Windows),可以临时将程序的时区设置为UTC,再用mktime转换,之后恢复原时区。
示例代码:
#include <iostream> #include <string> #include <ctime> #include <cstdlib> int main() { std::string my_time_str("2022-08-24 11:09:24"); struct tm tim = {}; if (!strptime(my_time_str.c_str(), "%Y-%m-%d %H:%M:%S", &tim)) { std::cerr << "时间解析失败" << std::endl; return 1; } tim.tm_isdst = 0; // 明确禁用夏令时(UTC无夏令时) // 保存原时区设置 char* old_tz = getenv("TZ"); // 设置时区为UTC setenv("TZ", "", 1); tzset(); // 使时区设置生效 // 此时mktime会把tm当作UTC时间处理 time_t epoch_sec = mktime(&tim); // 恢复原时区 if (old_tz != nullptr) { setenv("TZ", old_tz, 1); } else { unsetenv("TZ"); } tzset(); if (epoch_sec == -1) { std::cerr << "转换time_t失败" << std::endl; return 1; } std::cout << "Epoch秒: " << epoch_sec << std::endl; return 0; }
关键说明
strptime只会填充格式字符串中指定的字段(比如年、月、日、时、分、秒),其他字段(如tm_wday、tm_yday)会保留初始化的值,所以务必初始化tm为全0。mktime的默认行为是将输入的tm视为本地时间,因此直接用它转换UTC的tm会得到错误结果。gmtime的作用是把time_t(UTC秒数)转换为UTC的tm结构,和你需要的转换方向相反,所以不能用来解决当前问题。
内容的提问来源于stack exchange,提问作者intrigued_66
相关产品推荐
相关产品推荐

