tl; dr
java.util.Date.from( // Transfer the moment in UTC, truncating any microseconds or nanoseconds to milliseconds.
Instant.now() ; // Capture current moment in UTC, with resolution as fine as nanoseconds.
)
Embora não houvesse nenhum ponto naquele código acima. Ambos java.util.Date
e Instant
representam um momento na UTC, sempre na UTC. O código acima tem o mesmo efeito que:
new java.util.Date() // Capture current moment in UTC.
Nenhum benefício aqui para usar ZonedDateTime
. Se você já tiver um ZonedDateTime
, ajuste para UTC extraindo um Instant
.
java.util.Date.from( // Truncates any micros/nanos.
myZonedDateTime.toInstant() // Adjust to UTC. Same moment, same point on the timeline, different wall-clock time.
)
Outra resposta correta
A resposta de ssoltanid aborda corretamente sua questão específica, como converter um objeto java.time ( ZonedDateTime
) da nova escola em um objeto da velha escola java.util.Date
. Extraia o Instant
de ZonedDateTime e passe para java.util.Date.from()
.
Perda de dados
Observe que você sofrerá perda de dados , pois Instant
rastreia nanossegundos desde a época, enquanto java.util.Date
rastreia milissegundos desde a época.
Sua pergunta e comentários levantam outras questões.
Manter servidores em UTC
Seus servidores devem ter seu sistema operacional host definido para UTC como uma prática recomendada em geral. A JVM escolhe essa configuração do sistema operacional host como seu fuso horário padrão, nas implementações Java que conheço.
Especifique o fuso horário
Mas você nunca deve confiar no fuso horário padrão atual da JVM. Em vez de escolher a configuração do host, um sinalizador passado ao iniciar uma JVM pode definir outro fuso horário. Pior ainda: qualquer código em qualquer thread de qualquer aplicativo a qualquer momento pode fazer uma chamada para java.util.TimeZone::setDefault
para alterar esse padrão em tempo de execução!
Timestamp
Tipo Cassandra
Qualquer banco de dados e driver decente deve lidar automaticamente com o ajuste de uma data e hora passada para UTC para armazenamento. Eu não uso o Cassandra, mas parece ter algum suporte rudimentar para data e hora. A documentação diz que seu Timestamp
tipo é uma contagem de milissegundos da mesma época (primeiro momento de 1970 em UTC).
ISO 8601
Além disso, o Cassandra aceita entradas de string nos formatos padrão ISO 8601 . Felizmente, java.time usa formatos ISO 8601 como padrão para analisar / gerar strings. A implementação da Instant
classe toString
servirá perfeitamente.
Precisão: Milissegundo vs Nanosegordo
Mas primeiro precisamos reduzir a precisão de nanossegundos de ZonedDateTime para milissegundos. Uma maneira é criar um novo Instant usando milissegundos. Felizmente, java.time tem alguns métodos úteis para conversão de e para milissegundos.
Código de exemplo
Aqui está um exemplo de código no Java 8 Update 60.
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
…
Instant instant = zdt.toInstant();
Instant instantTruncatedToMilliseconds = Instant.ofEpochMilli( instant.toEpochMilli() );
String fodderForCassandra = instantTruncatedToMilliseconds.toString(); // Example: 2015-08-18T06:36:40.321Z
Ou de acordo com este documento de driver Cassandra Java , você pode passar uma java.util.Date
instância (não deve ser confundida com java.sqlDate
). Portanto, você pode fazer um juDate com isso instantTruncatedToMilliseconds
no código acima.
java.util.Date dateForCassandra = java.util.Date.from( instantTruncatedToMilliseconds );
Se fizer isso com freqüência, você pode fazer um one-liner.
java.util.Date dateForCassandra = java.util.Date.from( zdt.toInstant() );
Mas seria mais legal criar um pequeno método utilitário.
static public java.util.Date toJavaUtilDateFromZonedDateTime ( ZonedDateTime zdt ) {
Instant instant = zdt.toInstant();
// Data-loss, going from nanosecond resolution to milliseconds.
java.util.Date utilDate = java.util.Date.from( instant ) ;
return utilDate;
}
Observe a diferença em todo esse código em relação à pergunta. O código da pergunta estava tentando ajustar o fuso horário da instância ZonedDateTime para UTC. Mas isso não é necessário. Conceitualmente:
ZonedDateTime = Instant + ZoneId
Nós apenas extraímos a parte Instant, que já está em UTC (basicamente em UTC, leia a documentação da classe para detalhes precisos).
Sobre java.time
A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como java.util.Date
, Calendar
, e SimpleDateFormat
.
O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .
Para saber mais, consulte o tutorial Oracle . E pesquise no Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de cordas, não há necessidade de java.sql.*
classes.
Onde obter as classes java.time?
O projeto ThreeTen-Extra 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 .
java.util.Date
ejava.sql.Date
.