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 datetime-Spalten kennen und sich der Probleme mit der Sommerzeit bewusst sind.
Wenn Sie andererseits die Zeitzonen der Server, mit denen Sie arbeiten, kontrollieren können, können Sie intern alles auf UTC einstellen und müssen sich nie um Zeitzonen und Sommerzeit kümmern.
Hier sind einige Notizen, die ich gesammelt habe, wie man mit Zeitzonen als eine Art Cheatsheet für mich und andere arbeitet, die beeinflussen könnten, welche Zeitzone die Person für ihren Server wählt und wie sie Datum und Uhrzeit speichert.
MySQL-Zeitzonen-Cheatsheet
Hinweise:
-
Das Ändern der Zeitzone ändert nicht die gespeicherte Datumszeit oder den Zeitstempel , aber es wird eine andere datetime fromtimestamp-Spalte auswählen
-
Warnung! UTC hat Schaltsekunden, diese sehen wie '2012-06-30 23:59:60' aus und können aufgrund der Verlangsamung der Erdrotation mit 6 Monaten Vorankündigung zufällig hinzugefügt werden
-
GMT verwechselt Sekunden, weshalb UTC erfunden wurde.
-
Warnung! unterschiedliche regionale Zeitzonen könnten aufgrund der Sommerzeit denselben datetime-Wert erzeugen
-
Die Zeitstempelspalte unterstützt nur Daten von 1970-01-01 00:00:01 bis 2038-01-19 03:14:07 UTC, aufgrund von eine Einschränkung .
-
Intern eine MySQL-Zeitstempelspalte wird als UTC gespeichert Aber wenn Sie ein Datum auswählen, konvertiert MySQL es automatisch in die Zeitzone der aktuellen Sitzung.
Beim Speichern eines Datums in einem Zeitstempel geht MySQL davon aus, dass sich die Datei in der Zeitzone der aktuellen Sitzung befindet, und konvertiert sie zur Speicherung in UTC.
-
MySQL kann Teildaten in datetime-Spalten speichern, diese sehen aus wie „2013-00-00 04:00:00“
-
MySQL speichert „0000-00-00 00:00:00“, wenn Sie eine datetime-Spalte auf NULL setzen, es sei denn, Sie legen die Spalte ausdrücklich so fest, dass sie Null zulässt, wenn Sie sie erstellen.
Um eine Zeitstempelspalte im UTC-Format auszuwählen
egal in welcher Zeitzone sich die aktuelle MySQL-Session befindet:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
Sie können auch die Zeitzone des Servers oder der globalen oder aktuellen Sitzung auf UTC setzen und dann den Zeitstempel wie folgt auswählen:
SELECT `timestamp_field` FROM `table_name`
Um die aktuelle Datumszeit in UTC auszuwählen:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
Beispielergebnis:2015-03-24 17:02:41
Zum Auswählen der aktuellen Datumszeit in der Sitzungszeitzone
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
Zum Auswählen der Zeitzone, die beim Starten des Servers festgelegt wurde
SELECT @@system_time_zone;
Gibt "MSK" oder "+04:00" für Moskauer Zeit zurück, es gibt (oder gab) einen MySQL-Bug, bei dem bei Einstellung auf einen numerischen Offset die Sommerzeit nicht angepasst wurde
Um die aktuelle Zeitzone abzurufen
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
Es wird 02:00:00 zurückgegeben, wenn Ihre Zeitzone +2:00 ist.
So erhalten Sie den aktuellen UNIX-Zeitstempel (in Sekunden):
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
So erhalten Sie die Zeitstempelspalte als UNIX-Zeitstempel
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
So erhalten Sie eine UTC-Datetime-Spalte als UNIX-Zeitstempel
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
Erhalten Sie eine aktuelle Zeitzone datetime aus einer positiven UNIX-Zeitstempel-Ganzzahl
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
Eine UTC-Datumszeit aus einem UNIX-Zeitstempel erhalten
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
Erhalten Sie eine aktuelle Zeitzone datetime aus einer negativen UNIX-Zeitstempel-Ganzzahl
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
Es gibt 3 Stellen, an denen die Zeitzone in MySQL eingestellt werden kann:
Hinweis:Eine Zeitzone kann in 2 Formaten eingestellt werden:
- ein Offset von UTC:'+00:00', '+10:00' oder '-6:00'
- als benannte Zeitzone:„Europe/Helsinki“, „US/Eastern“ oder „MET“
Benannte Zeitzonen können nur verwendet werden, wenn die Zeitzonen-Informationstabellen 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;
Um einen Wert dafür festzulegen, verwenden Sie entweder:
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;
Um es einzustellen, verwenden Sie entweder:
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 (sogar für Standard-Zeitzone), müssen Sie Ihre Zeitzonen-Informationstabellen einrichten, die ausgefüllt werden müssen: http://dev.mysql.com/doc /refman/5.1/en/time-zone-support.html
Hinweis:Sie können dies nicht tun, da es NULL zurückgibt:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
Mysql-Zeitzonentabellen einrichten
Für CONVERT_TZ
Damit es funktioniert, müssen die Zeitzonentabellen gefü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 "data too long for column 'abbreviation' at row 1 “, dann könnte es daran liegen, dass am Ende der Zeitzonen-Abkürzung ein NULL-Zeichen angehängt wird
Die Lösung besteht darin, 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 die dst-Regeln Ihres Servers auf dem neuesten Stand sind zdump -v Europe/Moscow | grep 2011
https://chrisjean.com/updating-daylight-saving-time- on-linux/
)
Siehe den vollständigen Verlauf der Umstellung auf die Sommerzeit (DST) für jede Zeitzone
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 Sommerzeitänderungen basierend auf den Regeln in den obigen Tabellen und dem von Ihnen verwendeten Datum an.
Hinweis:
Laut den Dokumenten , ändert sich der Wert, den Sie für time_zone festlegen, nicht. Wenn Sie ihn beispielsweise auf „+01:00“ festlegen, wird die time_zone als Offset von UTC festgelegt, die nicht der Sommerzeit folgt, sodass sie für alle gleich bleibt ganzjährig.
Nur die genannten Zeitzonen ändert die Zeit während der Sommerzeit.
Abkürzungen wie CET
wird immer eine Winterzeit und CEST
sein Sommerzeit, während +01:00 immer UTC
ist Zeit + 1 Stunde und beide ändern sich nicht mit der Sommerzeit.
Das system
timezone ist die Zeitzone des Host-Rechners, auf dem mysql installiert ist (es sei denn, mysql kann sie nicht bestimmen)
Weitere Informationen zum Arbeiten mit der Sommerzeit finden Sie hier
Wann man UTC vom legendären Jon Skeet nicht verwenden sollte:https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ (Zum Beispiel ein geplantes Ereignis in der Zukunft, das einen Zeitpunkt darstellt, keinen Zeitpunkt)
verwandte Fragen:
- Wie stelle ich die Zeitzone von MySQL ein?
- MySql - SELECT TimeStamp Column im UTC-Format
- Anleitung Unix-Zeitstempel in MySQL von UTC-Zeit erhalten?
- Server MySQL TimeStamp in UTC konvertieren
- https://dba. stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- How do Ich bekomme die aktuelle Zeitzone von MySQL?
- MySQL-Datumszeitfelder und Sommerzeit – wie verweise ich auf die "zusätzliche" Stunde?
- Konvertieren negativer Werte von FROM_UNIXTIME
Quellen:
- https://bugs.mysql.com/bug.php?id=68861
- http://dev. mysql.com/doc/refman/5.0/en/date-and-time-functions.html
- http://dev.mysql.com/doc/ refman/5.1/en/datetime.html
- http://en.wikipedia.org/wiki/Coordinated_Universal_Time
- http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
- https://web.ivy.net/~carton/ rant/MySQL-Zeitzonen.txt