Ich habe Tausende von Fotos, die in Tansania aufgenommen wurden, und ich möchte das Datum und die Uhrzeit der Aufnahme jedes Fotos in einer MySQL-Datenbank speichern. Der Server befindet sich jedoch in den USA und ich habe Probleme, wenn ich versuche, eine tansanische Datums- und Uhrzeitangabe zu speichern, die während der Sommerzeit (in den USA) innerhalb der "ungültigen" Stunde liegt. Tansania führt keine Sommerzeit durch, 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- und Uhrzeitwerte zugreifen müssen. Ich möchte, dass sie immer als tansanische Zeit herauskommen und nicht in der lokalen Zeit, in der sich verschiedene Mitarbeiter befinden.
Ich zögere es, Sitzungszeiten festzulegen, da ich weiß, dass es Probleme geben wird, wenn jemand manchmal 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 sowie MySQL-Datums- und Uhrzeitfelder und Sommerzeit - wie verweise ich 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 keinen gesehen. Ansonsten sind 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.
Antworten:
Du sagtest:
Wenn dies der Fall ist, sollten Sie UTC nicht verwenden. Sie müssen lediglich einen
DATETIME
Typ in MySQL anstelle einesTIMESTAMP
Typs verwenden.Aus der MySQL-Dokumentation :
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 vielmehr 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 unbedingt mit der entsprechenden Sprache Ihres Anwendungscodes.quelle
TimestampJPG
Spalte einDATETIME
Typ im MySQL-Datenbankschema und keinTIMESTAMP
Typ ist?Keine der Antworten hier traf den Nagel auf den Kopf.
Verwenden Sie zwei Spalten :
DATETIME
, und aVARCHAR
, um die Zeitzoneninformationen zu speichern, die in verschiedenen Formen vorliegen können:Eine Zeitzone oder ein Ort wie
America/New_York
die höchste Datentreue.Eine Zeitzonenabkürzung wie
PST
die nächsthöhere Wiedergabetreue.Ein Zeitversatz wie dies
-2:00
ist die kleinste Datenmenge in dieser Hinsicht.Einige wichtige Punkte:
TIMESTAMP
da es auf das Jahr 2038 beschränkt ist und MySQL es mit der Server-Zeitzone in Verbindung bringt, was wahrscheinlich unerwünscht ist.INT
Feld gespeichert werden , da es Versätze von einer halben Stunde und einer Viertelstunde gibt.Wenn es für Ihren Anwendungsfall wichtig ist, dass MySQL diese Daten chronologisch vergleicht oder sortiert ,
DATETIME
liegt ein Problem vor:'2009-11-10 11:00:00 -0500'
ist vorher'2009-11-10 10:00:00 -0700'
in Bezug auf "Augenblick", aber sie würden in umgekehrter Reihenfolge sortieren, wenn sie in a eingefügt werdenDATETIME
.Sie können Ihre eigene Konvertierung in UTC durchführen. In dem obigen Beispiel würden Sie dann haben
'2009-11-10 16:00:00'
und'2009-11-10 17:00:00'
jeweils die würde Art richtig. Wenn Sie die Daten abrufen, verwenden Sie die Zeitzoneninformationen, um sie in ihre ursprüngliche Form zurückzusetzen.Eine Empfehlung, die mir sehr gefällt, sind drei Spalten:
local_time DATETIME
utc_time DATETIME
time_zone VARCHAR(X)
Dabei ist X für die Art der Daten geeignet, die Sie dort speichern. (Ich würde 64 Zeichen für Zeitzone / Ort wählen.)Ein Vorteil des 3-Spalten-Ansatzes besteht darin, dass er explizit ist: Bei einer einzelnen
DATETIME
Spalte können Sie nicht auf einen Blick erkennen, ob sie vor dem Einfügen in UTC konvertiert wurde.In Bezug auf die Abnahme der Genauigkeit durch Zeitzone / Abkürzung / Offset:
America/Juneau
können Sie wissen genau , was die Wanduhr Zeit für sie in der Vergangenheit oder Zukunft (abgesehen von Änderungen an der Art und Weise Sommer gehandhabt wird an dieser Stelle) an jedem Punkt ist. Die Start- / Endpunkte der Sommerzeit und ob sie überhaupt verwendet werden, hängen vom Standort ab. Dies ist also der einzig zuverlässige Weg.-0700
, können Sie keine Wanduhrzeit in der Vergangenheit oder Zukunft vorhersagen. In den USA verwenden beispielsweise Colorado und Arizona beide MST, Arizona beobachtet jedoch keine Sommerzeit. Wenn der Benutzer sein Katzenfoto14:00 -0700
während der Wintermonate hochlädt , war er dann in Arizona oder Kalifornien? Wenn Sie genau sechs Monate zu diesem Datum hinzufügen würden, wäre es14:00
oder13:00
für den Benutzer?Diese Dinge sind wichtig zu berücksichtigen, wenn Ihre Anwendung Zeit, Datum oder Zeitplanung als Kernfunktion hat.
Verweise:
(Offenlegung: Ich habe diesen ganzen Artikel nicht gelesen.)
quelle
time
undlocation
in separaten Spalten. Ich spreche auch über das Speichern der UTC-Zeit. Wenn Sie es vorziehen, nur die UTC-Zeit zu speichern, weil Ihrelocation
s Plural und / oder in einer anderen Tabelle sind, großartig. Mein einziger Vorschlag ist dann, es derutc_time
Klarheit halber zu kennzeichnen.MySQL speichert DATETIME ohne Zeitzoneninformationen. Angenommen, Sie speichern '2019-01-01 20:00:00' in einem DATETIME-Feld. Wenn Sie diesen Wert abrufen, müssen Sie wissen, zu welcher Zeitzone er gehört.
Wenn Sie also in Ihrem Fall einen Wert in einem DATETIME-Feld speichern, stellen Sie sicher, dass es Zeit für Tansania ist. Wenn Sie es dann herausbringen, ist es Zeit für Tansania. Yay!
Die haarige Frage lautet nun: Wenn ich ein INSERT / UPDATE mache, wie stelle ich sicher, dass der Wert Tansania-Zeit ist? Zwei Fälle:
Das tust du
INSERT INTO table (dateCreated) VALUES (CURRENT_TIMESTAMP or NOW())
.Sie tun dies
INSERT INTO table (dateCreated) VALUES (?)
und geben die aktuelle Zeit in Ihrem Anwendungscode an.FALL 1
MySQL wird die aktuelle Zeit in Anspruch nehmen. Nehmen wir an, es ist '2019-01-01 20:00:00' Zeit in Tansania. Dann konvertiert MySQL es in UTC , das auf '2019-01-01 17:00:00' erscheint, und speichert diesen Wert im Feld.
Wie können Sie also die Zeit in Tansania, die '20: 00: 00 'ist, auf dem Feld speichern? Es ist nicht möglich. Ihr Code muss beim Lesen aus diesem Feld mit der UTC-Zeit rechnen.
FALL 2
Dies hängt davon ab, als welche Art von Wert Sie übergeben
?
. Wenn Sie die Zeichenfolge '2019-01-01 20:00:00' übergeben, ist das gut für Sie, genau das wird in der Datenbank gespeichert. Wenn Sie ein Date-Objekt übergeben, hängt dies davon ab, wie der Datenbank-Treiber dieses Date-Objekt interpretiert und welche Zeichenfolge 'YYYY-MM-DD HH: mm: ss' MySQL zur Speicherung zur Verfügung stellt. Die Dokumentation des DB-Treibers sollte es Ihnen sagen.quelle
Alle von Ihnen beschriebenen Symptome deuten darauf hin, dass Sie MySQL niemals mitteilen, welche Zeitzone verwendet werden soll, sodass standardmäßig die Systemzone verwendet wird. Denken Sie darüber nach: Wenn alles, was es hat
'2011-03-13 02:49:10'
, wie kann es erraten, dass es ein lokales tansanisches Datum ist?Soweit ich weiß, bietet MySQL keine Syntax zur Angabe von Zeitzoneninformationen in Datumsangaben. Sie müssen es pro Verbindung ändern . etwas wie:
SET time_zone = 'EAT';
Wenn dies nicht funktioniert (um benannte Zonen zu verwenden, muss der Server dafür konfiguriert sein und dies ist häufig nicht der Fall), können Sie UTC-Offsets verwenden, da Tansania zum Zeitpunkt des Schreibens keine Sommerzeit einhält , aber natürlich es ist nicht die beste Option:
SET time_zone = '+03:00';
quelle
Ich war auch einmal mit einem solchen Problem konfrontiert, bei dem ich Daten speichern musste, die von verschiedenen Mitarbeitern verwendet wurden, und am Ende die Zeit in Unix-Zeitstempelform gespeichert habe, die die Anzahl der Sekunden seit Januar 1970 darstellt, was ein ganzzahliges Format ist. Beispiel heutiges Datum und Uhrzeit in Tansania ist das,
Friday, September 13, 2019 9:44:01 PM
was beim Speichern unter Unix-Zeitstempel wäre1568400241
Verwenden Sie jetzt beim Lesen der Daten einfach PHP oder eine andere Sprache und extrahieren Sie das Datum aus dem Unix-Zeitstempel. Ein Beispiel mit PHP wird sein
Dies macht es sogar einfacher, Daten mit anderen Mitarbeitern an verschiedenen Standorten zu speichern. Sie können das Datum einfach in einen Unix-Zeitstempel mit ihrem eigenen gmt-Offset konvertieren und in einem ganzzahligen Format speichern. Bei der Ausgabe wird dies einfach mit einem konvertiert
quelle