Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

614
Vistas
¿Cómo convertir java.sql.Timestamp a java.time.OffsetDateTime?

Estoy trabajando en un proyecto de Scala y necesito asignar el tipo OffsetDateTime al tipo de Timestamp de tiempo de SQL. En DB me gustaría tener tiempos UTC.

La conversión de OffsetDateTime a Timestamp es sencilla (sugerencia de esta pregunta ) y funciona como se esperaba:

 import java.time._ import java.sql.Timestamp val ofsdatetime = OffsetDateTime.now() // ofsdatetime: java.time.OffsetDateTime = 2017-04-04T21:46:33.567+02:00 val tstamp = Timestamp.valueOf(ofsdatetime.atZoneSameInstant(ZoneOffset.UTC).toLocalDateTime()) // tstamp: java.sql.Timestamp = 2017-04-04 19:46:33.567

Como puede ver, se elimina la zona horaria y la marca de tiempo retrocede dos horas en el tiempo (UTC), ¡excelente!

Volver a convertir la marca de OffsetDateTime Timestamp funciona como se esperaba :

 OffsetDateTime.ofInstant(Instant.ofEpochMilli(tstamp.getTime), ZoneId.systemDefault()) // java.time.OffsetDateTime = 2017-04-04T19:46:33.567+02:00

La zona horaria se ha agregado al OffsetDateTime recién creado, pero la hora no es correcta (sigue siendo UTC, necesito que esté adaptada a la zona horaria real).

¿Por qué? ¿Qué estoy haciendo mal?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Aunque java.sql.Timestamp almacena la época en milisegundos, el método .toString usa la zona horaria predeterminada para representar la cadena. Además, .valueOf interpreta LocalDateTime utilizando su zona horaria predeterminada.

La combinación de ambas cosas hace que la primera conversión "parezca" correcta, pero en realidad es incorrecta. El valor "2017-04-04 19:46:33.567" se muestra en su TZ predeterminado, no en UTC.

Porque pasó el método valueOf a LocalDateTime (UTC), pero lo interpretó como LocalDateTime (Su TZ predeterminado).

Aquí hay una prueba de que la primera conversión es incorrecta:

 scala> val now = OffsetDateTime.now now: java.time.OffsetDateTime = 2017-04-04T14:50:12.534-06:00 scala> Timestamp.valueOf(now.atZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime).getTime == now.toInstant.toEpochMilli res54: Boolean = false

Ahora con el .atZoneSameInstant eliminado:

 scala> Timestamp.valueOf(now.toLocalDateTime).getTime == now.toInstant.toEpochMilli res53: Boolean = true

La respuesta aceptada a la pregunta de stackoverflow a la que se hace referencia es incorrecta.

Una vez que corrija la primera conversión (elimine .atZoneSameInstant ), entonces su segunda conversión debería funcionar bien.

over 4 years ago · Santiago Trujillo Denunciar

0

java.sql.Timestamp es un envoltorio delgado alrededor de un valor long que representa milisegundos desde la época ( 1970-01-01T00:00:00.000 UTC ), por lo que la zona horaria UTC está implícita en java.sql.Timestamp . No puede almacenar ninguna información de zona horaria, pero implícitamente está en UTC, y mientras todos lo sepan, todo funciona. No hay forma de almacenar información de zona horaria en java.sql.Timestamp . Si necesita recordar qué zona horaria recibió en sus datos de entrada, guárdelo como una columna separada en la base de datos. Puede guardar un momento correcto en el tiempo en java.sql.Timestamp , pero no la zona horaria recibida en los datos de entrada. Para eso necesitas un campo extra.

Como le gusta que las fechas de su base de datos estén en UTC, puede recuperar los datos de la base de datos de esta manera: OffsetDateTime.ofInstant(Instant.ofEpochMilli(tstamp.getTime), ZoneId.of("UTC")) . Este será el momento correcto, pero en la zona horaria UTC. No puede recuperar de la base de datos el hecho de que OffsetDateTime estaba en la zona horaria +0200 antes de guardarlo en la base de datos, porque java.sql.Timestamp no almacena un componente de zona horaria. Si necesita esa información, debe almacenarla en una columna separada en la base de datos.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda