Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Abrufen des UTC-DATETIME-Felds von MySQL in Java, wenn die Serverzeitzone nicht UTC ist

Ihr Client getDate() Code sieht soweit korrekt aus. Ich denke, Sie müssen auch den MySQL Connector/J JDBC-Treiber dazu bringen, die Daten in der Tabelle gespeichert zu behandeln als UTC-Daten, um eine falsche Zeitzonenumrechnung zu vermeiden. Dies bedeutet, dass zusätzlich zur Zeitzone der Clientsitzung und dem Kalender, die für JDBC getTimestamp verwendet werden, die effektive Serverzeitzone festgelegt wird Anrufe, wie Sie es tun.

Sehen Sie sich die Werte an, die Sie in Ihrer fehlgeschlagenen Behauptung erhalten haben, und in welche Richtung der Fehler geht:

expected:<Thu Apr 16 11:30:30 BST 2015> but was:<Thu Apr 16 10:30:30 BST 2015>

Was Sie zurückbekamen, war 10:30 BST, was 9:30 GMT entspricht. Dies stimmt damit überein, dass die Datenbank diese 10:30 Uhr in der Tabelle als BST-Wert behandelt und sie fälschlicherweise für Sie in GMT umwandelt, bevor Sie sie als GMT-Datum analysieren. Das ist die entgegengesetzte Richtung eines GMT-Werts, der fälschlicherweise in BST umgewandelt wird.

Dies kann ein JDBC-spezifisches Problem sein, da JDBC erfordert, dass Uhrzeiten in die lokale Zone konvertiert werden. (Wo die MySQL-C-API dies nicht tut, wahrscheinlich, weil die klassischen Zeittypen von C nicht so zonenbewusst sind wie die von Java.) Und es muss wissen, aus welcher Zone es konvertiert aus , auch. Der MySQL-TIMESTAMP Typ wird immer als UTC gespeichert. Aber das wird für DATETIME nicht angegeben Typ. Ich denke das impliziert, dass MySQL DATETIME interpretieren wird Spaltenwerte als in der Zeitzone des Servers liegend. Was Sie als auf BST festgelegt erwähnt haben, und das stimmt mit der Richtung der Verschiebung überein, die in Ihrer Behauptungsfehlermeldung angezeigt wird.

Die Zeitzone Die von Ihnen festgelegte Sitzungsvariable teilt dem MySQL-Server die Zeitzone Ihres Client-Computers mit, hat jedoch keinen Einfluss darauf, was der Server für seine eigene Zeitzone hält. Dies kann mit <überschrieben werden code>serverTimezone JDBC-Verbindungseigenschaft . Legen Sie bei Ihrer Verbindung die serverTimezone fest auf UTC und stellen Sie sicher, dass useLegacyDatetimeCode ist aus. (Und sehen Sie sich die anderen zonenbezogenen Eigenschaften an, wenn das nicht funktioniert.) Prüfen Sie, ob Ihre Daten dadurch als UTC mit denselben Kalenderfeldwerten wie in der Datenbank angezeigt werden.

Beachten Sie, dass dies die Interpretation anderer DATETIME ändern wird Werte in Ihrer Datenbank:Sie werden jetzt alle wie UTC-Daten aussehen (im Kontext Ihrer JDBC-Verbindung). Ob das stimmt, hängt davon ab, wie sie ursprünglich bevölkert wurden. Während Ihr Client-Code das gewünschte Verhalten aufweisen wird, weiß ich nicht, ob dieses System als Ganzes dazu gebracht werden kann, sich vollständig konsistent zu verhalten, ohne die Zeitzone des Servers auf der Serverebene auf UTC einzustellen. Wenn die Zone nicht auf UTC eingestellt ist, ist sie im Grunde nicht vollständig für das gewünschte Verhalten konfiguriert, und Sie spielen herum.