Convertir java.util.La Date de ce "java.temps" type?

j'ai un objet java.util.Date ou un objet java.util.Calendar . Comment puis-je convertir cela au bon type dans java.temps cadre?

j'ai entendu dire que nous devrions maintenant faire l'essentiel de notre logique commerciale avec java.les types d'heures. Lorsque vous travaillez avec un ancien code qui n'est pas encore mis à jour pour java.temps j'ai besoin d'être en mesure de convertir en arrière et en avant. Quels types de carte java.util.Date ou java.util.Calendar ?

22
demandé sur Basil Bourque 2016-04-15 08:50:02

1 réponses

Oui, vous avez certainement devraient être à l'aide de la de java.cadre temporel dans la mesure du possible.

éviter les anciennes classes de date-heure

les anciennes classes de date-heure, y compris java.util.Date , java.util.Calendar , et java.text.SimpleTextFormat et Tels se sont avérés être mal conçu, confus, et gênant . Éviter d'eux quand vous le pouvez. Mais quand il le faut interopérer avec ces vieux types, vous pouvez convertir entre ancien et nouveau.

poursuivez votre lecture pour une introduction de base, un peu trop simplifiée, pour vous orienter dans les allers-retours entre les anciennes et les nouvelles classes de datation.

de java.temps

Le de java.time framework est défini par JSR 310 , inspiré par le très réussi Joda-Time bibliothèque, et prolongé par le projet ThreeTen-Extra . L'essentiel de la fonctionnalité a été rétroporté à Java 6 & 7 dans le ThreeTen-Backport projet, avec une autre adaptation pour Android dans le ThreeTenABP projet.

Ce que java.correspondances de type de temps java.util.Date ? Eh bien, un objet java.util.Date représente essentiellement un moment sur la ligne de temps en UTC, une combinaison d'un la date et l'heure de la journée. Nous pouvons traduire cela en plusieurs types en java.temps. Chacun est discuté ci-dessous. Notez que de nouvelles méthodes ont été ajoutées aux anciennes classes de date-heure pour faciliter les conversions.

diagram of converting from java.util.Date/.Calendar through ZonedDateTime (or OffsetDateTime) to the three <codeLocal…</code types

Instant

Le bloc de construction en java.le temps est un Instant , un moment sur la ligne du temps dans UTC avec une résolution de nanosecondes .

en général, vous devriez faire une grande partie de votre logique commerciale dans UTC. Dans ce travail, Instant sera utilisé fréquemment. Passer autour des objets Instant , en appliquant un fuseau horaire uniquement pour la présentation à un utilisateur. Lorsque vous do besoin d'appliquer un décalage ou un fuseau horaire, utilisez les types couverts ci-dessous.

de java.util.Date à Instant

étant donné que les deux Instant et java.util.Date sont un moment sur la ligne de temps en TUC, nous pouvons facilement passer d'un java.util.Date à un Instant . La vieille classe a acquis une nouvelle méthode, java.util.Date::toInstant .

Instant instant = myUtilDate.toInstant();

vous pouvez aller dans l'autre direction, d'un Instant à un java.util.Date . Mais vous pouvez perdre des informations sur la fraction de seconde. Une piste Instant nanosecondes , jusqu'à neuf chiffres après la décimale telle que 2016-01-23T12:34:56.123456789Z . Les deux java.util.Date. & De calendrier sont limités à la millisecondes , pour un maximum de trois chiffres après la virgule comme 2016-01-23T12:34:56.123Z . Dans cet exemple, passer de Instant à Date signifie la troncature du 456789 .

java.util.Date myUtilDate = java.util.Date.from( instant );

de java.util.Calendar à Instant

Qu'en est-il d'un java.util.Calendar au lieu de java.util.Date ? Interne à l'objet Calendar la date-heure est tracée comme un compte de millisecondes de la Date-Heure de référence d'époque du premier moment de 1970 en UTC ( 1970-01-01T00:00:00.0Z ). Cette valeur peut donc être facilement convertie en Instant .

Instant instant = myUtilCalendar.toInstant() ;

de java.util.GregorianCalendar à ZonedDateTime

encore mieux, si votre java.util.Calendar objet est en fait un java.util.GregorianCalendar vous pouvez facilement aller directement à un ZonedDateTime . Cette approche présente l'avantage de conserver l'information intégrée sur les fuseaux horaires.

Abattu de la interface de Calendar à la de la classe de béton de GregorianCalendar . Ensuite, appelez le toZonedDateTime et from méthodes pour faire l'aller-retour.

