たjava.sql.Timestampのコンストラクタは次のように行く:たjava.sql.Timestampの方法は
public Timestamp(long time) {
super((time/1000)*1000);
nanos = (int)((time%1000) * 1000000);
if (nanos < 0) {
nanos = 1000000000 + nanos;
super.setTime(((time/1000)-1)*1000);
}
}
それは基本的には、ミリ秒の時間を受け入れ、その後、最後の3桁の数字を抽出し、それがナノスます。だから、1304135631 のミリ秒値のために、私は 4.21億としてTimestamp.getnanos()を取得しています。これは単純な計算です(最後に6つのゼロを追加する)...最適ではないようです。
より良い方法は、ナノ秒単位で時間を受け取り、それからナノ秒の値を計算するタイムスタンプコンストラクタでした。
以下のプログラムを実行すると、実際のナノ秒と、ナノ秒を計算するTimestampの方法で返されたものとの違いがわかります。
long a = System.currentTimeMillis();
for(;;){
long b = System.currentTimeMillis();
Timestamp tm = new Timestamp(System.currentTimeMillis());
System.out.println(tm.getTime());
System.out.println(tm.getNanos());
System.out.println("This is actual nanos" + System.nanoTime()%1000000000);
System.out.println("--------------------------");
if(b-a >= 1)
break;
}
だから、ナノ秒までの時間を保存すると言うタイムスタンプに関するすべての議論は、とても正確であるように思われません...ではないですか?
はい。これは間違いなく機能します。だから、Timestampに実際にナノを保存させるには、それは2つのステップのプロセスでなければなりません。 1970年1月1日よりnanosを受け入れるコンストラクタは、より良い解決策でした。 – Vicky
これは安全ではありません!それはラップする!問題は、 'currentTimeMillis'と' nanoTime'がより大きい解像度で一致しないかもしれないということです。例えば'nanoTime'は、12:06:30.9999,12:06:** 31 ** .1111の値を返しますが、' currentTimeMillis'は12:06:30.666 12:06:** 30 ** ** 777を返します。タイムスタンプを初期化すると、タイムスタンプが12:06:30.9999,12:06:** 30 * .1111になります。これとは別に、@ Vickyさんのコメントを、1970年以前にタイムスタンプをどのように初期化しますか? – Luciano
ナノ秒の設定は別に設定する必要がありますが、このように 'System#nanoTime()'を使用することは間違っています。 「System#nanoTime()」のAPIドキュメントには次のように書かれています。「このメソッドは、経過時間を測定するためにのみ使用でき、システムや壁時計の時間の他の概念には関係しません。返される値は固定されているが任意の時刻以降のナノ秒を表します(将来的には値が負になる可能性もあります)。 "(http://download.oracle.com/javase/6/docs/api/java/lang/Systemを参照) .html#nanoTime%28%29) –