Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

O fuso horário java.sql.Timestamp é específico?


Embora não seja explicitamente especificado para setTimestamp(int parameterIndex, Timestamp x) os drivers devem seguir as regras estabelecidas pelo setTimestamp(int parameterIndex, Timestamp x, Calendar cal) javadoc:

Define o parâmetro designado para o java.sql.Timestamp fornecido valor, usando o Calendar fornecido objeto. O driver usa o Calendar objeto para construir um SQL TIMESTAMP valor, que o driver então envia para o banco de dados. Com um Calendar objeto, o driver pode calcular o timestamp levando em consideração um fuso horário personalizado. Se não houver Calendar for especificado, o driver usará o fuso horário padrão, que é o da máquina virtual que executa o aplicativo.

Quando você chama com setTimestamp(int parameterIndex, Timestamp x) o driver JDBC usa o fuso horário da máquina virtual para calcular a data e hora do carimbo de data/hora nesse fuso horário. Essa data e hora é o que é armazenado no banco de dados e, se a coluna do banco de dados não armazenar informações de fuso horário, qualquer informação sobre o fuso horário será perdida (o que significa que cabe aos aplicativos que usam o banco de dados usar o mesmo fuso horário de forma consistente ou crie outro esquema para discernir o fuso horário (ou seja, armazene em uma coluna separada).

Por exemplo:Seu fuso horário local é GMT+2. Você armazena "2012-12-25 10:00:00 UTC". O valor real armazenado no banco de dados é "2012-12-25 12:00:00". Você o recupera novamente:você o recupera novamente como "2012-12-25 10:00:00 UTC" (mas somente se você recuperá-lo usando getTimestamp(..) ), mas quando outro aplicativo acessar o banco de dados no fuso horário GMT+0, ele recuperará o carimbo de data/hora como "2012-12-25 12:00:00 UTC".

Se você quiser armazená-lo em um fuso horário diferente, precisará usar o setTimestamp(int parameterIndex, Timestamp x, Calendar cal) com uma instância do Calendar no fuso horário necessário. Apenas certifique-se de usar o getter equivalente com o mesmo fuso horário ao recuperar valores (se você usar um TIMESTAMP sem informações de fuso horário em seu banco de dados).

Então, supondo que você queira armazenar o fuso horário GMT real, você precisa usar:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
stmt.setTimestamp(11, tsSchedStartTime, cal);

Com JDBC 4.2, um driver compatível deve suportar java.time.LocalDateTime (e java.time.LocalTime ) para TIMESTAMP (e TIME ) por meio de get/set/updateObject . O java.time.Local* classes não têm fusos horários, portanto, nenhuma conversão precisa ser aplicada (embora isso possa abrir um novo conjunto de problemas se seu código assumir um fuso horário específico).