C++11 处理时间和日期的处理,以及chrono库介绍
C++11提供了日期和时间相关的库chrono,通过这个库可以很方便的对时间和日期进行处理:
chrono库主要包含三种类型:
1.时间间隔duration
介绍一下duraton的原型:
template<class Rep, class Period=std::ratio<1, 1>> class duration;
Rep表示时钟数的类型,Period表示时钟周期。
C++标准库中的一些时间间隔:
typedf duration<Rep, ratio<3600, 1>> hours; typedf duration<Rep, ratio<60, 1>> minutes; typedf duration<Rep, ratio<3600, 1>> seconds; typedf duration<Rep, ratio<1, 1000>> milliseconds;
同时,还提供了获取时钟周期数的方法count().
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <iostream> #include <random> #include <chrono> int main() { std::chrono::milliseconds ms(3); // 3ms std::chrono::microseconds micro_s = 2 * ms; std::cout << "milliseconds count is " << ms.count() << std::endl; std::cout << "microseconds count is " << micro_s.count() << std::endl; std::chrono::duration<double, std::ratio<1, 30>> hz30(3.5); // 30hz time clock // 时间相减 std::chrono::minutes t1(10); std::chrono::seconds t2(64); std::chrono::seconds t3 = t1 - t2; std::cout << "t3 count is " << t3.count() << std::endl; std::cout << typeid(t3).name() << std::endl; // 查看变量的类型 // 对时钟周期的转换 std::chrono::minutes h1 = std::chrono::duration_cast<std::chrono::minutes>(t3); // 这个转换只能转换为整数 std::cout << "The minute is " << h1.count() << std::endl; return 0; }
运行结果如下所示:
2.时钟clock
clocks表示当前的系统时钟。clock包含三种时钟:
1. system_clock: 代表真实世界的挂钟时间,具体指依赖于系统。保证提供的时间值是一个可读的时间。
2. steady_clock: 不能被调整的时钟,保证先后得到的时间是递增的。
3. high_resulution_clock: 高精度时钟。
例如:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <iostream> #include <random> #include <chrono> #include <ctime> #include <string> int main() { std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now(); // 获取时间 for (int i = 0; i < 10000; i++) { } std::chrono::system_clock::time_point t2 = std::chrono::system_clock::now(); // 两个时间点之间相差的时钟周期 std::cout << "Time elapsed " << (t2 - t1).count() << std::endl; // 将时间进行转换 int mico_s = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count(); std::cout << "Time is " << mico_s << " microseconds" << std::endl; // time_point(chrono库)和c_time(ctime库)之间的转换 // 函数to_time_t 和 from_time_t std::time_t t3 = clock(); for (int i = 0; i < 1000; i++) { for (int j = 0; j < 1000; j++) { } } std::time_t elapsed = clock() - t3; std::cout << "t3 is " << elapsed << std::endl; std::time_t t_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t(elapsed); return 0; }
3. 时间点time_point
time_point表示时间点,用来获取从纪元开始所经过的duration和当前时间,可以做一些时间的比较和算术运算。
#include "stdafx.h" #include <iostream> #include <random> #include <chrono> int main() { // 计算从1970-1-1至今经过的天数 typedef std::chrono::duration<int, std::ratio<60 * 60 * 24, 1>> day_type; // 定义一天的duration std::chrono::time_point<std::chrono::system_clock, day_type> today = std::chrono::time_point_cast<day_type>(std::chrono::system_clock::now()); std::cout << "Elapse days count is " << today.time_since_epoch().count() << std::endl; return 0; }
两个time_point支持相加减操作。但是不同clock的time_point是不能相加减的。
#include "stdafx.h" #include <iostream> #include <random> #include <chrono> #include <ctime> #include <string> // 由于没有找到put_time函数,所以自定义一个时间转换的函数 int main() { using namespace std::chrono; system_clock::time_point now = system_clock::now(); std::time_t last = system_clock::to_time_t(now - hours(24)); // 向time_T转换 std::time_t next = system_clock::to_time_t(now + hours(24)); std::cout << "one day ago the time was " << std::localtime(&last)->tm_mon << std::endl; // std::localtime(&last)返回的是一个结构体指针,该结构体中包含具体的时间信息,std::put_time不可用的话需要自己将时间拼接成需要的格式 return 0; }
计时器Timer
利用high_resolution_clock可以实现一个计时器,这样的timer在测试程序性能时经常用到,计时器的实现代码如下所示:
#pragma once #include <chrono> using namespace std; // 定义Timer类 class Timer { private: chrono::time_point<chrono::high_resolution_clock> begin; public: Timer() : begin(chrono::high_resolution_clock::now()) {} // 构造函数 // reset方法 void reset() { begin = chrono::high_resolution_clock::now(); } // 输出经过的时间,定义为模板函数 template<typename Duration=chrono::milliseconds> // 默认输出毫秒ms int64_t elapsed() const { return chrono::duration_cast<Duration>(chrono::high_resolution_clock::now() - begin).count(); } // 输出微妙 int64_t elapsed_microseconds() { return elapsed<chrono::milliseconds>(); } // 输出纳秒 int64_t elapsed_nanoseconds() { return elapsed<chrono::nanoseconds>(); } // 输出秒 int64_t elapsed_seconds() { return elapsed<chrono::seconds>(); } // 输出分minute int64_t elapsed_minutes() { return elapsed<chrono::minutes>(); } // 输出时hour int64_t elapsed_hours() { return elapsed<chrono::hours>(); } };
Timer的基本用法:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <iostream> #include "stdafx.h" #include "Timer.h" int main() { Timer timer; // 开始计时 for (int i = 0; i < 10000; i++) { for (int j = 0; j < 10000; j++) {} } std::cout << "Elapsed " << timer.elapsed() << " ms" << std::endl; std::cout << "Elapsed " << timer.elapsed_seconds() << " s" << std::endl; std::cout << "Elapsed " << timer.elapsed_nanoseconds() << " ns" << std::endl; return 0; }
输出结果:
---------------------------------------------------------------------------------------------------------------------------
ctime库中测量时间的方法:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <iostream> #include <ctime> #include "Timer.h" const double CLOCK_PER_SECOND = static_cast<double>(CLOCKS_PER_SEC); // 每秒钟的时钟数 const double CLOCK_PER_MILLISEC = CLOCK_PER_SECOND / 1000.0; // 每毫秒的时钟数 int main() { std::time_t start = clock(); for (int i = 0; i < 10000; i++) { for (int j = 0; j < 10000; j++) {} } double elapsed_ms = (clock() - start) / CLOCK_PER_MILLISEC; std::cout << "Timer elapsed " << elapsed_ms << " ms" << std::endl; return 0; }
将ctime中的测量时间的方法也可以封装为一个计时器Timer。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)