Convierta LocalDate a LocalDateTime o java.sql.Timestamp

Estoy usando JodaTime 1.6.2.

Tengo un LocalDate que necesito convertir a LocalDateTime (Joda) o a java.sqlTimestamp para el mapeo.

La razón de esto es que he descubierto cómo convertir entre LocalDateTime y java.sql.Timestamp :

 LocalDateTime ldt = new LocalDateTime(); DateTimeFormatter dtf = DateTimeFormatter.forPattern("yyyy-MM-dd HH:mm:ss"); Timestamp ts = Timestamp.valueOf(ldt.toString(dtf)); 

Entonces, si puedo convertir entre LocalDate y LocalDateTime , puedo hacer la conversión continua a java.sql.Timestamp . Gracias por todos los empujones en la dirección correcta!

JodaTime

Para convertir org.joda.time.LocalDate de org.joda.time.LocalDate a java.sql.Timestamp , simplemente haz

 Timestamp timestamp = new Timestamp(localDate.toDateTimeAtStartOfDay().getMillis()); 

Para convertir org.joda.time.LocalDateTime de org.joda.time.LocalDateTime en java.sql.Timestamp , solo haga

 Timestamp timestamp = new Timestamp(localDateTime.toDateTime().getMillis()); 

JavaTime

Para convertir java.time.LocalDate de java.time.LocalDate a java.sql.Timestamp , solo hazlo

 Timestamp timestamp = Timestamp.valueOf(localDate.atStartOfDay()); 

Para convertir java.time.LocalDateTime de java.time.LocalDateTime en java.sql.Timestamp , solo haz

 Timestamp timestamp = Timestamp.valueOf(localDateTime); 

La mejor manera de usar Java 8 time API:

  LocalDateTime ldt = timeStamp.toLocalDateTime(); Timestamp ts = Timestamp.valueOf(dateTime); 

Para usar con JPA, ingrese con su modelo ( https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa ):

 @Converter(autoApply = true) public class LocalDateTimeConverter implements AttributeConverter { @Override public Timestamp convertToDatabaseColumn(LocalDateTime ldt) { return Timestamp.valueOf(ldt); } @Override public LocalDateTime convertToEntityAttribute(Timestamp ts) { return ts.toLocalDateTime(); } } 

Entonces ahora es el tiempo independiente relativo de la zona horaria. Además, es fácil de hacer:

  LocalDate ld = ldt.toLocalDate(); LocalTime lt = ldt.toLocalTime(); 

Formateo:

  DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") String str = ldt.format(DATE_TME_FORMATTER); ldt = LocalDateTime.parse(str, DATE_TME_FORMATTER); 

ACTUALIZACIÓN: postgres 9.4.1208, HSQLDB 2.4.0 etc entienden Java 8 Time API sin conversaciones!

tl; dr

El proyecto Joda-Time está en modo de mantenimiento, ahora suplantado por las clases java.time .

  • Solo usa java.time.Instant class.
  • No es necesario para:
    • LocalDateTime
    • java.sql.Timestamp
    • Instrumentos de cuerda

Capture el momento actual en UTC.

 Instant.now() 

Para almacenar ese momento en la base de datos:

 myPreparedStatement.setObject( … , Instant.now() ) // Writes an `Instant` to database. 

Para recuperar ese momento de datbase:

 myResultSet.getObject( … , Instant.class ) // Instantiates a `Instant` 

Para ajustar el tiempo del reloj de pared al de una zona horaria particular.

 instant.atZone( z ) // Instantiates a `ZonedDateTime` 

LocalDateTime es la clase incorrecta

Otras respuestas son correctas, pero no señalan que LocalDateTime es la clase incorrecta para su propósito.

Tanto en java.time como en Joda-Time , un LocalDateTime deliberadamente carece de cualquier concepto de zona horaria o desplazamiento desde UTC. Como tal, no representa un momento, y no es un punto en la línea de tiempo. Un LocalDateTime representa una idea aproximada sobre los momentos potenciales a lo largo de un rango de aproximadamente 26-27 horas.

Use un LocalDateTime para cuando se desconoce la zona / desplazamiento (no es una buena situación), o cuando el desplazamiento de zona es indeterminado. Por ejemplo, “Navidad comienza en el primer momento del 25 de diciembre de 2018” se representaría como LocalDateTime .

