C++で現在時刻を取得する場合、現在では主に<chrono>を使う方法が基本です。
ただし、「現在時刻を取得したい」といっても、目的によって使うべき機能は変わります。
たとえば、現在の日時を表示したい場合と、プログラムの処理時間を計測したい場合では、適したクロックが異なります。
現在日時を取得したい場合は、主にstd::chrono::system_clockを使います。
一方、処理時間や経過時間を測定したい場合は、std::chrono::steady_clockを使うのが一般的です。
この違いを理解しておくと、ログ出力、タイムスタンプ生成、ベンチマーク、タイマー処理などで適切な実装を選びやすくなります。
現在日時の取得にはsystem_clockを使う
system_clockとは
std::chrono::system_clockは、システム上の現在時刻を扱うためのクロックです。
いわゆる実世界の日時、つまり「今が何年何月何日何時何分何秒か」を取得したいときに使います。
ログに現在日時を付けたい場合や、ファイル名に作成日時を入れたい場合などに適しています。
たとえば、次のような用途ではsystem_clockが向いています。
現在日時を画面に表示する場合、ログに時刻を記録する場合、UNIXタイムスタンプを取得する場合、ファイル名に日時を含める場合、APIへ送る日時データを作る場合などです。
system_clockはシステム時刻の影響を受ける
system_clockは、OSが管理しているシステム時刻をもとにしています。
そのため、PCやサーバーの時刻設定が変更されたり、NTPによる時刻補正が行われたりすると、取得される時刻も影響を受けます。
つまり、system_clockは「現在日時」を扱うには便利ですが、処理時間の計測には必ずしも向いていません。
なぜなら、処理中にシステム時刻が変更されると、経過時間の計算結果が不自然になる可能性があるからです。
処理時間の計測にはsteady_clockを使う
steady_clockとは
std::chrono::steady_clockは、経過時間を測定するために使いやすいクロックです。
steady_clockの大きな特徴は、時刻が逆戻りしないことです。
システム時刻が変更されても、steady_clockは単調に進むため、処理時間の計測に向いています。
たとえば、関数の実行時間を測定したい場合、ループ処理の時間を測りたい場合、タイムアウト処理を作りたい場合、ベンチマークを取りたい場合などには、steady_clockを使うのが適切です。
system_clockとsteady_clockの使い分け
現在日時を取得したい場合はsystem_clock、処理時間を測りたい場合はsteady_clockと覚えるとわかりやすいです。
ログに「2026年5月23日 15時30分45秒」のような日時を残したい場合はsystem_clockを使います。
一方で、「この処理に何ミリ秒かかったか」を測りたい場合はsteady_clockを使います。
この2つを混同すると、日時表示はできても処理時間の計測が不安定になったり、逆に経過時間の測定には向いていても人間が読める日時には変換しづらかったりします。
high_resolution_clockは慎重に使う
high_resolution_clockの特徴
C++にはstd::chrono::high_resolution_clockというクロックもあります。
名前だけ見ると、最も高精度で便利そうに見えます。
しかし、実際には注意が必要です。
high_resolution_clockは、環境によってsystem_clockの別名だったり、steady_clockの別名だったりすることがあります。
つまり、どのような性質を持つかは処理系に依存します。
実務ではsteady_clockを優先する
処理時間を測定したい場合、単に精度が高そうだからという理由でhigh_resolution_clockを選ぶよりも、まずはsteady_clockを検討する方が安全です。
steady_clockは時刻が逆戻りしないため、経過時間の測定に適しています。
高精度な時間計測が必要な場合でも、まずはsteady_clockで十分かどうかを確認し、それでも要件を満たせない場合に処理系の仕様を確認してhigh_resolution_clockを検討する、という順番が現実的です。
UNIX時間を取得する場合の考え方
UNIX時間とは
UNIX時間とは、1970年1月1日 00時00分00秒 UTCからの経過秒数を表す時間形式です。
Web API、ログ、データベース、ファイル管理など、さまざまな場面で使われます。
C++では、現在時刻を取得したあと、基準時刻からの経過時間を秒単位やミリ秒単位に変換することで、UNIX時間に近い値を得ることができます。
C++20以降ではより明確に扱える
C++20以降では、system_clockはUNIX時間を表すものとして定義されています。
そのため、C++20以降であれば、system_clockを使ってUNIXエポックからの経過時間を取得する、という説明はかなり自然です。
一方、C++11からC++17までは、標準仕様上、system_clockの基準時刻は厳密には未規定でした。
ただし、実際の主要な環境ではUNIXエポックを基準にしていることが多く、実務上はUNIX時間として扱えるケースが一般的です。
記事や教材として正確に書くなら、「C++20以降ではUNIX時間として定義されており、C++17以前でも多くの実装ではUNIXエポックを基準としている」と説明するとよいでしょう。
秒・ミリ秒・マイクロ秒・ナノ秒の取得
秒単位のタイムスタンプ
現在時刻を秒単位で扱いたい場合は、UNIXタイムスタンプとして使うことが多いです。
秒単位のタイムスタンプは、ログ、API連携、日付比較、キャッシュの有効期限管理などでよく使われます。
たとえば、「このデータはいつ作成されたか」「このセッションはいつ期限切れになるか」といった情報を扱う場合に便利です。
ミリ秒単位のタイムスタンプ
より細かい時間を扱いたい場合は、ミリ秒単位のタイムスタンプを使います。
ミリ秒単位の時刻は、Webアプリケーション、ゲーム、ログ解析、イベント管理などで使われることがあります。
特に、複数の処理が短時間に発生するシステムでは、秒単位だけでは順序を判別しにくいことがあります。
そのような場合に、ミリ秒単位の値が役立ちます。
マイクロ秒・ナノ秒単位の注意点
C++では、マイクロ秒やナノ秒単位の型を使って時間を扱うこともできます。
ただし、ナノ秒単位で値を取得できるからといって、実際の時計精度がナノ秒レベルであるとは限りません。
実際の精度は、OS、ハードウェア、標準ライブラリの実装に依存します。
つまり、型としてはナノ秒で表現できても、実際にその精度で時刻が測定されているとは限らないということです。
そのため、高精度な時間計測が必要な場合は、使用している環境でどの程度の分解能があるのかを確認する必要があります。
現在時刻を人間が読める形式で表示する
time_tへの変換
system_clockで取得した現在時刻は、そのままでは人間が読みやすい形式ではありません。
人間が読める日時として表示したい場合は、time_tに変換し、その後でローカル時刻やUTC時刻に変換して整形するのが一般的です。
たとえば、「2026-05-23 15:30:45」のような形式で表示したい場合は、現在時刻を取得してから、日付と時刻の各要素に分解し、表示用に整形します。
put_timeによる整形
C++では、日時を指定した形式で出力したい場合にstd::put_timeを使うことができます。
std::put_timeを使うと、年、月、日、時、分、秒などを自由な形式で表示できます。
たとえば、次のような形式に整形できます。
「2026-05-23 15:30:45」
「2026年05月23日 15時30分45秒」
「20260523_153045」
「Sat May 23 15:30:45 2026」
ファイル名に使う場合は、スラッシュやコロンを避けた形式にするのが安全です。
特にWindowsでは、ファイル名にコロンを使えないため、「20260523_153045」のような形式がよく使われます。
ローカル時刻とUTC時刻の違い
ローカル時刻とは
ローカル時刻とは、実行環境のタイムゾーンに基づいた時刻です。
日本の環境で実行すれば、日本標準時であるJSTとして扱われます。JSTはUTCより9時間進んでいます。
たとえば、UTCで午前6時30分の場合、日本時間では午後3時30分になります。
ユーザー向けに日時を表示する場合や、ローカル環境のログを確認する場合は、ローカル時刻で表示した方がわかりやすいことが多いです。
UTC時刻とは
UTCは、世界標準時として使われる時刻です。
サーバー間通信、API、データベース保存、ログ集約などでは、UTCで時刻を扱うことがよくあります。
特に、複数の国や地域にまたがるシステムでは、ローカル時刻のまま保存するとタイムゾーンの違いによって混乱しやすくなります。
そのため、内部的にはUTCで保存し、ユーザーに表示するときだけローカル時刻に変換する設計がよく使われます。
localtimeとgmtimeの注意点
localtimeはローカル時刻に変換する
localtimeは、time_tをローカル時刻に変換するために使われます。
日本の環境で実行すれば、日本時間として日時を取得できます。
ただし、localtimeは内部的に静的な領域を使うことがあり、複数スレッドから同時に呼び出すと安全でない場合があります。
簡単なサンプルやシングルスレッドのプログラムでは問題になりにくいですが、サーバーや並列処理を行うプログラムでは注意が必要です。
gmtimeはUTC時刻に変換する
gmtimeは、time_tをUTC時刻に変換するために使われます。
ローカル時刻ではなく、世界標準時として日時を扱いたい場合に使います。
ただし、gmtimeもlocaltimeと同様に、スレッド安全性には注意が必要です。
実務ではlocaltime_sやlocaltime_rを検討する
実務で安全性を重視する場合は、環境に応じてlocaltime_sやlocaltime_rを使うことがあります。
MSVC環境ではlocaltime_s、LinuxやmacOSなどのPOSIX環境ではlocaltime_rが使われることが一般的です。
ただし、localtime_sは処理系によって引数の順番などが異なる場合があるため、クロスプラットフォーム対応をする場合は注意が必要です。
C++20以降の日時処理
chronoの機能が強化された
C++20では、<chrono>の日時機能が大きく強化されました。
日付、時刻、タイムゾーン、カレンダー、フォーマットなどを扱いやすくするための機能が追加されています。
そのため、C++20以降に対応した環境であれば、従来よりも簡潔に日時を扱える場合があります。
formatを使う場合の注意点
C++20以降では、環境が対応していればstd::formatを使って日時を整形できます。
ただし、system_clockの時刻をそのままフォーマットすると、ローカル時刻ではなくUTC系の時刻として扱われる点に注意が必要です。
日本時間として表示したい場合は、単純に現在時刻をそのままフォーマットするだけでは、期待する時刻と9時間ずれる可能性があります。
そのため、ローカル時刻として表示したい場合は、タイムゾーンを考慮した処理を行うか、従来どおりtime_tに変換してローカル時刻として整形する方法を使うのが無難です。
コンパイラ対応にも注意する
C++20の日時関連機能は便利ですが、すべてのコンパイラや標準ライブラリで同じように使えるとは限りません。
特にstd::formatやタイムゾーン関連の機能は、環境によって対応状況に差があります。
実務で使う場合は、使用しているコンパイラ、標準ライブラリ、C++標準バージョンの対応状況を確認することが重要です。
安定性を重視するなら、C++11以降で使えるsystem_clock、to_time_t、localtime_sまたはlocaltime_r、put_timeを組み合わせる方法が無難です。
ファイル名に現在時刻を入れる場合
ファイル名向けの日時形式
ログファイルやバックアップファイルを作成するとき、ファイル名に現在時刻を入れることがあります。
この場合は、人間が読みやすいだけでなく、ファイルシステム上で扱いやすい形式にすることが大切です。
おすすめは、年月日と時分秒を数字だけで並べる形式です。
たとえば、「20260523_153045」のような形式です。
この形式には、次のようなメリットがあります。
日付順に並びやすいこと、スペースを含まないこと、スラッシュやコロンなどの扱いにくい記号を避けられること、WindowsやLinuxなど複数の環境で使いやすいことです。
コロンやスラッシュは避ける
日時を表すときに「2026/05/23」や「15:30:45」のような形式を使いたくなることがあります。
しかし、ファイル名として使う場合、スラッシュやコロンは避けた方が安全です。
スラッシュはディレクトリ区切りとして扱われることがあり、コロンはWindowsのファイル名では使えません。
そのため、ファイル名には「20260523_153045」のような形式を使うのが実務的です。
ログ出力で現在時刻を扱う場合
秒までで十分な場合
簡単なログであれば、秒単位の日時で十分なことが多いです。
たとえば、ユーザーの操作履歴、処理開始時刻、処理終了時刻などを記録する程度であれば、「年-月-日 時:分:秒」の形式で問題ないケースが多いです。
ミリ秒まで必要な場合
短時間に大量の処理が発生するシステムでは、秒単位だけでは不十分なことがあります。
たとえば、Webサーバー、ゲーム、リアルタイム処理、金融系システム、詳細なデバッグログなどでは、ミリ秒単位の時刻が必要になることがあります。
この場合は、秒までの日時に加えて、秒未満のミリ秒を付けると便利です。
ログではタイムゾーンも意識する
ログを出力するときは、ローカル時刻で出すのか、UTCで出すのかを決めておくことが重要です。
単一の地域で使う小規模なアプリケーションであれば、ローカル時刻でも問題ないことが多いです。
一方、サーバー、クラウド環境、海外ユーザーを含むシステムでは、UTCでログを保存した方が扱いやすい場合があります。
特に、複数のサーバーでログを突き合わせる場合、各サーバーのローカル時刻が異なると分析が難しくなります。
C言語由来のtime関数について
time関数でも現在時刻は取得できる
C++では、C言語由来のtime関数を使って現在時刻を取得することもできます。
これは古いコードやシンプルなサンプルでよく見かける方法です。
time関数を使うと、現在時刻をtime_tとして取得できます。
簡単に現在時刻を表示したいだけなら、この方法でも対応できます。
現在のC++ではchronoを優先する
ただし、現在のC++では<chrono>を使う方法が基本です。
time関数はシンプルですが、秒単位での扱いが中心になります。
ミリ秒やマイクロ秒などの細かい単位を扱いたい場合や、型安全に時間を扱いたい場合には、<chrono>の方が適しています。
そのため、新しくC++のコードを書く場合は、基本的にはstd::chronoを使うのがおすすめです。
実務でのおすすめの使い分け
現在日時を表示したい場合
現在の年月日や時分秒を表示したい場合は、system_clockを使います。
そこから表示用に変換し、必要に応じてローカル時刻やUTC時刻として整形します。
ユーザーに見せる日時であればローカル時刻、サーバー内部で保存する日時であればUTCを使うことが多いです。
UNIXタイムスタンプが欲しい場合
UNIXタイムスタンプが必要な場合も、基本的にはsystem_clockを使います。
秒単位でよいのか、ミリ秒単位が必要なのかを決めたうえで、適切な単位に変換します。
Web APIやデータベースでは、秒単位またはミリ秒単位のタイムスタンプがよく使われます。
処理時間を測りたい場合
処理時間を測定したい場合は、steady_clockを使います。
system_clockはシステム時刻の変更によって影響を受ける可能性があるため、経過時間の測定には向いていません。
関数の実行時間、ベンチマーク、タイムアウト、一定間隔の処理などには、steady_clockを使うのが安全です。
高精度な計測をしたい場合
高精度な計測が必要な場合でも、まずはsteady_clockを検討します。
high_resolution_clockは名前だけ見ると魅力的ですが、実装依存のため、必ずしも期待どおりの性質を持つとは限りません。
処理系の仕様を確認せずに使うよりも、単調性が保証されるsteady_clockを使う方が堅実です。
注意すべきポイント
現在時刻と経過時間を混同しない
C++で時刻を扱うときに最も重要なのは、現在時刻と経過時間を混同しないことです。
現在時刻は、カレンダー上の日時です。ログや表示に使います。
経過時間は、ある処理が始まってから終わるまでの時間です。
ベンチマークやタイマーに使います。
この2つは似ていますが、目的が違います。
現在時刻にはsystem_clock、経過時間にはsteady_clockを使うと考えると整理しやすいです。
タイムゾーンを意識する
日時を扱う場合、タイムゾーンの扱いも重要です。
ローカル時刻で表示するのか、UTCで保存するのかを明確にしておかないと、後から日時のずれやログ解析の混乱につながります。
特にWebサービスやサーバーアプリケーションでは、内部的にはUTCで保存し、表示時にユーザーのタイムゾーンへ変換する設計がよく使われます。
スレッド安全性を確認する
localtimeやgmtimeなどの関数は、簡単なサンプルでは便利ですが、マルチスレッド環境では注意が必要です。
サーバーや並列処理を行うアプリケーションでは、localtime_sやlocaltime_rなど、より安全な方法を検討する必要があります。
C++標準バージョンを確認する
C++11以降であれば、<chrono>を使った基本的な時刻処理が可能です。
C++20以降では、日時やフォーマット関連の機能が強化されていますが、環境によって対応状況に差があります。
そのため、記事や業務コードで紹介する場合は、対象とするC++標準バージョンを明確にしておくと親切です。
まとめ
C++で現在時刻を取得する場合、基本はstd::chronoを使います。
現在の日時を取得したい場合はsystem_clockを使い、処理時間を計測したい場合はsteady_clockを使います。
system_clockは実世界の日時を扱うためのクロックで、ログ出力、日時表示、UNIXタイムスタンプの取得などに向いています。
一方、steady_clockは時刻が逆戻りしないため、処理時間の測定、ベンチマーク、タイムアウト処理などに向いています。
UNIX時間を取得する場合、C++20以降ではsystem_clockをUNIXエポック基準の時刻として扱えます。
C++17以前でも多くの実装では同じように扱えますが、標準仕様上は基準時刻が未規定だった点には注意が必要です。
日時を人間が読める形式で表示する場合は、time_tに変換し、ローカル時刻またはUTC時刻として整形します。
実務では、スレッド安全性を考慮してlocaltime_sやlocaltime_rを使うこともあります。
C++20以降では日時処理が強化されていますが、std::formatでsystem_clockの時刻をそのまま表示すると、ローカル時刻ではなくUTC系として扱われる点に注意が必要です。
また、コンパイラや標準ライブラリの対応状況も確認する必要があります。
最も重要なのは、目的に応じてクロックを使い分けることです。
現在日時を知りたいならsystem_clock、処理時間を測りたいならsteady_clock。
この使い分けを押さえておけば、C++での時刻処理はかなり整理しやすくなります。
以上、C++で現在時刻を取得する方法についてでした。
最後までお読みいただき、ありがとうございました。
