C++ – 在某一天某个时间点定时执行任务,比如2022年9月19日晚上9点准点执行发送邮件函数
最近在写我自己的一个开源项目,就是能够按设定的时间录制HLS流的一个小工具,方便自己获取视频素材。然后首先需要解决的一个问题是,如何按照设定的时间准点的执行录制任务,这个过程可以简单地描述如下:
- 设定定时指定录制任务的时间戳,这里的时间戳可以认为是依据本地时区的自 1970 年 1 月 1 日以来持续时间的秒数;
- 获取当前程序指定的时间戳;
- 根据以上信息获取二者相差的秒数,然后子线程睡眠相差的秒数,然后执行录制任务;
过程比较简单,其中有两个地方需要处理,一个是根据给定的时间获取时间戳,二者是当前程序执行的时间戳,并且这两个时间戳可以进行比较,并可以获得二者之间相差的秒数。
1 根据设定的指定时间获取时间戳
这里转换时间为时间戳,我们用到的是C中mktime
函数
1.1 mktime函数
函数形式
time_t mktime(struct tm *timeptr)
函数功能
把 timeptr所指向的结构转换为一个依据本地时区的自 1970 年 1 月 1 日以来持续时间的秒数,如果转换错误则返回-1。
函数参数
- timeptr:这是指向表示日历时间的 time_t 值的指针,该日历时间可被分解为以下各部分。
struct tm {
int tm_sec; /* 秒,范围从 0 到 59 */
int tm_min; /* 分,范围从 0 到 59 */
int tm_hour; /* 小时,范围从 0 到 23 */
int tm_mday; /* 一月中的第几天,范围从 1 到 31 */
int tm_mon; /* 月份,范围从 0 到 11 */
int tm_year; /* 自 1900 起的年数 */
int tm_wday; /* 一周中的第几天,范围从 0 到 6 */
int tm_yday; /* 一年中的第几天,范围从 0 到 365 */
int tm_isdst; /* 夏令时 */
};
1.2 将指定时间转换为时间戳
我们将mktime
函数进行封装,
/**
* 如果我们要转换2022年9月19日21时0分0秒为时间戳,则传参为TimeToTimeStamp(2022, 9, 19, 21,0, 0)
*/
std::time_t TimeToTimeStamp(
int year,
int month,
int day,
int hour,
int minute,
int second
)
{
struct tm temp_tm;
memset(&temp_tm, 0, sizeof(tm));
temp_tm.tm_year = year - 1900;
temp_tm.tm_mon = month - 1;
temp_tm.tm_mday = day;
temp_tm.tm_hour = hour;
temp_tm.tm_min = minute;
temp_tm.tm_sec = second;
temp_tm.tm_isdst = 0;
int ret;
char buffer[128];
ret = mktime(&temp_tm);
if (ret == -1) {
std::cout << "Error: unable to make time using mktime" << std::endl;
}
return ret;
}
上述函数可以将设定的时间转换为本地时区的自 1970 年 1 月 1 日以来持续时间的秒数。
2 定时执行指定程序
下面我们写一个简单的示例,定时在2022年9月19日11时20分0秒准时打印当前的时间戳
#include <iostream>
#include <chrono>
#include <time.h>
#include <thread>
#include <sstream>
/**
* 如果我们要转换2022年9月19日21时0分0秒为时间戳,则传参为TimeToTimeStamp(2022, 9, 19, 21,0, 0)
*/
std::time_t TimeToTimeStamp(
int year,
int month,
int day,
int hour,
int minute,
int second
)
{
struct tm temp_tm;
memset(&temp_tm, 0, sizeof(tm));
temp_tm.tm_year = year - 1900;
temp_tm.tm_mon = month - 1;
temp_tm.tm_mday = day;
temp_tm.tm_hour = hour;
temp_tm.tm_min = minute;
temp_tm.tm_sec = second;
temp_tm.tm_isdst = 0;
int ret;
char buffer[128];
ret = mktime(&temp_tm);
if (ret == -1) {
std::cout << "Error: unable to make time using mktime" << std::endl;
}
return ret;
}
std::string GetCurrentTimeStamp(int time_stamp_type = 0)
{
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t now_time_t = std::chrono::system_clock::to_time_t(now);
std::tm* now_tm = std::localtime(&now_time_t);
char buffer[128];
strftime(buffer, sizeof(buffer), "%F %T", now_tm);
std::ostringstream ss;
ss.fill('0');
std::chrono::milliseconds ms;
std::chrono::microseconds cs;
std::chrono::nanoseconds ns;
switch (time_stamp_type)
{
case 0:
ss << buffer;
break;
case 1:
ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
ss << buffer << ":" << ms.count();
break;
case 2:
ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
cs = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()) % 1000000;
ss << buffer << ":" << ms.count() << ":" << cs.count() % 1000;
break;
case 3:
ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
cs = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()) % 1000000;
ns = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch()) % 1000000000;
ss << buffer << ":" << ms.count() << ":" << cs.count() % 1000 << ":" << ns.count() % 1000;
break;
default:
ss << buffer;
break;
}
return ss.str();
}
int main()
{
// 获取指定时间的时间戳
std::time_t input_time = TimeToTimeStamp(2022, 9, 19, 11,20, 0);
std::cout << input_time << std::endl;
// 获取当前时间的时间戳
time_t now_time_t;
time(&now_time_t);
std::cout << now_time_t << std::endl;
// 当前线程睡眠计算所得时间差
std::this_thread::sleep_for(std::chrono::seconds(input_time - now_time_t));
std::cout << "当前时间" << GetCurrentTimeStamp(0) << std::endl;
return 0;
}
执行结果
1663557600
1663557579
当前时间2022-09-19 11:20:00
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – 在某一天某个时间点定时执行任务,比如2022年9月19日晚上9点准点执行发送邮件函数
原文链接:https://www.stubbornhuang.com/2359/
发布于:2022年09月19日 11:22:08
修改于:2023年06月21日 18:03:34
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论
52