Qt+C+++SQLite:字符串格式时间列的AVG与SUM计算异常问题
解决方案
1. 替换strftime,用Qt的QTime解析时间字符串转秒数
strftime是用于格式化时间结构体的工具,不能直接解析HH:mm:ss格式的字符串,这是你出现异常数值的核心原因。改用Qt原生的QTime类处理,适配性和准确性更强:
// 解析HH:mm:ss为整数秒数 int timeStrToSec(const QString& timeStr) { QTime time = QTime::fromString(timeStr, "HH:mm:ss"); if (!time.isValid()) { // 处理无效格式,比如返回0或根据业务抛出异常 return 0; } return time.hour() * 3600 + time.minute() * 60 + time.second(); } // 如果需要支持带小数的秒(如HH:mm:ss.zzz),用这个版本 double timeStrToSecDouble(const QString& timeStr) { QTime time = QTime::fromString(timeStr, "HH:mm:ss.zzz"); if (!time.isValid()) { return 0.0; } return time.hour() * 3600.0 + time.minute() * 60.0 + time.second() + time.msec() / 1000.0; }
2. 计算SUM和AVG
假设你已从数据库取出所有FlightTime字符串,直接累加计算:
// 示例:从数据库获取所有FlightTime数据 QStringList flightTimeList = queryFlightTimes(); // 自行实现数据库查询逻辑 // 计算总秒数 double totalSec = 0.0; for (const QString& t : flightTimeList) { totalSec += timeStrToSecDouble(t); } // 计算平均秒数(避免除以0) double avgSec = 0.0; if (!flightTimeList.isEmpty()) { avgSec = totalSec / flightTimeList.size(); }
3. 将秒数转换为目标展示格式
写两个工具函数分别生成两种格式的结果:
// 转换为HH:mm:ss格式(支持超过24小时的时长,如30小时显示30:00:00) QString secToHHmmss(double seconds) { int totalIntSec = qRound(seconds); // 四舍五入到整数秒 int hours = totalIntSec / 3600; int remain = totalIntSec % 3600; int mins = remain / 60; int secs = remain % 60; return QString("%1:%2:%3").arg(hours, 2, 10, QChar('0')) .arg(mins, 2, 10, QChar('0')) .arg(secs, 2, 10, QChar('0')); } // 转换为"X hrs,Y min,Z sec"可读格式 QString secToHumanReadable(double seconds) { int totalIntSec = qRound(seconds); int hours = totalIntSec / 3600; int remain = totalIntSec % 3600; int mins = remain / 60; int secs = remain % 60; QStringList parts; if (hours > 0) parts.append(QString("%1 hrs").arg(hours)); if (mins > 0) parts.append(QString("%1 min").arg(mins)); if (secs > 0 || parts.isEmpty()) parts.append(QString("%1 sec").arg(secs)); return parts.join(", "); }
4. 输出到QTextBrowser
直接将转换后的字符串插入控件:
QTextBrowser* textBrowser = ...; // 你的QTextBrowser实例 textBrowser->append(QString("总和(HH:mm:ss):%1").arg(secToHHmmss(totalSec))); textBrowser->append(QString("总和(可读格式):%1").arg(secToHumanReadable(totalSec))); textBrowser->append(QString("平均值(HH:mm:ss):%1").arg(secToHHmmss(avgSec))); textBrowser->append(QString("平均值(可读格式):%1").arg(secToHumanReadable(avgSec)));
关键注意事项
- 必须校验时间字符串有效性:数据库中可能存在不符合HH:mm:ss格式的数据,解析时通过
time.isValid()判断,避免计算错误。 - 平均值小数处理:如果需要更高精度,可以保留小数秒(比如不使用
qRound,直接拆分毫秒部分),但业务要求的两种格式均为整数单位,四舍五入到秒即可。
内容的提问来源于stack exchange,提问作者FsxRwt
相关产品推荐
相关产品推荐

