Convierta java.time.LocalDate en tipo java.util.Date

372

Quiero convertir java.time.LocalDateen java.util.Datetipo. Porque quiero establecer la fecha en JDateChooser. ¿O hay algún selector de fecha que admita java.timefechas?

Kavinda Gehan
fuente
1
¿Has leído stackoverflow.com/questions/21242110/… ?
Daksh Shah
2
LGoodDatePicker utiliza de forma nativa el paquete java.time (también conocido como Java 8 time o JSR-310 . Específicamente, LGoodDatePicker utiliza un "java.time.LocalDate" para almacenar los valores de fecha. Las capturas de pantalla y una demostración están en la página de inicio del proyecto .
BlakeTNC
Se pueden encontrar más respuestas en: LocalDate a java.util.Date y viceversa, ¿la conversión más simple?
Basil Bourque

Respuestas:

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

Eso supone que su selector de fecha utiliza la zona horaria predeterminada del sistema para transformar las fechas en cadenas.

JB Nizet
fuente
JB Nizet quizás Java 8 estaba en una etapa temprana de desarrollo / lanzamiento y @ user3509494 lo estaba probando de alguna manera.
russellhoff
2
¿Es posible evitarlo atStartOfDay(), ya que cambia el valor de la fecha, según tengo entendido?
yegor256
1
@JBNizet tu respuesta no tiene mucho sentido para mí, por eso decidí aclarar. ¿Por qué no lo aclaras en lugar de hacer comentarios inútiles?
yegor256
12
Porque no veo cómo y por qué necesitaría alguna aclaración. 232 personas votaron a favor de esta respuesta, por lo que la encontraron clara. Usted dice que atStartOfDay cambia el valor de la fecha. Eso no tiene sentido. atStartOfDay hace lo que el javadoc dice que hace: transforma un LocalDate en un LocalDateTime, en la misma fecha y al comienzo del día.
JB Nizet
2
@cornz ¿Estás seguro de que tus resultados son incorrectos? Si está en Alemania, entonces podría tener algo que ver con el problema técnico de 6 minutos y 32 segundos en Alemania, en abril de 1893. Consulte timeanddate.com/time/zone/germany/berlin?syear=1850 para obtener más detalles. .
Dawood ibn Kareem el
104

Aquí hay una clase de utilidad que uso para convertir las java.timeclases más nuevas en java.util.Dateobjetos y viceversa:

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 en base al comentario de @Oliv.

Brice Roncace
fuente
No es ZoneId.systemDefault()problemático porque las zonas horarias cambian a lo largo del año. Entonces, si el 01-enero estoy en la zona horaria -05: 00 (central), pero luego el 01-julio estoy en la zona horaria -06: 00 (luz del día central), ¿eso no causará resultados inexactos debido al horario de verano? ¿hora?
jhilden
95

Puedes usar el java.sql.Date.valueOf()método como:

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

No es necesario agregar información de hora y zona horaria aquí porque se toman implícitamente.
Ver LocalDate a java.util.Date y viceversa, ¿la conversión más simple?

Jorge
fuente
Esto fue perfecto para mí, ya que lo que necesitaba era pasar LocalDate a SQL. Sin embargo, si su formateador de fecha va a hacer algo sobre el cambio de zona horaria antes de formatear la fecha, es posible que llegue un día demasiado temprano dependiendo de la zona horaria local, en cuyo caso deseará una de las opciones anteriores.
Tom Dibble
77
java.sql.Dateestá destinado a la capa de base de datos, JDBC, JPA. La capa web (o cualquier aplicación cliente) debe estar absolutamente libre de cualquier dependencia de java.sql.*.
Diminuto
2
@Tiny java.sql.Date reside en rt.jar. No hay dependencias externas. Solo usas funciones de lenguaje.
George
2
java.sql.Datees solo java.util.Datecon su tiempo establecido, 00:00:00pero el punto en la perspectiva del diseño es que java.sql.*no está destinado a una capa frontal con la que los clientes interactúan como Servlets / JSP. java.util.Dateen el lado de Java y / java.sql.Timestampo lo que sea aplicable desde el java.sql.*lado de JDBC .
Diminuto
55
Este es un "truco horrible" de acuerdo con el java.time. * Autor: stackoverflow.com/questions/33066904/… . En Java 9 las java.sql.*clases serán una dependencia separada.
Dherik
16

java.time tiene la interfaz Temporal que puede usar para crear objetos instantáneos de la mayoría de las clases de tiempo. Instant representa milisegundos en la línea de tiempo en la Época, la referencia base para todas las demás fechas y horas.

Necesitamos convertir la fecha en un ZonedDateTime, con una hora y una zona, para hacer la conversión:

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

Para crear un java.util.Date a partir de un java.time.LocalDate , debe

  • agregar una hora a LocalDate
  • interpretar la fecha y la hora dentro de una zona horaria
  • obtener el número de segundos / milisegundos desde la época
  • crear un java.util.Date

El código podría tener el siguiente aspecto:

LocalDate localDate = LocalDate.now();
Date date = new Date(localDate.atStartOfDay(ZoneId.of("America/New_York")).toEpochSecond() * 1000);
nosid
fuente
1
Typo in zone id (ZoneIf)
assylias
localDate.atStartOfDay () crea un ZonedDateTime, pero no hay un método toEpochSecond () para ZonedDateTime.
Kevin Sadler
@KevinSadler: el método toEpochSecondse hereda de java.time.chrono.ChronoZonedDateTime. Ver docs.oracle.com/javase/8/docs/api/java/time/chrono/…
nosid
@nosid Gracias por tu corrección. Cuando uso la finalización de código en Eclipse, (y toInstance) no está presente como una opción. Pero si lo escribo completo parece ser aceptado. Había concluido erróneamente que no era un método debido a este hecho y que no lo vi en el Javadoc para ZonedDateTime, ya que está listado como un método heredado, como usted dice. Lo sentimos, por favor acepte un upclick :)
Kevin Sadler
11

Esto funciona para mi:

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
fuente
66
esto es bastante ineficiente
AndresQ
1
La conversión a Instant puede ser detallada, pero construir y analizar un String es como ir de Nueva York a la Ciudad de México a través de Tokio ...
ehecatl
1
Sí, no tan eficiente, pero la mayoría de las soluciones son muy detalladas. Esto es simplemente detallado y es más fácil de leer y comprender.
ceklock
2
@ehecatl Cuidado ... en el futuro NY -> Tokio -> Ciudad de México se puede hacer en una hora (s);)
Stephan
3

Solución Kotlin:

1) Pegue esta función de extensión en alguna parte.

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

2) Úselo y nunca vuelva a googlear esto.

val myDate = myLocalDate.toDate()
gyoder
fuente
11
¿Cómo es simple "cambiar a Kotlin"? Esta es una pregunta de Java.
ehecatl
2
La conversión de Java LocalDate a Date es un problema común y molesto para cualquier desarrollador de JVM. Esta es una solución para los desarrolladores de Kotlin.
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
fuente
2
Por favor explique su solución.
Martin Zabel
-2

Simple

public Date convertFrom(LocalDate date) {
    return java.sql.Timestamp.valueOf(date.atStartOfDay());
}
Artur Luiz Oliveira
fuente
-3
java.util.Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
Mahendra Sri
fuente
¿en qué se diferencia su respuesta de la aceptada después de 4 años? Copiar y pegar para lograr aumentar la reputación?
aguijón