PostgreSQL 9.2 JDBC-Treiber verwendet den client Zeit-zone?
Ich habe laufen in eine interessante Herausforderung mit einer PostgreSQL-Datenbank mit der PostgreSQL-JDBC-Treiber. Es scheint, dass die neueste version des Treibers, 9.2, verwendet die client Zeitzone bei der Durchführung Datum/Zeit entspricht.
Dies wird zu einem problem, wenn der server (JasperReports Server) auf UTC eingestellt ist und die Datenbank-server-US/Eastern.
Wenn ich führen Sie die folgende Abfrage von einem client setzen der UTC-Zeitzone, erhalte ich unterschiedliche Ergebnisse mit der 9.0 JDBC-Treiber und die 9.2 JDBC-Treiber.
select now(), extract(timezone FROM now()), current_setting('TIMEZONE'), now()-interval '1 hour' as "1HourAgo"
Ergebnisse mit 9.0 JDBC-Treiber:
now date_part current_setting 1HourAgo
2013-08-26 15:33:57.590089 -14,400 US/Eastern 2013-08-26 14:33:57.590089
Ergebnisse mit 9.2 JDBC-Treiber:
now date_part current_setting 1HourAgo
2013-08-26 15:41:49.067903 0 UTC 2013-08-26 14:41:49.067903
Dadurch verursacht wird, dass eine WHERE-Anweisung für eine Abfrage falsche Ergebnisse zurück. Zum Beispiel,
WHERE end_time between now() - interval '1 hour' and now()
arbeitet wie erwartet mit der 9,0 Treiber, aber keine Ergebnisse zurückgegeben mit dem 9,2-Treiber, da der Treiber zu sein scheint Aufrechnung den Wert der Endzeit zu entsprechen UTC (Zeitzone des Clients)). Das folgende ist ein workaround, aber eine hässliche:
WHERE end_time at time zone 'EDT' between now() - interval '1 hour' and now()
Fragen:
- Hat jemand sonst noch ausführen über das vor?
- Gibt es eine Erklärung für diese änderung im Verhalten? Ich habe nicht in der Lage etwas zu finden, in der JDBC-release-notes
- Alle Ratschläge, wie dies zu umgehen, andere als die Rollen die Fahrer zurück zu einer älteren version?
Dank!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich lief in dieses Problem mich. Ich habe überprüft, dass der postgres-jdbc-Treiber ist in der Tat der Kommissionierung bis die Verbindung timezone aus der jvm, und ich war nicht in der Lage, einen Weg zu finden, um dieses Verhalten zu überschreiben. Es wäre wirklich schön, wenn Sie eine jdbc-url-Verbindung-parameter für diesen Zweck.
Als workaround habe ich herausgefunden, dass mein connection-pool library (HikariCP) können ausführen einer sql-Anweisung für jede neue Verbindung:
-Duser.timezone=UTC
beim starten der JVMDie Verwendung der lokalen Zeitzone als Standardzeitzone erforderlich ist, durch die JDBC-standard (und API-Dokumentation), und wird explizit gemacht durch PreparedStatement.setTimestamp. Aber es gilt auch für alle anderen Bereiche, in denen JDBC setzt oder ruft zeitbezogene Daten.
Siehe auch meine Antwort auf Ist java.sql.Timestamp timezone spezifischen?
TimeZone
session-parameter bei der Verbindung der Bühne, und es macht die DB mit Hilfe von client-Zeitzone für Berechnungen, wo es sich nicht feststellen, welche Zeitzone sich die Daten an.Nur im Fall, dass andere mit diesem Kampf - Sie können Bearbeiten Sie die "conf" - Datei, startet SQLDeveloper und fügen Sie die folgende Zeile :
Fand ich diese Datei auf meinem Rechner an :
Dank @a_horse_with_no_name für den Hinweis mich in die richtige Richtung-ein Kommentar in einer der anderen Antworten
Ich weiß nicht, JasperReports, aber im Allgemeinen, mit dem JSR-310 (Java 8) Datum/Zeit-Typen (unterstützt durch JDBC 4.2) funktionieren sollte, ohne befürchten zu müssen über Zeit-zone Diskrepanzen zwischen Datenbank-server und-client.
Sehen Mit Java-8-Datum und Zeit-Klassen in der PostgreSQL-JDBC-Treiber-Dokumentation.