C++使用chrono庫(kù)處理日期和時(shí)間的實(shí)現(xiàn)方法
C++11 中提供了日期和時(shí)間相關(guān)的庫(kù) chrono,通過 chrono 庫(kù)可以很方便地處理日期和時(shí)間,為程序的開發(fā)提供了便利。chrono 庫(kù)主要包含三種類型的類:時(shí)間間隔duration、時(shí)鐘clocks、時(shí)間點(diǎn)time point。
1. 時(shí)間間隔 duration
1.1 常用類成員
duration表示一段時(shí)間間隔,用來記錄時(shí)間長(zhǎng)度,可以表示幾秒、幾分鐘、幾個(gè)小時(shí)的時(shí)間間隔。duration 的原型如下:
// 定義于頭文件 <chrono> template< class Rep, class Period = std::ratio<1> > class duration;
ratio 類表示每個(gè)時(shí)鐘周期的秒數(shù),其中第一個(gè)模板參數(shù) Num 代表分子,Denom 代表分母,該分母值默認(rèn)為 1,因此,ratio 代表的是一個(gè)分子除以分母的數(shù)值,比如:ratio<2> 代表一個(gè)時(shí)鐘周期是 2 秒,ratio<60 > 代表一分鐘,ratio<60*60 > 代表一個(gè)小時(shí),ratio<60*60*24 > 代表一天。而 ratio<1,1000 > 代表的是 1/1000 秒,也就是 1 毫秒,ratio<1,1000000 > 代表一微秒,ratio<1,1000000000 > 代表一納秒。
為了方便使用,在標(biāo)準(zhǔn)庫(kù)中定義了一些常用的時(shí)間間隔,比如:時(shí)、分、秒、毫秒、微秒、納秒,它們都位于 chrono 命名空間下,定義如下:
類型 | 定義 |
---|---|
納秒:std::chrono::nanoseconds | duration<Rep/ 至少 64 位的有符號(hào)整數(shù)類型 /, std::nano> |
微秒:std::chrono::microseconds | duration<Rep/ 至少 55 位的有符號(hào)整數(shù)類型 /, std::micro> |
毫秒:std::chrono::milliseconds | duration<Rep/ 至少 45 位的有符號(hào)整數(shù)類型 /, std::milli> |
秒:std::chrono::seconds | duration<Rep/ 至少 35 位的有符號(hào)整數(shù)類型 /> |
分鐘:std::chrono::minutes | duration<Rep/ 至少 29 位的有符號(hào)整數(shù)類型 /, std::ratio<60>> |
小時(shí):std::chrono::hours | duration<Rep/ 至少 23 位的有符號(hào)整數(shù)類型 /, std::ratio<3600>> |
注意:到 hours 為止的每個(gè)預(yù)定義時(shí)長(zhǎng)類型至少涵蓋 ±292 年的范圍。
duration 類的構(gòu)造函數(shù)原型如下:
// 1. 拷貝構(gòu)造函數(shù) duration( const duration& ) = default; // 2. 通過指定時(shí)鐘周期的類型來構(gòu)造對(duì)象 template< class Rep2 > constexpr explicit duration( const Rep2& r ); // 3. 通過指定時(shí)鐘周期類型,和時(shí)鐘周期長(zhǎng)度來構(gòu)造對(duì)象 template< class Rep2, class Period2 > constexpr duration( const duration<Rep2,Period2>& d );
為了更加方便的進(jìn)行 duration 對(duì)象之間的操作,類內(nèi)部進(jìn)行了操作符重載:
操作符重載 | 描述 |
---|---|
operator= | 賦值內(nèi)容 (公開成員函數(shù)) |
operator+ operator- | 賦值內(nèi)容 (公開成員函數(shù)) |
operator++ operator++(int) operator– operator–(int) | 遞增或遞減周期計(jì)數(shù) (公開成員函數(shù)) |
operator+= operator-= operator*= operator/= operator%= | 實(shí)現(xiàn)二個(gè)時(shí)長(zhǎng)間的復(fù)合賦值 (公開成員函數(shù)) |
duration 類還提供了獲取時(shí)間間隔的時(shí)鐘周期數(shù)的方法 count (),函數(shù)原型如下:
constexpr rep count() const;
1.2 類的使用
通過構(gòu)造函數(shù)構(gòu)造事件間隔對(duì)象示例代碼如下:
#include <chrono> #include <iostream> using namespace std; int main() { chrono::hours h(1); // 一小時(shí) chrono::milliseconds ms{ 3 }; // 3 毫秒 chrono::duration<int, ratio<1000>> ks(3); // 3000 秒 // chrono::duration<int, ratio<1000>> d3(3.5); // error chrono::duration<double> dd(6.6); // 6.6 秒 // 使用小數(shù)表示時(shí)鐘周期的次數(shù) chrono::duration<double, std::ratio<1, 30>> hz(3.5); }
- h(1) 時(shí)鐘周期為 1 小時(shí),共有 1 個(gè)時(shí)鐘周期,所以 h 表示的時(shí)間間隔為 1 小時(shí)
- ms(3) 時(shí)鐘周期為 1 毫秒,共有 3 個(gè)時(shí)鐘周期,所以 ms 表示的時(shí)間間隔為 3 毫秒
- ks(3) 時(shí)鐘周期為 1000 秒,一共有三個(gè)時(shí)鐘周期,所以 ks 表示的時(shí)間間隔為 3000 秒
- d3(3.5) 時(shí)鐘周期為 1000 秒,時(shí)鐘周期數(shù)量只能用整形來表示,但是此處指定的是浮點(diǎn)數(shù),因此語法錯(cuò)誤
- dd(6.6) 時(shí)鐘周期為默認(rèn)的 1 秒,共有 6.6 個(gè)時(shí)鐘周期,所以 dd 表示的時(shí)間間隔為 6.6 秒
- hz(3.5) 時(shí)鐘周期為 1/30 秒,共有 3.5 個(gè)時(shí)鐘周期,所以 hz 表示的時(shí)間間隔為 1/30*3.5 秒
chrono 庫(kù)中根據(jù) duration 類封裝了不同長(zhǎng)度的時(shí)鐘周期(也可以自定義),基于這個(gè)時(shí)鐘周期再進(jìn)行周期次數(shù)的設(shè)置就可以得到總的時(shí)間間隔了(時(shí)鐘周期 * 周期次數(shù) = 總的時(shí)間間隔)。
示例代碼如下:
#include <chrono> #include <iostream> int main() { std::chrono::milliseconds ms{3}; // 3 毫秒 std::chrono::microseconds us = 2*ms; // 6000 微秒 // 時(shí)間間隔周期為 1/30 秒 std::chrono::duration<double, std::ratio<1, 30>> hz(3.5); std::cout << "3 ms duration has " << ms.count() << " ticks\n" << "6000 us duration has " << us.count() << " ticks\n" << "3.5 hz duration has " << hz.count() << " ticks\n"; }
輸出的結(jié)果為:
3 ms duration has 3 ticks
6000 us duration has 6000 ticks
3.5 hz duration has 3.5 ticks
- ms 時(shí)間單位為毫秒,初始化操作 ms{3} 表示時(shí)間間隔為 3 毫秒,一共有 3 個(gè)時(shí)間周期,每個(gè)周期為 1 毫秒
- us 時(shí)間單位為微秒,初始化操作 2*ms 表示時(shí)間間隔為 6000 微秒,一共有 6000 個(gè)時(shí)間周期,每個(gè)周期為 1 微秒
- hz 時(shí)間單位為秒,初始化操作 hz(3.5) 表示時(shí)間間隔為 1/30*3.5 秒,一共有 3.5 個(gè)時(shí)間周期,每個(gè)周期為 1/30 秒
由于在 duration 類內(nèi)部做了操作符重載,因此時(shí)間間隔之間可以直接進(jìn)行算術(shù)運(yùn)算,比如我們要計(jì)算兩個(gè)時(shí)間間隔的差值,就可以在代碼中做如下處理:
#include <iostream> #include <chrono> using namespace std; int main() { chrono::minutes t1(10); chrono::seconds t2(60); chrono::seconds t3 = t1 - t2; cout << t3.count() << " second" << endl; }
程序輸出的結(jié)果:
540 second
在上面的測(cè)試程序中,t1 代表 10 分鐘,t2 代表 60 秒,t3 是 t1 減去 t2,也就是 60*10-60=540,這個(gè) 540 表示的時(shí)鐘周期,每個(gè)時(shí)鐘周期是 1 秒,因此兩個(gè)時(shí)間間隔之間的差值為 540 秒。
注意事項(xiàng):duration 的加減運(yùn)算有一定的規(guī)則,當(dāng)兩個(gè) duration 時(shí)鐘周期不相同的時(shí)候,會(huì)先統(tǒng)一成一種時(shí)鐘,然后再進(jìn)行算術(shù)運(yùn)算,統(tǒng)一的規(guī)則如下:假設(shè)有 ratio<x1,y1> 和 ratio<x2,y2 > 兩個(gè)時(shí)鐘周期,首先需要求出 x1,x2 的最大公約數(shù) X,然后求出 y1,y2 的最小公倍數(shù) Y,統(tǒng)一之后的時(shí)鐘周期 ratio 為 ratio<X,Y>。
#include <iostream> #include <chrono> using namespace std; int main() { chrono::duration<double, ratio<9, 7>> d1(3); chrono::duration<double, ratio<6, 5>> d2(1); // d1 和 d2 統(tǒng)一之后的時(shí)鐘周期 chrono::duration<double, ratio<3, 35>> d3 = d1 - d2; }
對(duì)于分子 6,、9 最大公約數(shù)為 3,對(duì)于分母 7、5 最小公倍數(shù)為 35,因此推導(dǎo)出的時(shí)鐘周期為 ratio<3,35>
2. 時(shí)間點(diǎn) time point
chrono 庫(kù)中提供了一個(gè)表示時(shí)間點(diǎn)的類 time_point,該類的定義如下:
// 定義于頭文件 <chrono> template< class Clock, class Duration = typename Clock::duration > class time_point;
它被實(shí)現(xiàn)成如同存儲(chǔ)一個(gè) Duration 類型的自 Clock 的紀(jì)元起始開始的時(shí)間間隔的值,通過這個(gè)類最終可以得到時(shí)間中的某一個(gè)時(shí)間點(diǎn)。
- Clock:此時(shí)間點(diǎn)在此時(shí)鐘上計(jì)量
- Duration:用于計(jì)量從紀(jì)元起時(shí)間的 std::chrono::duration 類型
time_point 類的構(gòu)造函數(shù)原型如下:
// 1. 構(gòu)造一個(gè)以新紀(jì)元(epoch,即:1970.1.1)作為值的對(duì)象,需要和時(shí)鐘類一起使用,不能單獨(dú)使用該無參構(gòu)造函數(shù) time_point(); // 2. 構(gòu)造一個(gè)對(duì)象,表示一個(gè)時(shí)間點(diǎn),其中d的持續(xù)時(shí)間從epoch開始,需要和時(shí)鐘類一起使用,不能單獨(dú)使用該構(gòu)造函數(shù) explicit time_point( const duration& d ); // 3. 拷貝構(gòu)造函數(shù),構(gòu)造與t相同時(shí)間點(diǎn)的對(duì)象,使用的時(shí)候需要指定模板參數(shù) template< class Duration2 > time_point( const time_point<Clock,Duration2>& t );
在這個(gè)類中除了構(gòu)造函數(shù)還提供了另外一個(gè) time_since_epoch() 函數(shù),用來獲得 1970 年 1 月 1 日到 time_point 對(duì)象中記錄的時(shí)間經(jīng)過的時(shí)間間隔(duration),函數(shù)原型如下:
duration time_since_epoch() const;
除此之外,時(shí)間點(diǎn) time_point 對(duì)象和時(shí)間段對(duì)象 duration 之間還支持直接進(jìn)行算術(shù)運(yùn)算(即加減運(yùn)算),時(shí)間點(diǎn)對(duì)象之間可以進(jìn)行邏輯運(yùn)算,具體細(xì)節(jié)可以參考下面的表格:
其中 tp 和 tp2 是 time_point 類型的對(duì)象, dtn 是 duration 類型的對(duì)象。
描述 | 操作 | 返回值 |
---|---|---|
復(fù)合賦值 (成員函數(shù)) operator+= | tp += dtn | *this |
復(fù)合賦值 (成員函數(shù)) operator-= | tp -= dtn | *this |
算術(shù)運(yùn)算符 (非成員函數(shù)) operator+ | tp + dtn | a time_point value |
算術(shù)運(yùn)算符 (非成員函數(shù)) operator+ | dtn + tp | a time_point value |
算術(shù)運(yùn)算符 (非成員函數(shù)) operator- | tp - dtn | a time_point value |
算術(shù)運(yùn)算符 (非成員函數(shù)) operator- | ttp - tp2 | aduration value |
關(guān)系操作符 (非成員函數(shù)) operator== | tp == tp2 | a bool value |
關(guān)系操作符 (非成員函數(shù)) operator!= | tp != tp2 | a bool value |
關(guān)系操作符 (非成員函數(shù)) operator< | tp < tp2 | a bool value |
關(guān)系操作符 (非成員函數(shù)) operator> | tp > tp2 | a bool value |
關(guān)系操作符 (非成員函數(shù)) operator>= | tp >= tp2 | a bool value |
關(guān)系操作符 (非成員函數(shù)) operator<= | tp <= tp2 | a bool value |
由于該時(shí)間點(diǎn)類經(jīng)常和下面要介紹的時(shí)鐘類一起使用,所以在此先不舉例,在時(shí)鐘類的示例代碼中會(huì)涉及到時(shí)間點(diǎn)類的使用,到此為止只需要搞明白時(shí)間點(diǎn)類的提供的這幾個(gè)函數(shù)的作用就可以了。
3. 時(shí)鐘 clocks
chrono 庫(kù)中提供了獲取當(dāng)前的系統(tǒng)時(shí)間的時(shí)鐘類,包含的時(shí)鐘一共有三種:
- system_clock:系統(tǒng)的時(shí)鐘,系統(tǒng)的時(shí)鐘可以修改,甚至可以網(wǎng)絡(luò)對(duì)時(shí),因此使用系統(tǒng)時(shí)間計(jì)算時(shí)間差可能不準(zhǔn)。
- steady_clock:是固定的時(shí)鐘,相當(dāng)于秒表。開始計(jì)時(shí)后,時(shí)間只會(huì)增長(zhǎng)并且不能修改,適合用于記錄程序耗時(shí)
- high_resolution_clock:和時(shí)鐘類 steady_clock 是等價(jià)的(是它的別名)。
在這些時(shí)鐘類的內(nèi)部有 time_point、duration、Rep、Period 等信息,基于這些信息來獲取當(dāng)前時(shí)間,以及實(shí)現(xiàn) time_t 和 time_point 之間的相互轉(zhuǎn)換。
時(shí)鐘類成員類型 | 描述 |
---|---|
rep | 表示時(shí)鐘周期次數(shù)的有符號(hào)算術(shù)類型 |
period | 表示時(shí)鐘計(jì)次周期的 std::ratio 類型 |
duration | 時(shí)間間隔,可以表示負(fù)時(shí)長(zhǎng) |
time_point | 表示在當(dāng)前時(shí)鐘里邊記錄的時(shí)間點(diǎn) |
在使用chrono提供的時(shí)鐘類的時(shí)候,不需要?jiǎng)?chuàng)建類對(duì)象,直接調(diào)用類的靜態(tài)方法就可以得到想要的時(shí)間了。
3.1 system_clock
具體來說,時(shí)鐘類 system_clock 是一個(gè)系統(tǒng)范圍的實(shí)時(shí)時(shí)鐘。system_clock 提供了對(duì)當(dāng)前時(shí)間點(diǎn) time_point 的訪問,將得到時(shí)間點(diǎn)轉(zhuǎn)換為 time_t 類型的時(shí)間對(duì)象,就可以基于這個(gè)時(shí)間對(duì)象獲取到當(dāng)前的時(shí)間信息了。
system_clock 時(shí)鐘類在底層源碼中的定義如下:
struct system_clock { // wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime using rep = long long; using period = ratio<1, 10'000'000>; // 100 nanoseconds using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<system_clock>; static constexpr bool is_steady = false; _NODISCARD static time_point now() noexcept { // get current time return time_point(duration(_Xtime_get_ticks())); } _NODISCARD static __time64_t to_time_t(const time_point& _Time) noexcept { // convert to __time64_t return duration_cast<seconds>(_Time.time_since_epoch()).count(); } _NODISCARD static time_point from_time_t(__time64_t _Tm) noexcept { // convert from __time64_t return time_point{seconds{_Tm}}; } };
通過以上源碼可以了解到在 system_clock 類中的一些細(xì)節(jié)信息:
- rep:時(shí)鐘周期次數(shù)是通過整形來記錄的 long long
- period:一個(gè)時(shí)鐘周期是 100 納秒 ratio<1, 10'000'000>
- duration:時(shí)間間隔為 rep*period 納秒 chrono::duration<rep, period>
- time_point:時(shí)間點(diǎn)通過系統(tǒng)時(shí)鐘做了初始化 chrono::time_p- oint<system_clock>,里面記錄了新紀(jì)元時(shí)間點(diǎn)
另外還可以看到 system_clock 類一共提供了三個(gè)靜態(tài)成員函數(shù):
// 返回表示當(dāng)前時(shí)間的時(shí)間點(diǎn)。 static std::chrono::time_point<std::chrono::system_clock> now() noexcept; // 將 time_point 時(shí)間點(diǎn)類型轉(zhuǎn)換為 std::time_t 類型 static std::time_t to_time_t( const time_point& t ) noexcept; // 將 std::time_t 類型轉(zhuǎn)換為 time_point 時(shí)間點(diǎn)類型 static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept;
比如,我們要獲取當(dāng)前的系統(tǒng)時(shí)間,并且需要將其以能夠識(shí)別的方式打印出來,示例代碼如下:
#include <chrono> #include <iostream> using namespace std; using namespace std::chrono; int main() { // 新紀(jì)元1970.1.1時(shí)間 system_clock::time_point epoch; duration<int, ratio<60*60*24>> day(1); // 新紀(jì)元1970.1.1時(shí)間 + 1天 system_clock::time_point ppt(day); using dday = duration<int, ratio<60 * 60 * 24>>; // 新紀(jì)元1970.1.1時(shí)間 + 10天 time_point<system_clock, dday> t(dday(10)); // 系統(tǒng)當(dāng)前時(shí)間 system_clock::time_point today = system_clock::now(); // 轉(zhuǎn)換為time_t時(shí)間類型 time_t tm = system_clock::to_time_t(today); cout << "今天的日期是: " << ctime(&tm); time_t tm1 = system_clock::to_time_t(today+day); cout << "明天的日期是: " << ctime(&tm1); time_t tm2 = system_clock::to_time_t(epoch); cout << "新紀(jì)元時(shí)間: " << ctime(&tm2); time_t tm3 = system_clock::to_time_t(ppt); cout << "新紀(jì)元時(shí)間+1天: " << ctime(&tm3); time_t tm4 = system_clock::to_time_t(t); cout << "新紀(jì)元時(shí)間+10天: " << ctime(&tm4); }
示例代碼打印的結(jié)果為:
今天的日期是: Thu Apr 8 11:09:49 2021
明天的日期是: Fri Apr 9 11:09:49 2021
新紀(jì)元時(shí)間: Thu Jan 1 08:00:00 1970
新紀(jì)元時(shí)間+1天: Fri Jan 2 08:00:00 1970
新紀(jì)元時(shí)間+10天: Sun Jan 11 08:00:00 1970
3.2 steady_clock
如果我們通過時(shí)鐘不是為了獲取當(dāng)前的系統(tǒng)時(shí)間,而是進(jìn)行程序耗時(shí)的時(shí)長(zhǎng),此時(shí)使用 syetem_clock 就不合適了,因?yàn)檫@個(gè)時(shí)間可以跟隨系統(tǒng)的設(shè)置發(fā)生變化。在 C++11 中提供的時(shí)鐘類 steady_clock 相當(dāng)于秒表,只要啟動(dòng)就會(huì)進(jìn)行時(shí)間的累加,并且不能被修改,非常適合于進(jìn)行耗時(shí)的統(tǒng)計(jì)。
steady_clock 時(shí)鐘類在底層源碼中的定義如下:
struct steady_clock { // wraps QueryPerformanceCounter using rep = long long; using period = nano; using duration = nanoseconds; using time_point = chrono::time_point<steady_clock>; static constexpr bool is_steady = true; // get current time _NODISCARD static time_point now() noexcept { // doesn't change after system boot const long long _Freq = _Query_perf_frequency(); const long long _Ctr = _Query_perf_counter(); static_assert(period::num == 1, "This assumes period::num == 1."); const long long _Whole = (_Ctr / _Freq) * period::den; const long long _Part = (_Ctr % _Freq) * period::den / _Freq; return time_point(duration(_Whole + _Part)); } };
通過以上源碼可以了解到在 steady_clock 類中的一些細(xì)節(jié)信息:
- rep:時(shí)鐘周期次數(shù)是通過整形來記錄的 long long
- period:一個(gè)時(shí)鐘周期是 1 納秒 nano
- duration:時(shí)間間隔為 1 納秒 nanoseconds
- time_point:時(shí)間點(diǎn)通過系統(tǒng)時(shí)鐘做了初始化 chrono::time_point<steady_clock>
另外,在這個(gè)類中也提供了一個(gè)靜態(tài)的 now () 方法,用于得到當(dāng)前的時(shí)間點(diǎn),函數(shù)原型如下:
static std::chrono::time_point<std::chrono::steady_clock> now() noexcept;
假設(shè)要測(cè)試某一段程序的執(zhí)行效率,可以計(jì)算它執(zhí)行期間消耗的總時(shí)長(zhǎng),示例代碼如下:
#include <chrono> #include <iostream> using namespace std; using namespace std::chrono; int main() { // 獲取開始時(shí)間點(diǎn) steady_clock::time_point start = steady_clock::now(); // 執(zhí)行業(yè)務(wù)流程 cout << "print 1000 stars ...." << endl; for (int i = 0; i < 1000; ++i) { cout << "*"; } cout << endl; // 獲取結(jié)束時(shí)間點(diǎn) steady_clock::time_point last = steady_clock::now(); // 計(jì)算差值 auto dt = last - start; cout << "總共耗時(shí): " << dt.count() << "納秒" << endl; }
3.3 high_resolution_clock
high_resolution_clock 提供的時(shí)鐘精度比 system_clock 要高,它也是不可以修改的。在底層源碼中,這個(gè)類其實(shí)是 steady_clock 類的別名。
using high_resolution_clock = steady_clock;
因此 high_resolution_clock 的使用方式和 steady_clock 是一樣的,在此就不再過多進(jìn)行贅述了。
4. 轉(zhuǎn)換函數(shù)
4.1 duration_cast
duration_cast 是 chrono 庫(kù)提供的一個(gè)模板函數(shù),這個(gè)函數(shù)不屬于 duration 類。通過這個(gè)函數(shù)可以對(duì) duration 類對(duì)象內(nèi)部的時(shí)鐘周期 Period,和周期次數(shù)的類型 Rep 進(jìn)行修改,該函數(shù)原型如下:
template <class ToDuration, class Rep, class Period> constexpr ToDuration duration_cast (const duration<Rep,Period>& dtn);
在源周期能準(zhǔn)確地為目標(biāo)周期所整除的場(chǎng)合(例如小時(shí)到分鐘),浮點(diǎn)時(shí)長(zhǎng)和整數(shù)時(shí)長(zhǎng)間轉(zhuǎn)型能隱式進(jìn)行無需使用 duration_cast ,其他情況下都需要通過函數(shù)進(jìn)行轉(zhuǎn)換。
我們可以修改一下上面測(cè)試程序執(zhí)行時(shí)間的代碼,在代碼中修改 duration 對(duì)象的屬性:
#include <iostream> #include <chrono> using namespace std; using namespace std::chrono; void f() { cout << "print 1000 stars ...." << endl; for (int i = 0; i < 1000; ++i) { cout << "*"; } cout << endl; } int main() { auto t1 = steady_clock::now(); f(); auto t2 = steady_clock::now(); // 整數(shù)時(shí)長(zhǎng):要求 duration_cast auto int_ms = duration_cast<chrono::milliseconds>(t2 - t1); // 小數(shù)時(shí)長(zhǎng):不要求 duration_cast duration<double, ratio<1, 1000>> fp_ms = t2 - t1; cout << "f() took " << fp_ms.count() << " ms, " << "or " << int_ms.count() << " whole milliseconds\n"; }
示例代碼輸出的結(jié)果:
print 1000 stars ....
****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
f() took 40.2547 ms, or 40 whole milliseconds
4.2 time_point_cast
time_point_cast 也是 chrono 庫(kù)提供的一個(gè)模板函數(shù),這個(gè)函數(shù)不屬于 time_point 類。函數(shù)的作用是對(duì)時(shí)間點(diǎn)進(jìn)行轉(zhuǎn)換,因?yàn)椴煌臅r(shí)間點(diǎn)對(duì)象內(nèi)部的時(shí)鐘周期 Period,和周期次數(shù)的類型 Rep 可能也是不同的,一般情況下它們之間可以進(jìn)行隱式類型轉(zhuǎn)換,也可以通過該函數(shù)顯示的進(jìn)行轉(zhuǎn)換,函數(shù)原型如下:
template <class ToDuration, class Clock, class Duration> time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration> &t);
關(guān)于函數(shù)的使用,示例代碼如下:
#include <chrono> #include <iostream> using namespace std; using Clock = chrono::high_resolution_clock; using Ms = chrono::milliseconds; using Sec = chrono::seconds; template<class Duration> using TimePoint = chrono::time_point<Clock, Duration>; void print_ms(const TimePoint<Ms>& time_point) { std::cout << time_point.time_since_epoch().count() << " ms\n"; } int main() { TimePoint<Sec> time_point_sec(Sec(6)); // 無精度損失, 可以進(jìn)行隱式類型轉(zhuǎn)換 TimePoint<Ms> time_point_ms(time_point_sec); print_ms(time_point_ms); // 6000 ms time_point_ms = TimePoint<Ms>(Ms(6789)); // error,會(huì)損失精度,不允許進(jìn)行隱式的類型轉(zhuǎn)換 TimePoint<Sec> sec(time_point_ms); // 顯示類型轉(zhuǎn)換,會(huì)損失精度。6789 truncated to 6000 time_point_sec = std::chrono::time_point_cast<Sec>(time_point_ms); print_ms(time_point_sec); // 6000 ms }
注意事項(xiàng):關(guān)于時(shí)間點(diǎn)的轉(zhuǎn)換如果沒有沒有精度的損失可以直接進(jìn)行隱式類型轉(zhuǎn)換,如果會(huì)損失精度只能通過顯示類型轉(zhuǎn)換,也就是調(diào)用 time_point_cast 函數(shù)來完成該操作。
到此這篇關(guān)于C++使用chrono庫(kù)處理日期和時(shí)間的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)C++ chrono日期和時(shí)間處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章

C語言實(shí)現(xiàn)數(shù)獨(dú)游戲的求解

C++?Qt實(shí)現(xiàn)一個(gè)解除文件占用小工具