Use un ZonedDateTime para representar un momento en un huso horario en particular. Por ejemplo, las navidades que comiencen en cualquier zona particular como Pacific/Auckland o America/Montreal se representarán con un objeto ZonedDateTime .

Por un momento siempre en UTC, usa Instant .

 Instant instant = Instant.now() ; // Capture the current moment in UTC. 

Aplicar una zona horaria Mismo momento, mismo punto en la línea de tiempo, pero visto con un tiempo de reloj de pared diferente.

 ZoneId z = ZoneId.of( "Africa/Tunis" ) ; ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time. 

Entonces, si solo puedo convertir LocalDate y LocalDateTime,

No, estrategia equivocada Si tiene un valor de solo fecha y desea un valor de fecha y hora, debe especificar una hora del día. Esa hora del día puede no ser válida en esa fecha para una zona en particular, en cuyo caso la clase ZonedDateTime ajusta automáticamente la hora del día según sea necesario.

 LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ; LocalTime lt = LocalTime.of( 14 , 0 ) ; // 14:00 = 2 PM. ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ; 

Si desea que el primer momento del día sea su hora del día, deje que java.time determine ese momento. No suponga que el día comienza a las 00:00:00. Las anomalías como el horario de verano (DST) significan que el día puede comenzar en otro momento, como 01:00:00.

 ZonedDateTime zdt = ld.atStartOfDay( z ) ; 

java.sql.Timestamp es la clase incorrecta

java.sql.Timestamp es parte de las problemáticas antiguas clases de fecha y hora que ahora son heredadas, suplantadas por completo por las clases de java.time . Esa clase se usó para representar un momento en UTC con una resolución de nanosegundos . Ese propósito ahora se sirve con java.time.Instant .

JDBC 4.2 con getObject / setObject

A partir de JDBC 4.2 y posterior, su controlador JDBC puede intercambiar directamente objetos java.time con la base de datos al llamar:

  • PreparedStatement::setObject
  • ResultSet::getObject

Por ejemplo:

 myPreparedStatement.setObject( … , instant ) ; 

… y …

 Instant instant = myResultSet.getObject( … , Instant.class ) ; 

Convertir legado ⬌ moderno

Si debe interactuar con un código antiguo que aún no se ha actualizado a java.time , conviértalo de un lado a otro con los nuevos métodos agregados a las clases anteriores.

 Instant instant = myJavaSqlTimestamp.toInstant() ; // Going from legacy class to modern class. 

…y…

 java.sql.Timestamp myJavaSqlTimestamp = java.sql.Timestamp.from( instant ) ; // Going from modern class to legacy class. 

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases heredadas de fecha y hora 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 Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

Puede intercambiar objetos java.time directamente con su base de datos. Use un controlador JDBC que cumpla con JDBC 4.2 o posterior. Sin necesidad de cadenas, sin necesidad de clases java.sql.* .

¿Dónde obtener las clases de 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 y correcciones menores.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • Versiones posteriores de las implementaciones del paquete de Android de las clases java.time.
    • Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo utilizar ThreeTenABP ….

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y más .

Dependiendo de su zona horaria, puede perder unos minutos (1650-01-01 00:00:00 se convierte en 1649-12-31 23:52:58)

Use el siguiente código para evitar eso

 new Timestamp(localDateTime.getYear() - 1900, localDateTime.getMonthOfYear() - 1, localDateTime.getDayOfMonth(), localDateTime.getHourOfDay(), localDateTime.getMinuteOfHour(), localDateTime.getSecondOfMinute(), fractional); 

Debido a que Joda se está desvaneciendo, alguien podría querer convertir LocaltDate a LocalDateTime en Java 8. En Java 8 LocalDateTime le dará una forma de crear una instancia de LocalDateTime usando LocalDate y LocalTime . Mira aquí.

público LocalDateTime estático de (fecha LocalDate, hora LocalTime)

La muestra sería,

  // just to create a sample LocalDate DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDate ld = LocalDate.parse("20180306", dtf); // convert ld into a LocalDateTime // We need to specify the LocalTime component here as well, it can be any accepted value LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00 

Solo como referencia, para obtener los segundos de época a continuación, se puede usar,

  ZoneId zoneId = ZoneId.systemDefault(); long epoch = ldt.atZone(zoneId).toEpochSecond(); // If you only care about UTC long epochUTC = ldt.toEpochSecond(ZoneOffset.UTC);