it-swarm.com.de

Sollte die Zeitzone von MySQL auf UTC eingestellt sein?

Folge der Frage von https://serverfault.com/questions/191331/should-servers-have-their-timezone-set-to-gmt-utc

Sollte die MySQL-Zeitzone auf UTC oder auf dieselbe Zeitzone wie der Server eingestellt sein oder PHP ist eingestellt? (Wenn es nicht UTC ist)

Was sind die Vor- und Nachteile?

132
Timo Huovinen

Es scheint, dass es keine Rolle spielt, welche Zeitzone sich auf dem Server befindet, solange Sie die richtige Zeit für die aktuelle Zeitzone eingestellt haben, die Zeitzone der von Ihnen gespeicherten Datums- und Uhrzeitspalten kennen und die Probleme mit der Sommerzeit kennen.

Wenn Sie dagegen die Zeitzonen der Server steuern können, mit denen Sie arbeiten, können Sie alles intern auf UTC einstellen, ohne sich um Zeitzonen und Sommerzeit kümmern zu müssen.

Hier sind einige Notizen, die ich gesammelt habe, wie ich mit Zeitzonen als eine Art Spickzettel für mich und andere arbeite. Diese können Einfluss darauf haben, welche Zeitzone die Person für ihren Server wählt und wie sie Datum und Uhrzeit speichert.

MySQL Timezone Cheatsheet

Anmerkungen:

  1. Durch Ändern der Zeitzone werden die gespeicherte Datums- und Uhrzeitangabe nicht geändert, es wird jedoch eine andere Datums- und Uhrzeitangabe aus den Zeitstempelspalten ausgewählt
  2. Achtung! UTC hat Schaltsekunden, diese sehen aus wie '2012-06-30 23:59:60' und können nach dem Zufallsprinzip mit einer Vorlaufzeit von 6 Monaten hinzugefügt werden bemerken, aufgrund der Verlangsamung der Erdrotation
  3. GMT verwirrt Sekunden, weshalb UTC erfunden wurde.

  4. Achtung! Unterschiedliche regionale Zeitzonen können aufgrund der Sommerzeit den gleichen Datums-/Uhrzeitwert erzeugen

  5. Die Timestamp-Spalte unterstützt aufgrund von eine Einschränkung nur Daten von 1970-01-01 00:00:01 bis 2038-01-19 03:14:07 UTC.
  6. Intern wird eine MySQL-Zeitstempel-Spalte als UTC gespeichert, aber wenn Sie ein Datum auswählen, konvertiert MySQL es automatisch in die aktuelle Sitzungszeitzone.

    Beim Speichern eines Datums in einem Zeitstempel geht MySQL davon aus, dass das Datum in der aktuellen Sitzungszeitzone liegt, und konvertiert es zum Speichern in UTC.

  7. MySQL kann Teildaten in Datums-/Uhrzeitspalten speichern. Diese sehen aus wie "2013-00-00 04:00:00".
  8. MySQL speichert "0000-00-00 00:00:00", wenn Sie eine datetime-Spalte als NULL festlegen, es sei denn, Sie haben die Spalte so festgelegt, dass sie beim Erstellen NULL zulässt.
  9. Lesen Sie dies

Auswählen einer Zeitstempelspalte im UTC-Format

egal in welcher Zeitzone sich die aktuelle MySQL-Sitzung befindet:

SELECT 
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime` 
FROM `table_name`

Sie können auch die Zeitzone für den Server, die globale oder die aktuelle Sitzung auf UTC einstellen und dann den Zeitstempel wie folgt auswählen:

SELECT `timestamp_field` FROM `table_name`

So wählen Sie die aktuelle Datumszeit in UTC aus:

SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');

Beispielergebnis: 2015-03-24 17:02:41

So wählen Sie die aktuelle Datums- und Uhrzeiteinstellung in der Sitzungszeitzone aus

SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();

Auswählen der Zeitzone, die beim Start des Servers festgelegt wurde

SELECT @@system_time_zone;

Gibt "MSK" oder "+04: 00" für die Moskauer Zeit zurück. Es gibt (oder gab) einen MySQL-Fehler, bei dem die Sommerzeit nicht angepasst wird, wenn ein numerischer Versatz festgelegt wird

Um die aktuelle Zeitzone zu erhalten

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

Es wird 02:00:00 zurückgegeben, wenn Ihre Zeitzone +2: 00 ist.

So rufen Sie den aktuellen UNIX-Zeitstempel (in Sekunden) ab:

SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();

So rufen Sie die Zeitstempelspalte als UNIX-Zeitstempel ab

SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`

So rufen Sie eine UTC-Datetime-Spalte als UNIX-Zeitstempel ab

SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`

Ermittelt eine aktuelle Zeitzone aus einer positiven Ganzzahl mit UNIX-Zeitstempel

SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`

Abrufen einer UTC-Datumszeit von einem UNIX-Zeitstempel

SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00') 
FROM `table_name`

Ermittelt eine aktuelle Zeitzone aus einer negativen Ganzzahl mit UNIX-Zeitstempel

SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND) 

