MySQL devrait-il avoir son fuseau horaire réglé sur UTC?

question de suivi de https://serverfault.com/questions/191331/should-servers-have-their-timezone-set-to-gmt-utc

le fuseau horaire MySQL doit-il être défini à UTC ou doit-il être défini comme le même fuseau horaire que le serveur ou PHP est défini? (Si ce n'est pas UTC)

Quels sont les avantages et les inconvénients?

119
demandé sur Community 2013-09-26 13:11:40

3 réponses

il semble que peu importe ce que timezone est sur le serveur tant que vous avez l'heure correcte pour le fuseau horaire actuel, connaître le fuseau horaire des colonnes datetime que vous stockez, et être au courant des problèmes avec l'heure d'été.

d'un autre côté si vous avez le contrôle des fuseaux horaires des serveurs avec lesquels vous travaillez, alors vous pouvez avoir tout réglé sur UTC en interne et ne jamais vous soucier des fuseaux horaires et DST.

ici sont quelques notes que j'ai recueillies sur la façon de travailler avec timezones comme une forme de cheatsheet pour moi-même et d'autres qui pourraient influencer le fuseau horaire que la personne choisira pour son serveur et comment il/elle va stocker la date et l'heure.

MySQL Fuseau Horaire Triche

Notes:

  1. changer le fuseau horaire ne changera pas le datetime stocké ou timestamp , mais il sélectionnera une date différente de colonnes timestamp
  2. UTC n'utilise pas l'heure d'été, GMT (la région) n'utilise pas, GMT (le fuseau horaire) n'en utilise pas (GMT confond également la définition des secondes, raison pour laquelle UTC a été inventé).
  3. attention! UTC a des secondes bissextiles, celles-ci ressemblent à '2012-06-30 23:59:60' et peut être ajouté au hasard, avec 6 mois de préavis, en raison du ralentissement de la rotation des terres
  4. attention! des fuseaux horaires régionaux différents pourraient produire la même valeur de datetime due à l'heure avancée
  5. La colonne timestamp prend uniquement en charge les dates 1970-01-01 00:00:01 à 2038-01-19 03:14:07 UTC, en raison de limitation .
  6. interne a MySQL timestamp colonne est stocké comme UTC mais lors de la sélection D'une date MySQL le convertira automatiquement en le fuseau horaire de la session en cours.

    lors du stockage d'une date dans une horodatage, MySQL supposera que la date est dans le fuseau horaire de la session en cours et le convertit en UTC pour stockage.

  7. MySQL peut stocker des dates partielles dans les colonnes datetime, celles-ci ressemblent à "2013-00-00 04:00:00"
  8. MySQL stocke "0000-00-00 00:00:00" si vous définissez une colonne datetime comme NULL, sauf si vous définissez spécifiquement la colonne pour permettre null lorsque vous créer il.
  9. Lire

pour sélectionner une colonne timestamp au format UTC

peu importe le fuseau horaire de la session MySQL actuelle:

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

vous pouvez également définir le fuseau horaire de la session ou global ou current à UTC et ensuite sélectionner le timestamp comme suit:

SELECT `timestamp_field` FROM `table_name`

pour sélectionner la date actuelle dans UTC:

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

exemple de résultat: 2015-03-24 17:02:41

pour sélectionner la date actuelle dans le fuseau horaire de la session

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

pour sélectionner le fuseau horaire qui a été défini lors du lancement du serveur

SELECT @@system_time_zone;

renvoie "MSK" ou "+04: 00 " Pour L'Heure de Moscou par exemple, il y a (ou il y avait) un bug MySQL où si réglé à un décalage numérique il ne réglerait pas l'heure D'été

pour obtenir le fuseau horaire actuel

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

il retournera 02:00:00 si votre fuseau horaire est +2:00.

pour obtenir le timestamp UNIX actuel (en secondes):

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

Pour obtenir la colonne timestamp UNIX timestamp

SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`

Pour obtenir un UTC colonne datetime comme un timestamp UNIX

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

obtenez un datetime de fuseau horaire courant à partir D'un entier de timestamp UNIX positif

SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`

UTC datetime à partir d'un timestamp UNIX

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

Obtenir un fuseau horaire actuel datetime à partir d'un négatif timestamp UNIX entier

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

il y a 3 endroits où le fuseau horaire pourrait être défini dans MySQL:

Note: un fuseau horaire peut être défini en 2 formats:

  1. un décalage UTC: '+00:00', '+10:00' ou '-6:00'
  2. comme un fuseau horaire nommé: "Europe / Helsinki", "US/Eastern", ou " MET "

les fuseaux horaires nommés ne peuvent être utilisés que si les tableaux d'information des fuseaux horaires dans la base de données mysql ont été créés et remplis.

dans le fichier "my.cnf "

default_time_zone='+00:00'

ou

timezone='UTC'

@@global.variable du fuseau horaire

pour voir quelle valeur elles sont à 1519320920"

SELECT @@global.time_zone;

Pour définir une valeur pour utiliser un:

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

@@session.variable du fuseau horaire

SELECT @@session.time_zone;

utilisez l'un ou l'autre:

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

les deux " @@global.variable time_zone " et " @ @ session.time_zone variable" pourrait revenir "SYSTÈME", ce qui signifie qu'ils utilisent le fuseau horaire défini dans "mon.cnf".

pour les noms de fuseaux horaires pour fonctionner (même par défaut-Fuseau horaire), vous devez configurer vos tables d'information de fuseau horaire doivent être remplis: http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html

Note: vous ne pouvez pas faire cela car il retournera NULL:

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

le programme d'Installation de mysql fuseau horaire tables

Pour CONVERT_TZ au travail, vous avez besoin de le fuseau horaire tables à être peuplée

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` ;

s'ils sont vides, remplissez-les en exécutant la commande

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

si cette commande vous donne l'erreur " données trop longues pour la colonne "Abréviation" à la ligne 1 ", alors il pourrait être causé par un caractère nul étant ajouté à la fin du fuseau horaire abréviation

le point étant d'exécuter ce

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

(assurez-vous que vos règles dst serveurs sont à jour zdump -v Europe/Moscow | grep 2011 https://chrisjean.com/updating-daylight-saving-time-on-linux / )

voir l'historique complet de la transition DST (heure D'été) pour chaque fuseau horaire

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 " s'applique également à toute modification nécessaire de l'heure D'hiver en fonction des règles des tableaux ci-dessus et de la date que vous utilisez.

Note:

Selon l' docs , la valeur que vous avez définie pour time_zone ne change pas, si vous la définissez comme "+01:00" Par exemple, alors time_zone sera défini comme un décalage de UTC, qui ne suit pas DST, de sorte qu'il restera le même toute l'année.

Uniquement le nom fuseaux horaires va changer de temps au cours de l'heure d'été.

les abréviations comme CET seront toujours un temps d'hiver et CEST sera heure d'été pendant que + 01:00 sera toujours UTC heure + 1 heure et les deux ne changeront pas avec DST.

le fuseau horaire system sera le fuseau horaire de la machine hôte où mysql est installé (sauf si mysql ne parvient pas à le déterminer)

vous pouvez en savoir plus sur le travail avec DST ici

questions connexes:

Sources:

426
répondu Timo Huovinen 2018-07-17 09:37:51

PHP et MySQL ont leurs propres configurations de fuseau horaire par défaut. Vous devriez synchroniser le temps entre votre base de données et l'application web, sinon vous pourriez exécuter certains problèmes.

lisez ce tutoriel: Comment synchroniser vos Timezones PHP et MySQL

2
répondu 2013-09-26 09:21:59

les avantages et les inconvénients sont à peu près identiques.Ça dépend si tu le veux ou pas.

faites attention, si le fuseau horaire MySQL diffère de votre temps système (par exemple PHP), comparer le temps ou l'impression à l'utilisateur impliquera un bricolage.

1
répondu alandarev 2013-09-26 09:17:31