Ya no tienes que buscar más por todo internet porque llegaste al lugar indicado, contamos con la solución que necesitas recibir y sin liarte.
Solución:
Clase java.sql.TimeStamp
se extiende desde java.util.Date
.
Puede asignar directamente un TimeStamp
oponerse a Date
referencia:
TimeStamp timeStamp = //whatever value you have;
Date startDate = timestampValue;
Deberías usar un calendario en su lugar:
Calendar start = Calendar.getInstance();
start.setTimeInMillis( timeStampValue.getTime() );
tl; dr
Instant instant = myResultSet.getObject( … , Instant.class ) ;
… o, si su controlador JDBC no es compatible con el opcional Instant
, se requiere para apoyar OffsetDateTime
:
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Evita ambos java.util.Date
Y java.sql.Timestamp
. Han sido reemplazados por las clases java.time. Específicamente, el Instant
clase que representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos (hasta nueve (9) dígitos de una fracción decimal).
Valores diferentes → Problema no verificado
Para abordar la parte principal de la pregunta: “¿Por qué diferentes fechas entre los objetos java.util.Date y java.sql.Timestamp cuando uno se deriva del otro?”
Debe haber un problema con su código. No publicó su código, por lo que no podemos identificar el problema.
Primero, eso string el valor que muestra para el valor de java.util.Date no proviene de su valor predeterminado toString
método, por lo que obviamente estaba haciendo operaciones adicionales.
En segundo lugar, cuando ejecuto un código similar, obtengo exactamente los mismos valores de fecha y hora.
Primero cree un objeto java.sql.Timestamp.
// Timestamp
long millis1 = new java.util.Date().getTime();
java.sql.Timestamp ts = new java.sql.Timestamp(millis1);
Ahora extraiga la cuenta de milisegundos desde la época para crear una instancia de un objeto java.util.Date.
// Date
long millis2 = ts.getTime();
java.util.Date date = new java.util.Date( millis2 );
Volcar valores a la consola.
System.out.println("millis1 = " + millis1 );
System.out.println("ts = " + ts );
System.out.println("millis2 = " + millis2 );
System.out.println("date = " + date );
Cuando se ejecuta.
millis1 = 1434666385642
ts = 2015-06-18 15:26:25.642
millis2 = 1434666385642
date = Thu Jun 18 15:26:25 PDT 2015
Entonces, el código que se muestra en la Pregunta es de hecho una forma válida de convertir de java.sql.Timestamp a java.util.Date, aunque perderá los datos en nanosegundos.
java.util.Date someDate = new Date( someJUTimestamp.getTime() );
Diferentes formatos de salida de cadena
Tenga en cuenta que la salida del toString
métodos es un formato diferente, como se documenta. El java.sql.Timestamp sigue el formato SQL, similar al formato ISO 8601 pero sin el T
en el medio.
Ignorar herencia
Como se discutió en los comentarios sobre otras Respuestas y la Pregunta, debe ignorar el hecho de que java.sql.Timestamp hereda de java.util.Date. El documento jsTimestamp establece claramente que debe no ver uno como un subtipo del otro: (énfasis mío)
Debido a las diferencias entre la clase Timestamp y la clase java.util.Date mencionada anteriormente, se recomienda que el código no ver los valores de marca de tiempo de forma genérica como una instancia de java.util.Date. La relación de herencia entre Timestamp y java.util.Date realmente denota herencia de implementación y no herencia de tipo.
Si ignora el consejo del equipo de Java y adopta tal punto de vista, un problema crítico es que perderás datos: cualquier microsegundo o nanosegundo de un segundo que pueda provenir de la base de datos se pierde, ya que una fecha solo tiene una resolución de milisegundos.
Básicamente, todas las clases de fecha y hora antiguas de Java temprano son un gran desastre: java.util.Date
, j.u.Calendar
, java.text.SimpleDateFormat
, java.sql.Timestamp
/.Date
/.Time
. Fueron uno de los primeros esfuerzos valientes en un marco de fecha y hora en la industria, pero finalmente fracasaron. Específicamente aquí, java.sql.Timestamp es un java.util.Date con nanosegundos añadidos; esto es un truco, no un buen diseño.
java.time
Evite las antiguas clases de fecha y hora incluidas con las primeras versiones de Java.
En su lugar, utilice el paquete java.time (Tutorial) integrado en Java 8 y versiones posteriores siempre que sea posible.
Conceptos básicos de java.time… Un Instant
es un momento en la línea de tiempo en UTC. Aplicar una zona horaria (ZoneId
) conseguir un ZonedDateTime
.
Código de ejemplo usando java.time a partir de Java 8. Con un controlador JDBC que admita JDBC 4.2 y posterior, puede intercambiar directamente clases java.time con su base de datos; sin necesidad de las clases heredadas.
Instant instant = myResultSet.getObject( … , Instant.class) ; // Instant is the raw underlying data, an instantaneous point on the time-line stored as a count of nanoseconds since epoch.
Es posible que desee adaptarse a una zona horaria que no sea UTC.
ZoneId z = ZoneId.of( "America/Montreal" ); // Always make time zone explicit rather than relying implicitly on the JVM’s current default time zone being applied.
ZonedDateTime zdt = instant.atZone( z ) ;
Realice su lógica empresarial. Aquí simplemente agregamos un día.
ZonedDateTime zdtNextDay = zdt.plusDays( 1 ); // Add a day to get "day after".
En la última etapa, si es absolutamente necesario, conviértalo a java.util.Date para la interoperabilidad.
java.util.Date dateNextDay = Date.from( zdtNextDay.toInstant( ) ); // WARNING: Losing data (the nanoseconds resolution).
Volcado a la consola.
System.out.println( "instant = " + instant );
System.out.println( "zdt = " + zdt );
System.out.println( "zdtNextDay = " + zdtNextDay );
System.out.println( "dateNextDay = " + dateNextDay );
Cuando se ejecuta.
instant = 2015-06-18T16:44:13.123456789Z
zdt = 2015-06-18T19:44:13.123456789-04:00[America/Montreal]
zdtNextDay = 2015-06-19T19:44:13.123456789-04:00[America/Montreal]
dateNextDay = Fri Jun 19 16:44:13 PDT 2015
Conversiones
Si debe utilizar los tipos heredados para interactuar con el código antiguo que aún no se ha actualizado para java.time, puede convertir. Utilice nuevos métodos agregados a las antiguas clases java.util.Date y java.sql. * Para la conversión.
Instant instant = myJavaSqlTimestamp.toInstant() ;
…y…
java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;
Consulte el capítulo Tutorial, Código de fecha y hora heredado, para obtener más información sobre las conversiones.
Segundo fraccionario
Tenga en cuenta la resolución de la fracción de segundo. Las conversiones de nanosegundos a milisegundos significan potencialmente perder algunos datos.
- Milisegundos
- java.util.Date
- Joda-Time (el marco que inspiró java.time)
- Nanosegundos
- java.sql.Timestamp
- java.time
Sobre java.time
los java.time framework está integrado en Java 8 y versiones posteriores. Estas clases suplantan las antiguas y problemáticas clases de fecha y hora heredadas, como java.util.Date
, Calendar
Y SimpleDateFormat
.
los Joda-Time proyecto, 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.
Puedes intercambiar java.time objetos directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. Sin necesidad de cuerdas, sin necesidad de java.sql.*
clases.
¿Dónde obtener las clases java.time?
- Java SE 8, Java SE 9, Java SE 10, y después
- Incorporado.
- Parte de la API estándar de Java 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 está retroportada a Java 6 y 7 en ThreeTen-Backport.
- Androide
- Versiones posteriores de implementaciones de paquetes de Android de las clases java.time.
- Para Android anterior (<26), el ThreeTenABP el proyecto se adapta ThreeTen-Backport (mencionado anteriormente). Ver Cómo usar ThreeTenABP….
los ThreeTen-Extra el proyecto 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 más.
Eres capaz de corroborar nuestra tarea añadiendo un comentario y dejando una puntuación te damos las gracias.