現在、本日が始まってから何ミリ秒過ぎたかを求めるため、c++11で追加されたstd::chronoライブラリを勉強がてら使ってみた。もっとスマートな方法もあるかもしれないが。以下、c++11/Windows環境の場合。c++17やLinux環境だと別の方法もあるらしい。
現在時刻に関する情報はnow()関数で取れる。なおこの時刻はUTC(協定世界時)であり日本時間とは異なる。
1 2 3 4 |
#include <chrono> std::chrono::system_clock::time_point tp = std::chrono::system_clock::now(); |
time_since_epoc関数で「エポックからの経過時間」を求めて、メンバ関数countでミリ秒を取得。そこから現在時刻のミリ秒部分を得る。この「エポック」が何時なのかは未規定だが概ね1970/1/1で、経過ミリ秒は軽く1兆を超える値になり、32bit intでは正常に収容できないので注意が必要。(もちろんautoを使えば問題ない)。
1 2 3 4 5 6 7 8 |
//エポックからの経過時間 std::chrono::milliseconds tp_msec = std::chrono::duration_cast<std::chrono::milliseconds> ( tp.time_since_epoch() ); //経過時間を総ミリ秒(整数値)に変換 long long all_msec = tp_msec.count(); //1秒未満の値を取り出す int msec = all_msec % 1000; |
時間・分・秒を取得するため、time_tに変換。さらに現地時間(日本時間)に変換する。
1 2 |
time_t time = std::chrono::system_clock::to_time_t( tp ); struct tm* t = localtime( &time ); |
この時点で本日の経過ミリ秒は自前で計算可能だが、せっかくtime_pointは減算が効くので、本日0時0分0秒000のtime_stampを求めてみる。
1 2 3 4 5 6 7 8 9 10 |
// 本日0時0分0秒000のtime_pointを求める std::chrono::system_clock::time_point day_tp = tp; // 0時にする day_tp -= std::chrono::hours( t->tm_hour ); // 0分にする day_tp -= std::chrono::minutes( t->tm_min ); // 0秒にする day_tp -= std::chrono::seconds( t->tm_sec ); // コンマ0秒にする day_tp -= std::chrono::milliseconds( msec ); |
time_point同士の減算から本日の経過ミリ秒を求める。
1 2 3 4 |
std::chrono::milliseconds tp_msec_today = std::chrono::duration_cast<std::chrono::milliseconds> ( tp - day_tp ); int msec_today = tp_msec_today.count(); |
以下、まとめてシンプルに。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <chrono> using namespace std::chrono; //現在時刻を取得 system_clock::time_point tp = system_clock::now(); //現在時刻のミリ秒部分を取得 auto msec = duration_cast<milliseconds>( tp.time_since_epoch() ).count() % 1000; //時間・分・秒を得るためtime_tに変換 time_t time = system_clock::to_time_t( tp ); struct tm* t = localtime( &time ); //本日00:00:00:000のtime_pointを計算 system_clock::time_point day_start = tp - hours( t->tm_hour ) - minutes( t->tm_min ) - seconds( t->tm_sec ) - milliseconds( msec ); //本日開始時点からの経過ミリ秒を得る auto msec_tody = duration_cast<milliseconds>( tp - day_start ).count(); |
月初めからや年頭からの経過ミリ秒も求めたいが、std::chrono::monthやstd::chrono::yearはc++20で追加予定らしいので、c++11だとすんなりとはいかないようだ。
c++20では、ローカル時間用のtime_pointとか、 1日内の時間情報を取得するクラスtime_of_dayなども追加されるらしく、time_t変換などせずに、もっと楽に取得できるようになるかも。
c++builder10.2.3/Windows10(64bit/1909)で確認。