nueva - manejo de horas en java
UnsupportedOperationException: ¿por qué no puedes llamar a Instante() en un java.sql.Date? (4)
La clase java.util.Date
tiene un método llamado toInstant()
que convierte la instancia de Date
a java.time.Instant
.
La clase java.sql.Date
extiende la clase java.util.Date
, pero cuando intento llamar a toInstant()
en un java.sql.Date
, recibo una UnsupportedOperationException
.
¿Por qué toInstant()
una operación no soportada en java.sql.Date
?
¿Y cuál es la forma "correcta" de convertir un java.sql.Date
a un java.time.Instant
?
Compruebe el JavaDoc
Como sql.Date
no tiene un componente de tiempo, no hay posibilidad de convertirlo a time.Instant
Este método siempre arroja una excepción UnsupportedOperationException y no se debe utilizar porque los valores de Fecha SQL no tienen un componente de tiempo.
La asignación correcta entre java.sql.Date
y java.time
es LocalDate
:
LocalDate date = sqlDate.toLocalDate();
Si realmente debes hacerlo , puedes obtener un Instant
, aunque la información adicional (tiempo) será arbitraria. Por ejemplo:
Instant i = date.atStartOfDay(ZoneOffset.UTC).toInstant();
Las respuestas proporcionadas hasta ahora se concentran en el detalle de que java.sql.Date
no tiene información de tiempo. Eso es correcto pero no es la razón real o suficiente por la que este tipo no puede ofrecer una conversión directa a Instant
. Desafortunadamente, la documentación de Java-8 comete el mismo error al dejar que los usuarios piensen que el problema se debe a que falta información de tiempo.
Conceptualmente, el tipo java.sql.Date
representa un tipo local. Modela una fecha del calendario que puede ser diferente en cualquier región de nuestro mundo. Pero un Instant
es el mismo en nuestro globo alrededor. Por lo tanto, los usuarios necesitan una zona horaria o un desplazamiento de zona horaria para realizar la conversión.
Trágicamente, el tipo java.sql.Date
hereda de java.util.Date
que es un tipo global (parecido a un instantáneo). Sin embargo, esta herencia realmente denota la herencia de implementación y no la herencia de tipo. Una razón más para considerar que el diseño de estas antiguas clases de JDBC se ha roto. Por lo tanto, es posible utilizar el truco para envolver java.sql.Date
través de su método getTime()
dentro de una instancia de java.util.Date
que finalmente permite la conversión directa a un instante. Pero: esta conversión utiliza implícitamente la zona horaria predeterminada del sistema.
Entonces, ¿cómo convertir correctamente de una manera pedante? Consideremos nuevamente la documentación de Java-8 que aquí apunta en la dirección correcta:
java.sql.Date sqlDate = ...;
LocalDate calendarDate = sqlDate.toLocalDate();
ZonedDateTime zdt = calendarDate.atStartOfDay(ZoneId.of("Europe/Paris"));
Instant instant = zdt.toInstant();
java.sql.Date solo tiene componentes de fecha (fecha, mes y año). NO tiene componentes de fecha y hora. toInstant requiere ambos componentes de Fecha / Hora, por lo que la instancia Instante en java.sql.Date arroja la excepción UnsupportedOperationException.
java.util.Date O java.sql.Timestamp tiene ambos componentes Fecha / Hora así que toInstant () funciona!
Puedes hacer así:
// Time is 00:00:00.000
new java.util.Date(sqlDate.getTime()).toInstant()
Actualizado:
Instant.ofEpochMilli(sqlDate.getTime());
// OR
new java.util.Date(sqlDate.getTime()).toInstant();
Devolverá el mismo resultado porque toInstant () llama a Instant.ofEpochMilli (getTime ()) internamente.
public Instant toInstant() {
return Instant.ofEpochMilli(getTime());
}