web-dev-qa-db-fra.com

Comment stocker une date / heure dans MySQL avec les informations de fuseau horaire

J'ai des milliers de photos prises en Tanzanie et je souhaite stocker la date et l'heure de la prise de chaque photo dans une base de données MySQL. Le serveur, cependant, est situé aux États-Unis et j’ai des problèmes lorsque j’essaie de stocker une date-heure tanzanienne qui se situe dans l’heure "invalide" au printemps (heure avancée du printemps). La Tanzanie ne fait pas l’heure d’été, l’heure est donc réellement valide.

Des complications supplémentaires sont dues au fait que des collaborateurs de plusieurs fuseaux horaires différents devront accéder aux valeurs date-heure stockées dans la base de données. Je veux qu’ils sortent toujours à l’heure tanzanienne et non à l’heure locale où se trouvent divers collaborateurs.

Je suis réticent à définir les heures de session parce que je sais qu'il y aura des problèmes si quelqu'un oublie parfois de définir une heure de session et obtient le temps totalement erroné. Et je n'ai pas le pouvoir de changer quoi que ce soit à propos du serveur.

J'ai lu: Méthodes conseillées pour l'heure d'été et le fuseau horaire et champs de date et heure MySQL et heure d'été - comment référencer l'heure "supplémentaire"? et - Stocker la date/heure au format UTC en PHP/MySQL

Mais aucun d'entre eux ne semble résoudre mon problème particulier. Je ne suis pas un expert en SQL; Existe-t-il un moyen de spécifier un fuseau horaire lors de la définition de DATETIME? Je n'en ai pas vu. Sinon, toute suggestion sur la façon d'aborder cette question est grandement appréciée.

Edit: Voici un exemple du problème que je rencontre. J'envoie la commande:

INSERT INTO Images (CaptureEvent, SequenceNum, PathFilename, TimestampJPG) 
VALUES (122,1,"S2/B04/B04_R1/IMAG0148.JPG","2011-03-13 02:49:10")

Et je reçois l'erreur:

Error 1292: Incorrect datetime value: '2011-03-13 02:49:10' for column 'TimestampJPG'

Cette date et cette heure existent en Tanzanie, mais pas aux États-Unis, où se trouve la base de données.

57
mkosmala

Tu as dit:

Je veux qu’ils sortent toujours à l’heure tanzanienne et non à l’heure locale où se trouvent divers collaborateurs.

Si tel est le cas, vous devriez ne pas utiliser l'UTC. Tout ce que vous avez à faire est d’utiliser un type DATETIME dans MySQL au lieu d’un type TIMESTAMP.

de la documentation MySQL :

MySQL convertit les valeurs TIMESTAMP du fuseau horaire actuel en UTC pour le stockage, puis de UTC vers le fuseau horaire actuel pour les récupérer. (Cela ne se produit pas pour d'autres types tels que DATETIME.)

Si vous utilisez déjà un type DATETIME, vous ne devez pas le définir avant l'heure locale. Vous devrez vous concentrer moins sur la base de données et davantage sur votre code d'application - ce que vous n'avez pas montré ici. Le problème et la solution varient considérablement en fonction de la langue. Veillez donc à baliser la question avec la langue appropriée du code de votre application.

51

Tous les symptômes que vous décrivez suggèrent de ne jamais indiquer à MySQL le fuseau horaire à utiliser. Par défaut, il correspond au fuseau horaire du système. Pensez-y: si tout ce qu'il a c'est '2011-03-13 02:49:10', comment peut-il deviner que c'est une date tanzanienne locale?

Autant que je sache, MySQL ne fournit aucune syntaxe pour spécifier les informations de fuseau horaire dans les dates. Vous devez le changer un par connexion ; quelque chose comme:

SET time_zone = 'EAT';

Si cela ne fonctionne pas (pour utiliser des zones nommées, vous avez besoin de le serveur a été configuré pour le faire et ce n'est souvent pas le cas), vous pouvez simplement utiliser des décalages UTC:

SET time_zone = '+03:00';
5
Álvaro González

MySQL stocke DATETIME sans informations sur le fuseau horaire. Supposons que vous stockiez '2019-01-01 20:00:00' dans un champ DATETIME, lorsque vous récupérez cette valeur que vous êtes censé connaître à quel fuseau horaire il appartient.

Ainsi, dans votre cas, lorsque vous stockez une valeur dans un champ DATETIME, assurez-vous que c'est l'heure de la Tanzanie. Ensuite, lorsque vous le sortirez, ce sera l'heure de la Tanzanie. Yay!

Maintenant, la question délicate est la suivante: quand je fais une INSERT/UPDATE, comment puis-je m'assurer que la valeur correspond à l'heure de la Tanzanie? Deux cas:

  1. Vous faites INSERT INTO table (dateCreated) VALUES (CURRENT_TIMESTAMP or NOW()).

  2. Vous faites INSERT INTO table (dateCreated) VALUES (?) et spécifiez l'heure actuelle à partir du code de votre application.

CAS # 1

MySQL va prendre l'heure actuelle, disons qu'il s'agit de '2019-01-01 20:00:00' heure de Tanzanie. Ensuite, MySQL le convertira en UTC , ce qui correspond à '2019-01-01 17:00:00', et le stockera cette valeur dans le champ.

Alors, comment obtenez-vous l'heure de la Tanzanie, qui correspond à "20:00: 00", à stocker sur le terrain? Ce n'est pas possible. Votre code devra attendre l'heure UTC lors de la lecture de ce champ.

CAS N ° 2

Cela dépend du type de valeur que vous transmettez en tant que ?. Si vous passez la chaîne '2019-01-01 20:00:00', tant mieux, c'est exactement ce qui sera stocké dans la base de données. Si vous transmettez un objet Date, cela dépendra de la manière dont le pilote de base de données interprète cet objet Date , et de ce que "AAAA-MM -DD ​​HH: mm: la chaîne ss fournie à MySQL pour le stockage. La documentation du pilote de base de données devrait vous l'indiquer.

4
Hai Phan