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 aulas de data e hora legadas
Você está usando terríveis classes de data e hora que foram suplantadas anos atrás pelo java.time Aulas.
Nunca use
Date
ou Timestamp
. UTC
Capture o momento atual, em UTC. A maioria dos bancos de dados armazena um momento em UTC. E geralmente você deve fazer a maior parte de sua lógica de negócios, depuração, log, armazenamento e troca de dados em UTC.
OffsetDateTime
Represente um momento com um deslocamento de UTC usando o
OffsetDateTime
apropriadamente chamado classe. Queremos o próprio UTC, ou um deslocamento de zero. Podemos usar uma constante para isso,
ZoneOffset.UTC
. OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;
JDBC 4.2
A partir do JDBC 4.2, podemos trocar diretamente java.time objetos com o banco de dados.
Para salvar este momento em uma coluna de um tipo de dados semelhante ao padrão SQL
TIMESTAMP WITH TIME ZONE
:myPreparedStatement.setObject( … , odt ) ;
Recuperação:
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime
Para apresentar esse momento recuperado ao usuário, convém ajustar o fuso horário esperado/desejado do usuário.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Nunca confie no fuso horário padrão
Observe no código acima que sempre especificamos o deslocamento ou zona desejado/esperado.
Se você não especificar, um deslocamento ou zona será aplicado de forma silenciosa e implícita. É melhor especificar suas intenções explicitamente, pois o padrão atual de sua JVM, banco de dados e sistema operacional host estão fora de suas mãos como programador. O que significa que o código que depende do padrão variará em comportamento em tempo de execução.
Java 6 e 7
O mesmo homem, Stephen Colebourne, que lidera o JSR 310 e o java.time implementação, bem como o famoso Joda-Time projeto, também lidera outro projeto, ThreeTen-Backport . A maior parte do java.time a funcionalidade é portada para Java 6 e 7 nesta biblioteca, com API quase idêntica.
Então faça todo o seu trabalho em classes de back-port. Então, no último momento, converta para/de
java.sql.Timestamp
através do DateTimeUtils
classe. Esses métodos de conversão usam principalmente
Instant
objetos. Um Instant
é um momento em UTC, sempre em UTC. Você pode ajustar a partir do seu OffsetDateTime
para UTC extraindo um Instant
. O Instant
class é a classe básica do bloco de construção em java.time , com OffsetDateDate
ter mais flexibilidade, como padrões de formatação alternativos ao gerar uma string. Mas ambos Instant
e OffsetDateTime
representam um momento, um ponto na linha do tempo. Instant instant = odt.toInstant() ;
java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;
Indo na outra direção, recuperando um
Timestamp
do seu banco de dados e, em seguida, convertendo imediatamente para um Instant
. java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;
Sobre java.time
O java.time framework é construído em Java 8 e posterior. Essas classes substituem o antigo e problemático legado classes de data e hora, como
java.util.Date
, Calendar
, &SimpleDateFormat
. O Joda-Time projeto, agora em modo de manutenção , aconselha a migração para o java.time Aulas.
Para saber mais, consulte o Tutorial do Oracle . E pesquise no Stack Overflow muitos exemplos e explicações. A especificação é JSR 310 .
Você pode trocar java.time objetos diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou mais tarde. Não há necessidade de strings, não há necessidade de
java.sql.*
Aulas. Onde obter as classes java.time?
- Java SE 8
, Java SE 9
, Java SE 10
, Java SE 11
, e posterior - parte da API Java padrão com uma implementação em pacote.
- O Java 9 adiciona alguns pequenos recursos e correções.
- Java SE 6
e Java SE 7
- A maior parte do java.time a funcionalidade é retroportada para Java 6 e 7 em ThreeTen-Backport .
- Android
- Versões posteriores de implementações do pacote Android do java.time aulas.
- Para Android anterior (<26), o ThreeTenABP projeto adapta ThreeTen-Backport (Mencionado acima). Consulte Como usar o ThreeTenABP… .
O ThreeTen-Extra projeto estende java.time com classes adicionais. Este projeto é um campo de provas para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como
Interval
, YearWeek
, YearQuarter
e mais
.