技术分享:深入C++时间操作函数的应用与实践

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
全局流量管理 GTM,标准版 1个月
简介: 技术分享:深入C++时间操作函数的应用与实践

在软件开发中,时间是无处不在的一个概念,无论是日志记录、定时任务还是用户界面,时间的处理都至关重要。C++标准库提供了一套完整的工具来帮助我们处理时间相关的操作。本文将详细介绍几个时间操作函数的使用场景、代码实现以及它们在实际开发中的应用。

函数列表与使用场景

  1. 判断当前秒数是否是指定的秒数-isCurrentSecond
  • 使用场景:定时任务触发、性能测试中的特定时间点检查等。
  1. 获取当前时间的分钟部分-getCurrentTimeMinute
  • 使用场景:生成时间戳、日志记录、定时备份等。
  1. 将time_point转换为格式化的字符串-formatTimePoint
  • 使用场景:日志输出、用户界面显示、数据格式化等。
  1. 获取两个时间点之间的所有分钟字符串-getMinutesInRange
  • 使用场景:生成时间范围内的报告、时间序列分析等。
  1. 将时间字符串转换为MySQL的DATETIME格式-convertToMySqlDateTime
  • 使用场景:数据库时间数据的插入、更新等操作。
  1. 检查输入数据是否是合法的年月日时分秒-isValidDateTime
  • 使用场景:用户输入验证、数据导入前的数据校验等。

代码实现与注释

以下是每个函数的详细介绍和注释。

1. 判断当前秒数是否是指定的秒数
bool isCurrentSecond(int targetSecond) {
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();
    // 转换为time_t类型
    std::time_t nowTimeT = std::chrono::system_clock::to_time_t(now);
    // 转换为tm结构体
    struct tm nowTm;
    localtime_r(&nowTimeT, &nowTm); // 使用localtime_r是线程安全的

    // 获取当前的秒数
    int currentSecond = nowTm.tm_sec;

    // 判断当前秒数是否是指定的秒数
    return currentSecond == targetSecond;
}
2. 获取当前时间的分钟部分
std::string getCurrentTimeMinute() {
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();
    // 转换为time_t类型
    std::time_t nowTimeT = std::chrono::system_clock::to_time_t(now);
    // 转换为tm结构体
    struct tm nowTm;
    gmtime_r(&nowTimeT, &nowTm); // 使用gmtime_r来避免时区的影响

    // 使用stringstream和iomanip来格式化时间字符串为"YYYYMMDDHHMM"格式
    std::stringstream ss;
    ss << std::put_time(&nowTm, "%Y%m%d%H%M");

    // 返回格式化的时间字符串
    return ss.str();
}
3. 将time_point转换为格式化的字符串
std::string formatTimePoint(const std::chrono::system_clock::time_point& timePoint) {
    // 将time_point转换为time_t
    auto tt = std::chrono::system_clock::to_time_t(timePoint);
    // 使用gmtime来避免时区问题
    std::tm tm = *std::gmtime(&tt);

    // 使用stringstream和put_time来格式化时间为"YYYYMMDDHHMM"格式
    std::stringstream ss;
    ss << std::put_time(&tm, "%Y%m%d%H%M");

    // 返回格式化的时间字符串
    return ss.str();
}
4. 获取两个时间点之间的所有分钟字符串
std::vector<std::string> getMinutesInRange(const std::string& startTimeStr, const std::string& endTimeStr) {
    // 解析时间字符串为time_point
    std::tm startTimeTm, endTimeTm;
    std::istringstream ssStartTime(startTimeStr);
    std::istringstream ssEndTime(endTimeStr);

    // 使用get_time来解析时间字符串
    ssStartTime >> std::get_time(&startTimeTm, "%Y%m%d%H%M");
    ssEndTime >> std::get_time(&endTimeTm, "%Y%m%d%H%M");

    // 转换tm结构体为time_point
    std::chrono::system_clock::time_point startTime = std::chrono::system_clock::from_time_t(std::mktime(&startTimeTm));
    std::chrono::system_clock::time_point endTime = std::chrono::system_clock::from_time_t(std::mktime(&endTimeTm));

    // 存储分钟字符串的向量
    std::vector<std::string> minutes;

    // 循环遍历两个时间点之间的每一分钟
    for (auto currentTime = startTime; currentTime <= endTime; currentTime += std::chrono::minutes(1)) {
        // 将当前时间点格式化为字符串并添加到向量中
        minutes.push_back(formatTimePoint(currentTime));
    }

    // 返回包含所有分钟字符串的向量
    return minutes;
}
5. 将时间字符串转换为MySQL的DATETIME格式
std::string convertToMySqlDateTime(const std::string &timeStr, bool forceFormat = false) {
    // MySQL的DATETIME格式为"YYYY-MM-DD HH:MM:SS"
    const std::string mysqlFormat = "%Y-%m-%d %H:%M:%S";
    std::istringstream iss(timeStr);
    int year, month, day, hour, minute, second;
    char dash1, dash2, colon1, colon2;

    // 如果需要强制格式化,则调整输入字符串
    if (forceFormat) {
        if (timeStr.length() < 14) {
            // 如果时间字符串长度不足14位,则补零
            std::string paddedStr = timeStr;
            paddedStr.resize(14, '0');
            iss.str(paddedStr);
        } else if (timeStr.length() > 14) {
            // 如果时间字符串长度超过14位,则截断
            iss.str(timeStr.substr(0, 14));
        }
    }

    // 解析时间字符串
    if (!(iss >> year >> dash1 >> month >> dash2 >> day >> colon1 >> hour >> colon2 >> minute >> second)) {
        // 如果解析失败,返回空字符串
        return "";
    }

    // 构建MySQL的DATETIME格式字符串
    std::ostringstream oss;
    oss << std::setfill('0') << std::setw(4) << year << "-"
        << std::setw(2) << month << "-"
        << std::setw(2) << day << " "
        << std::setw(2) << hour << ":"
        << std::setw(2) << minute << ":"
        << std::setw(2) << second;

    // 返回格式化后的字符串
    return oss.str();
}
6. 检查输入数据是否是合法的年月日时分秒
bool isValidDateTime(const std::string &timeStr) {
    // 设置istringstream以两位数字的格式提取日期和时间的各个部分
    std::istringstream iss(timeStr);
    int year, month, day, hour, minute, second;
    char dash1, dash2, colon1, colon2;

    // 解析时间字符串
    if (!(iss >> std::setw(4) >> year >> dash1 >> std::setw(2) >> month >> dash2 >> std::setw(2) >> day
          >> colon1 >> std::setw(2) >> hour >> colon2 >> std::setw(2) >> minute >> second)) {
        // 如果解析失败,返回false
        return false;
    }

    // 检查年份是否在合理的范围内
    if (year < 0 || year > 9999) return false;

    // 检查月份是否在1到12之间
    if (month < 1 || month > 12) return false;

    // 检查日期是否在1到31之间
    if (day < 1 || day > 31) return false;

    // 检查小时是否在0到23之间
    if (hour < 0 || hour > 23) return false;

    // 检查分钟和秒是否在0到59之间
    if (minute < 0 || minute > 59) return false;
    if (second < 0 || second > 59) return false;

    // 如果所有检查都通过,则返回true
    return true;
}

