话不多说,直接上代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <thread>
//本文只探讨C++11中的功能,C++20该库进行了升级
//官方网址https://en.cppreference.com/w/cpp/chrono
//有一篇博客讲的也很好https://blog.csdn.net/albertsh/article/details/105468687
int main()
{
//最开始,列出程序中最常用的,一个程序片段使用时间的计算(建议直接用第一种duration_cast + steady_clock):
{
//1、duration_cast + steady_clock
auto timePoint_start_1 = std::chrono::steady_clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(100));//do somethings
auto timePoint_end_1 = std::chrono::steady_clock::now();
auto takeTime_1 = std::chrono::duration_cast<std::chrono::milliseconds>(timePoint_end_1 - timePoint_start_1).count();
printf("takeTime_1: %lldms\n", takeTime_1);//%lld打印long long
std::cout << "takeTime_1: " << takeTime_1 << "ms" << std::endl;
printf("\n");
//
//
//
//2、time_point_cast + steady_clock
using ms_time_point = std::chrono::time_point<std::chrono::steady_clock, std::chrono::milliseconds>;
auto timePoint_start_2 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now());
std::this_thread::sleep_for(std::chrono::milliseconds(100));//do somethings
auto timePoint_end_2 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now());
auto takeTime_2 = (timePoint_end_2 - timePoint_start_2).count();
printf("takeTime_2: %lldms\n", takeTime_2);//%lld打印long long
std::cout << "takeTime_2: " << takeTime_2 << "ms" << std::endl;
printf("\n");
}
//std::chrono主要由三部分组成,分别是durations、clocks、time_point
{
/*
1、std::chrono::duration(持续时间),duration是类模板,它有两个参数:std::chrono::duration<数值类型, 时间单位>
第一个参数_Rep是一个数值类型,通常是内置数值类型,后面构造对象时数值是多少就表示有多少个时间单位,这样就构成了一个时间长度(持续时间);
第二个参数_Period是std::ratio模板类的一个实例,代表一个时间单位。_Period缺省值为std::ratio<1>,此时它的单位为秒。
*/
{
/*
0、std::ratio(比例)
定义在<ratio>文件中,提供了编译期的比例计算功能,为std::chrono::duration提供基础服务。
标准库预定义了一些常用比例,见https://en.cppreference.com/w/cpp/numeric/ratio/ratio
*/
{
std::ratio<3, 1> raito_3_1;
std::ratio<1, 3> raito_1_3;
using ratio_1_10 = std::deci;
using ratio_1_1000 = std::milli;
using ratio_1_1000000 = std::micro;
using ratio_10_1 = std::deca;
using ratio_1000_1 = std::kilo;
using ratio_1000000_1 = std::mega;
}
/*
chrono中已经定义了nanoseconds、microseconds、milliseconds、seconds、minutes、hours这些常用的类
可以通过这些类构造一些比较常用的对象以供使用
*/
{
//chrono中的持续时间类和对象构造使用
auto _24_hours = std::chrono::hours{ 24 };//传参24给类std::chrono::hours,构造出一个对象_24_hours,下面含义相同
auto _60_minutes = std::chrono::minutes(60);
auto _2_seconds = std::chrono::seconds(2);
auto _100_milliseconds = std::chrono::milliseconds(100);
auto _100000_microseconds = std::chrono::microseconds(100000);
auto _1_nanoseconds = std::chrono::nanoseconds(1);
std::this_thread::sleep_for(_2_seconds);
std::this_thread::sleep_for(std::chrono::seconds(1));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
printf("\n");
auto _1_2_seconds_format1 = std::chrono::milliseconds(500);
//auto _1_2_seconds_format2 = std::chrono::seconds(0.5);//这句话不被允许,因为std::chrono::seconds第一个参数为long long
printf("\n");
std::chrono::seconds duration1;//假设构造duration对象时不给数值参数,则会以一个负数初始化
std::cout << "cnt: " << duration1.count() << std::endl;
std::cout << "min: " << duration1.min().count() << std::endl;
duration1 = std::chrono::seconds(10001);
std::cout << "cnt: " << duration1.count() << std::endl;
printf("hello1\n");
}
/*
std::chrono::duration类对象的count、max、min方法
count表示当前对象拥有的时间单位的数量,而时间长度=时间单位*数量
max表示当前对象最多能够拥有的时间单位的数量,min表示当前对象最少能够拥有的时间单位的数量
*/
{
auto _1_seconds = std::chrono::seconds(1);
auto cnt1 = _1_seconds.count();
auto min1 = _1_seconds.min();
auto max1 = _1_seconds.max();
std::cout << "cnt1: " << cnt1 << std::endl;
std::cout << "min1: " << min1.count() << std::endl;
std::cout << "max1: " << max1.count() << std::endl;
printf("\n");
auto _2_seconds = std::chrono::seconds(2);
auto cnt2 = _2_seconds.count();
auto min2 = _2_seconds.min();
auto max2 = _2_seconds.max();
std::cout << "cnt2: " << cnt2 << std::endl;
std::cout << "min2: " << min2.count() << std::endl;
std::cout << "max2: " << max2.count() << std::endl;
printf("\n");
auto _1_minutes = std::chrono::minutes(1);
auto cnt3 = _1_minutes.count();
auto min3 = _1_minutes.min();
auto max3 = _1_minutes.max();
std::cout << "cnt3: " << cnt3 << std::endl;
std::cout << "min3: " << min3.count() << std::endl;
std::cout << "max3: " << max3.count() << std::endl;
printf("\n");
auto _60_minutes = std::chrono::minutes(60);
auto cnt4 = _60_minutes.count();
auto min4 = _60_minutes.min();
auto max4 = _60_minutes.max();
std::cout << "cnt4: " << cnt4 << std::endl;
std::cout << "min4: " << min4.count() << std::endl;
std::cout << "max4: " << max4.count() << std::endl;
printf("\n");
}
/*
自定义持续时间类,构造对象和使用
*/
{
/
//自定义持续时间类
using _int_one_second = std::chrono::duration<int>;//std::chrono::duration第二个参数缺省值为std::ratio<1>
using _short_one_second = std::chrono::duration<short>;
using _double_one_second = std::chrono::duration<double>;
using _longlong_one_second = std::chrono::duration<long long>;//std::chrono::seconds就是这个
using _int_two_second = std::chrono::duration<int, std::ratio<2, 1>>;
using _float_half_second = std::chrono::duration<float, std::ratio<1, 2>>;
using _double_1_3_second = std::chrono::duration<double, std::ratio<1, 3>>;
/
//构造对象
_int_one_second duration1;//假设构造duration对象时不给数值参数,则会以一个负数初始化
std::cout << "cnt: " << duration1.count() << std::endl;
std::cout << "min: " << duration1.min().count() << std::endl;
duration1 = _int_one_second(1);
std::cout << "cnt: " << duration1.count() << std::endl;
printf("hello1\n");
//auto _1_2_seconds_format1 = _int_one_second(0.5);//这句话不被允许,因为_int_one_second类第一个参数应该为int
auto _1_2_seconds_format2 = _double_one_second(0.5);
auto _2_2_second = _float_half_second(2.0f);
auto _2_3_second = _double_1_3_second(2.0);
/
//使用
std::this_thread::sleep_for(_double_one_second(0.5));
std::this_thread::sleep_for(_1_2_seconds_format2);
std::this_thread::sleep_for(_float_half_second(4.0f));
std::this_thread::sleep_for(_short_one_second(1));
printf("hello2\n");
printf("\n");
}
/*
持续时间作和、差、比较
*/
{
{
//普通的和、差
auto _1_seconds = std::chrono::seconds(1);
auto _2_seconds = std::chrono::seconds(2);
auto duration1_1 = _1_seconds + _2_seconds;
auto duration1_2 = _1_seconds - _2_seconds;
std::cout << "duration1_1: " << duration1_1.count() << std::endl;
std::cout << "duration1_1 type is: " << typeid(duration1_1).name() << std::endl;
std::cout << "duration1_2: " << duration1_2.count() << std::endl;
std::cout << "duration1_1 type is: " << typeid(duration1_2).name() << std::endl;
auto _1_milliseconds = std::chrono::milliseconds(1);
auto duration2_1 = _1_seconds + _1_milliseconds;
auto duration2_2 = _1_seconds - _1_milliseconds;
std::cout << "duration2_1: " << duration2_1.count() << std::endl;
std::cout << "duration2_1 type is: " << typeid(duration2_1).name() << std::endl;
std::cout << "duration2_2: " << duration2_2.count() << std::endl;
std::cout << "duration2_2 type is: " << typeid(duration2_2).name() << std::endl;
printf("\n");
}
/
{
//对于两个不同的std::ratio类型相加(减),最终得到的std::ratio类型为两个std::ratio分子取最大公约数,分母取最小公倍数
auto duration1_1 = std::chrono::duration<double, std::ratio<9, 7>>(3);
auto duration1_2 = std::chrono::duration<double, std::ratio<6, 5>>(1);
auto duration1_3 = duration1_1 + duration1_2;
auto duration1_4 = duration1_1 - duration1_2;
std::cout << "duration1_3: " << duration1_3.count() << std::endl;
std::cout << "duration1_3 type is: " << typeid(duration1_3).name() << std::endl;
std::cout << "duration1_4: " << duration1_4.count() << std::endl;
std::cout << "duration1_4 type is: " << typeid(duration1_4).name() << std::endl;
printf("\n");
}
/
{
//比较
auto _1_seconds = std::chrono::seconds(1);
auto _2_seconds = std::chrono::seconds(2);
auto _double_1_3_seconds = std::chrono::duration<double, std::ratio<1, 3>>(1);
if (_1_seconds * 2 == _2_seconds)
printf("_1_seconds * 2 == _2_seconds\n");//显然成立
if (_double_1_3_seconds * 3 == _1_seconds)
printf("_double_1_3_seconds * 2 == _1_seconds\n");//如果不相等,可能的原因是浮点数的关系
if ((_double_1_3_seconds * 3 - _1_seconds).count() < 1e-4)
printf("(_double_1_3_seconds * 2 - _1_seconds).count() < 1e-4\n");//这样就满足啦
printf("\n");
}
}
/*
持续时间的单位转换std::chrono::duration_cast
*/
{
auto _1_seconds = std::chrono::seconds(1);
auto duration1 = std::chrono::duration_cast<std::chrono::minutes>(_1_seconds);//秒转为分钟为单位
std::cout << "duration1: " << duration1.count() << std::endl;//这里得到的是0
auto duration2 = std::chrono::duration_cast<std::chrono::duration<double, std::ratio<60>>>(_1_seconds);//因此我们自定义一个double类型的分钟
std::cout << "duration2: " << duration2.count() << std::endl;//这里得到的是小数
auto duration3 = std::chrono::duration_cast<std::chrono::milliseconds>(_1_seconds);//秒转为毫秒为单位
std::cout << "duration3: " << duration3.count() << std::endl;
printf("\n");
}
}
}
printf("\n");
{
/*
2、clocks(时钟),主要包括system_clock、steady_clock、high_resolution_clock
system_clock表示系统时钟,代表真实世界的时间,具体值依赖于系统;(如果两次调用now()方法之间,系统时间被修改了,那么两次的差值就很难说了)
steady_clock不能被“调整”的时钟,不一定是世界时钟,但通过其now()方法得到的时间值不会是递减的;(系统时间修改不会影响它)
high_resolution_clock,实际上是system_clock或者steady_clock的别名而已,具体是谁根据系统而定
*/
{
//查看system_clock和steady_clock的成员和成员函数
{
/*
std::chrono::system_clock的成员和成员函数,system_clock比steady_clock多两个成员函数to_time_t、from_time_t
*/
auto time_point1 = std::chrono::system_clock::now();//这里得到一个time_point
//std::cout << "time_point1: " << time_point1 << std::endl;//time_point不能被打印
std::cout << "system_clock::is_steady is: " << std::chrono::system_clock::is_steady << std::endl;
std::cout << "system_clock::period type is: " << typeid(std::chrono::system_clock::period).name() << std::endl;
std::cout << "system_clock::rep type is: " << typeid(std::chrono::system_clock::rep).name() << std::endl;
std::cout << "system_clock::duration type is: " << typeid(std::chrono::system_clock::duration).name() << std::endl;
std::cout << "system_clock::time_point type is: " << typeid(std::chrono::system_clock::time_point).name() << std::endl;
auto ctime1 = std::chrono::system_clock::to_time_t(time_point1);//将一个time_point转换成ctime
auto time_point2 = std::chrono::system_clock::from_time_t(ctime1);//将一个ctime转换成time_point
printf("\n");
}
{
/*
std::chrono::steady_clock的成员和成员函数
*/
auto time_point2 = std::chrono::steady_clock::now();//这里得到一个time_point
//std::cout << "time_point2: " << time_point2 << std::endl;//time_point不能被打印
std::cout << "steady_clock::is_steady is: " << std::chrono::steady_clock::is_steady << std::endl;
std::cout << "steady_clock::period type is: " << typeid(std::chrono::steady_clock::period).name() << std::endl;
std::cout << "steady_clock::rep type is: " << typeid(std::chrono::steady_clock::rep).name() << std::endl;
std::cout << "steady_clock::duration type is: " << typeid(std::chrono::steady_clock::duration).name() << std::endl;
std::cout << "steady_clock::time_point type is: " << typeid(std::chrono::steady_clock::time_point).name() << std::endl;
printf("\n");
}
}
{
/*
计算两个时间点的时间间隔,通常用于计算一个步骤所花费的时间,通常system_clock和steady_clock都能够胜任,
只用来计算时间间隔的话,理论上steady_clock更好一些
*/
auto time1 = std::chrono::system_clock::now();//这里得到一个time_point
std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto time2 = std::chrono::system_clock::now();
auto takeTime1 = (time2 - time1).count();
auto takeTime2 = std::chrono::duration_cast<std::chrono::milliseconds>(time2 - time1).count();
std::cout << "takeTime1: " << takeTime1 << std::endl;
std::cout << "takeTime2: " << takeTime2 << std::endl;
printf("\n");
auto time3 = std::chrono::steady_clock::now();//这里得到一个time_point
std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto time4 = std::chrono::steady_clock::now();
auto takeTime3 = std::chrono::duration_cast<std::chrono::milliseconds>(time4 - time3).count();
std::cout << "takeTime3: " << takeTime3 << std::endl;
printf("\n");
}
{
/*
std::chrono::system_clock::to_time_t 方法将一个time_point转换成ctime
std::chrono::system_clock::from_time_t 方法将一个ctime转换成time_point
结合<iomanip>中的std::put_time和<ctime>中的std::localtime可以将时间格式化输出
注意GCC对<iomanip>中std::put_time的支持未知
*/
auto ctime1 = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
auto time_point1 = std::chrono::system_clock::from_time_t(ctime1);
//时间格式化输出
std::cout << std::put_time(std::localtime(&ctime1), "%Y-%m-%d %X") << std::endl;
std::cout << std::put_time(std::localtime(&ctime1), "%Y-%m-%d %H.%M.%S") << std::endl;
printf("\n");
auto t1 = std::localtime(&ctime1);
auto t1_sec = t1->tm_sec;
auto t1_min = t1->tm_min;
auto t1_hour = t1->tm_hour;
auto t1_mday = t1->tm_mday;
auto t1_mon = t1->tm_mon + 1;
auto t1_year = t1->tm_year + 1900;
std::cout << t1_year << "." << t1_mon << "." << t1_mday << "." << t1_hour << "." << t1_min << "." << t1_sec << "." << std::endl;
}
}
{
/*
3、time_point(时间点)
*/
{
{
/*
在clocks调试中我们已经使用std::chrono::system_clock::now()来获取时间点,
也知道std::chrono::system_clock::time_point的类型为:
std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<__int64, std::ratio<1,10000000>>>
这个duration我们并不常用,因此我们会自定义std::chrono::time_point类型
这里我们定义一个以天为单位的time_point
我们
*/
using day_dura = std::chrono::duration<int, std::ratio<60 * 60 * 24>>;//自定义duration
using day_time_point = std::chrono::time_point<std::chrono::system_clock, day_dura>;//自定义time_point
day_time_point time_point1 = std::chrono::time_point_cast<day_dura>(std::chrono::system_clock::now());//获取当前时间点,然后用time_point_cast转换到我们自定义的时间点单位
auto cnt = time_point1.time_since_epoch().count();//time_since_epoch就是得到当前时间点距离1970.1.1有多少的持续时间duration
//std::cout << "time_point1 is: " << time_point1 << std::endl;//时间点不能打印
std::cout << "cnt is: " << cnt << std::endl;
printf("\n");
}
{
/*
程序中常用的以毫秒ms为单位的time_point的使用
*/
using ms_time_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>;
auto time_point1 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto time_point2 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
auto takeTime = (time_point2 - time_point1).count();
printf("\n");
}
}
}
return 0;
}