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
当前分类随机文章推荐
- C++ - 字节数组byte[]或者unsigned char[]与double的相互转换 阅读2964次,点赞0次
- C++ - 得到字符串中某个字符串出现的个数 阅读4416次,点赞2次
- C++ - return this和return *this的含义和区别 阅读664次,点赞0次
- C++ - 基于no-boost Asio实现一个异步TCP服务器 阅读143次,点赞0次
- C++ - std::unordered_map中使用结构体或者vector等复杂的数据结构作为Key值 阅读1321次,点赞0次
- C++ - 对字符串和图片进行base64编解码 阅读1114次,点赞0次
- C++ - 数组初始化 阅读574次,点赞0次
- C++ - 我在项目实际开发中用到的第三方库/开源项目,涵盖网络、加密解密、GUI、网络、音视频、图片等等 阅读554次,点赞0次
- C++STL容器 - std::vector构造方式与分配值方式总结 阅读1050次,点赞0次
- C++ - vector存储动态指针时正确释放内存 阅读6594次,点赞0次
全站随机文章推荐
- Linux - 编译Crypto++加密库 阅读2147次,点赞1次
- 资源分享 - Geometric tools for computer graphics(Philip J. Schneider, and David H. Eberly)英文高清PDF下载 阅读3893次,点赞0次
- 计算机图形学 - 常用的3D数学知识备忘,如三角函数、向量运算、矩阵运算、图形学常用的平移缩放旋转矩阵,视图矩阵,投影矩阵 阅读1695次,点赞4次
- WordPress - 在浏览器的console输出信息 阅读4236次,点赞0次
- OpenCV - cv::VideoWriter::fourcc可支持的视频编码格式 阅读3932次,点赞0次
- C++ – 字节数组byte[]或者unsigned char[]与bool的相互转换 阅读1420次,点赞1次
- C++11 - std::shared_ptr初始化的几种方式 阅读7505次,点赞2次
- Unity - 字节数组byte[]保存为文件 阅读5257次,点赞2次
- 资源分享 - 3D Game Engine Design - A Practical Approach to Real-Time Computer Graphics 英文高清PDF下载 阅读1866次,点赞0次
- C++ - Windows下实现程序开机自启动功能或者关闭开机自启动 阅读27次,点赞0次
评论
169