2013-03-26 2 views
10

Hallo Ich habe einen Code-Schnipsel wie folgt aus:java.sql.Timestamp Vergleichsfehler?

Date d1 = new java.sql.Timestamp(new Date().getTime()); 
Thread.sleep(10); 
Date d2 = new java.sql.Timestamp(new Date().getTime()); 
System.out.println("Date1: " + d1); 
System.out.println("Date2: " + d2); 
System.out.println("Comparing times d1.t < d2.t: " + (d1.getTime() < d2.getTime())); 
System.out.println("Comparing dates d1.before(d2): " + (d1.before(d2))); 

Die Ausgabe sieht wie folgt aus:

Date1: 2013-03-26 11:04:01.093 
Date2: 2013-03-26 11:04:01.103 
Comparing times d1.t < d2.t: true 
Comparing dates d1.before(d2): false 

Was ist mit dieser java.sql.Timestamp Klasse falsch?

Ja, ich habe gesehen:

Hinweis: Dieser Typ ist ein Verbund aus einem java.util.Date und ein separater ns Wert. Nur ganzzahlige Sekunden werden in der Komponente java.util.Date gespeichert. Die Bruchsekunden - die Nanos - sind getrennt. Die Methode Timestamp.equals (Object) gibt nie true zurück, wenn ein Wert vom Typ java.util.Date übergeben wird, weil die Nanokomponente eines Datums unbekannt ist. Daher ist die Methode Timestamp.equals (Object) in Bezug auf die Methode java.util.Date.equals (Object) nicht symmetrisch. Außerdem verwendet die Hashcode-Methode die zugrunde liegende java.util.Date-Implementierung und enthält daher keine Nanos in ihrer Berechnung.

Aufgrund der Unterschiede zwischen der Timestamp-Klasse und der java.util.Date-Klasse wird empfohlen, dass Timestamp-Werte nicht generisch als Instanz von java.util.Date angezeigt werden. Die Vererbungsbeziehung zwischen Timestamp und java.util.Date steht für die Implementierungsvererbung und nicht für die Vererbung.

Aber es ist für Datum < -> Timestamp Relation.

In meinem Beispiel habe ich nur Zeitstempel, und immer noch das Verhalten ist unerwartet ..

UPDATE: ANTWORT

Der Grund dafür ist, dass before() Methode überlastet ist, nicht in java.sql.Timestamp außer Kraft gesetzt. Ich habe ein 'override' Verhalten erwartet. Der korrekte Vergleich von Zeitstempeln besteht darin, Timestamp-Variablen und keine Datumsangaben zu verwenden.

Dies ist immer noch eine schlechte Entscheidung Design im Java-Kern, da Vererbung Zeitmarke ist-ein Datum, ohne Strafen und Ausnahmen ..

+0

Ich glaube, ich habe das Problem in einem anderen Beitrag gefunden. Bitte [Rezension] (http://Stackoverflow.com/a/13141377/1758149). Das Problem ist, dass Sie einen 'TimeStamp' nicht als Date behandeln sollen. – RyPope

Antwort

2

Versuchen Sie, Timestamp anstelle von Date zu verwenden, und es wird funktionieren.

Timestamp d1 = new java.sql.Timestamp(new Date().getTime()); 

Timestamp und Date haben beide eine eigene Implementierung von Verfahren before. Prüfen Sie.

3

Nun, es scheint, als eine Unter dokumentiert bedeuten sollte Feature.

Die before und after Methoden von Timestamp scheinen bis zum zweiten zu vergleichen, aber nicht die Millisekunden Teil berücksichtigen. Versuchen Sie es auszuführen, bis beide TimeStamp in bestimmten Sekunden fallen und der Vergleich funktioniert wie erwartet (erhöhen Sie den Schlaf auf 500, um es einfacher zu machen).

Übrigens, die compareTo Methode berücksichtigt die Millisekunden, so dass Sie stattdessen verwenden könnten.

1

Wenn Sie die Methode Timestamp.before(Timestamp) aufrufen, erhalten Sie das erwartete Ergebnis.

Aber anscheinend mit einem Timestamp als Date wird ein rundum Durcheinander sein. Sie müssen Timestamp als Timestampstatisch verwenden.

0

Wie hier erwähnte

timestamp is a thin wrapper

Ein Zeitstempel fügt einfach die Möglichkeit, den SQL TIMESTAMP Sekundenbruchwert (mit einer Genauigkeit von Nanosekunden, wo das Problem in Ihrem Fall ist entstehen) zu halten