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?
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:
- changer le fuseau horaire ne changera pas le datetime stocké ou timestamp , mais il sélectionnera une date différente de colonnes timestamp
- 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é).
- 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
- attention! des fuseaux horaires régionaux différents pourraient produire la même valeur de datetime due à l'heure avancée
- 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 .
-
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.
- MySQL peut stocker des dates partielles dans les colonnes datetime, celles-ci ressemblent à "2013-00-00 04:00:00"
- 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.
- 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:
- un décalage UTC: '+00:00', '+10:00' ou '-6:00'
- 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:
- comment définir le fuseau horaire de MySQL?
- MySql - SÉLECTIONNER la Colonne TimeStamp au format UTC
- comment obtenir Unix timestamp en MySQL à partir de UTC time?
- Conversion Serveur MySQL TimeStamp De l'heure UTC
- https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- Comment puis-je obtenir le fuseau horaire actuel de MySQL?
- les champs datetime de MySQL et de l'heure d'été -- comment dois-je faire référence "extra" à l'heure?
- conversion des valeurs négatives de FROM_UNIXTIME
Sources:
- 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-timezones.txt
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
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.