使用std::chrono计算两日期剩余天数的编译与运行错误排查
问题1:编译报错"expected unqualified-id before = token"的解决方案
报错原因
你代码里的typedef std::chrono::duration<int> tiempo;是给std::chrono::duration<int>定义了类型别名tiempo,而你后面直接写tiempo = end - now;是把类型名当成变量名赋值,属于基础语法错误,编译器自然无法识别。
此外你的代码还有三处隐藏问题:
- 当前时间转字符串用的格式符是
%Y-%m-%d %H:%M:%S(日期分隔符为横杠),但std::get_time解析用的格式符是%Y:%m:%d %H:%M:%S(日期分隔符为冒号),格式不匹配会导致解析完全失败 - 你已经通过
std::chrono::system_clock::to_time_t(now)拿到了当前时间的time_t值,后续又调用time (&now_c)会覆盖这个值,属于冗余无效操作 - 两个
system_clock时间点相减得到的差值单位是系统时钟的最小周期(通常是纳秒/微秒),直接赋值给duration<int>(默认单位是秒)会有精度截断问题,计算天数需要显式做单位转换
修复代码
void Silo::RevisarDiasRestantes(){ // 获取当前时间点 auto now = std::chrono::system_clock::now(); // 示例:从数据库取到的到期时间字符串,格式为yyyy-mm-dd HH:MM:SS std::string expire_str = "2025-12-31 23:59:59"; // 解析字符串到tm结构体 struct std::tm tm = {}; // 这里先用手动解析替代get_time,后面问题2会讲原因 int year, month, day, hour, minute, second; sscanf(expire_str.c_str(), "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second); tm.tm_year = year - 1900; // tm的年份是从1900年开始算的偏移量 tm.tm_mon = month - 1; // tm的月份范围是0-11 tm.tm_mday = day; tm.tm_hour = hour; tm.tm_min = minute; tm.tm_sec = second; tm.tm_isdst = -1; // 让mktime自动判断是否是夏令时 // 转成system_clock时间点 std::time_t expire_time = mktime(&tm); auto end = std::chrono::system_clock::from_time_t(expire_time); // 计算时间差,转成天 // C++20及以上可以直接用std::chrono::days using days = std::chrono::duration<int, std::ratio<86400>>; auto diff = std::chrono::duration_cast<days>(end - now); Log( "剩余到期天数: " + QString::number(diff.count())); }
问题2:std::istringstream配合std::get_time运行报错的替代方案
报错原因
这个错误常见于MinGW编译环境,是标准库运行时组件缺失/静态编译配置错误导致的,和你的代码逻辑无关。
替代方案
完全可以不用std::get_time和std::istringstream,直接用sscanf或者手动分割字符串提取年月日时分秒赋值给tm结构体即可,如上面修复代码里的写法,兼容性更强,也不会受locale影响导致解析失败。
内容的提问来源于stack exchange,提问作者lightshadown
相关产品推荐
相关产品推荐

