QDateTime.time()精确度的“坑”

介绍

从Qt的帮助文档中可以看到,QDateTime提供了获取日期和时间的方法等。是QDate和QTime这两个类的组合。可以从当前系统获取时间,也可以进行增减时间,如秒、天、月、年。具体不再赘述,可以直接查看帮助文档。

QTime QDateTime::time() const

帮助文档中描述这个函数的作用是“Returns the time part of the datetime.”,即datetime中的时间部分,datetime包含年、月、日、时间(时刻),分别有不同的函数可以获取。函数作用描述得十分简洁。
但是如果用这个函数获取出来的QTime和一个定好的时间的QTime比较得话,会发现二者总是不相等。
例如:使用一个每秒刷新一次的函数来计时,判断是否到达“闹钟时间”。如下代码:

void Widget::updateTime()
{
    m_currentDateTime = QDateTime::currentDateTime();

    m_currentTimeLabel->setText(m_currentDateTime.toString());

    QDateTime targetTime = QDateTime::currentDateTime();
    targetTime.setTime(QTime(23, 26, 0));

    if (m_currentDateTime.time() == targetTime.time()) {
        qDebug() << "闹钟响了";
    }
    else {
        qDebug() << "闹钟时间未到";
    }
}

最终的测试效果发现“闹钟”并没有响。
原因是这个函数获取出来的QTime是默认将毫秒转换进去了,因此导致比较总是不相等。
查看源码,也可以发现比较明显的信息:
QDateTime.time()精确度的“坑”_第1张图片
从上图可以看出在转化的时候调用了一个msecsToTime()的函数,将毫秒转换为QTime。
QDateTime.time()精确度的“坑”_第2张图片
由于只是比较时间(精确到秒)的值是否相等,精确度要求不高,没有考虑到毫秒级,因此比较方便的方法是直接比较time().toString(),这样子它会转化为QString类型进行比较,而参数可以决定具体的形式(精确度)。如图所示:
QDateTime.time()精确度的“坑”_第3张图片
而toString()的默认参数是Qt::TextDate,只精确到秒。

void Widget::updateTime()
{
    m_currentDateTime = QDateTime::currentDateTime();

    m_currentTimeLabel->setText(m_currentDateTime.toString());

    QDateTime targetTime = QDateTime::currentDateTime();
    targetTime.setTime(QTime(23, 31, 0));

    //这里增加了toString()的转换
    if (m_currentDateTime.time().toString() == targetTime.time().toString()) {
        qDebug() << "闹钟响了";
    }
    else {
        qDebug() << "闹钟时间未到";
    }
}

最终的时间比对是正常的:
QDateTime.time()精确度的“坑”_第4张图片

你可能感兴趣的:(Qt)