大抵の計算機は、現在時刻として世界協定時(UTC:Coordinated Universal Time)などの時刻を保持して更新しています。これによって、ユーザが認識している「現在時刻」と互換性のある時刻をプログラム内で使用することができます。ただし、UTC時刻と合わせるための仕組みが必要になります。また、計算機は時刻の進みを次節で説明するクロックから算出して更新しているため、定期的にUTC時刻と同期を行なわないと徐々にずれていくことになります。
UTC時刻は、グリニッジ子午線(経度0度)での真夜中を0時0分0秒として1日の時間を表現します。しかし、ユーザの生活している国・地域(ロケール)では、それぞれロケール毎に基準となる子午線(経度)を決めて時刻を表現しています。例えば日本標準時は東経135度を子午線として時刻を表現します。UTC時刻とは9時間(経度15度につき1時間の差)のずれが生じます。
コンピュータの中では、ユーザの時刻とは別に内部の電子回路が動作するための基準となる電気信号クロック(日本語に訳すと「時計」となってしまうが意味が異なる)を持っています。プログラム内でこのクロックに基づく時刻を使用することができます。
クロックは大抵の場合電子回路上で発振器によって得られる一定の周波数信号に基づいて刻まれます。したがって、同じ1クロックでも計算機のハードウェアによって長さが異なります。例えば、1GHzのCPUを持つ計算機において計測されるクロックは、1ナノ秒の分解能となります。ただし、クロックが基準とする発振器は素材の特性や環境によって周波数にずれやゆらぎが生じるため、クロックで算出する1秒と前述のUTCにおける1秒とでは長さに誤差が生じます。
現在のシステム時刻を、UTC1970年1月1日0時0分0秒からの経過時間でミリ秒単位で取得します。ただし、精度はプログラムを実行しているプラットフォームに依存し、Windows OSのPCでは10ミリ秒や15ミリ秒が典型的な値です。
プログラム内において、ある瞬間から別の瞬間までの時間を計測するニーズがあります。処理時間の計測などが例です。この場合、システム時刻(カレンダー)は不要です。ただし、プログラムは非常に高速に実行されるため、ある瞬間の時刻を取得する際の分解能が重要となります。
Java 2 Standard Edition, v5.0から追加されたメソッドです。プログラムを実行しているプラットフォーム上で利用可能なもっとも正確(高分解能)なクロックの値を取得します。値は相対的なもので、システム起動後のCPUクロックのカウント値などが典型的なものです。APIとしてはナノ秒単位の値を返却しますが、実際に得られる精度はプラットフォームで利用可能なクロックに依存します。
System.nanoTimeメソッドは、nativeメソッドで、以下のように実装されています。(1)
参考までに、各OS毎の時間を計測する方法を紹介します。
| API名 | 時間種類 | 内容 |
|---|---|---|
| QueryPerformanceCounter |
| API名 | 時間種類 | 内容 |
|---|---|---|
| clock | ||
| gettimeofday | システム時刻 | UTC1970年1月1日0時0分0秒からの経過時間をマイクロ秒単位で取得 |
| API名 | 時間種類 | 内容 |
|---|---|---|
| gettimeofday | システム時刻 | UTC1970年1月1日0時0分0秒からの経過時間をマイクロ秒単位で取得 |
| gethrtime | 相対時刻 | CPUのTICKレジスタから算出したシステム起動からの経過時間をナノ秒単位で取得 |