dedlfix: Richtiges Datensatz-Updatedatum in einer SQL DB

Beitrag lesen

Tach!

Ich sitze jetzt seit über 3 Stunden vor dem Laptop und lese eine Seite nach der anderen zu dem Thema - leider verwirrt mich das Thema dadurch von Minute zu Minute noch mehr.

Es gibt zwei (sinnvolle) Wege. Dass du UTC im DBMS speichern solltest, steht wohl außer Frage. Du überlässt das Zeitzonenhandling dem DMBS, verwendest TIMESTAMPs und teilst beim Verbindungsaufbau immer mit, welche Zeitzone du verwendest. Dann rechnet MySQL die Zeit nach UTC um und wieder zurück. Du kannst aber auch das Zeitzonenhandling komplett selbst übernehmen, dann musst du selbst immer von und nach UTC umrechnen - und darauf achten, dass das DBMS nicht auch noch umrechnet (also TIMESTAMP vermeiden).

Jetzt habe ich mir überlegt: Ich könnte doch sowohl bei CREATED, als auch bei MODIFIED den Typ 'Datetime' verwenden und bei der Speicherung/Änderung eines Datensatzes nehme ich statt dem NOW() im prepared Statement ein UTC_TIMESTAMP(). Dann habe ich systematisch - unabhängig von anderen Einstellungen am Server - _immer_ die UTC Zeit gespeichert.

Jein. DATETIME hat für deinen Anwendungsfall einen viel zu hohen Wertebereich, aber sei's drum. Wenn du UTC_TIMESTAMP() nimmst, muss der Server ebenfalls korrekt konfiguriert sein. UTC_TIMESTAMP() kann nicht aus heiterem Himmel wissen, was die aktuelle Zeit ist, weder für UTC noch für lokal. Du musst dich darauf verlassen, dass der Server richtig konfiguriert ist. Unabhängigkeit vom DBMS bekommst du nur, wenn du DATETIME nimmst, was ja ohne Konvertierung speichert, und alle Zeit-Rechnungen und -Bestimmungen im Client vornimmst.

Ich habe das jetzt gerade getestet. Es funktioniert einwandfrei. Es steht jetzt eine um 2 Stunden frühere Zeit in der DB.

Dann scheint dein Server derzeit richtig konfiguriert zu sein.

Die Frage ist nur, wenn ich eine so gespeicherte Zeit jetzt mittels einer php Ressource ausgeben möchte - nehmen wir als Beispiel ein Gästebuch oder einen Blog - wie gehe ich denn dann vor, wenn im Endeffekt jene Zeit dastehen soll, die zu diesem Zeitpunkt in Mitteleuropa war?

Na, umrechnen musst du das dann schon selbst. Vom DBMS geliefert musst du den Wert in seine Einzelteile zerlegen, damit gmmktime() füttern (beachte das gm!), und dessen Ergebnis kannst du dann mit date() formatieren (date ohne gm). Für diese Umrechnung muss dein PHP-Server korrekt konfiguriert und mit PHP (d)eine Zeitzone gesetzt worden sein.

Soweit zum theoretischen Teil. Rein praktisch können wir sicherlich davon ausgehen, dass sowohl Datenbank- als auch Webserver in einer Weise konfiguriert worden sind, dass sie zumindest die UTC richtig berechnen können. Das heißt, dass die notwendigen Zeitzonendaten installiert sind. Auch muss deine Befürchtung nicht zutreffen. Wenn der Hoster nach T... umzieht, heißt das noch lange nicht, dass er auch die dortige Zeitzone in seinen Serveren einstellt, wenn er vorwiegend mitteleuropäische Kunden hat. Aber egal, selbst wenn du am Server an der Kommandozeile dir die Zeit ausgeben lässt und da was dortiges lokales angezeigt wird, muss dich das nicht weiter stören, wenn du stets angibst, welche Zeitzone du meinst. Du kannst also durchaus TIMESTAMP nehmen, beim Verbindungsaufbau deine Zeitzone festlegen und dann mit NOW() arbeiten. Intern abgelegt wird dann der zugehörige UTC-Wert. Beim Verbindungsaufbau zum Abfragen hast du wieder deine Zeitzone angegeben und bekommst nun den Wert in dieser Lokalzeit zurück. - Wobei mir gerade auffällt, dass es bei NOW() egal ist, welche Zeitzone eingestellt ist. Wenn es eine andere ist, wir eben von der nach UTC umgerechnet. Nur beim Abfragen musst du deine angeben. Also selbst wenn irgendwer anders ohne explizite Zeitzonenkonfiguration Daten ändert, sollte mit TIMESTAMP alles problemlos als UTC abgelegt werden.

Im Grunde genommen ist es gehüpft wie gesprungen. Wenn du sichergehen willst, musst du selbst die Zeitzoneneinstellungen individuell setzen und dich nicht auf Systemdefaulteinstellungen verlassen. Das heißt also, dass du mindestens unter PHP die Zone konfigurierst. Der einfachte Weg wäre nun der TIMESTAMP-Weg. Bei dem musst du lediglich beim Verbindungsaufbau zum DBMS (und das zwingend nur beim Abfragen) die Zeitzone setzen (neben der Konfiguration für die Zeichenkodierung). Alle Umrechnungen erfolgen im DBMS. Selbst nach deinem Wunsch formatiert kannst du die Datümer abfragen, so dass sie PHP nur noch durchreichen muss. Aufwendiger hingegen ist es, wenn du selbst mit PHP umrechnen musst. Sicherer als die TIMESTAMP-Lösung wird es dadurch auch nicht.

dedlfix.