Resposta curta:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
Explicação: (com base nesta pergunta sobre LocalDate
)
Apesar do nome, java.util.Date
representa um instante na linha do tempo, não uma "data". Os dados reais armazenados no objeto são umlong
contagem de milissegundos desde 01-01-2009 - 00: 00Z (meia-noite no início de 1970 GMT / UTC).
A classe equivalente java.util.Date
na JSR-310 é Instant
, portanto, existem métodos convenientes para fornecer a conversão de um lado para outro:
Date input = new Date();
Instant instant = input.toInstant();
Date output = Date.from(instant);
Uma java.util.Date
instância não tem conceito de fuso horário. Isso pode parecer estranho se você chamar toString()
um java.util.Date
, porque toString
é relativo a um fuso horário. No entanto, esse método realmente usa o fuso horário padrão de Java rapidamente para fornecer a string. O fuso horário não faz parte do estado real de java.util.Date
.
Um Instant
também não contém nenhuma informação sobre o fuso horário. Portanto, para converter de uma Instant
data para hora local, é necessário especificar um fuso horário. Esse pode ser o fuso horário padrão - ZoneId.systemDefault()
- ou pode ser um fuso horário que seu aplicativo controla, como um fuso horário nas preferências do usuário. LocalDateTime
possui um método conveniente de fábrica que utiliza o instante e o fuso horário:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Ao contrário, o LocalDateTime
fuso horário é especificado chamando o atZone(ZoneId)
método O ZonedDateTime
pode então ser convertido diretamente em um Instant
:
LocalDateTime ldt = ...
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date output = Date.from(zdt.toInstant());
Observe que a conversão de LocalDateTime
para ZonedDateTime
tem o potencial de introduzir um comportamento inesperado. Isso ocorre porque nem todas as datas locais existem devido ao horário de verão. No outono / outono, há uma sobreposição na linha do tempo local, onde a mesma data e hora local ocorre duas vezes. Na primavera, há uma lacuna, onde uma hora desaparece. Veja o Javadoc deatZone(ZoneId)
para obter mais a definição do que a conversão fará.
Resumo, se você ida e volta uma java.util.Date
a uma LocalDateTime
e de volta a um java.util.Date
você pode acabar com um instante diferente devido ao horário de verão.
Informações adicionais: Há outra diferença que afetará datas muito antigas. java.util.Date
usa um calendário que muda em 15 de outubro de 1582, com datas anteriores a usar o calendário juliano em vez do calendário gregoriano. Por outro lado, java.time.*
usa o sistema de calendário ISO (equivalente ao gregoriano) para todos os tempos. Na maioria dos casos de uso, o sistema de calendário ISO é o que você deseja, mas você pode observar efeitos estranhos ao comparar datas anteriores ao ano de 1582.