Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment gérer le fuseau horaire MySQL dans le script

Vous avez exécuté cette requête de diagnostic temporel sur votre serveur MySQL.

select @@time_zone, now(), utc_timestamp()

Il ressort clairement de votre heure locale et de votre heure utc que le paramètre de fuseau horaire système de votre machine serveur est "Canada/Montagne", et que le logiciel du serveur MySQL n'a pas son propre paramètre de fuseau horaire.

Si vous récupérez vos tables et les déplacez telles quelles vers un serveur dans un fuseau horaire proche, vous pouvez toujours mettre à jour votre logiciel pour émettre la commande

set time_zone = 'Canada/Mountain';

juste après vous être connecté depuis votre logiciel. Cela fera en sorte que votre nouvelle connexion MySQL se comporte comme votre connexion actuelle en termes de fuseau horaire. Si vous possédez le serveur MySQL, vous pouvez définir son fuseau horaire par défaut en suivant les instructions de cette page. http://dev.mysql.com/doc /refman/5.5/en/time-zone-support.html

Maintenant, voici l'histoire des types de données temporelles. DATE , TIME , et DATETIME sont tous ignorants du fuseau horaire . Une fois que vous avez enregistré une valeur de date/heure, vous retrouverez la même valeur même si vous modifiez vos paramètres de fuseau horaire.

Le TIMESTAMP le type de données est sensible au fuseau horaire . Ces éléments de données sont toujours stockés en UTC, également appelé Z, time , anciennement connu sous le nom de temps moyen de Greenwich. Ils sont toujours convertis en UTC lors de leur stockage et toujours reconvertis lors de leur récupération.

Les fonctions intégrées pour obtenir la date et l'heure actuelles (NOW() et amis) sont sensibles au fuseau horaire . Ils donneront des valeurs en heure locale. Les exceptions sont les trois fonctions commençant par UTC_ qui donnent des valeurs en temps UTC.

De nombreuses applications MySQL multi-fuseaux horaires utilisent la discipline opérationnelle suivante :

  1. Demandez à chaque utilisateur un fuseau horaire de préférence, ou déterminez-le à partir d'autres données personnelles sur l'utilisateur. (Les téléphones reçoivent ces informations à partir du réseau.) Stockez-les en tant que zoneinfo-friendly descripteur de fuseau horaire ("America/New_York", "Canada/Mountain", "Europe/Vienne", etc.) au nom de l'utilisateur.
  2. Lors de l'établissement d'une session MySQL au nom de l'utilisateur, définissez le fuseau horaire de l'utilisateur avec un set time_zone requête comme celle montrée ci-dessus. Vous devriez le faire juste après votre connect opération.
  3. Stocker les dates et heures des utilisateurs dans TIMESTAMP Types de données. Ils seront convertis en UTC au fur et à mesure de leur stockage.
  4. Récupérez-les au besoin. Elles seront reconverties à l'heure locale.

L'idée est que le fuseau horaire de votre utilisateur fait partie de son contexte. Cela fonctionne bien, car si l'utilisateur A est à Vancouver et l'utilisateur B à Halifax, et que pour une raison quelconque l'utilisateur B consulte les données temporelles de l'utilisateur A, elles seront présentées à B en heure de l'Atlantique plus ou moins automatiquement.

C'est aussi bien parce qu'il traite de manière transparente les aléas mondiaux du passage de l'heure d'été à l'heure d'hiver. Un horodatage de l'été dernier sera affiché à l'heure locale de l'été dernier.

De nombreux gestionnaires de serveurs à usage mondial définissent l'heure de leur serveur système, ou leur fuseau horaire MySQL par défaut, sur UTC. (Ce n'est pas le cas pour vous.)

Une autre façon de gérer tout cela est la façon dont vous avez commencé. Choisissez un fuseau horaire et stockez vos horodatages par rapport à ce fuseau horaire. Il est préférable de choisir un fuseau horaire qui n'alterne pas entre l'heure d'été et l'heure d'hiver dans ce cas. Ensuite, lors du stockage des heures dans la base de données, convertissez-les explicitement. Vous stockeriez les temps des utilisateurs à Ottawa en faisant quelque chose comme ça.

INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)

et vous obtiendriez les valeurs de la même manière. Ceci est sujet aux erreurs, mais vous pouvez le faire fonctionner.

Enfin, vous pouvez faire vos conversions vous-même. Si vous voulez savoir combien de minutes de décalage il y a entre un fuseau horaire arbitraire et UTC, essayez ces deux requêtes.

set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());

A cette époque de l'année ça redonne -240, soit -4h00. Vous devez utiliser les minutes plutôt que les heures en raison des décalages horaires d'une demi-heure ou d'un quart d'heure dans certains pays.

Enfin, attention. TIMESTAMP les types de données ne représentent pas les heures avant 1970. Et, sur mon instance MariaDB 10.0, il semble aller en enfer dans un seau juste après 2038-01-19T03:14:07 UTC lorsque l'heure dépasse de 32 bits.