sql >> Base de Datos >  >> RDS >> Mysql

Recuperación del campo UTC DATETIME de MySQL en Java cuando la zona horaria del servidor no es UTC

Tu cliente getDate() el código parece correcto hasta donde llega. Creo que también necesita obtener el controlador MySQL Connector/J JDBC para tratar las fechas almacenadas en la tabla como fechas UTC, para evitar una conversión de zona horaria falsa. Esto significa configurar la zona horaria efectiva del servidor, además de la zona horaria de la sesión del cliente y el Calendario utilizado para JDBC getTimestamp llamadas como lo estás haciendo.

Eche un vistazo a los valores que obtuvo en su afirmación fallida y en qué dirección está el error:

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

Lo que obtuviste fue a las 10:30 BST, que son las 9:30 GMT. Esto es consistente con la base de datos que trata las 10:30 en la tabla como un valor BST y lo convierte falsamente a GMT para usted, antes de que lo analice como una fecha GMT. Esa es la dirección opuesta a la conversión falsa de un valor GMT a BST.

Este puede ser un problema específico de JDBC, porque JDBC requiere que las horas se conviertan a la zona local. (Donde la API MySQL C no lo hace, probablemente porque los tipos de tiempo clásicos de C no son conscientes de la zona como lo son los de Java). Y necesita saber de qué zona se está convirtiendo desde , también. MySQL TIMESTAMP type siempre se almacena como UTC. Pero eso no se indica para el DATETIME escribe. yo creo eso implica que MySQL va a interpretar DATETIME valores de columna como si estuvieran en la zona horaria del servidor. Que mencionó que está configurado en BST, y eso es consistente con la dirección del cambio que se muestra en su mensaje de error de afirmación.

La time_zone La variable de sesión que configura le dice al servidor MySQL cuál es la zona horaria de su máquina cliente, pero no afecta lo que el servidor cree que es su propia zona horaria. Eso se puede anular con serverTimezone Propiedad de conexión JDBC . En su conexión, configure el serverTimezone a UTC y asegúrese de useLegacyDatetimeCode esta apagado. (Y revise las otras propiedades relacionadas con la zona si eso no funciona). Vea si eso hace que sus fechas aparezcan como UTC con los mismos valores de campo de calendario que en la base de datos.

Tenga en cuenta que esto va a cambiar la interpretación de otros DATETIME valores en su base de datos:ahora todos se verán como fechas UTC (en el contexto de su conexión JDBC). Si eso es correcto dependerá de cómo se poblaron inicialmente. Si bien su código de cliente tendrá el comportamiento que desea, no sé si se puede hacer que este sistema en su conjunto se comporte de manera totalmente consistente sin configurar la zona horaria del servidor en UTC en el nivel del servidor. Básicamente, si no tiene su zona configurada en UTC, no está completamente configurado para el comportamiento que desea y lo está esquivando.