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

Umgang mit der MySQL-Zeitzone im Skript

Sie haben diese Zeitdiagnose-Abfrage auf Ihrem MySQL-Server ausgeführt.

select @@time_zone, now(), utc_timestamp()

Aus Ihrer Ortszeit und UTC-Zeit geht hervor, dass die Systemzeitzoneneinstellung Ihres Servercomputers „Kanada/Mountain“ ist und die MySQL-Serversoftware keine eigene Zeitzoneneinstellung hat.

Wenn Sie Ihre Tabellen abholen und sie unverändert auf einen Server in einer nahe gelegenen Zeitzone verschieben, können Sie Ihre Software immer aktualisieren, um den Befehl

auszugeben
set time_zone = 'Canada/Mountain';

direkt nachdem Sie sich von Ihrer Software aus verbunden haben. Dadurch verhält sich Ihre neue MySQL-Verbindung in Bezug auf die Zeitzone wie Ihre aktuelle. Wenn Sie den MySQL-Server besitzen, können Sie seine Standardzeitzone gemäß den Anweisungen auf dieser Seite festlegen. http://dev.mysql.com/doc /refman/5.5/en/time-zone-support.html

Nun, hier ist die Geschichte über Zeitdatentypen. DATE , TIME , und DATETIME sind alle Zeitzonen-ignorant . Sobald Sie einen Datums-/Uhrzeitwert gespeichert haben, erhalten Sie denselben Wert zurück, selbst wenn Sie Ihre Zeitzoneneinstellungen ändern.

Der TIMESTAMP Datentyp ist zeitzonenabhängig . Diese Datenelemente werden immer in UTC, auch bekannt als Z, Zeit , gespeichert , früher bekannt als Greenwich Mean Time. Sie werden beim Speichern immer in UTC konvertiert und beim Abrufen immer wieder zurückkonvertiert.

Die eingebaute Funktionen um das aktuelle Datum und die Uhrzeit zu erhalten (NOW() und Freunde) sind zeitzonenabhängig . Sie liefern Werte in Ortszeit. Ausnahmen sind die drei Funktionen, die mit UTC_ beginnen die Werte in UTC-Zeit liefern.

Viele MySQL-Anwendungen für mehrere Zeitzonen verwenden die folgende Betriebsdisziplin:

  1. Fragen Sie jeden Benutzer nach einer bevorzugten Zeitzone oder finden Sie sie anhand anderer persönlicher Daten über den Benutzer heraus. (Telefone haben diese Informationen vom Netzwerk bereitgestellt.) Speichern Sie das als zoneninfo-freundlich Zeitzonendeskriptor ('America/New_York', 'Canada/Mountain', 'Europe/Vienna' usw.) im Namen des Benutzers.
  2. Nachdem Sie eine MySQL-Sitzung im Namen des Benutzers eingerichtet haben, legen Sie die Zeitzone des Benutzers mit einem set time_zone fest Abfrage wie die oben gezeigte. Sie sollten dies direkt nach Ihrem connect tun Betrieb.
  3. Speichern Sie Daten und Zeiten für Benutzer in TIMESTAMP Datentypen. Sie werden beim Speichern in UTC konvertiert.
  4. Rufen Sie sie nach Bedarf ab. Sie werden wieder in die Ortszeit umgerechnet.

Die Idee ist, dass die Zeitzone Ihres Benutzers Teil ihres Kontexts ist. Das funktioniert gut, denn wenn sich Benutzer A in Vancouver und Benutzer B in Halifax befindet und Benutzer B aus irgendeinem Grund die Zeitdaten von Benutzer A anzeigt, werden sie B mehr oder weniger automatisch in atlantischer Zeit angezeigt.

Es ist auch gut, weil es transparent mit den globalen Schwankungen der Umstellung von Sommer- auf Winterzeit umgeht. Ein Zeitstempel vom letzten Sommer wird in der Ortszeit des letzten Sommers angezeigt.

Viele Manager von Servern für den globalen Einsatz stellen ihre Systemserverzeit oder ihre MySQL-Standardzeitzone auf UTC ein. (Ihrer nicht.)

Eine andere Möglichkeit, mit all dem umzugehen, ist die Art und Weise, wie Sie begonnen haben. Wählen Sie eine Zeitzone aus und speichern Sie Ihre Zeitstempel in Bezug auf diese Zeitzone. Am besten wählen Sie in diesem Fall eine Zeitzone aus, die nicht zwischen Sommer- und Winterzeit wechselt. Dann beim Speichern von Zeiten in die Datenbank explizit umwandeln. Sie würden Zeiten von Benutzern in Ottawa speichern, indem Sie so etwas tun.

INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)

und Sie würden die Werte auf die gleiche Weise erhalten. Dies ist fehleranfällig, aber Sie können es zum Laufen bringen.

Schließlich können Sie Ihre Umrechnungen selbst vornehmen. Wenn Sie wissen möchten, wie viele Minuten zwischen einer beliebigen Zeitzone und UTC liegen, versuchen Sie es mit diesen beiden Abfragen.

set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());

Zu dieser Jahreszeit ergibt das -240, also -4:00. Sie müssen Minuten anstelle von Stunden verwenden, da es in einigen Ländern Zeitzonenverschiebungen von halben oder viertel Stunden gibt.

Endlich aufpassen. TIMESTAMP Datentypen stellen keine Zeiten vor 1970 dar. Und auf meiner MariaDB 10.0-Instanz scheint es direkt nach 2038-01-19T03:14:07 UTC zum Teufel zu gehen, wenn die Zeit über 32 Bit hinausläuft.