Tach!
Soweit ich weiß, geht das mit einem Statement SET time_zone = timezone.
Das war leider die falsche Syntax.
Nö, wars nicht, aber ...
Es kam eine Fehlermeldung. Ich hab dann Gottseidank eine Seite gefunden, wo geschrieben stand, wie ich das richtig zu formulieren habe.
Eine solche hatte ich auch verlinkt, da stand auch, dass man das als Stunden-Differenz angeben kann.
Also es wird nach dem
$db->set_charset('utf8');
noch zusätzlich ein$db->query("set time_zone='+02:00'");
gesetzt. (Dann kommt keine Fehlermeldung mehr.)
SET liefert kein Resultset. Du kannst für dessen Aufruf die Methode exec() nehmen.
Nun zum obigen "aber". MySQL kann entgegen meiner ersten Annahme doch nicht direkt auf die Zeitzonendaten des Systems zugreifen. Ich überlas bisher diesen Satz: "Named time zones can be used only if the time zone information tables in the mysql database have been created and populated." Der steht auch auf obiger Seite und anschließend steht geschrieben, wie man diese Tabelle füllt. Du bist dazu auf den Administrator angewiesen, denn das ist eine Systemtabelle in der Datenbank "mysql". Erwähnt ist auch ein Script, welches die MySQL-Timezone-Tabellen-Daten aus dem Inhalt der System-Timezone-Daten generiert. Und das muss im Prinzip nach jeder Änderung der Zeitzonendaten erfolgen.
Allerdings hat das leider auch absolut _Null_ Auswirkung auf die Speicherung und die Ausgabe der Timestamps. Egal, ob ich da jetzt als Zeitzone ein 'Europe/Athens', ein 'Europe/Berlin' ... ein '-02:00' oder ein '+04:00' setze - es veränder absolut _nichts_ am Geschehen.
Was meinst du mit "Speicherung"? Die Speicherung kannst du nicht direkt anschauen, wenn dir das Binärformat der MySQL-Tabellen-Dateien nicht geläufig ist. Du kannst mit SQL immer nur das sehen, was MySQL dir zu geben bereit ist. Das kann unter Umständen auch bereits in irgendwas umgewandelt sein.
Definiere dein Geschehen. Bei mir hat sowohl mit der +/-0:00-Syntax als auch nach dem Füllen der Timezone-Tabellen mit Zonen-Namen alles bestens funktioniert.
SET time_zone='Europe/Berlin';
INSERT INTO test (t) VALUES ('1970-01-01 03:00:00');
SELECT t, UNIX_TIMESTAMP(t) FROM test;
Ausgabe; 1970-01-01 03:00:00, 7200
SET time_zone='UTC';
SELECT t, UNIX_TIMESTAMP(t) FROM test;
Ausgabe; 1970-01-01 02:00:00, 7200
SET time_zone='Europe/Athens';
SELECT t, UNIX_TIMESTAMP(t) FROM test;
Ausgabe; 1970-01-01 04:00:00, 7200
Der Unix-Timestamp-Wert ändert sich nicht, denn er gibt ja immer die Sekunden in UTC aus (7200 = 2 x 3600 Sekunden = 2 Uhr). Das Handbuch statiert der Funktion UNIX_TIMESTAMP() auch, dass sie auf ein TIMESTAMP-Feld angewendet keine Konvertierung vornimmt - wenn man die Ausgaben anschaut stimmt das augenscheinlich.
Und wäre das dann so, dass wenn ein Zeitpunkt als 14:00 UTC gespeichrt ist und ich hier zB. Athen als Zeitzone nehme, dann beim Abruf ein 17:00 ausgegeben wird?
So ist das, zumindest zur Sommerzeit. So funktioniert der Unix-Timestamp, so funktioniert der TIMESTAMP unter MySQL.
Leider ist dem nicht so!
Dann machst du vielleicht was falsch oder ziehst die falschen Schlüsse.
In der ersten TS Spalte, das ist die, die automatisch bei der Speicherung eines neuen Datensatzes den momentanen Zeitpunkt speichert, steht _immer_ die aktuelle mitteleuropäische Sommerzeit.
In der zweiten TS Spalte, steht bei Speicherung mit einemNOW()
im Query _immer_ die aktuelle mitteleuropäische Sommerzeit und mit einemUTC_TIMESTAMP()
im Query _immer_ die UTC Zeit. (Wobei letzteres das Einzige ist, das so geschieht, wie von mir erwartet.)
Nach welchem Vorgang und wie hast du das kontrolliert? "Steht" kannst du nicht wissen, wenn du nur SELECT darauf anwendest. Nimm UNIX_TIMESTAMP() zum Anzeigen der Sekunden. Zeige diese Sekunden dann mit einer UTC-Funktion (z.B. PHPs gmdate()) in einem lesbaren Format an.
Und wie gesagt, die gespeicherten und ausgegeben Werte sind _immer_ so wie in den letzten 2 Absätzen beschrieben. Unabhängig davon, ob ich nach dem Verbindungsaufbau eine Zeitzone festlege oder nicht und unabhängig davon, was als Zeitzone festgelegt wird. [Mit Ausgabe meine ich nicht, was ich sehe, wenn ich mir den Tabelleninhalt in phpMyAdmin ansehe - dort steht das selbe übrigens, sondern wirklich das, was ich mir mit php/mysqli über den Browser ausgeben lasse!]
Der PMA macht auch nur ein SELECT und hat einen Verbindungsaufbau, bei dem er ohne weiteres keine Zeitzone setzt. Bei mir sehe ich ohne vorheriges SET im PMA immer die Lokalzeiten. Über den Startbildschirm vom PMA kann man sich die Variablen anzeigen lassen, und sogar bearbeiten (Version 3.5.2.2). Ich sehe bei 'time zone' ein SYSTEM und bei 'system time zone' ein CEST. Bearbeite ich 'time zone' zu UTC, sehe ich beim einfachen Anzeigen nun die UTC-Werte. Man muss das aber nicht dort ändern, sondern kann das angezeigte SQL-Statement bearbeiten und ein 'SET time_zone...;' voranstellen.
Ich bin also nicht einen Schritt weiter. :-(
Du musst es nur richtig machen :-)
PS: Was ich natürlich _nicht_ weiß, ist, ob das
$db->query("set time_zone='+02:00'");
auch wirklich der richtige Weg zur Festlegung einer Zeitzone ist. Es wird zumindest, wie geschrieben, keine Fehlermeldung oder Warnung ausgegeben.
Jein. Du hast in dieser Differenzangabe keine Sommerzeit-Information. Nimmst du +2:00 sind Zeiten außerhalb der Sommerzeit fehlerhaft und bei +1:00 die zur Sommerzeit. Du müsstest, um die richtige Differenz zu setzen, also immer vorher wissen, welche Zeit du abfragst - und das geht ja nicht. Du brauchst also die gefüllten Zeitzonentabellen, um das Zeitzonenhandling namensbasiert dem MySQL überlassen zu können. Sonst geht nur UTC-Speicherung in MySQL mit Lokal-Umrechnung in PHP.
dedlfix.