java - from - set date to localdate
LocalDate a java.util.Date y viceversa ¿la conversión más simple? (7)
Esta pregunta ya tiene una respuesta aquí:
- Convierta java.time.LocalDate en java.util.Date tipo 11 respuestas
¿Hay una manera simple de convertir un
LocalDate
(introducido con Java 8) en un objeto
java.util.Date
?
Por ''simple'', quiero decir más simple que esto:
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
lo cual me parece un poco incómodo.
Como solo estamos interesados en la parte de la fecha y no hay información de zona horaria en ninguno de los objetos, ¿por qué introducir zonas horarias explícitamente? La hora de medianoche y la zona horaria predeterminada del sistema deben tomarse implícitamente para la conversión.
tl; dr
¿Hay una manera simple de convertir un LocalDate (introducido con Java 8) en un objeto java.util.Date? Por "simple", quiero decir más simple que esto
No Lo hiciste correctamente y de la manera más concisa posible.
java.util.Date.from( // Convert from modern java.time class to troublesome old legacy class. DO NOT DO THIS unless you must, to inter operate with old code not yet updated for java.time.
myLocalDate.atStartOfDay( // Let java.time determine the first moment of the day on that date in that zone. Never assume the day starts at 00:00:00.
ZoneId.of( "America/Montreal" ) // Specify time zone using proper name in `continent/region` format, never 3-4 letter pseudo-zones such as “PST”, “CST”, “IST”.
) // Produce a `ZonedDateTime` object.
.toInstant() // Extract an `Instant` object, a moment always in UTC.
)
Lea a continuación los problemas y luego piense en ello. ¿Cómo podría ser más simple? Si me preguntas a qué hora comienza una cita, ¿de qué otra manera podría responderte pero preguntarte "¿Dónde?" Un nuevo día amanece más temprano en París FR que en Montreal CA, y aún más temprano en Kolkata IN, e incluso antes en Auckland NZ, todos los momentos diferentes.
Entonces, al convertir una fecha solo (
LocalDate
) en una fecha y hora,
debemos
aplicar una zona horaria (
ZoneId
) para obtener un valor zonal (
ZonedDateTime
) y luego pasar a UTC (
Instant
) para que coincida con la definición de un
java.util.Date
.
Detalles
En primer lugar, evite las antiguas clases de fecha y hora heredadas como
java.util.Date
siempre que sea posible.
Están mal diseñados, son confusos y problemáticos.
Fueron suplantados por las clases java.time por una razón, en realidad, por
muchas
razones.
Pero si debe hacerlo, puede convertir a / desde los tipos java.time a los antiguos. Busque nuevos métodos de conversión agregados a las clases antiguas.
java.util.Date
→
java.time.LocalDate
Tenga en cuenta que un
java.util.Date
es un nombre inapropiado ya que representa una fecha
más
una hora del día, en UTC.
Por el contrario, la clase
LocalDate
representa un valor de solo fecha sin hora del día y sin zona horaria.
Pasar de
java.util.Date
a java.time significa convertir a la clase equivalente de
java.time.Instant
.
La clase
Instant
representa un momento en la línea de tiempo en
UTC
con una resolución de
nanoseconds
(hasta nueve (9) dígitos de una fracción decimal).
Instant instant = myUtilDate.toInstant();
La clase
LocalDate
representa un valor de solo fecha sin hora del día y sin zona horaria.
Una zona horaria es crucial para determinar una fecha. Para cualquier momento, la fecha varía en todo el mundo por zona. Por ejemplo, unos minutos después de la medianoche en París, Francia es un nuevo día mientras todavía "ayer" en Montreal Québec .
Entonces necesitamos mover ese
Instant
a una zona horaria.
Aplicamos
ZoneId
para obtener un
ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
A partir de ahí, solicite una fecha solo, una fecha
LocalDate
.
LocalDate ld = zdt.toLocalDate();
java.time.LocalDate
→
java.util.Date
Para mover la otra dirección, de
java.time.LocalDate
a
java.util.Date
significa que vamos de una fecha solamente a una fecha y hora.
Entonces debemos especificar una hora del día.
Probablemente quieras ir para el primer momento del día.
No asuma que es
00:00:00
.
Anomalías como el horario de verano (DST) significa que el primer momento puede ser otro momento como
01:00:00
.
Deje que java.time determine ese valor llamando a
atStartOfDay
en
LocalDate
.
ZonedDateTime zdt = myLocalDate.atStartOfDay( z );
Ahora extrae un
Instant
.
Instant instant = zdt.toInstant();
Convierta ese
Instant
a
java.util.Date
llamando
from( Instant )
.
java.util.Date d = java.util.Date.from( instant );
Más información
- Tutorial de Oracle
- Pregunta similar, Convertir java.util.Date a qué tipo "java.time"?
Sobre java.time
El marco
java.time
está integrado en Java 8 y
java.time
posteriores.
Estas clases suplantan a las antiguas y problemáticas clases de fecha y hora
legacy
, como
java.util.Date
,
Calendar
y
SimpleDateFormat
.
El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Para obtener más información, consulte el Tutorial de Oracle . Y busque para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar objetos
java.time
directamente con su base de datos.
Utilice un
controlador JDBC
compatible con
JDBC 4.2
o posterior.
No necesita cadenas, no necesita clases
java.sql.*
.
¿Dónde obtener las clases java.time?
-
Java SE 8
,
Java SE 9
y posterior
- Incorporado.
- Parte de la API Java estándar con una implementación integrada.
- Java 9 agrega algunas características menores y correcciones.
-
Java SE 6
y
Java SE 7
- Gran parte de la funcionalidad java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
-
Android
- Versiones posteriores de las implementaciones de paquetes de Android de las clases java.time.
- Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Vea Cómo usar ThreeTenABP ...
El proyecto
ThreeTen-Extra
extiende java.time con clases adicionales.
Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time.
Puede encontrar algunas clases útiles aquí, como
Interval
,
YearWeek
,
YearQuarter
y
more
.
En realidad lo hay.
Hay un método estático
valueOf
en el objeto
java.sql.Date
que hace exactamente eso.
Entonces tenemos
java.util.Date date = java.sql.Date.valueOf(localDate);
y eso es. No hay configuración explícita de zonas horarias porque la zona horaria local se toma implícitamente.
De documentos:
El LocalDate proporcionado se interpreta como la fecha local en la zona horaria local.
Las subclases
java.sql.Date
java.util.Date
por lo que el resultado es también
java.util.Date
.
Y para la operación inversa hay un método toLocalDate en la clase java.sql.Date. Entonces tenemos:
LocalDate ld = new java.sql.Date(date.getTime()).toLocalDate();
Fecha -> LocalDate:
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate -> Fecha:
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
Puede convertir el objeto
java.util.Date
en un objeto
String
, que formateará la fecha como aaaa-mm-dd.
LocalDate tiene un método de
parse
que lo convertirá en un objeto
LocalDate
.
La cadena debe representar una fecha válida y se analiza mediante DateTimeFormatter.ISO_LOCAL_DATE.
Fecha a LocalDate
LocalDate.parse(Date.toString())
Resolví esta pregunta con la solución a continuación
import org.joda.time.LocalDate;
Date myDate = new Date();
LocalDate localDate = LocalDate.fromDateFields(myDate);
System.out.println("My date using Date" Nov 18 11:23:33 BRST 2016);
System.out.println("My date using joda.time LocalTime" 2016-11-18);
En este caso, localDate imprime su fecha en este formato "aaaa-MM-dd"
Convertir LocalDateTime a java.util.Date
LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.systemDefault());
Instant instant = zonedDateTime.toInstant();
Date date = Date.from(instant);
System.out.println("Result Date is : "+date);
Fecha a LocalDate
Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Fecha local hasta la fecha
LocalDate localDate = LocalDate.now();
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());