web-dev-qa-db-de.com

So speichern Sie eine Datums- / Uhrzeitangabe in MySQL mit Zeitzoneninformationen

Ich habe Tausende von Fotos, die in Tansania aufgenommen wurden, und ich möchte das Datum und die Uhrzeit jeder Aufnahme in einer MySQL-Datenbank speichern. Der Server befindet sich jedoch in den USA und es treten Probleme auf, wenn ich versuche, eine tansanische Datumszeit zu speichern, die während der Sommerzeit (in den USA) innerhalb der "ungültigen" Stunde liegt. Tansania macht keine Sommerzeit, daher ist die Zeit eine tatsächlich gültige Zeit.

Zusätzliche Komplikationen sind, dass es Mitarbeiter aus vielen verschiedenen Zeitzonen gibt, die auf die in der Datenbank gespeicherten Datums-/Uhrzeitwerte zugreifen müssen. Ich möchte, dass sie immer als tansanische Zeit herauskommen und nicht in der Ortszeit, in der sich verschiedene Mitarbeiter befinden.

Ich zögere es, Sitzungszeiten festzulegen, da ich weiß, dass es Probleme geben wird, wenn irgendwann jemand vergisst, eine Sitzungszeit festzulegen, und die Zeiten falsch angegeben werden. Und ich habe keine Berechtigung, etwas am Server zu ändern.

Ich habe gelesen: Best Practices für Sommerzeit und Zeitzone und MySQL-Datenzeitfelder und Sommerzeit - wie beziehe ich mich auf die "zusätzliche" Stunde? und - Speichern von datetime als UTC in PHP/MySQL

Aber keiner von ihnen scheint mein spezielles Problem anzusprechen. Ich bin kein SQL-Experte. Gibt es eine Möglichkeit, die Zeitzone beim Festlegen von DATETIMEs anzugeben? Ich habe noch keinen gesehen. Ansonsten sind alle Vorschläge zur Lösung dieses Problems sehr willkommen.

Bearbeiten: Hier ist ein Beispiel für das Problem, auf das ich stoße. Ich sende den Befehl:

INSERT INTO Images (CaptureEvent, SequenceNum, PathFilename, TimestampJPG) 
VALUES (122,1,"S2/B04/B04_R1/IMAG0148.JPG","2011-03-13 02:49:10")

Und ich bekomme den Fehler:

Error 1292: Incorrect datetime value: '2011-03-13 02:49:10' for column 'TimestampJPG'

Dieses Datum und diese Uhrzeit existieren in Tansania, jedoch nicht in den USA, wo sich die Datenbank befindet.

57
mkosmala

Du sagtest:

Ich möchte, dass sie immer als tansanische Zeit herauskommen und nicht zu den lokalen Zeiten, in denen verschiedene Mitarbeiter arbeiten.

In diesem Fall sollten Sie nicht UTC verwenden. Sie müssen lediglich einen DATETIME -Typ in MySQL anstelle eines TIMESTAMP -Typs verwenden.

Aus der MySQL-Dokumentation :

MySQL konvertiert TIMESTAMP Werte von der aktuellen Zeitzone in UTC zum Speichern und zurück von UTC in die aktuelle Zeitzone zum Abrufen. (Dies tritt bei anderen Typen wie DATETIME nicht auf.)

Wenn Sie bereits einen DATETIME -Typ verwenden, müssen Sie ihn zunächst nicht auf die Ortszeit einstellen. Sie müssen sich weniger auf die Datenbank als auf Ihren Anwendungscode konzentrieren, den Sie hier nicht angezeigt haben. Das Problem und die Lösung variieren je nach Sprache drastisch. Kennzeichnen Sie die Frage daher mit der entsprechenden Sprache Ihres Anwendungscodes.

51

Alle von Ihnen beschriebenen Symptome deuten darauf hin, dass Sie MySQL niemals mitteilen, welche Zeitzone verwendet werden soll, sodass standardmäßig die Zone des Systems verwendet wird. Denken Sie darüber nach: Wenn alles was es hat, ist '2011-03-13 02:49:10', wie kann es erraten, dass es sich um ein lokales tansanisches Date handelt?

Meines Wissens bietet MySQL keine Syntax, um Zeitzoneninformationen in Datumsangaben anzugeben. Sie müssen es ändern pro Verbindung ; so etwas wie:

SET time_zone = 'EAT';

Wenn dies nicht funktioniert (um benannte Zonen zu verwenden, benötigen Sie Folgendes der Server wurde konfiguriert und dies ist häufig nicht der Fall), können Sie einfach UTC-Offsets verwenden:

SET time_zone = '+03:00';
5

MySQL speichert DATETIME ohne Zeitzoneninformationen. Angenommen, Sie speichern '2019-01-01 20:00:00' in einem DATETIME-Feld, wenn Sie den Wert abrufen, von dem erwartet wird , dass Sie wissen , zu welcher Zeitzone er gehört.

Wenn Sie also einen Wert in einem DATETIME-Feld speichern, stellen Sie sicher, dass Tansania-Zeit ist. Wenn Sie es dann herausbringen, wird es Zeit für Tansania. Yay!

Die haarige Frage ist nun: Wie stelle ich sicher, dass der Wert Tansania-Zeit ist, wenn ich ein INSERT/UPDATE mache? Zwei Fälle:

  1. Du machst INSERT INTO table (dateCreated) VALUES (CURRENT_TIMESTAMP or NOW()).

  2. Sie führen INSERT INTO table (dateCreated) VALUES (?) aus und geben die aktuelle Uhrzeit in Ihrem Anwendungscode an.

CASE # 1

MySQL nimmt die aktuelle Zeit an, sagen wir, es ist '2019-01-01 20:00:00' Tansania-Zeit. Dann konvertiert MySQL es in UTC , was zu '2019-01-01 17:00:00' führt, und speichert , dass Wert in das Feld.

Wie können Sie die Zeit in Tansania (20: 00: 00) auf dem Feld speichern? Es ist nicht möglich. Ihr Code muss UTC-Zeit erwarten, wenn Sie aus diesem Feld lesen.

FALL # 2

Es hängt davon ab, welche Art von Wert Sie als ? Übergeben. Wenn Sie die Zeichenfolge '2019-01-01 20:00:00' übergeben, ist dies genau das, was in der DB gespeichert wird. Wenn Sie ein Date-Objekt übergeben, hängt es davon ab, wie der Datenbanktreiber dieses Date-Objekt interpretiert , und letztendlich, was 'JJJJ-MM-TT HH: mm: ss-String, der MySQL zur Speicherung zur Verfügung gestellt wird. Die Dokumentation des DB-Treibers sollte es Ihnen sagen.

4
Hai Phan