zona horaria java
Antes de escribir una fecha de Java en una columna SQL TIMESTAMP, ¿JDBC traduce la fecha de la zona horaria de la JVM a la zona horaria de la sesión de la base de datos? (4)
Ahora mi requisito es que almacene el valor en GMT / UTC independientemente de la zona horaria de la JVM. ¿Hay alguna manera de configurar la zona horaria sobre la marcha y luego desarmarla una vez que haya terminado con JDBC?
Editar: Ok, encontré una forma de resolver ese problema. Hizo lo siguiente
TimeZone default = TimeZone.getDefault();
try
{
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
//Do stuff with JDBC
}
finally
{
TimeZone.setDefault(default);
}
Antes de escribir una Date Java en una columna SQL TIMESTAMP , ¿ JDBC traduce la fecha de la zona horaria de la máquina virtual de Java a la de la sesión de la base de datos?
Por ejemplo, supongamos que la zona horaria de la máquina virtual Java es UTC y la zona horaria de la sesión de la base de datos es UTC-5 . Si un programa Java intenta almacenar 2000-01-01 00:00:00
pasándolo a PreparedStatement#setTimestamp(int, Timestamp)
, de acuerdo con el estándar JDBC, la base de datos almacenará TIMESTAMP ''2000-01-01 00:00:00''
o TIMESTAMP ''1999-12-31 19:00:00''
?
La especificación es tonta. Java.util.Date almacena milisegundos de época en el marco de referencia GMT. Java.sql.Timestamp es una fecha más nanosegundos en el mismo marco de referencia. Todos los get y depreciadores no en desuso utilizan el marco de referencia GMT. Para cualquier tipo de cordura, la zona horaria predeterminada para almacenar una marca de tiempo debe ser GMT.
En una aplicación de varios niveles, el front-end, el controlador y el servidor de la base de datos podrían estar en distintas zonas horarias. Algunos de los niveles pueden estar en diferentes zonas horarias al mismo tiempo; por ejemplo, si está equilibrando la carga de Internet en un continente, o si tiene una aplicación móvil que se conecta a un servidor central. Un entorno operativo en la nube sería prácticamente el mismo escenario en el que no tienes idea de dónde se ejecutará el controlador JDBC, ni ninguna garantía que nunca cambie.
La única manera que conozco para lograr coherencia en estos entornos es usar solo el parámetro setter y ResultSet getter que aceptan un calendario, y asegurarme de que cada aplicación que accede a los datos usa algunos calendarios, preferiblemente GMT o UTC.
No, JDBC es solo una API sobre cómo el cliente puede acceder a la base de datos. Para el almacenamiento de marca de tiempo, esto tendrá que ser dependiente de la organización que escribe sus controladores de base de datos que cumplen con el estándar API de JDBC.
Here''s una implementación de la implementación de MySQL de PreparedStatement
. Parecen tomar la zona horaria JVM de Java a la zona horaria MySQL (verifique el método setTimestampInternal()
).
Puede usar el setTimestamp
setter sobrecargado aceptando la instancia de Calendar
para especificar la zona horaria
Muestra (si usa Joda datetime):
org.joda.time.DateTime sendDateUTC = new DateTime( DateTimeZone.UTC ).withMillis( millis );
statement.setTimestamp (1, sendDateUTC, sendDateUTC.toGregorianCalendar() );
Según javaDoc: establece el parámetro designado para el valor java.sql.Timestamp
dado, utilizando el objeto Calendar
dado. El controlador utiliza el objeto Calendar
para construir un valor SQL TIMESTAMP
, que luego el controlador envía a la base de datos. Con un objeto de Calendar
, el controlador puede calcular la marca de tiempo teniendo en cuenta una zona horaria personalizada. Si no se especifica ningún objeto de calendario, el controlador utiliza la zona horaria predeterminada, que es la de la máquina virtual que ejecuta la aplicación.
void setTimestamp(int parameterIndex, java.sql.Timestamp x, Calendar cal)
throws SQLException;