日期与时间处理
# 04.日期与时间处理
# 目录介绍
- 4.1 时间类
- 4.1.1 QDate
- 4.1.2 QTime
- 4.1.3 QDateTime
- 4.1.4 QTimeZone
- 4.2 计时器
- 4.2.1 计时器分类
- 4.3 QTimer
- 4.3.1 基本用法
- 4.3.2 QTimer用法
- 4.3.3 QTimer作用
- 4.3.4 QTimer原理
- 4.3.5 高级用法
- 4.4 QElapsedTimer
- 4.4.1 基本用法
- 4.4.2 常用方法
- 4.5 QDeadlineTimer
- 4.5.1 基本用法
- 4.5.2 常用方法
# 4.1 时间类
Qt 提供了多个类用于处理日期、时间和时区,包括 QDate、QTime、QDateTime 和 QTimeZone。
- QDate:日期处理
- QTime:时间处理
- QDateTime:日期时间处理
- QTimeZone:时区支持
# 4.1.1 QDate
QDate 用于处理日期(年、月、日),不包含时间信息。
(1)基本用法
#include <QDate>
#include <QDebug>
int main() {
// 创建日期
QDate date(2023, 10, 5);
// 获取日期信息
qDebug() << "Year:" << date.year(); // 2023
qDebug() << "Month:" << date.month(); // 10
qDebug() << "Day:" << date.day(); // 5
// 格式化日期
qDebug() << "Formatted date:" << date.toString("yyyy-MM-dd"); // 2023-10-05
// 计算日期
QDate nextWeek = date.addDays(7);
qDebug() << "Next week:" << nextWeek.toString("yyyy-MM-dd"); // 2023-10-12
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(2)常用方法
isValid():检查日期是否有效。daysInMonth():返回当前月份的天数。daysInYear():返回当前年份的天数。dayOfWeek():返回星期几(1 = 星期一,7 = 星期日)。
# 4.1.2 QTime
QTime 用于处理时间(时、分、秒、毫秒),不包含日期信息。
(1)基本用法
#include <QTime>
#include <QDebug>
int main() {
// 创建时间
QTime time(14, 30, 45);
// 获取时间信息
qDebug() << "Hour:" << time.hour(); // 14
qDebug() << "Minute:" << time.minute(); // 30
qDebug() << "Second:" << time.second(); // 45
// 格式化时间
qDebug() << "Formatted time:" << time.toString("HH:mm:ss"); // 14:30:45
// 计算时间
QTime laterTime = time.addSecs(3600); // 增加 1 小时
qDebug() << "Later time:" << laterTime.toString("HH:mm:ss"); // 15:30:45
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(2)常用方法
isValid():检查时间是否有效。msecsSinceStartOfDay():返回从当天开始到当前时间的毫秒数。secsTo():计算两个时间之间的秒数差。
# 4.1.3 QDateTime
QDateTime 用于处理日期和时间,结合了 QDate 和 QTime 的功能。
(1)基本用法
#include <QDateTime>
#include <QDebug>
int main() {
// 创建日期时间
QDateTime dateTime(QDate(2023, 10, 5), QTime(14, 30, 45));
// 获取日期和时间信息
qDebug() << "Date:" << dateTime.date().toString("yyyy-MM-dd"); // 2023-10-05
qDebug() << "Time:" << dateTime.time().toString("HH:mm:ss"); // 14:30:45
// 格式化日期时间
qDebug() << "Formatted datetime:" << dateTime.toString("yyyy-MM-dd HH:mm:ss"); // 2023-10-05 14:30:45
// 计算日期时间
QDateTime laterDateTime = dateTime.addDays(1).addSecs(3600); // 增加 1 天和 1 小时
qDebug() << "Later datetime:" << laterDateTime.toString("yyyy-MM-dd HH:mm:ss"); // 2023-10-06 15:30:45
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(2)常用方法
isValid():检查日期时间是否有效。toTime_t():将日期时间转换为 Unix 时间戳。fromTime_t():从 Unix 时间戳创建日期时间。setTimeZone():设置时区(需要 Qt 5.2 及以上版本)。
# 4.1.4 QTimeZone
QTimeZone 用于处理时区信息,支持全球时区的转换和计算。
(1)基本用法
#include <QDateTime>
#include <QTimeZone>
#include <QDebug>
int main() {
// 创建时区
QTimeZone timeZone("America/New_York");
// 创建日期时间并设置时区
QDateTime dateTime(QDate(2023, 10, 5), QTime(14, 30, 45), timeZone);
// 转换为 UTC 时间
QDateTime utcDateTime = dateTime.toUTC();
qDebug() << "Local time:" << dateTime.toString("yyyy-MM-dd HH:mm:ss"); // 2023-10-05 14:30:45
qDebug() << "UTC time:" << utcDateTime.toString("yyyy-MM-dd HH:mm:ss"); // 2023-10-05 18:30:45
// 获取时区信息
qDebug() << "Time zone ID:" << timeZone.id(); // America/New_York
qDebug() << "Time zone offset:" << timeZone.offsetFromUtc(dateTime); // -14400 (秒)
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(2)常用方法
isValid():检查时区是否有效。offsetFromUtc():返回时区与 UTC 的偏移量(秒)。id():返回时区的 ID(如 "America/New_York")。availableTimeZoneIds():返回所有可用的时区 ID。
# 4.2 计时器
# 4.2.1 计时器分类
Qt 提供了多种计时器类,用于实现定时任务、高精度计时和截止时间管理。
QTimer:用于定时任务,支持周期性或单次触发。QElapsedTimer:用于高精度计时,适合测量代码执行时间。QDeadlineTimer:用于管理截止时间,适合超时控制。(Qt 6)
# 4.3 QTimer
QTimer 是一个定时器类,用于在指定的时间间隔触发信号。
QTimer 是 Qt 框架中用于定时器功能的核心类,它允许你在指定的时间间隔内触发事件或执行代码。
# 4.3.1 基本用法
#include <QTimer>
#include <QDebug>
#include <QCoreApplication>
class MyClass : public QObject {
Q_OBJECT
public:
MyClass(QObject *parent = nullptr) : QObject(parent) {
// 创建定时器
QTimer *timer = new QTimer(this);
// 连接定时器的 timeout 信号到槽函数
connect(timer, &QTimer::timeout, this, &MyClass::onTimeout);
// 启动定时器,每隔 1 秒触发一次
timer->start(1000);
}
private slots:
void onTimeout() {
qDebug() << "Timer triggered at:" << QTime::currentTime().toString("HH:mm:ss");
}
};
int main(int argc, char *argv[]){
QCoreApplication app(argc, argv);
MyClass myObject;
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 4.3.2 QTimer用法
start(int msec):启动定时器,msec为时间间隔(毫秒)。stop():停止定时器。setSingleShot(bool singleShot):设置是否为单次触发。isActive():检查定时器是否正在运行。
(1) 基本用法
#include <QTimer>
#include <QDebug>
QTimer *timer = new QTimer(this);
// 连接定时器的 timeout() 信号到槽函数
connect(timer, &QTimer::timeout, this, []() {
qDebug() << "Timer triggered!";
});
// 启动定时器,每隔 1000 毫秒(1 秒)触发一次
timer->start(1000);
2
3
4
5
6
7
8
9
10
11
12
(2) 停止定时器
timer->stop(); // 停止定时器
(3) 单次触发定时器
timer->setSingleShot(true); // 设置为单次触发
timer->start(1000); // 1 秒后触发一次,然后停止
// 使用静态方法创建单次定时器
QTimer::singleShot(2000, this, {
qDebug() << "This will run once after 2 seconds";
});
2
3
4
5
6
7
8
(4) 检查定时器状态
if (timer->isActive()) {
qDebug() << "Timer is running";
} else {
qDebug() << "Timer is not running";
}
2
3
4
5
# 4.3.3 QTimer作用
(1) 定时触发任务:QTimer 可以在指定的时间间隔内触发 timeout() 信号,用于执行周期性任务,例如:
- 更新 UI。
- 轮询数据。
- 执行定时操作。
(2) 单次延迟执行:通过 setSingleShot(true),QTimer 可以用于延迟执行某个任务,例如:
- 延迟加载数据。
- 延迟显示提示信息。
(3) 事件驱动:QTimer 依赖于 Qt 的事件循环,因此可以与其他事件驱动的功能无缝集成。
# 4.3.4 QTimer原理
(1) 底层实现:QTimer 基于操作系统的定时器机制(如 Linux 的 timerfd 或 Windows 的 SetTimer)。
- 在 Qt 的事件循环中,
QTimer会注册一个定时器事件,当时间到达时,事件循环会触发timeout()信号。
(2) 事件循环依赖:QTimer 必须运行在 Qt 的事件循环中。如果没有事件循环,定时器将无法工作。例如:
- 在主线程中,
QApplication::exec()启动了事件循环。 - 在子线程中,需要调用
QThread::exec()。
(3) 精度问题:QTimer 的精度取决于操作系统和硬件,通常为毫秒级别。
- 如果需要高精度定时器,可以考虑使用平台特定的 API(如
nanosleep或QueryPerformanceCounter)。
# 4.3.5 高级用法
(1) 动态调整定时器间隔
timer->setInterval(500); // 将定时器间隔调整为 500 毫秒
(2) 多定时器管理
如果需要管理多个定时器,可以使用 QTimer 的 timerId() 方法:
int timerId = timer->timerId();
(3) 在子线程中使用 QTimer
在子线程中使用 QTimer 时,需要确保子线程有事件循环:
QThread *thread = new QThread;
QTimer *timer = new QTimer;
timer->moveToThread(thread);
connect(thread, &QThread::started, [timer]() {
timer->start(1000);
});
connect(timer, &QTimer::timeout, []() {
qDebug() << "Timer triggered in thread!";
});
thread->start();
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4.4 QElapsedTimer
QElapsedTimer 用于高精度计时,适合测量代码执行时间。
# 4.4.1 基本用法
#include <QElapsedTimer>
#include <QDebug>
#include <QThread>
int main() {
QElapsedTimer timer;
timer.start(); // 开始计时
// 模拟耗时操作
QThread::msleep(1000); // 休眠 1 秒
// 获取经过的时间
qint64 elapsed = timer.elapsed(); // 毫秒
qDebug() << "Elapsed time:" << elapsed << "ms";
// 获取纳秒级时间
qint64 nsecsElapsed = timer.nsecsElapsed(); // 纳秒
qDebug() << "Elapsed time in nanoseconds:" << nsecsElapsed << "ns";
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 4.4.2 常用方法
start():开始计时。elapsed():返回从开始计时到现在的毫秒数。nsecsElapsed():返回从开始计时到现在的纳秒数。hasExpired(qint64 timeout):检查是否已经超过指定的时间(毫秒)。
# 4.5 QDeadlineTimer
QDeadlineTimer 用于管理截止时间,适合需要设置超时时间的场景。
# 4.5.1 基本用法
#include <QDeadlineTimer>
#include <QDebug>
#include <QThread>
int main() {
// 设置截止时间为 2 秒后
QDeadlineTimer deadline(2000); // 2000 毫秒
// 模拟耗时操作
QThread::msleep(1000); // 休眠 1 秒
// 检查是否超时
if (deadline.hasExpired()) {
qDebug() << "Deadline has expired!";
} else {
qDebug() << "Time remaining:" << deadline.remainingTime() << "ms";
}
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 4.5.2 常用方法
setRemainingTime(qint64 msec):设置剩余时间(毫秒)。remainingTime():返回剩余时间(毫秒)。hasExpired():检查是否已经超时。isForever():检查是否为无限时间。