# Speicherung von java.sql.Date liefert inkorrekte Ergebnisse



## Juggl3r (15. Okt 2012)

Hallo,

folgendes Problem.
Ich erstelle einen Datensatz so:



```
this.einfuehrungsDatum = new Date(new java.util.Date().getTime());
```


Mein Prepaired Statement zum Einfügen:


```
pStmt.setDate(6, p.getEinfuehrungsDatum());
```

und wenn ichs auslese:


```
p.setEinfuehrungsDatum(rs.getDate(6));
```


Wenn ichs per .toString() ausgebe, passt das Datum:
Produkt{ pNummer: 174 name: Name1 nettoPreis: 50 kategorie: Kategorie1 hersteller: Hersteller1 einfuehrungsDatum: 2012-10-15 istGeloescht: false}
Produkt{ pNummer: 174 name: Name1 nettoPreis: 50 kategorie: Kategorie1 hersteller: Hersteller1 einfuehrungsDatum: 2012-10-15 istGeloescht: false}
1:true
2:true
3:true
4:true
5:true
6:false
7:true

Aber der 6te Vergleich schlägt fehl, also die 2 Date Objekte unterscheiden sein.
Wenn ich .getTime() Darauf aufrufe, sieht man es noch besser:


Produkt{ pNummer: 177 name: Name1 nettoPreis: 50 kategorie: Kategorie1 hersteller: Hersteller1 einfuehrungsDatum: 1350252000000 istGeloescht: false}
Produkt{ pNummer: 177 name: Name1 nettoPreis: 50 kategorie: Kategorie1 hersteller: Hersteller1 einfuehrungsDatum: 1350291528443 istGeloescht: false}
1:true
2:true
3:true
4:true
5:true
6:false
7:true

Kann mir jemand sagen warum sich die Zeiten unterscheiden? Und was ich machen muss, damit das wieder passt? (sowas wie einfuehrungsDatum.setHours(0) usw. hab ich schon probiert, das ist aber depricated).

lg


----------



## SlaterB (15. Okt 2012)

die beiden Dates ausgegeben zeigt die Probleme, wie du auch schon vermutest:
Mon Oct 15 10:58:48 CEST 2012 // 1350291528443
Mon Oct 15 00:00:00 CEST 2012 // 1350252000000

leider sparst du an Details, z.B. welcher von diesen beiden Werten aus der DB kommt, wie er vor dem Speichern aussah, welcher Typ Date in der ersten Code-Zeile 
> this.einfuehrungsDatum = new Date(new java.util.Date().getTime());
gemeint ist, wlechen Typ hat die Variable, java.sql.Date?

womit genau wird verglichen, wie entsteht dieses Date?

wahrscheinlich ist es so:
das java.sql.Date in Java enthält trotz knackig kurzer Ausgabe '2012-10-15' noch den kompletten long-Wert, anschauen,
in der DB (wiederum SQL-Typ der Tabellenspalte nicht genannt) wird nur der Tag gespeichert, der Rest gekürzt,
zurück kommt das reine 00:00:00, verglichen wird mit irgendwas von 10:58:48 usw.

> sowas wie einfuehrungsDatum.setHours(0) usw. hab ich schon probiert, das ist aber deprecated

lange Rede kurzer Sinn:
Calendar kann dir dabei helfen, das Date setzen, die nicht-deprecated Methoden nutzen und fertig,
allerdings auch darauf achten, dass die richtige Zeitzone eingestellt ist und ähnliches,
wenn der DB-Wert genau 00:00:00 ist und nicht 23:00:00 usw., dann sieht es ja schon ganz gut aus,

oder eine andere Art von Vergleich ausführen, oder nur aus der DB geladene Daten vergleichen,
ach schon schwer, müsste das für meine Programme eigentlich auch noch besser klären,

vielleicht schreibt noch wer anders was, soweit aber schon zumindest zur Aufklärung der Abläufe


----------



## Bernd Hohmann (15. Okt 2012)

Ich kann gerade nicht in die Sourcen schauen, aber habe noch in Erinnerung dass bei java.sql.Date die Zeitfraktion auf 0 gesetzt wird.

java.sql.Date = Nur Datum (tag,monat,jahr)
java.sql.Time = Nur Zeit (stunde, minute, sekunde)

hingegen:

java.util.Date = Datum + Zeit (tag,monat,jahr,stunde,minute,sekunde)

Wenn man also java.sql.Date gegen ein anderes Datum über den Vergleich der long-Zeitwerte machen will, dann muss das andere Datum auch vom Typ java.sql.Date sein (und nicht java.util.Date).

Bernd


----------



## SlaterB (15. Okt 2012)

tja, eine solch simple Aussage ist so leicht nachzuprüfen, bevor man sie postet

```
public class Test {
    public static void main(String[] args)    throws Exception   {
        java.sql.Date a = new java.sql.Date(System.currentTimeMillis());
        Thread.sleep(100);
        java.sql.Date b = new java.sql.Date(System.currentTimeMillis());
        System.out.println(a.getTime());
        System.out.println(b.getTime());
        System.out.println(a.equals(b));

    }
}
```
wenn es dann nicht stimmt, dann nicht so gut..


----------



## Bernd Hohmann (15. Okt 2012)

SlaterB hat gesagt.:


> tja, eine solch simple Aussage ist so leicht nachzuprüfen, bevor man sie postet



Ich sagte doch, dass ich keinen Source dabei habe (und auch keinen Compiler).

_To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date 
 instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in 
 the particular time zone with which the instance is associated._

Daher kam das woran ich mich erinnerte. Beim schreiben in die Datenbank erledigt das spätestens der Treiber.

Bernd


----------

