引言
QDateTime
是Qt框架中用于处理日期和时间的类,它结合了QDate和QTime的功能,可以表示从公元1年1月1日到公元9999年12月31日的日期和时间。QDateTime支持时区转换、时间戳操作、日期时间格式化等功能,适用于需要同时处理日期和时间的场景。QTime
是Qt中专门处理时间的类,仅表示一天内的时间(小时、分钟、秒、毫秒),不包含日期信息。适用于需要独立处理时间的场景,支持计算时间差,可判断时间是否有效 (isValid)。
一、问题描述
- 打印一个QDateTime,时间部分显示为全0,经调试QTime显示无效,时间未赋值成功,问题如下所示:
- 问题原因为QTime赋值错误,超过其可表示的范围,可稳定复现的代码如下所示:
#include <QCoreApplication>
#include <QDateTime>
#include <QTime>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTime time;
quint32 ms = 1000000;
qDebug() << time.setHMS(1, 1, 1, ms);
qDebug() << time;
QDateTime dt = QDateTime::currentDateTime();
dt.setTime(time);
qDebug()<<dt;
return a.exec();
}
二、解决方案
-
- 需在赋值前手动判断数值范围是否正确
-
- 根据赋值函数的返回值或
isValid()
判断时间是否有效
- 根据赋值函数的返回值或
-
官方文档:
三、深入源码
-
setHMS
函数,就是把时分秒都转为毫秒存储起来. 只有是否有效的检测,其中NullTime = -1
。
bool QTime::setHMS(int h, int m, int s, int ms)
{
if (!isValid(h,m,s,ms)) {
mds = NullTime; // make this invalid
return false;
}
mds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
return true;
}
-
isValid
将输入转为uint
,再看取值是否符合实际范围.
bool QTime::isValid(int h, int m, int s, int ms)
{
return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
}
四、参考链接
对QDateTime进行操作,使QDateTime::isNull() ==true:https://blog.csdn.net/xie__jin__cheng/article/details/146903868
QDateTime修改时区导致时间戳不对的坑:https://blog.csdn.net/doujianyoutiao/article/details/147953902
QDateTime类在C++中的应用与深度解析:https://blog.csdn.net/qq_21438461/article/details/132927850