C++实现DDMMMYY日期转YYYYMMDD及get_time年份偏移问题解决
问题原因排查
- tm结构体的
tm_year成员定义为「实际年份减去1900」:你用%y解析两位数年份20后,tm_year的存储值为120(2020-1900),直接输出就会出现120的偏移。 - 未初始化tm结构体:你声明的tm结构体没有初始化成员值,内部未使用的字段(如夏令时标记
tm_isdst、时分秒等)是随机值,会导致mktime计算结果异常。 - locale不匹配风险:如果运行环境的默认locale不是英文,
%b无法正确解析英文月份缩写(如JUN),会导致解析失败。
修复后的完整实现
#include <iostream> #include <sstream> #include <iomanip> #include <ctime> #include <locale> int main() { // 初始化tm所有成员为0 struct std::tm tm = {}; std::istringstream ss("25JUN20"); // 指定C locale保证英文月份缩写可正常解析 ss.imbue(std::locale("C")); // 按格式解析日期 ss >> std::get_time(&tm, "%d%b%y"); // 校验解析是否成功 if (ss.fail()) { std::cout << "日期解析失败" << std::endl; return 1; } // 调用mktime补全tm结构体其他字段 std::mktime(&tm); // 转换为YYYYMMDD格式输出,注意补前导零 std::cout << std::setfill('0') << (tm.tm_year + 1900) // 加1900得到实际年份 << std::setw(2) << (tm.tm_mon + 1) // tm_mon从0开始计数,加1得到实际月份 << std::setw(2) << tm.tm_mday << std::endl; return 0; }
补充说明
- 两位数年份的解析规则:标准库默认将
%y解析的0069映射为20002069,7099映射为19701999,如果你的业务场景需要调整这个映射规则,可以手动修改tm_year的值后再调用mktime。 - 输入日期校验:如果需要兼容非法输入场景,可以在
get_time后判断ss.fail()状态做异常处理。
内容的提问来源于stack exchange,提问作者sparsh jain
相关产品推荐
相关产品推荐

