java.time
Com o lançamento do Java SE 8 em março de 2014, a API Date-Time legada desatualizada e propensa a erros (
java.util
Tipos de data e hora e seu tipo de formatação, SimpleDateFormat
etc.) foi suplantado por java.time
, a moderna API Date-Time. A tabela a seguir
descreve o mapeamento de tipos SQL ANSI com java.time
tipos:ANSI SQL | Java SE 8 |
---|---|
DATA | LocalData |
HORA | LocalTime |
TIMESTAMP | LocalDateTime |
HORA COM FUSO HORÁRIO | Hora de deslocamento |
TIMESTAMP COM FUSO HORÁRIO | OffsetDateTime |
Observe que
ZonedDateTime
e Instant
não são suportados por nenhum driver JDBC, enquanto alguns drivers, por exemplo, PostgreSQL também não suporta OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Além disso, observe que todos os OffsetDateTime
instâncias terão que estar em UTC (com deslocamento 0). Isso ocorre porque o back-end os armazena como UTC. Como usá-lo no JDBC?
Abaixo está um código de exemplo para inserir o atual
OffsetDateTime
em UTC, em columnfoo
(que é 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();
Um
Instant
representa um ponto instantâneo na linha do tempo e é independente de um fuso horário, ou seja, tem um deslocamento de fuso horário de +00:00
horas. Abaixo está um código de exemplo para recuperar um
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();
Caso você precise converter um
OffsetDateTime
em outro com um deslocamento diferente: Existem várias maneiras de fazer isso, mas eu uso principalmente
OffsetDateTime#withOffsetSameInstant
, para converter um OffsetDateTime
em outro com um deslocamento de fuso horário diferente, por exemplo 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);
}
}
Saída:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Alguns pontos relacionados ao código dado acima:
- O
Z
na saída está o designador de fuso horário para deslocamento de fuso horário zero. Significa Zulu e especifica oEtc/UTC
fuso horário (que tem o deslocamento de fuso horário de+00:00
horas). - O código converte
odt
em duas instâncias deOffsetDateTime
- cada um de uma forma diferente. A primeira instância é com um deslocamento de fuso horário fixo de+02:00
horas enquanto o segundo é com o deslocamento de fuso horário da JVM. Observe que o deslocamento do fuso horário de um local observando o DST muda de acordo com o horário de verão/inverno. Portanto, se um local observar o horário de verão, em vez de usar um deslocamento de fuso horário fixo, por exemplo,+02:00
horas; devemos obtê-lo da API. - O fuso horário da minha JVM é
Europe/London
e atualmente seu deslocamento é+01:00
horas.
Saiba mais sobre a API moderna de data e hora de Trilha:Data Hora .