java.tiempo
Con el lanzamiento de Java SE 8 en marzo de 2014, la API de fecha y hora heredada, obsoleta y propensa a errores (java.util
Tipos de fecha y hora y su tipo de formato, SimpleDateFormat
etc.) fue suplantado por java.time
, la moderna API de fecha y hora. La siguiente tabla
representa el mapeo de tipos ANSI SQL con java.time
tipos:
ANSI SQL | Java SE 8 |
---|---|
FECHA | Fecha local |
TIEMPO | HoraLocal |
MARCA DE TIEMPO | FechaHoraLocal |
TIEMPO CON TIMEZONE | Tiempo de compensación |
SELLO DE TIEMPO CON ZONA HORARIA | DesplazamientoFechaHora |
Tenga en cuenta que ZonedDateTime
y Instant
no son compatibles con ningún controlador JDBC, mientras que algunos controladores, p. PostgreSQL tampoco es compatible con OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Además, tenga en cuenta que todas las OffsetDateTime
las instancias tendrán que estar en UTC (tener desplazamiento 0). Esto se debe a que el backend los almacena como UTC.
¿Cómo usarlo en JDBC?
A continuación se muestra un código de muestra para insertar el OffsetDateTime
actual en UTC, en columnfoo
(que es de TIMESTAMP WITH TIMEZONE
tipo):
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
Un Instant
representa un punto instantáneo en la línea de tiempo y es independiente de una zona horaria, es decir, tiene un desplazamiento de zona horaria de +00:00
horas.
A continuación se muestra un código de muestra para recuperar un OffsetDateTime
de columnfoo
:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
// Assuming the column index of columnfoo is 1
OffsetDateTime odt = rs.getObject(1, OffsetDateTime.class));
System.out.println(odt);
}
rs.close();
st.close();
En caso de que necesite convertir un OffsetDateTime
en otro con un desplazamiento diferente:
Hay varias formas de hacerlo, pero yo uso principalmente OffsetDateTime#withOffsetSameInstant
, para convertir un OffsetDateTime
en otro con un desplazamiento de zona horaria diferente, por ejemplo,
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
// A sample OffsetDateTime in UTC.
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
System.out.println(odt);
OffsetDateTime offsetTimeAtOffset0100 = odt.withOffsetSameInstant(ZoneOffset.of("+02:00"));
System.out.println(offsetTimeAtOffset0100);
// Time at JVM's default timezone offset
ZoneOffset jvmTzOffset = ZonedDateTime.now(ZoneId.systemDefault()).getOffset();
OffsetDateTime offsetTimeAtJvmTzOffset = odt.withOffsetSameInstant(jvmTzOffset);
System.out.println(offsetTimeAtJvmTzOffset);
}
}
Salida:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Algunos puntos relacionados con el código anterior:
- El
Z
en la salida está el designador de zona horaria para el desplazamiento de zona horaria cero. Significa Zulu y especifica elEtc/UTC
zona horaria (que tiene el desplazamiento de zona horaria de+00:00
horas). - El código convierte
odt
en dos instancias deOffsetDateTime
- cada uno de una manera diferente. La primera instancia es con una diferencia de zona horaria fija de+02:00
horas mientras que el segundo es con el desplazamiento de zona horaria de la JVM. Tenga en cuenta que el desplazamiento de la zona horaria de un lugar observando DST cambia según el horario de verano/invierno. Por lo tanto, si un lugar observa el horario de verano, en lugar de usar una diferencia de zona horaria fija, p.+02:00
horas; deberíamos obtenerlo de la API. - La zona horaria de mi JVM es
Europe/London
y actualmente su desplazamiento es+01:00
horas.
Obtenga más información sobre la API moderna de fecha y hora de Sendero:fecha y hora .