C++使用%d%m%y格式将字符串转为std::time_t不生效问题求助
问题成因
- 未初始化
std::tm结构体:你定义的tm变量没有做初始化清零操作,结构体内部除了std::get_time写入的字段外,其余字段(如tm_isdst夏令时标记、tm_hour/tm_min/tm_sec时间字段等)都是随机的无效值,mktime校验到非法字段就会返回-1。 - 未校验解析状态:你没有判断
std::get_time是否解析成功,如果输入流解析失败(比如格式不匹配、本地locale影响解析规则),tm结构体的字段值是无效的,也会导致mktime返回错误。 - 格式串与输入顺序不匹配(可选):如果你预期解析的
191121是2019年11月21日,那当前的%d%m%y格式串是完全错误的,该格式会把前两位当日期、中间两位当月份、最后两位当年份,最终得到的是2021年11月19日,如果不符合你的预期也会出现逻辑错误。
解决方法
- 初始化
std::tm结构体,保证所有字段初始为合法值,也可额外显式设置tm.tm_isdst = -1,让mktime自动判断夏令时状态,适配不同时区场景 - 增加
std::get_time的解析状态校验,确认解析成功后再调用mktime - 确认格式串和输入字符串的顺序匹配
正确示例代码:
#include <sstream> #include <iomanip> #include <ctime> #include <iostream> int main() { struct std::tm tm = {}; // 零初始化所有字段 tm.tm_isdst = -1; // 让mktime自动判断夏令时 std::istringstream stringStream("191121"); // 如果预期是年-月-日顺序,把格式串改成"%y%m%d"即可 stringStream >> std::get_time(&tm, "%d%m%y"); if (stringStream.fail()) { std::cout << "日期解析失败" << std::endl; return 1; } std::time_t time = mktime(&tm); std::cout << "解析得到的时间戳:" << time << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者Mathieu Poulin
相关产品推荐
相关产品推荐