Es gibt drei Stellen, an denen die Zeitzone in MySQL festgelegt werden kann:

Hinweis: Eine Zeitzone kann in zwei Formaten festgelegt werden:

  1. ein Versatz von UTC: '+00: 00', '+10: 00' oder '-6: 00'
  2. als benannte Zeitzone: 'Europe/Helsinki', 'US/Eastern' oder 'MET'

Benannte Zeitzonen können nur verwendet werden, wenn die Zeitzoneninformationstabellen in der mysql-Datenbank erstellt und ausgefüllt wurden.

in der Datei "my.cnf"

default_time_zone='+00:00'

oder

timezone='UTC'

@@ global.time_zone Variable

Um zu sehen, auf welchen Wert sie eingestellt sind

SELECT @@global.time_zone;

Verwenden Sie einen der folgenden Werte, um einen Wert festzulegen:

SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';

@@ session.time_zone Variable

SELECT @@session.time_zone;

Verwenden Sie eine der folgenden Optionen, um sie festzulegen:

SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";

sowohl "@@ global.time_zone variable" als auch "@@ session.time_zone variable" geben möglicherweise "SYSTEM" zurück, was bedeutet, dass sie die in "my.cnf" festgelegte Zeitzone verwenden.

Damit Zeitzonennamen funktionieren (auch für die Standardzeitzone), müssen Sie Ihre Zeitzoneninformationstabellen einrichten, die ausgefüllt werden müssen: http: //dev.mysql.com/doc/refman/5.1/de/time-zone-support.html

Hinweis: Sie können dies nicht tun, da NULL zurückgegeben wird:

SELECT 
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime` 
FROM `table_name`

Richten Sie MySQL-Zeitzonentabellen ein

Zum CONVERT_TZ Damit Sie arbeiten können, müssen die Zeitzonentabellen ausgefüllt sein

SELECT * FROM mysql.`time_zone` ;
SELECT * FROM mysql.`time_zone_leap_second` ;
SELECT * FROM mysql.`time_zone_name` ;
SELECT * FROM mysql.`time_zone_transition` ;
SELECT * FROM mysql.`time_zone_transition_type` ;

Wenn sie leer sind, füllen Sie sie mit diesem Befehl auf

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

wenn dieser Befehl den Fehler " Daten für Spalte 'Abkürzung' in Zeile 1 zu lang " ausgibt, wird möglicherweise ein NULL-Zeichen am Ende der Abkürzung für die Zeitzone angehängt

das Update ist, dies auszuführen

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
(if the above gives error "data too long for column 'abbreviation' at row 1")
mysql_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql

echo "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sql

mysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql

(Stellen Sie sicher, dass Ihre Server-Regeln auf dem neuesten Stand sind. zdump -v Europe/Moscow | grep 2011https://chrisjean.com/updating-daylight-saving-time-on-linux/ )

Zeigen Sie für jede Zeitzone den vollständigen DST-Verlauf (Sommerzeit) an

SELECT 
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND)  AS transition_date
FROM mysql.`time_zone_transition` tzt
INNER JOIN mysql.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN mysql.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC

CONVERT_TZ wendet auch alle erforderlichen DST-Änderungen an, die auf den Regeln in den obigen Tabellen und dem von Ihnen verwendeten Datum basieren.

Hinweis:
Gemäß docs ändert sich der Wert, den Sie für die Zeitzone festgelegt haben, nicht. Wenn Sie ihn beispielsweise auf "+01: 00" festlegen, wird die Zeitzone als Versatz festgelegt von UTC, die nicht DST folgt, so wird es das ganze Jahr über gleich bleiben.

Nur das benannte Zeitzonen ändert die Zeit während der Sommerzeit.

Abkürzungen wie CET sind immer eine Winterzeit und CEST sind Sommerzeit, während +01: 00 immer UTC ist + 1 Stunde und beide ändern sich nicht mit DST.

Die system -Zeitzone ist die Zeitzone des Host-Rechners, auf dem MySQL installiert ist (es sei denn, MySQL kann dies nicht feststellen).

Sie können mehr über die Arbeit mit Sommerzeit lesen hier

verwandte Fragen:

Quellen:

479
Timo Huovinen

Dies ist ein funktionierendes Beispiel:

jdbc:mysql://localhost:3306/database?useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Europe/Moscow
2
tatka

PHP und MySQL haben ihre eigenen Standardkonfigurationen für die Zeitzone. Sie sollten die Zeit zwischen Ihrer Datenbank und der Webanwendung synchronisieren, da sonst Probleme auftreten können.

Lesen Sie dieses Tutorial: So synchronisieren Sie Ihre PHP und MySQL-Zeitzonen

2
user1202826

Die Vor- und Nachteile sind ziemlich identisch. Es hängt davon ab, ob Sie dies möchten oder nicht.

Seien Sie vorsichtig, wenn die MySQL-Zeitzone von Ihrer Systemzeit abweicht (z. B. PHP). Wenn Sie die Zeit vergleichen oder dem Benutzer mitteilen, dass Sie drucken möchten, müssen Sie einige Änderungen vornehmen.

1
alandarev