原文转载于:https://blog.csdn.net/hou8389846/article/details/77962343
/// \brief 获取当前系统时间
/// \return 当前系统时间
std::wstring getCurrentSystemTime()
{
auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
struct tm ptm;
localtime_s(&ptm, &tt);
wchar_t date[60] = { 0 };
swprintf_s(date, L"%d-%02d-%02d %02d:%02d:%02d",
(int)ptm.tm_year + 1900, (int)ptm.tm_mon + 1, (int)ptm.tm_mday,
(int)ptm.tm_hour, (int)ptm.tm_min, (int)ptm.tm_sec);
return std::wstring(date);
}
chrono是c++ 11中的时间库,提供计时,时钟等功能。
学习chrono,关键是理解里面时间段(Durations)、时间点(Time points)的概念。
1.精度:
时钟节拍(时间精度):
template <intmax_t N, intmax_t D = 1> class ratio;
其中N表示分子,D表示分母,默认用秒表示的时间单位。
N对应于其成员num,D对应于其成员den
常用的单位:
ratio<60, 1> minute
ratio<1, 1> second
ratio<1, 1000> microsecond
...
ratio主要是是为后面将要讲解的时间段,时间点等提供精度(单位)
- #include<iostream>
- #include<chrono>
- using namespace std;
- int main()
- {
- cout << "millisecond : ";
- cout << std::chrono::milliseconds::period::num << "/" << std::chrono::milliseconds::period::den << "s" <<endl;
- system("pause");
- return 0;
- }
-
-
-
using namespace std;
-
int main()
-
{
-
cout << "millisecond : ";
-
cout << std::chrono::milliseconds::period::num << "/" << std::chrono::milliseconds::period::den << "s" << endl;
-
system( "pause");
-
return 0;
-
}
![](https://i-blog.csdnimg.cn/blog_migrate/df6fddfd863bfb94ae2e7e3a6846b896.png)
2.时间段:
template <class Rep, class Period = ratio<1> >
class duration;
std::chrono::duration 表示一段时间,比如两个小时,12.88秒,半个时辰,一炷香的时间等等
- (1)duration() = default; //默认构造
- (2)duration (const duration& dtn); //(2)(3)拷贝构造
- (3)template<class Rep2, class Period2>
- constexpr duration (const duration<Rep2,Period2>& dtn);
- (4)template<class Rep2> //传递一个某类型(int等)的数值,构造一个时间段
- constexpr explicit duration (const Rep2& n);
-
( 1)duration() = default; //默认构造
-
( 2)duration ( const duration& dtn); //(2)(3)拷贝构造
-
( 3) template< class Rep2, class Period2>
-
constexpr duration ( const duration<Rep2,Period2>& dtn);
-
( 4) template< class Rep2> //传递一个某类型(int等)的数值,构造一个时间段
-
constexpr explicit duration ( const Rep2& n);
(2)成员函数count()返回单位时间的数量。
- #include <iostream>
- #include <chrono>
- int main()
- {
- std::chrono::milliseconds mscond(1000); // 1 second
- std::cout << mscond.count() << " milliseconds.\n";
- std::cout << mscond.count() * std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den;
- std::cout << " seconds.\n";
- system("pause");
- return 0;
- }
-
-
-
int main()
-
{
-
std::chrono:: milliseconds mscond(1000); // 1 second
-
std:: cout << mscond.count() << " milliseconds.\n";
-
-
std:: cout << mscond.count() * std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den;
-
std:: cout << " seconds.\n";
-
system( "pause");
-
return 0;
-
}
![](https://i-blog.csdnimg.cn/blog_migrate/354dbc8cb3e63dca1d39defb7b978058.png)
(2)当不要求截断值的情况下(时转换成秒是没问题,但是秒转换成时就不行)时间段的转换是隐式
的。显示转换可以由 std::chrono::duration_cast<> 来完成。
比如 std::chrono::milliseconds ms(54802);
std::chrono::seconds s=std::chrono::duration_cast<std::chrono::seconds>(ms);
这里的结果就是截断的,而不是进行了舍入,所以s最后的值将为54。
3.时间点:
template <class Clock, class Duration = typename Clock::duration>
class time_point;
std::chrono::time_point 表示一个具体时间,如上个世纪80年代、今天下午3点、火车出发时间等,只要它能用计算机时钟表示。
第一个模板参数Clock用来指定所要使用的时钟(标准库中有三种时钟,system_clock,steady_clock和high_resolution_clock。见4时钟详解),第二个模板函数参数用来表示时间的计量单位(特化的std::chrono::duration<> )
时间点都有一个时间戳,即时间原点。chrono库中采用的是Unix的时间戳1970年1月1日 00:00。所以time_point也就是距离时间戳(epoch)的时间长度(duration)。
(1)构造函数:
(1) | time_point(); //默认构造函数,时间戳作为其值 |
---|---|
(2) | template <class Duration2> time_point (const time_point<clock,Duration2>& tp); //拷贝构造函数 |
(3) | explicit time_point (const duration& dtn); //使用duration构造,就是距离时间戳的时间长度 |
即经常用来得到当前时间点到1970年1月1日00:00的时间距离、该函数返回的duration的精度和构造time_point的时钟(Clock)有关(见4时钟详解)。
- #include <iostream>
- #include <chrono>
- #include <ctime>
- using namespace std;
- int main()
- {
- //距离时间戳2两秒
- chrono::time_point<chrono::system_clock, chrono::seconds> tp(chrono::seconds(2));
- cout << "to epoch : " <<tp.time_since_epoch().count() << "s" <<endl;
- //转化为ctime,打印输出时间点
- time_t tt = chrono::system_clock::to_time_t(tp);
- char a[50];
- ctime_s(a, sizeof(a), &tt);
- cout << a;
- system("pause");
- return 0;
- }
-
-
-
-
using namespace std;
-
int main()
-
{
-
//距离时间戳2两秒
-
chrono::time_point<chrono::system_clock, chrono::seconds> tp(chrono::seconds( 2));
-
cout << "to epoch : " <<tp.time_since_epoch().count() << "s" << endl;
-
//转化为ctime,打印输出时间点
-
time_t tt = chrono::system_clock:: to_time_t(tp);
-
char a[ 50];
-
ctime_s(a, sizeof(a), &tt);
-
cout << a;
-
system( "pause");
-
return 0;
-
}
![](https://i-blog.csdnimg.cn/blog_migrate/e9cba87c0cbfa5420367260739f8276f.png)
可以看出,时间戳就是使用的Unix的时间戳。
4.时钟:(代表当前系统的时间)
chrono中有三种时钟:system_clock,steady_clock和high_resolution_clock。每一个clock类中都有确定的time_point, duration, Rep, Period类型。
system_clock是不稳定的。因为时钟是可调的,即这种是完全自动适应本地账户的调节。这种调节可能造成的是,首次调用now()返回的时间要早于上次调用now()所返回的时间,这就违反了节拍频率的均匀分布。稳定闹钟对于超时的计算很重要,所以C++标准库提供一个稳定时钟 std::chrono::steady_clock。std::chrono::high_resolution_clock 是标准库中提供的具有最小节拍周期(因此具有最高的精度的时钟)。
上文所说time_since_epoch(),以及将要介绍的now()函数的返回值都依赖于时钟的精度,测试时钟的精度的一种方法就是:
- <SPAN style="FONT-SIZE: 18px">#include <iostream>
- #include <chrono>
- using namespace std;
- int main()
- {
- cout << "system clock : ";
- cout << chrono::system_clock::period::num << "/" << chrono::system_clock::period::den << "s" << endl;
- cout << "steady clock : ";
- cout << chrono::steady_clock::period::num << "/" << chrono::steady_clock::period::den << "s" << endl;
- cout << "high resolution clock : ";
- cout << chrono::high_resolution_clock::period::num << "/" << chrono::high_resolution_clock::period::den << "s" << endl;
- system("pause");
- return 0;
- }</SPAN>
-
-
-
using namespace std;
-
int main()
-
{
-
cout << "system clock : ";
-
cout << chrono::system_clock::period::num << "/" << chrono::system_clock::period::den << "s" << endl;
-
cout << "steady clock : ";
-
cout << chrono::steady_clock::period::num << "/" << chrono::steady_clock::period::den << "s" << endl;
-
cout << "high resolution clock : ";
-
cout << chrono::high_resolution_clock::period::num << "/" << chrono::high_resolution_clock::period::den << "s" << endl;
-
system( "pause");
-
return 0;
-
}
![](https://i-blog.csdnimg.cn/blog_migrate/36e0c177576570ff9548b96387825791.png)
windows系统的测试结果是system_clock的精度是100纳秒,而high_resolution的精度是1纳秒,对于程序来说,一般毫秒级就够了,所以说chrono提供的时钟精度绰绰有余。
(1)成员函数static time_point now() noexcept; 用于获取系统的当前时间。
(2)由于各种time_point表示方式不同,chrono也提供了相应的转换函数 time_point_cast。
template <class ToDuration, class Clock, class Duration> time_point<Clock,ToDuration> time_point_cast (const time_point<Clock,Duration>& tp);传一个要转换为的精度的duration模板参数和一个要转换的time_point参数(用法见下面综合应用)
(3)其他成员函数:
to_time_t() time_point转换成time_t秒
from_time_t() 从time_t转换成time_point
综合应用:
输出当前时间,并且计算当前的时间距离1970年1月1日00:00的毫秒数
- #include <iostream>
- #include <chrono>
- #include <ctime>
- using namespace std;
- int main()
- {
- //定义毫秒级别的时钟类型
- typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> microClock_type;
- //获取当前时间点,windows system_clock是100纳秒级别的(不同系统不一样,自己按照介绍的方法测试),所以要转换
- microClock_type tp = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
- //转换为ctime.用于打印显示时间
- time_t tt = chrono::system_clock::to_time_t(tp);
- char _time[50];
- ctime_s(_time,sizeof(_time),&tt);
- cout << "now time is : " << _time;
- //计算距离1970-1-1,00:00的时间长度,因为当前时间点定义的精度为毫秒,所以输出的是毫秒
- cout << "to 1970-1-1,00:00 " << tp.time_since_epoch().count() << "ms" << endl;
- system("pause");
- return 0;
- }
-
-
-
-
using namespace std;
-
int main()
-
{
-
//定义毫秒级别的时钟类型
-
typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> microClock_type;
-
//获取当前时间点,windows system_clock是100纳秒级别的(不同系统不一样,自己按照介绍的方法测试),所以要转换
-
microClock_type tp = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
-
//转换为ctime.用于打印显示时间
-
time_t tt = chrono::system_clock:: to_time_t(tp);
-
char _time[ 50];
-
ctime_s(_time, sizeof(_time),&tt);
-
cout << "now time is : " << _time;
-
//计算距离1970-1-1,00:00的时间长度,因为当前时间点定义的精度为毫秒,所以输出的是毫秒
-
cout << "to 1970-1-1,00:00 " << tp.time_since_epoch().count() << "ms" << endl;
-
system( "pause");
-
return 0;
-
}
![](https://i-blog.csdnimg.cn/blog_migrate/1d155c2b642ba8a494141346c7a592a2.png)
通过两张图片对比,时间点上相差48-34=14秒、、下面的一长串数字,切掉3位(毫秒)、是28-14=14秒、、正确!说明这一串数字的最后三位就是毫秒数、、充分说明了达到了毫秒级别。
将上面的程序中millisconds换成microseconds或者更小的单位,便可达到微妙,甚至更高的精度。