SQL Oracle: Diskrepanz Timestamps/Dates und java.util.Date

mental.dIseASe

Lieutenant
Registriert
Dez. 2008
Beiträge
665
Hallo zusammen,

ich wundere mich gerade über den folgenden Unterschied bei der Datumsarithmetik in Oracle:

Wenn ich mit einer Zeitspanne von 1522879200000 Millisekunden seit 01.01.1970 folgendes in Oracle tue:

Code:
SELECT TO_DATE('19700101', 'YYYYMMDD') + (1/24/60/60/1000) * 1522879200000 FROM DUAL

dann bekomme ich den 04.04.2018.

Wenn ich in Java aber folgendes tue:

Code:
new Date(1522879200000l)

dann kriege ich den 05.04.2018. Ich habe jetzt die Vermutung (und darauf deutet auch meine Google-Recherche hin), dass es irgendwie damit zusammenhängt, dass DATE keine Millisekunden unterstützt.

Deswegen hätte ich eigentlich gedacht, dass ich mit Timestamp ein richtiges Ergebnis bekomme:

Code:
SELECT TO_TIMESTAMP('19700101', 'YYYYMMDD') + (1/24/60/60/1000) * 1522879200000 FROM DUAL

Tatsächlich bekomme ich aber nachwievor den 04.04.2018. Kann mir jemand zeigen, was ich hier übersehe? Es wäre übrigens auch kein Problem, die Millisekunden als Long rauszuziehen und das Mapping dann außerhalb der Datenbank vorzunehmen, aber ich will gerne meinen Denkfehler verstehen.
 
Benutzt Du bei beiden Varianten die gleiche Zeitzone?

Bei UTC ist Deine Zeit gleich 04.04.2018 um 22:00:00 Uhr. Wenn Du in Java UTC+2 verwendest, wäre das eine Erklärung.

/edit: Ab 25. März ist ja Sommerzeit. Also wenn Du in Java die hiesige Ortszeit verwendest, erklärt das die 2 Stunden Differenz.
 
Zuletzt bearbeitet:
Über Zeitzonen habe ich mir noch gar keine Gedanken gemacht, weil bisher ohne einen SELECT dieser Art alles so funktionierte wie erwartet. Aber daran könnte es tatsächlich liegen.

Auf die Tabelle, die dort einen Timestamp als NUMBER speichert, habe ich leider keinen Einfluss. Das sind Tabellen des Quartz-Frameworks. Sonst hätte ich das schon längst nativ auf TIMESTAMP umgestellt und alles wäre paletti.

Ich werde nochmal ein bisschen mit Timezones rumspielen, werde den Timestamp dann aber wohl als Long aus der DB ziehen und weiter oben durch new Date(Long); verwursten. Das Ergebnis ist für mich das erwartete Verhalten und kostet mich am wenigsten Nerven.

Danke!
 
Zurück
Oben