UnsupportedOperationException-pourquoi ne pouvez-vous pas appeler toInstant() sur java.SQL.Date?
La classe java.util.Date
a une méthode appelée toInstant()
qui convertit l'instance Date
en java.time.Instant
.
Le java.sql.Date
classe étend la java.util.Date
classe, mais quand je tente d'appeler toInstant()
sur java.sql.Date
, j'ai un message d' UnsupportedOperationException
.
Pourquoi toInstant()
est-il une opération non prise en charge sur java.sql.Date
?
Et quelle est la "bonne" façon de convertir un java.sql.Date
pour un java.time.Instant
?
4 réponses
Vérifiez le JavaDoc
Puisque sql.Date
n'a pas de Composant temps, il n'y a aucune possibilité de le convertir en time.Instant
Cette méthode lance toujours une exception UnsupportedOperationException et devrait ne pas être utilisé car les valeurs de date SQL n'ont pas de Composant time.
La bonne correspondance entre les java.sql.Date
et java.time
est LocalDate
:
LocalDate date = sqlDate.toLocalDate();
Si vous devez vraiment, vous pouvez alors déduire un Instant
, bien que les informations supplémentaires (temps) est arbitraire. Par exemple:
Instant i = date.atStartOfDay(ZoneOffset.UTC).toInstant();
Java.SQL.Date n'a que des composants de Date (date, mois et année). Il n'a pas les deux composants Date et heure. toInstant nécessite les deux composants Date / Heure, donc toInstant sur java.SQL.L'instance de Date lance une exception UnsupportedOperationException.
Java.util.Date ou java.SQL.Timestamp a les deux composants Date / Heure donc toInstant () fonctionne!
, Vous pouvez faire comme ceci:
// Time is 00:00:00.000
new java.util.Date(sqlDate.getTime()).toInstant()
Mise à Jour:
Instant.ofEpochMilli(sqlDate.getTime());
// OR
new java.util.Date(sqlDate.getTime()).toInstant();
Renverra le même résultat car toInstant () appelle Instantané.ofEpochMilli (getTime ()) en interne.
public Instant toInstant() {
return Instant.ofEpochMilli(getTime());
}
Les réponses données jusqu'à présent se concentrent sur le détail que java.sql.Date
n'a pas d'information temporelle. C'est correct mais pas la raison réelle ou suffisante pour laquelle ce type ne peut pas offrir une conversion directe en Instant
. Malheureusement, la documentation de Java-8 fait la même erreur pour laisser les utilisateurs penser que le problème est juste à cause des informations temporelles manquantes.
Conceptuellement, le type java.sql.Date
représente un type local. Il modélise une date de calendrier qui peut être différente dans n'importe quel région de notre globe. Mais un Instant
est le même sur notre globe autour. les utilisateurs ont donc besoin d'un fuseau horaire ou d'un décalage de fuseau horaire pour effectuer la conversion.
Tragiquement, le type java.sql.Date
hérite de {[6] } qui est un type global (instantané). Cependant, cet héritage dénote vraiment l'héritage d'implémentation, et non l'héritage de type. Une raison de plus de considérer que la conception de ces anciennes classes JDBC est brisée. Par conséquent, il est en effet possible d'utiliser le hack pour envelopper le java.sql.Date
via son méthode getTime()
à l'intérieur d'une instance de java.util.Date
qui permet finalement la conversion directe en un instant. Mais: Cette conversion utilise implicitement le fuseau horaire par défaut du système.
Alors, comment convertir correctement de manière pédante? Considérons à nouveau la documentation de Java-8 qui pointe ici dans la bonne direction:
java.sql.Date sqlDate = ...;
LocalDate calendarDate = sqlDate.toLocalDate();
ZonedDateTime zdt = calendarDate.atStartOfDay(ZoneId.of("Europe/Paris"));
Instant instant = zdt.toInstant();