メインコンテンツまでスキップ

6. Data Types (データ型)

すべてのNTP時刻値は2の補数形式 (twos-complement format) で表され、ビットは ([RFC0791]の付録Aで説明されているように) ビッグエンディアン (big-endian) 方式で、左側または上位の位置からゼロから始まる番号が付けられます。図3に示すように、3つのNTP時刻形式があります。128ビット日付形式 (date format)、64ビットタイムスタンプ形式 (timestamp format)、および32ビット短形式 (short format) です。128ビット日付形式は、十分なストレージとワードサイズが利用可能な場所で使用されます。5840億年にわたる64ビット符号付き秒フィールド (signed seconds field) と、0.05アト秒 (attosecond、つまり0.5e-18) を解決する64ビット分数フィールド (fraction field) が含まれています。形式間のマッピングを容易にするために、秒フィールドは32ビット紀元番号フィールド (Era Number field) と32ビット紀元オフセットフィールド (Era Offset field) に分割されています。紀元 (Eras) はNTPによって直接生成することはできず、そうする必要もありません。必要に応じて、ファイルシステムや専用ハードウェアなどの外部手段から派生させることができます。

    0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Seconds | Fraction |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

NTP短形式

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Seconds |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Fraction |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

NTPタイムスタンプ形式

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Era Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Era Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Fraction |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

NTP日付形式

図3: NTP時刻形式

64ビットタイムスタンプ形式は、パケットヘッダーやワードサイズが制限されている他の場所で使用されます。136年にわたる32ビット符号なし秒フィールド (unsigned seconds field) と、232ピコ秒 (picoseconds) を解決する32ビット分数フィールドが含まれています。32ビット短形式は、他の形式の完全な解像度と範囲が正当化されない遅延および分散ヘッダーフィールドで使用されます。16ビット符号なし秒フィールドと16ビット分数フィールドが含まれています。

日付およびタイムスタンプ形式では、主紀元 (prime epoch)、または紀元0の基準日は、すべてのビットがゼロのとき、1900年1月1日0時UTCです。厳密に言えば、UTCは1972年1月1日より前には存在しませんでしたが、すべての歴史的閏秒の知識が失われたとしても、永遠に存在していたと仮定するのが便利です。日付は主紀元を基準としています。ゼロより大きい値はその日付以降の時刻を表し、ゼロより小さい値はそれ以前の時刻を表します。日付形式の紀元オフセットフィールドとタイムスタンプ形式の秒フィールドは同じ解釈を持つことに注意してください。

タイムスタンプは符号なしの値であり、それらに対する操作は同じまたは隣接する紀元で結果を生成します。紀元0には、最上位ビットがゼロのとき、主紀元から2036年のある時点までの日付が含まれます。紀元1はその時点から続き、136年間続き、その後紀元2が始まり、以下同様です。紀元0では、ゼロのタイムスタンプは主紀元を表し、2^(31)秒は2036年の時刻を表し、2^(32)-1秒は主紀元の1秒前を表します。符号なしタイムスタンプを使用する場合、それらは同じ方法で処理されます。2036年に可能なような、紀元にまたがる64ビットタイムスタンプ計算に対する認識されたハザードは、オーバーランをもたらす可能性があります。実際には、プロトコルが開始される前にクライアントがサーバーの68年以内に設定されていれば、クライアントとサーバーが隣接する紀元にあっても、正しい値が得られます。

一部の時間値は、精度 (precision)、時定数 (time constant)、およびポーリング間隔 (poll interval) を含む指数形式 (exponent format) で表されます。これらは、log2 (底2の対数) 秒での8ビット符号付き整数形式です。それらに対して許可される唯一の算術演算は、インクリメントとデクリメントです。このドキュメントの目的およびプレゼンテーションを簡素化するために、これらの変数の1つを名前で参照することは指数値を意味します。たとえば、ポーリング間隔は1024秒ですが、名前と指数で参照することは実際の値を意味します。たとえば、ポーリング指数は10です。

任意の形式のシステム時刻をNTP日付およびタイムスタンプ形式に変換するには、主紀元からシステム時刻までの秒数sを決定する必要があります。sが与えられた場合の整数紀元とタイムスタンプを決定するには、

era = s / 2^(32) かつ timestamp = s - era * 2^(32),

これは正および負の日付で機能します。紀元とタイムスタンプが与えられた場合のsを決定するには、

s = era * 2^(32) + timestamp.

NTPとシステム時刻の間の変換は少し面倒で、このドキュメントの範囲を超えています。紀元0の日数は他のほとんどの紀元の日数より1日多いことに注意してください。これは紀元3の2400年まで再び起こりません。

後述する状態変数の説明では、整数型への明示的な参照は32ビット符号なし整数を意味します。これにより、上限のみを定義する必要があるため、境界チェックが簡素化されます。明示的な参照がない場合、デフォルトの型は64ビット浮動小数点倍精度 (floating double) です。必要に応じて例外が記載されます。