结论

通过上述函数的介绍和代码实现,我们可以看到C++标准库在处理时间方面的功能是非常全面和强大的。这些函数不仅可以帮助我们完成日常的时间处理任务,还可以在复杂的时间计算和格式化中发挥重要作用。希望这篇技术分享能够帮助你更好地理解和使用C++中的时间操作函数。

点赞过20 直接分享源码库。


分享一个有趣的 学习链接


目录
打赏
0
1
1
0
43
分享
相关文章
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
53 15
|
3月前
|
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
182 77
|
30天前
|
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
87 6
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
66 12
|
3月前
|
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
【数据结构——树】哈夫曼树(头歌实践教学平台习题)【合集】目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:任务描述 本关任务:编写一个程序构建哈夫曼树和生成哈夫曼编码。 相关知识 为了完成本关任务,你需要掌握: 1.如何构建哈夫曼树, 2.如何生成哈夫曼编码。 测试说明 平台会对你编写的代码进行测试: 测试输入: 1192677541518462450242195190181174157138124123 (用户分别输入所列单词的频度) 预
92 14
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
|
3月前
|
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
93 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
3月前
|
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】
【数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】 目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:实现二叉排序树的基本算法。 相关知识 为了完成本关任务,你需要掌握:二叉树的创建、查找和删除算法。具体如下: (1)由关键字序列(4,9,0,1,8,6,3,5,2,7)创建一棵二叉排序树bt并以括号表示法输出。 (2)判断bt是否为一棵二叉排序树。 (3)采用递归方法查找关键字为6的结点,并输出其查找路径。 (4)分别删除bt中关键
81 11
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】
|
3月前
|
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
100 19
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
105 13
|
3月前
|
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
86 12
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等