5

バグに続いて、ミリ秒かかるコンストラクターを使用して java.util.Date から java.sql.Timestamp を作成すると、Date インスタンスは常に Timestamp の after() になることに気付きました。(a) before() のコントラクトは厳密な比較を指定し、(b) 等しくない場合、タイムスタンプはナノ秒であるため、それ自体が after() 日付である可能性があるため、これは不可解です。しかし、結果は逆で、再現可能です (JDK 1.6 と 1.7 では、JVM タイムゾーンが異なります)。2 つの Date の比較は正しく機能しますが、Date で before() または after() を呼び出して Timestamp 引数を指定すると、予期しない結果が生じます。

以下のサンプル コードには、2 つの Date インスタンスと 1 つの Timestamp インスタンスがあり、すべて同じミリ秒値です。しかし、日付とタイムスタンプを比較すると、日付がタイムスタンプの after() であることがわかります。

import java.util.Date;
import java.sql.Timestamp;

public class X extends Date {

    public static void main(String[] args) {
        Date d1 = new Date();
        Date d2 = new Date(d1.getTime());
        Timestamp t = new Timestamp (d1.getTime());
        System.out.println ("date1 = " + d1 + " (" + d1.getTime() + ")" );
        System.out.println ("date2 = " + d2 + " (" + d2.getTime() + ")" );
        System.out.println ("timestamp = " + t + "  (" + t.getTime() + ")" );
        System.out.println ("d1 before d2: " + d1.before(d2));
        System.out.println ("d1 after  d2: " + d1.after(d2));
        System.out.println ("d1 before ts: " + d1.before(t));
        System.out.println ("d1 after  ts: " + d1.after(t)); //why true?
    }
}

出力例:

C:\>\Java\jdk1.7.0_05\bin\java X
date1 = Tue Oct 30 10:15:59 EDT 2012 (1351606559812)
date2 = Tue Oct 30 10:15:59 EDT 2012 (1351606559812)
timestamp = 2012-10-30 10:15:59.812  (1351606559812)
d1 before d2: false
d1 after  d2: false
d1 before ts: false
d1 after  ts: true

最後の行は興味深いものです。

ありがとうございました。

4

2 に答える 2

7

内部表現とafter()メソッドで比較されるものを見ると、たとえば

millis = 1351607849957

あなたはDate

fastTime = 1351607849957

Timestamp_

fastTime = 1351607849000
nanos = 957000000

比較されるのはfastTime部分だけなので、観察された動作が得られます。上で @ user714965 が指摘しているように、 aTimestampを として扱うことは想定されていませんDate

于 2012-10-30T14:40:52.417 に答える
4

の API ドキュメントにjava.sql.Timestampは次のように書かれています。

注:この型は、java.util.Dateと別のナノ秒値の合成です。コンポーネントには整数秒のみが格納されjava.util.Dateます。小数秒 - ナノ - は別のものです。

(それはケッピルの答えに同意します)。

また、次のようにも述べています。

Timestampクラスと上記のクラスの違いにより、コードは値を一般的に のインスタンスとしてjava.util.Date表示しないことをお勧めします。と の間の継承関係は、型の継承ではなく、実際には実装の継承を示しています。Timestampjava.util.DateTimestampjava.util.Date

つまり、Timestampとして扱うべきではないことを意味しますjava.util.Date。これは、に渡す場合に行っていることですjava.util.Date.after()(そのメソッドは a を期待してjava.util.Dateいます - あなたはそれを であるTimestampかのように扱い、java.util.Dateこのコメントはあなたがすべきではないと言っています) .

もちろん、これは標準 Java ライブラリの悪い設計です。日付と時刻を扱う必要がある場合は、より優れた設計でより強力なライブラリであるJoda Timeを使用してください。

于 2012-10-30T14:41:44.967 に答える