Converta java.time.LocalDate no tipo java.util.Date

372

Eu quero converter java.time.LocalDateem java.util.Datetipo. Porque eu quero definir a data JDateChooser. Ou existe algum seletor de data que suporte java.timedatas?

Kavinda Gehan
fonte
11
Você leu stackoverflow.com/questions/21242110/… ?
Daksh Shah
2
O LGoodDatePicker usa nativamente o pacote java.time (também conhecido como Java 8 time ou JSR-310 . Especificamente, o LGoodDatePicker usa um "java.time.LocalDate" para armazenar os valores da data. Capturas de tela e uma demonstração estão na Página inicial do projeto .
BlakeTNC
Mais respostas podem ser encontradas em: LocalDate para java.util.Date e vice-versa da conversão mais simples?
Basil Bourque

Respostas:

560
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

Isso pressupõe que o seletor de datas use o fuso horário padrão do sistema para transformar datas em strings.

JB Nizet
fonte
JB Nizet talvez o Java 8 estivesse em um estágio inicial de desenvolvimento / lançamento e o @ user3509494 estivesse testando de alguma forma.
russellhoff
2
É possível evitar atStartOfDay(), pois altera o valor da data, como eu a entendo.
yegor256
11
@JBNizet, sua resposta não faz muito sentido para mim, por isso decidi esclarecer. Por que você não esclarece isso em vez de fazer comentários inúteis?
yegor256
12
Porque não vejo como e por que precisaria de algum esclarecimento. 232 pessoas votaram positivamente nesta resposta, encontrando-a assim clara. Você diz que atStartOfDay altera o valor da data. Isso não faz sentido. atStartOfDay faz o que o javadoc diz que faz: transforma um LocalDate em LocalDateTime, na mesma data e no início do dia.
JB Nizet 18/10
2
@cornz Tem certeza de que seus resultados estão incorretos? Se você estiver na Alemanha, pode haver algo a ver com a falha de 6 minutos e 32 segundos do tempo na Alemanha, em abril de 1893. Consulte timeanddate.com/time/zone/germany/berlin?syear=1850 para obter mais detalhes .
Dawood ibn Kareem
104

Aqui está uma classe de utilitário que eu uso para converter as java.timeclasses mais recentes em java.util.Dateobjetos e vice-versa:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class DateUtils {

  public static Date asDate(LocalDate localDate) {
    return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
  }

  public static Date asDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }

  public static LocalDate asLocalDate(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
  }

  public static LocalDateTime asLocalDateTime(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
  }
}

Editado com base no comentário do @Oliv.

Brice Roncace
fonte
Não está usando ZoneId.systemDefault()problemas porque os fusos horários mudam ao longo do ano. Portanto, se em 01 de janeiro estou no fuso horário -05: 00 (central), mas em 01-julho estou no fuso -06: 00 (horário de verão central) não causará resultados imprecisos devido ao horário de verão Tempo?
precisa saber é o seguinte
95

Você pode usar o java.sql.Date.valueOf()método como:

Date date = java.sql.Date.valueOf(localDate);

Não há necessidade de adicionar informações de hora e fuso horário aqui, pois elas são obtidas implicitamente.
Consulte LocalDate para java.util.Date e vice-versa da conversão mais simples?

George
fonte
Isso foi perfeito para mim, pois o que eu precisava era passar o LocalDate para o SQL. No entanto, se o seu formatador de data fizer algo sobre a mudança de fuso horário antes de formatar a data, você poderá receber um dia muito cedo, dependendo do fuso horário local; nesse caso, você desejará uma das opções acima.
quer
7
java.sql.Datedestina-se à camada de banco de dados, JDBC, JPA. A camada da web (ou qualquer aplicativo cliente) deve estar absolutamente livre de qualquer dependência java.sql.*.
minúsculo
2
@Tiny java.sql.Date reside em rt.jar. Não há dependências externas. Você acabou de usar os recursos de idioma.
George
2
java.sql.Dateé apenas java.util.Datecom o tempo definido, 00:00:00mas o ponto na perspectiva do design é que java.sql.*não se destina a uma camada frontal com a qual os clientes interagem, como Servlets / JSP. java.util.Dateno lado Java e java.sql.Timestampou o que for aplicável java.sql.*no lado JDBC .
minúscula
5
Este é um "hack horrível" de acordo com o java.time. * Autor: stackoverflow.com/questions/33066904/… . No Java 9, as java.sql.*classes serão uma dependência separada.
Dherik
16

