chrono是C++11新加入的方便時間日期操作的標准庫,它既是相應的頭文件名稱,也是std命名空間下的一個子命名空間,所有時間日期相關定義均在std::chrono命名空間下。通過這個新的標准庫,可以非常方便進行時間日期相關操作。
chrono庫主要包含了三種類型:duration, time_point 和 clock
需要:
#include <ratio> //表示時間單位的庫
#include <chrono>
duration 時間段類型
/* ratio這個類模版的原型:格式:std::ratio<intmax_t N, intmax_t D = 1> 用來表示單位:【用秒表示的時間單位】比如:秒,分,小時等 N代表分子,D代表分母(可省略,默認值是1),所以ratio表示一個分數值
為了方便,C++標准委員會還預定義了下面這些單位比率,供用戶使用
typedef std::ratio<1, 1000000000000000000> atto;
typedef std::ratio<1, 1000000000000000> femto;
typedef std::ratio<1, 1000000000000> pico;
typedef std::ratio<1, 1000000000> nano;
typedef std::ratio<1, 1000000> micro;
typedef std::ratio<1, 1000> milli;
typedef std::ratio<1, 100> centi;
typedef std::ratio<1, 10> deci;
typedef std::ratio< 10, 1> deca;
typedef std::ratio< 100, 1> hecto;
typedef std::ratio< 1000, 1> kilo;
typedef std::ratio< 1000000, 1> mega;
typedef std::ratio< 1000000000, 1> giga;
typedef std::ratio< 1000000000000, 1> tera;
typedef std::ratio< 1000000000000000, 1> peta;
typedef std::ratio< 1000000000000000000, 1> exa;
ratio<3600, 1> 小時 ratio<60, 1> 分 ratio<1, 1> 秒 ratio<1, 1000> 毫秒 milli ratio<1, 1000000> 微妙 micro ratio<1, 1000000000> 納秒 nano 注意,我們自己可以定義:比如ratio<1, 2>表示單位時間是0.5秒 */
#include <iostream> #include <ratio> //表示時間單位的庫 #include <chrono> #include <thread> int main() { std::chrono::duration<int, std::ratio<60 * 60>> h_oneday(24); // 創建一段時間對象 24h /* std::chrono::duration 表示一段時間 int是數據類型,可以是float double等 std::ratio<60 * 60> 是單位比率,默認為std::ratio<1> h_oneday(24) 表示時間是:24*單位比率=24h
24(rep)理解成周期數 單位比率理解成一個周期 */ std::chrono::duration<int> s_oneday(60 * 60 * 24); // 86400s //使用默認單位比率std::ratio<1> /* 為了方便使用,chrono庫定義了如下的常用時間單位: typedef duration<int64_t, nano> nanoseconds; //納秒 typedef duration<int64_t, micro> microseconds; //微妙 typedef duration<int64_t, milli> milliseconds; //毫秒 typedef duration<int64_t> seconds; //秒 typedef duration<int, ratio< 60>> minutes; //分 typedef duration<int, ratio<3600>> hours; //時 */ //通過定義上述常用類型,可以非常方便的使用: for (int i = 0; i < 100; i++) { std::cout << "i=" << i << std::endl; std::this_thread::sleep_for(std::chrono::seconds(3)); //本線程休眠3秒 } return 0; }
#include <iostream> #include <ratio> //表示時間單位的庫 #include <chrono> #include <thread> int main() { std::chrono::milliseconds ms(10);//10個tick==10個單位比率 std::chrono::duration<double, std::ratio<1, 30>> dur(10.5);//10.5 tick==10.5個單位比率 float x = ms.count(); //返回ms這個時間段對象中有多少個單位比率 std::cout << x<< std::endl; x = dur.count(); std::cout << x << std::endl; //duration實例化后,對於給定的rep表示周期個數的類型,提供了min、max和zero三個靜態成員函數,用來獲取當前類型能表示的最小、最大周期數和0周期數 double y = std::chrono::seconds::max().count(); //返回seconds的最大周期數 std::cout << y << std::endl; y = std::chrono::seconds::min().count();//返回seconds的最小周期數 std::cout << y << std::endl; y = std::chrono::seconds::zero().count();//返回seconds的0周期數 std::cout << y << std::endl; return 0; }
//duration支持基本所有算術運算操作,而且不同單位之間的可以自動進行匹配。這是通過duration_cast模板類實現的 std::chrono::minutes t1(5); //創建以分為單位的時間段 std::chrono::seconds t2(30); std::chrono::seconds t3 = t1 - t2; std::cout << t3.count() << std::endl; float x = std::chrono::duration_cast<std::chrono::minutes>(t3).count(); //單位轉換 //把t3的單位轉換為分並返回 //注意:對於類型轉換返回值只取指定單位的整數,零頭舍去 std::cout << x << std::endl;
時鍾clock
C++11為我們提供了三種時鍾類型:system_clock、steady_clock、high_resolution_clock
這三個時間類都提供了rep【周期】、period【單位比率】、duration成員類型
這三個時鍾類都提供了一個靜態成員函數now()用於獲取當前時間,該函數的返回值是一個time_point類型
注意:雖然這三個時鍾都很多相同的成員類型和成員函數,但它們是沒有親緣關系的。這三個時鍾類型都是類,並非模板類
這三個時鍾有什么區別呢?
system_clock:就類似Windows系統右下角那個時鍾,是系統時間。明顯這個時鍾是可以自己設置的。
system_clock除了now()函數外,還提供了to_time_t()靜態成員函數。用於將系統時間轉換成熟悉的std::time_t類型,得到了std::time_t類型的值,就可以很方便地打印當前時間了
steady_clock:是單調的時鍾,相當於教練手中的秒表;只會增長,適合用於記錄程序耗時,他表示時鍾是不能設置的
high_resolution_clock:是當前系統能夠提供的最高精度的時鍾;它也是不可以修改的。相當於 steady_clock 的高精度版本
system_clock例子
#include <iostream> #include <ratio> //表示時間單位的庫 #include <chrono> #include<ctime> int main() { auto tp = std::chrono::system_clock::now(); //獲取系統當前時間點 std::time_t cur_time = std::chrono::system_clock::to_time_t(tp); //將時間轉換為ctime的time_t格式 char stime[30]; errno_t err=ctime_s(stime, sizeof(stime), &cur_time); //轉換為字符串 std::cout << stime << std::endl; return 0; }
注意:不要將steady_clock、high_resolution_clock時鍾的now()返回值作為to_time_t的參數,這會導致編譯通不過。因為類型不匹配
auto自動為此變量選擇匹配的類型
steady_clock例子
steady_clock的實現是使用monotonic時間,而monotonic時間一般是從boot啟動后開始計數的。明顯這不能獲取日歷時間(年月日時分秒)。那么steady_clock有什么用途呢?時間比較!並且是不受用戶調整系統時鍾影響的時間比較
#include <iostream> #include <ratio> //表示時間單位的庫 #include <chrono> #include<ctime> #include <thread> int main() { auto begin = std::chrono::steady_clock::now(); //獲取系統啟動后到現在的時間點 for (int i = 0; i < 10; ++i) { std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << i << std::endl; } auto end = std::chrono::steady_clock::now(); auto diff = (end - begin).count(); //返回時間差--【單位:納秒】 std::cout << "diff="<<diff << std::endl; return 0; }
time_point 時間點類型
chrono庫中用一個time_point模板類,表示一個時間點,如生日、今天日落時刻等
通過一個相對epoch的時間間隔duration來實現,epoch就是1970-01-01T00:00:00時刻,對於同一個時鍾來說,所有的time_point的epoch都是固定的。這個類可以與標准庫ctime結合起來顯示時間,ctime內部的time_t類型就是代表這個秒數。
#include <iostream> #include <chrono> #include<ctime> int main() { //std::chrono::system_clock::time_point tp; //創建一個time_point類的時間點對象--格式一 std::chrono::time_point<std::chrono::system_clock> tp; //創建一個time_point類的時間點對象--格式二 //system_clock 采用的時鍾 tp= std::chrono::system_clock::now();//獲取系統現在的時間點--time_point時間點 std::time_t cur_time = std::chrono::system_clock::to_time_t(tp); char stime[30]; errno_t err = ctime_s(stime, sizeof(stime), &cur_time); std::cout << stime << std::endl; return 0; }
#include <iostream> #include <chrono> #include<ctime> int main() { std::chrono::time_point<std::chrono::system_clock> tp; tp= std::chrono::system_clock::now(); typedef std::chrono::duration<int, std::ratio<60 * 60 * 24>> days_type; //創建duration時間段--別名 std::chrono::time_point<std::chrono::system_clock, days_type> today ; //創建time_point時間點對象 //std::chrono::system_clock 采用的時鍾 //days_type 以這個時間段為單位 today = std::chrono::time_point_cast<days_type>(tp); //單位轉換 //把tp轉換成以days_type為單位的時間點 int x = today.time_since_epoch().count(); //返回 //函數time_from_eproch()用來獲得1970年1月1日到time_point時間經過的duration。舉個例子,如果timepoint以天為單位,函數返回的duration就以天為單位 //返回值的單位跟today一樣 std::cout << x << std::endl; return 0; }
#include <iostream> #include <chrono> #include<ctime> #include <ctime> int main() { std::chrono::time_point<std::chrono::system_clock> tp; tp= std::chrono::system_clock::now(); std::chrono::duration<int, std::ratio<60 * 60 * 24>> one_day(1); //創建duration時間段對象 std::chrono::system_clock::time_point today = std::chrono::system_clock::now(); std::chrono::system_clock::time_point tomorrow = today + one_day; //兩個時間點相加 std::time_t tt; char stime[30]; tt = std::chrono::system_clock::to_time_t(today); //把time_point轉換成time_t errno_t err = ctime_s(stime, sizeof(stime), &tt); std::cout << "today is: " << stime << std::endl; tt = std::chrono::system_clock::to_time_t(tomorrow); err = ctime_s(stime, sizeof(stime), &tt); std::cout << "tomorrow will be: " << stime << std::endl; tomorrow = std::chrono::system_clock::from_time_t(tt); //從time_t轉換成time_point return 0; }