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

JPA TemporalType.Date dando una fecha incorrecta

Lo siento mucho, pero todas las respuestas hasta ahora son generalmente incorrectas. La respuesta es bastante simple pero requiere que separemos cinco puntos:

  1. DATE =java.sql.Date, que es un contenedor alrededor de java.util.Date que es la cantidad de milisegundos desde la época en la zona horaria UTC. Esto tiene el año/mes/fecha/horas/minutos/segundos en una zona horaria fija GMT+0 (UTC). Sin embargo, tenga en cuenta que java.sql.Date establece los componentes de tiempo en cero.
  2. TIMESTAMP =java.sql.TimeStamp, que es un contenedor de componentes alrededor de la fecha que agrega fracciones de segundo para admitir el estándar de tipo SQL DATE. Esta clase/tipo no es relevante o necesario para esta pregunta pero, en resumen, tiene la fecha más la hora.
  3. La base de datos almacena objetos DATE como se define (usando UTC como el desplazamiento de Java) pero puede traduce la hora si está configurada en la base de datos para estar en una zona horaria diferente. De forma predeterminada, la mayoría de las bases de datos utilizan la zona horaria del servidor local, lo cual es una muy mala idea. Señoras, señores... Almacenar SIEMPRE los objetos DATE en UTC. Sigue leyendo...
  4. La hora en la JVM y la zona horaria deben ser correctas. Dado que el objeto Date está utilizando UTC, ¿se calcula un desplazamiento para la hora de su servidor? Considere eso con la fuerte recomendación de que la hora del servidor se establezca en GMT+0 (UTC).
  5. Finalmente, cuando queremos mostrar la FECHA desde la base de datos (usando JSF o lo que sea), debería estar configurado para ser la zona horaria GMT + 0 y, si se hace desde el servidor también ... sus fechas y horas SIEMPRE serán consistentes, referenciales y todas las cosas buenas. Todo lo que queda es representar la hora y ESTO es donde el agente de usuario (para una aplicación web, por ejemplo) podría utilizarse para traducir la hora GMT+0 a la zona horaria "local" de los usuarios.

Resumen:Use UTC (GMT+0) en el servidor, en la base de datos, en sus objetos Java.

DATE y TIMESTAMP solo son diferentes desde la perspectiva de la base de datos en que TIMESTAMP lleva fracciones de segundos adicionales. Ambos usan GMT+0 (implícito). JodaTime es un marco de calendario preferido para manejar todo esto, pero no solucionará los problemas de JVM no coincidentes con la configuración de la zona horaria de la base de datos.

Si los diseños de aplicaciones de JVM a DB no usan GMT, debido al horario de verano, los ajustes de reloj y todo tipo de otros juegos regionales que se juegan en los relojes locales del mundo... los tiempos de las transacciones y todo lo demás estarán sesgados para siempre. , no referencial, inconsistente, etc.

Otra buena respuesta relacionada con los tipos de datos:java.util .Fecha frente a java.sql.Fecha

También tenga en cuenta que Java 8 tiene actualizaciones con un mejor manejo de fecha/hora (finalmente), pero esto no soluciona el hecho de que el reloj del servidor en el que se ejecuta la JVM esté en una zona horaria y la base de datos esté en otra. En este punto siempre está ocurriendo la traducción. En todos los clientes grandes (inteligentes) con los que trabajo, las zonas horarias de la base de datos y del servidor JVM están configuradas en UTC por este mismo motivo, incluso si sus operaciones ocurren en gran medida en alguna otra zona horaria.