java.time possui a interface Temporal, que você pode usar para criar objetos Instantâneos na maioria das classes de tempo. Instantâneo representa milissegundos na linha do tempo na época - a referência básica para todas as outras datas e horas.

Precisamos converter a data em um ZonedDateTime, com uma hora e um fuso, para fazer a conversão:

LocalDate ldate = ...;
Instant instant = Instant.from(ldate.atStartOfDay(ZoneId.of("GMT")));
Date date = Date.from(instant);
Kevin Sadler
fonte
12

Para criar um java.util.Date a partir de um java.time.LocalDate , você deve

  • adicione um horário ao LocalDate
  • interpretar a data e hora dentro de um fuso horário
  • obter o número de segundos / milissegundos desde a época
  • crie um java.util.Date

O código pode ter a seguinte aparência:

LocalDate localDate = LocalDate.now();
Date date = new Date(localDate.atStartOfDay(ZoneId.of("America/New_York")).toEpochSecond() * 1000);
nosid
fonte
11
Erro de digitação no id da zona (ZoneIf)
assylias
localDate.atStartOfDay () cria um ZonedDateTime, mas não há método toEpochSecond () para ZonedDateTime.
Kevin Sadler
@ KevinSadler: O método toEpochSecondé herdado de java.time.chrono.ChronoZonedDateTime. Veja docs.oracle.com/javase/8/docs/api/java/time/chrono/…
nosid
@nosid Obrigado por sua correção. Quando uso o preenchimento de código no Eclipse, ele (e toInstance) não está presente como opção. Mas se eu digitar na íntegra, parece ser aceito. Eu concluí erroneamente que não era um método por causa desse fato e que não o vi no Javadoc para ZonedDateTime, pois está listado como um método herdado, como você diz. Desculpe, por favor aceite um upclick :)
Kevin Sadler
11

Isso funciona para mim:

java.util.Date d = new SimpleDateFormat("yyyy-MM-dd").parse(localDate.toString());

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#toString--

ceklock
fonte
6
isso é bastante ineficiente
AndresQ
11
Convertendo para instantâneo pode ser detalhado, mas construir e analisar um String é como ir de Nova York para Cidade do México via Tóquio ...
ehecatl
11
Sim, não é tão eficiente, mas a maioria das soluções é muito detalhada. Isso é detalhado e é mais fácil de ler e entender.
precisa saber é
2
@ehecatl Cuidado ... no futuro NY -> Tóquio -> Cidade do México pode ser feita dentro de uma (s) hora (s);)
Stephan
3

Solução Kotlin:

1) Cole esta função de extensão em algum lugar.

fun LocalDate.toDate(): Date = Date.from(this.atStartOfDay(ZoneId.systemDefault()).toInstant())

2) Use-o e nunca faça o google novamente.

val myDate = myLocalDate.toDate()
Gyoder
fonte
11
Como é simples "mudar para Kotlin"? Esta é uma pergunta do Java.
ehecatl
11
A conversão do Java LocalDate para Date é um problema comum e irritante para qualquer desenvolvedor de JVM. Esta é uma solução para desenvolvedores do Kotlin.
perfil completo de gyoder
-1
public static Date convertToTimeZone(Date date, String tzFrom, String tzTo) {
    return Date.from(LocalDateTime.ofInstant(date.toInstant(), ZoneId.of(tzTo)).atZone(ZoneId.of(tzFrom)).toInstant());
} 
William Nguyen
fonte
2
Por favor, explique sua solução.
Martin Zabel
-2

Simples

public Date convertFrom(LocalDate date) {
    return java.sql.Timestamp.valueOf(date.atStartOfDay());
}
Artur Luiz Oliveira
fonte
-3
java.util.Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
Mahendra Sri
fonte
como sua resposta é diferente da resposta aceita após quatro anos? Copiar e colar para obter aumento de reputação?
Stinger #