Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

612
Views
¿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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!