tl;dr
myPreparedStatement
.setObject(
… , // Specify which placeholder `?` in your SQL statement.
OffsetDateTime.now( ZoneOffset.UTC ) // Capture the current moment as seen in the wall-clock time of UTC (an offset-from-UTC of zero).
) ;
Evite las clases de fecha y hora heredadas
Está utilizando terribles clases de fecha y hora que fueron suplantadas hace años por java.time clases
Nunca use Date
o Timestamp
.
UTC
Captura el momento actual, en UTC. La mayoría de las bases de datos almacenan un momento en UTC. Y, en general, debe realizar la mayor parte de su lógica comercial, depuración, registro, almacenamiento e intercambio de datos en UTC.
OffsetDateTime
Representar un momento con un desplazamiento desde UTC usando el bien llamado OffsetDateTime
clase.
Queremos UTC en sí, o una compensación de cero. Podemos usar una constante para eso, ZoneOffset.UTC
.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;
JDBC 4.2
A partir de JDBC 4.2 podemos intercambiar directamente java.time objetos con la base de datos.
Para guardar este momento en una columna de un tipo de datos similar al estándar SQL TIMESTAMP WITH TIME ZONE
:
myPreparedStatement.setObject( … , odt ) ;
Recuperación:
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime
Para presentar este momento recuperado al usuario, es posible que desee ajustarse a la zona horaria esperada/deseada del usuario.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Nunca confíes en la zona horaria predeterminada
Observe en el código anterior que siempre especificamos la zona o el desplazamiento deseado/esperado.
Si no lo especifica, se aplica implícitamente un desfase o una zona. Es mejor especificar sus intenciones explícitamente ya que el valor predeterminado actual de su JVM, base de datos y sistema operativo host están fuera de sus manos como programador. Lo que significa que el código que se basa en el valor predeterminado variará en comportamiento en tiempo de ejecución.
Java 6 y 7
El mismo hombre, Stephen Colebourne, que dirige JSR 310 y java.time implementación, así como el famoso Joda-Time proyecto, también lidera otro proyecto, ThreeTen-Backport . La mayor parte del java.time la funcionalidad está adaptada a Java 6 y 7 en esta biblioteca, con una API casi idéntica.
Así que haga todo su trabajo en clases de back-port. Luego, en el último momento, convierta a/desde java.sql.Timestamp
a través de DateTimeUtils
clase.
Esos métodos de conversión utilizan principalmente Instant
objetos. Un Instant
es un momento en UTC, siempre en UTC. Puede ajustar desde su OffsetDateTime
a UTC extrayendo un Instant
. El Instant
class es la clase de bloque de construcción básica en java.time , con OffsetDateDate
tener más flexibilidad, como patrones de formato alternativos al generar una cadena. Pero tanto Instant
y OffsetDateTime
representan un momento, un punto en la línea de tiempo.
Instant instant = odt.toInstant() ;
java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;
Yendo en la otra dirección, recuperando una Timestamp
desde su base de datos, luego se convierte inmediatamente a un Instant
.
java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;
Acerca de java.time
El java.time
framework está integrado en Java 8 y versiones posteriores. Estas clases reemplazan al viejo y problemático legacy
clases de fecha y hora como java.util.Date
, Calendar
, &SimpleDateFormat
.
El Joda-Time proyecto, ahora en modo de mantenimiento , recomienda la migración a java.time clases.
Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar java.time objetos directamente con su base de datos. Use un controlador JDBC
compatible con JDBC 4.2
o después. Sin necesidad de cadenas, sin necesidad de java.sql.*
clases.
¿Dónde obtener las clases java.time?
- Java SE 8
, Java SE 9
, Java SE 10
, Java SE 11
, y posteriores:parte de la API de Java estándar con una implementación integrada.
- Java 9 agrega algunas funciones y correcciones menores.
- Java SE 6
y Java SE 7
- La mayor parte del java.time la funcionalidad está adaptada a Java 6 y 7 en ThreeTen-Backport .
- Android
- Versiones posteriores de implementaciones de paquetes de Android de java.time clases.
- Para Android anterior (<26), ThreeTenABP proyecto adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo usar ThreeTenABP… .
El ThreeTen-Extra
proyecto extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval
, YearWeek
, YearQuarter
y más
.