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

Récupération du champ UTC DATETIME de MySQL en Java lorsque le fuseau horaire du serveur n'est pas UTC

Votre client getDate() le code semble correct dans la mesure où il va. Je pense que vous devez également obtenir le pilote MySQL Connector/J JDBC pour traiter les dates stockées dans la table comme dates UTC, pour éviter une fausse conversion de fuseau horaire. Cela signifie définir le fuseau horaire effectif du serveur, en plus du fuseau horaire de la session client et du calendrier utilisé pour JDBC getTimestamp appels pendant que vous le faites.

Examinez les valeurs que vous avez obtenues dans votre assertion ayant échoué et dans quelle direction se trouve l'erreur :

expected:<Thu Apr 16 11:30:30 BST 2015> but was:<Thu Apr 16 10:30:30 BST 2015>

Ce que vous avez récupéré était à 10h30 BST, soit 9h30 GMT. Ceci est cohérent avec le fait que la base de données traite cette heure 10h30 dans la table comme une valeur BST et la convertit faussement en GMT pour vous, avant de l'analyser comme une date GMT. C'est le sens inverse d'une valeur GMT faussement convertie en BST.

Il peut s'agir d'un problème spécifique à JDBC, car JDBC exige que les heures soient converties dans la zone locale. (Là où l'API MySQL C ne le fait pas, probablement parce que les types de temps classiques de C ne sont pas sensibles à la zone comme ceux de Java.) Et il doit savoir de quelle zone il convertit à partir , aussi bien. Le MySQL TIMESTAMP type est toujours stocké au format UTC. Mais ce n'est pas indiqué pour le DATETIME taper. Je pense cela implique que MySQL va interpréter DATETIME les valeurs des colonnes comme étant dans le fuseau horaire du serveur. Ce que vous avez mentionné comme étant défini sur BST, et cela correspond à la direction du décalage indiquée dans votre message d'erreur d'assertion.

Le time_zone La variable de session que vous définissez indique au serveur MySQL quel est le fuseau horaire de votre machine cliente, mais cela n'affecte pas ce que le serveur pense être son propre fuseau horaire. Cela peut être remplacé par le serverTimezone Propriété de connexion JDBC . Sur votre connexion, définissez le serverTimezone à UTC, et assurez-vous que useLegacyDatetimeCode est éteint. (Et examinez les autres propriétés liées à la zone si cela ne fonctionne pas.) Voyez si cela fait passer vos dates en UTC avec les mêmes valeurs de champ de calendrier que dans la base de données.

Soyez conscient que cela va changer l'interprétation des autres DATETIME valeurs dans votre base de données :elles vont toutes ressembler à des dates UTC maintenant (dans le contexte de votre connexion JDBC). Que ce soit correct dépendra de la façon dont ils ont été peuplés initialement. Bien que votre code client ait le comportement souhaité, je ne sais pas si ce système dans son ensemble peut être amené à se comporter de manière totalement cohérente sans définir le fuseau horaire du serveur sur UTC au niveau du serveur. Fondamentalement, si sa zone n'est pas définie sur UTC, elle n'est pas entièrement configurée pour le comportement que vous souhaitez, et vous la contournez.