if( myUtilCalendar instanceof GregorianCalendar ) {
    GregorianCalendar gregCal = (GregorianCalendar) myUtilCalendar; // Downcasting from the interface to the concrete class.
    ZonedDateTime zdt = gregCal.toZonedDateTime();  // Create `ZonedDateTime` with same time zone info found in the `GregorianCalendar`
end if 

aller dans l'autre direction ...

    java.util.Calendar myUtilCalendar = java.util.GregorianCalendar.from( zdt ); // Produces an instant of `GregorianCalendar` which implements `Calendar` interface.

comme indiqué ci-dessus, prenez garde que vous puissiez être en train de perdre des informations sur la fraction de seconde . Le nanosecondes dans le java.le type de temps ( ZonedDateTime ) est tronqué à millisecondes dans le .Calendar / .GregorianCalendar .

OffsetDateTime

à Partir d'un Instant nous pouvons appliquer un offset-de-UTC de se déplacer dans un horloge murale pour une localité. Un décalage est un nombre d'heures, et peut-être de minutes et de secondes, devant UTC (vers l'est) ou derrière UTC (vers l'Ouest). La classe ZoneOffset représente de cette idée. Le résultat est un objet OffsetDateTime .

ZoneOffset offset = ZoneOffset.of( "-04:00" ); 
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );

vous pouvez aller dans l'autre direction, d'un OffsetDateTime à un java.util.Date . Extraire un Instant puis procéder comme nous l'avons vu dans le code ci-dessus. Comme indiqué ci-dessus, tout nanosecondes est tronqué en millisecondes ( perte de données ).

java.util.Date myUtilDate = java.util.Date.from( odt.toInstant() );

ZonedDateTime

mieux encore, appliquer un fuseau horaire . Un fuseau horaire est un décalage plus règles pour le traitement des anomalies telles que heure D'été (HAE) .

l'Application d'un ZoneId vous procure un ZonedDateTime objet. Utilisez un nom du fuseau horaire approprié (continent/région). N'utilisez jamais la lettre 3-4 abréviations couramment utilisées, telles que EST ou IST , car elles ne sont ni normalisées ni uniques.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

vous pouvez aller dans l'autre direction, d'un ZonedDateTime à un java.util.Date . Extraire un Instant puis procéder comme nous l'avons vu dans le code ci-dessus. Comme indiqué ci-dessus, tout nanosecondes est tronqué en millisecondes ( perte de données ).

java.util.Date myUtilDate = java.util.Date.from( zdt.toInstant() );

Et nous avons vu plus haut qu'une ZonedDateTime peut être converti en un GregorianCalendar .

LocalDate

parfois, vous pouvez vouloir une date seulement valeur, sans Heure de la journée et sans fuseau horaire. Pour cela, utilisez un objet java.time.LocalDate .

Voir cette Question pour plus de discussion, Convertir java.util.Date de java.temps.Date locale , en particulier cette réponse écrite par l'homme principal derrière l'invention de Joda-Time et de java.temps.

la clé est de passer par un ZonedDateTime (tel que généré dans le code ci-dessus). Nous avons besoin d'un fuseau horaire à déterminer une date. La date varie à travers le monde, avec un nouveau jour plus tôt dans l'est. Par exemple, après minuit à Paris est un nouveau jour alors qu'encore "hier" à Montréal. Donc, alors qu'un LocalDate ne contient un fuseau horaire, un le fuseau horaire est requis pour déterminer a LocalDate .

LocalDate localDate = zdt.toLocalDate();

passer dans l'autre sens de LocalDate à une date-heure signifie inventer une heure de la journée. Vous pouvez choisir n'importe quel moment de la journée qui a du sens dans votre scénario d'affaires. Pour la plupart des gens, le premier moment de la journée a du sens. Vous pourriez être tenté de coder ce premier moment comme le temps 00:00:00.0 . Dans certains fuseaux horaires, ce temps peut ne pas être valide comme le premier moment en raison de heure D'été (HNE) ou d'autres anomalies. Alors laisse java.heure déterminez l'heure exacte avec un appel à atStartOfDay .

ZonedDateTime zdt = localDate.atStartOfDay( zoneId );

LocalTime

en de rares occasions, vous pouvez vouloir seulement un moment de la journée sans date et sans fuseau horaire. Ce concept est représenté par la classe LocalTime . Comme discuté ci-dessus avec LocalDate , nous avons besoin d'un fuseau horaire pour déterminer un LocalTime même si l'objet LocalTime ne contient pas (ne se "rappelle pas") ce fuseau horaire. Donc, encore une fois, nous passons à travers un ZonedDateTime objet obtenu à partir d'un Instant comme vu ci-dessus.

LocalTime localTime = zdt.toLocalTime();

LocalDateTime

comme pour les deux autres types de Local… , un LocalDateTime n'a pas de fuseau horaire ni de décalage. En tant que tel vous peut rarement utiliser ceci. Il vous donne une idée approximative d'une date-heure mais est pas un point sur la ligne du temps. Utilisez ceci si vous voulez dire une date générale et une heure qui pourrait être appliquée à un fuseau horaire.

Par exemple, "Noël commence cette année" serait 2016-12-25T00:00:00.0 . Notez l'absence de décalage ou de fuseau horaire dans cette représentation textuelle d'un LocalDateTime . Noël commence plus tôt à Delhi en Inde qu'à Paris en France, et plus tard encore à Montréal Québec Canada. Appliquer le fuseau horaire de chacune de ces zones donnerait un moment différent sur la ligne du temps.

LocalDateTime ldt = zdt.toLocalDateTime();
70
répondu Basil Bourque 2017-05-23 12:02:45