Java 8 dispose d'une toute nouvelle API pour la date et l'heure. L'une des classes les plus utiles de cette API consiste LocalDateTime
à conserver une valeur de date-heure indépendante du fuseau horaire.
Il existe probablement des millions de lignes de code utilisant la classe héritée java.util.Date
à cet effet. En tant que tel, lors de l'interfaçage de l'ancien et du nouveau code, il sera nécessaire de convertir entre les deux. Comme il ne semble pas y avoir de méthode directe pour y parvenir, comment le faire?
Réponses:
Réponse courte:
Explication: (basé sur cette question concernant
LocalDate
)Malgré son nom,
java.util.Date
représente un instant sur la ligne du temps, pas une "date". Les données réelles stockées dans l'objet sont unlong
décompte des millisecondes depuis le 1970-01-01T00: 00Z (minuit au début de 1970 GMT / UTC).La classe équivalente à
java.util.Date
JSR-310 estInstant
, il existe donc des méthodes pratiques pour effectuer la conversion de va-et-vient:Une
java.util.Date
instance n'a pas de concept de fuseau horaire. Cela peut sembler étrange si vous appeleztoString()
unjava.util.Date
, car letoString
est relatif à un fuseau horaire. Cependant, cette méthode utilise en fait le fuseau horaire par défaut de Java à la volée pour fournir la chaîne. Le fuseau horaire ne fait pas partie de l'état réel dejava.util.Date
.Un
Instant
ne contient pas non plus d'informations sur le fuseau horaire. Ainsi, pour convertir d'unInstant
en une date-heure locale, il est nécessaire de spécifier un fuseau horaire. Il peut s'agir du fuseau par défaut -ZoneId.systemDefault()
- ou il peut s'agir d'un fuseau horaire contrôlé par votre application, tel qu'un fuseau horaire issu des préférences de l'utilisateur.LocalDateTime
a une méthode d'usine pratique qui prend à la fois l'instant et le fuseau horaire:À l'inverse, le
LocalDateTime
fuseau horaire est spécifié en appelant laatZone(ZoneId)
méthode. LeZonedDateTime
peut ensuite être converti directement enInstant
:Notez que la conversion de
LocalDateTime
àZonedDateTime
a le potentiel d'introduire un comportement inattendu. En effet, toutes les dates et heures locales n'existent pas en raison de l'heure d'été. En automne / automne, il y a un chevauchement dans la chronologie locale où la même date-heure locale se produit deux fois. Au printemps, il y a un écart, où une heure disparaît. Voir le Javadoc deatZone(ZoneId)
pour plus de définition de ce que fera la conversion.En résumé, si vous faites un aller-retour entre un et
java.util.Date
unLocalDateTime
retour,java.util.Date
vous pouvez vous retrouver avec un instant différent en raison de l'heure d'été.Informations supplémentaires: Il existe une autre différence qui affectera les dates très anciennes.
java.util.Date
utilise un calendrier qui change au 15 octobre 1582, avec des dates antérieures à celles du calendrier julien au lieu du calendrier grégorien. En revanche,java.time.*
utilise le système de calendrier ISO (équivalent au grégorien) pour tous les temps. Dans la plupart des cas d'utilisation, le système de calendrier ISO est ce que vous voulez, mais vous pouvez voir des effets étranges lors de la comparaison des dates avant l'année 1582.la source
java.util.Date
ne contient pas de fuseau horaire, mais imprimez-le pendanttoString()
. La documentation officielle de l' événement ne le dit pas clairement lorsque vous postez.LocalDateTime.ofInstant(date.toInstant()...
ne se comporte pas comme on pourrait s'y attendre naïvement. Par exemplenew Date(1111-1900,11-1,11,0,0,0);
deviendra en1111-11-17 23:53:28
utilisant cette approche. Jetez un œil à l'implémentation dejava.sql.Timestamp#toLocalDateTime()
si vous aviez besoin que le résultat soit1111-11-11 00:00:00
dans l'exemple précédent.java.sql.Date#toInstant
jette unUnsupportedOperationException
. Ne l'utilisez donc pastoInstant
dans un RowMapperjava.sql.ResultSet#getDate
.Voici ce que j'ai trouvé (et comme toutes les énigmes de la date et de l'heure, cela va probablement être réfuté sur la base d'un ajustement étrange du fuseau horaire, du pas de jour et de la lumière du jour: D)
Déclenchement aller-retour:
Date
<<->>LocalDateTime
Donné:
Date date = [some date]
(1)
LocalDateTime
<<Instant
<<Date
(2)
Date
<<Instant
<<LocalDateTime
Exemple:
Donné:
(1)
LocalDateTime
<<Instant
<<Date
:Créer à
Instant
partir deDate
:Créer à
Date
partir deInstant
(pas nécessaire, mais à titre d'illustration):Créer à
LocalDateTime
partir deInstant
(2)
Date
<<Instant
<<LocalDateTime
Créer à
Instant
partir deLocalDateTime
:Créer à
Date
partir deInstant
:La sortie est:
la source
Instant.ofEpochMilli(date.getTime())
fairedate.toInstant()
toInstant()
air bien, sauf qu'il échouejava.sql.Date
, arggggh! Il est donc finalement plus facile à utiliserInstant.ofEpochMilli(date.getTime())
.Un moyen beaucoup plus pratique si vous êtes sûr d'avoir besoin d'un fuseau horaire par défaut:
la source
ce qui suit semble fonctionner lors de la conversion de la nouvelle API LocalDateTime en java.util.date:
la conversion inverse peut être (espérons-le) réalisée de manière similaire ...
J'espère que cela aide...
la source
Tout est ici: http://blog.progs.be/542/date-to-java-time
La réponse avec "aller-retour" n'est pas exacte: quand vous le faites
si le fuseau horaire de votre système n'est pas UTC / GMT, vous changez l'heure!
la source
Le moyen le plus rapide pour
LocalDateTime
->Date
est:Date.from(ldt.toInstant(ZoneOffset.UTC))
la source
Je ne sais pas si c'est le moyen le plus simple ou le meilleur, ou s'il y a des pièges, mais cela fonctionne:
la source
LocalDateTime
àDate
. Lors des transitions à l'heure d'été, aLocalDateTime
peut être inexistant ou se produire deux fois. Vous devez déterminer ce que vous voulez faire dans chaque cas.GregorianCalendar
appartient à une ancienne API maladroite que la nouvellejava.time
API vise à remplacerSi vous êtes sur Android et utilisez Threetenbp, vous pouvez utiliser à la
DateTimeUtils
place.ex:
vous ne pouvez pas l'utiliser
Date.from
car il n'est pris en charge que sur api 26+la source