
tl; dr
Instantet LocalDateTimesont deux animaux entièrement différents: l'un représente un moment, l'autre non.
Instant représente un moment, un point spécifique de la chronologie.
LocalDateTimereprésente une date et une heure. Mais sans fuseau horaire ou décalage par rapport à l'UTC, cette classe ne peut pas représenter un instant . Il représente des moments potentiels sur une plage d'environ 26 à 27 heures, la plage de tous les fuseaux horaires du globe.
Présomption incorrecte
LocalDateTime est plutôt une représentation date / horloge incluant des fuseaux horaires pour l'homme.
Votre déclaration est incorrecte: A LocalDateTimen'a pas de fuseau horaire . Ne pas avoir de fuseau horaire est tout l'intérêt de cette classe.
Pour citer le doc de cette classe:
Cette classe ne stocke ni ne représente un fuseau horaire. Au lieu de cela, il s'agit d'une description de la date, utilisée pour les anniversaires, combinée à l'heure locale telle qu'elle apparaît sur une horloge murale. Il ne peut pas représenter un instant sur la ligne de temps sans informations supplémentaires telles qu'un décalage ou un fuseau horaire.
Signifie donc Local…«pas zoné, pas de décalage».
Instant

An Instantest un moment de la chronologie en UTC , un décompte de nanosecondes depuis l'époque du premier moment de 1970 UTC (en gros, voir le doc de classe pour les détails les plus fins). Étant donné que la plupart de votre logique métier, stockage de données et échange de données doivent être en UTC, il s'agit d'une classe pratique à utiliser souvent.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
OffsetDateTime

La classe OffsetDateTimeclass représente un moment comme une date et une heure avec un contexte d'un certain nombre d'heures-minutes-secondes avant ou derrière UTC. La quantité de décalage, le nombre d'heures-minutes-secondes, est représentée par leZoneOffset classe.
Si le nombre d'heures-minutes-secondes est nul, an OffsetDateTimereprésente un moment en UTC identique à an Instant.
ZoneOffset

La ZoneOffsetclasse représente un décalage par rapport à UTC , un certain nombre d'heures-minutes-secondes devant UTC ou derrière UTC.
A ZoneOffsetn'est qu'un nombre d'heures-minutes-secondes, rien de plus. Une zone, c'est beaucoup plus, ayant un nom et un historique des changements à compenser. Il est donc toujours préférable d'utiliser une zone que d'utiliser un simple décalage.
ZoneId

Un fuseau horaire est représenté par la ZoneIdclasse.
Un nouveau jour se lève plus tôt à Paris qu'à Montréal , par exemple. Nous devons donc déplacer les aiguilles de l'horloge pour mieux refléter midi (lorsque le soleil est directement au-dessus) pour une région donnée. Plus la distance est / ouest est éloignée de la ligne UTC en Europe occidentale / Afrique, plus le décalage est important.
Un fuseau horaire est un ensemble de règles pour gérer les ajustements et les anomalies tels que pratiqués par une communauté ou une région locale. L'anomalie la plus courante est la folie bien trop populaire connue sous le nom d' heure d'été (DST) .
Un fuseau horaire a l'historique des règles passées, des règles actuelles et des règles confirmées pour un avenir proche.
Ces règles changent plus souvent que vous ne le pensez. Assurez-vous de garder à jour les règles de votre bibliothèque date-heure, généralement une copie de la base de données «tz» . La mise à jour est plus facile que jamais maintenant dans Java 8 avec Oracle libérant un outil de mise à jour de fuseau horaire .
Indiquez un nom de fuseau horaire approprié dans le format Continent/Region, tels que America/Montreal, Africa/Casablancaou Pacific/Auckland. N'utilisez jamais l'abréviation de 2 à 4 lettres telles que ESTou ISTcar ce ne sont pas de vrais fuseaux horaires, ni standardisés, ni même uniques (!).
Fuseau horaire = décalage + règles d'ajustement
ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
ZonedDateTime

Pensez ZonedDateTimeconceptuellement Instantà un assigné ZoneId.
ZonedDateTime = (Instant + ZoneId)
Pour capturer le moment actuel tel qu'il apparaît dans l'heure de l'horloge murale utilisée par les habitants d'une région particulière (un fuseau horaire):
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Pass a `ZoneId` object such as `ZoneId.of( "Europe/Paris" )`.
La quasi-totalité de votre backend, base de données, logique métier, persistance des données, échange de données devraient tous être en UTC. Mais pour la présentation aux utilisateurs, vous devez vous ajuster dans un fuseau horaire attendu par l'utilisateur. C'est le but de la ZonedDateTimeclasse et des classes de formateur utilisées pour générer des représentations String de ces valeurs date-heure.
ZonedDateTime zdt = instant.atZone( z ) ;
String output = zdt.toString() ; // Standard ISO 8601 format.
Vous pouvez générer du texte au format localisé à l'aide de DateTimeFormatter.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ;
String outputFormatted = zdt.format( f ) ;
mardi 30 avril 2019 à 23 h 22 min 55 s heure de l'Inde
LocalDate, LocalTime,LocalDateTime



Les classes de date et heure « locale », LocalDateTime, LocalDate, LocalTime, sont un autre type de créature. Ils ne sont liés à aucune localité ou fuseau horaire. Ils ne sont pas liés à la chronologie. Ils n'ont aucune signification réelle jusqu'à ce que vous les appliquiez à une localité pour trouver un point sur la chronologie.
Le mot «local» dans ces noms de classe peut être contre-intuitif pour les non-initiés. Le mot signifie n'importe quelle localité, ou chaque localité, mais pas une localité particulière.
Ainsi, pour les applications professionnelles, les types "locaux" ne sont pas souvent utilisés car ils représentent simplement l'idée générale d'une date ou d'une heure possible et non d'un moment spécifique sur la chronologie. Les applications professionnelles ont tendance à se soucier du moment exact où une facture est arrivée, un produit expédié pour le transport, un employé a été embauché ou le taxi a quitté le garage. Les développeurs d'applications métier utilisent donc Instantet les ZonedDateTimeclasses le plus souvent.
Alors, quand utiliserions-nous LocalDateTime? Dans trois situations: où nous voulons appliquer une certaine date et heure à plusieurs endroits, où nous prenons des rendez-vous ou où nous avons un fuseau horaire prévu mais indéterminé. Notez qu'aucun de ces trois cas n'est un seul point spécifique sur la chronologie, aucun d'entre eux n'est un moment.
Un moment de la journée, plusieurs moments
Parfois, nous voulons représenter un certain moment de la journée à une certaine date, mais nous voulons l'appliquer à plusieurs localités à travers les fuseaux horaires.
Par exemple, "Noël commence à minuit le 25 décembre 2015" est un LocalDateTime. Minuit frappe à différents moments à Paris qu'à Montréal, et à nouveau différent à Seattle et à Auckland .
LocalDate ld = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
LocalTime lt = LocalTime.MIN ; // 00:00:00
LocalTime ldt = LocalDateTime.of( ld , lt ) ; // Xmas morning anywhere.
Un autre exemple, «Acme Company a pour politique que l'heure du déjeuner commence à 12 h 30 dans chacune de ses usines à travers le monde» est a LocalTime. Pour avoir un vrai sens, vous devez l'appliquer à la chronologie pour comprendre le moment de 12h30 à l' usine de Stuttgart ou de 12h30 à l' usine de Rabat ou de 12h30 à l' usine de Sydney .
Prise de rendez-vous
Une autre situation à utiliser LocalDateTimeest de réserver des événements futurs (ex: rendez-vous chez le dentiste). Ces nominations pourraient être suffisamment éloignées à l'avenir pour que vous risquiez que les politiciens redéfinissent le fuseau horaire. Les politiciens donnent souvent peu d'avertissement, voire aucun avertissement. Si vous voulez dire "15 h le 23 janvier prochain", quelle que soit la façon dont les politiciens peuvent jouer avec l'horloge, vous ne pouvez pas enregistrer un instant - cela verrait 15 h se transformer en 14 h ou 16 h si cette région adoptait ou abandonnait l'heure d'été, par exemple.
Pour les rendez-vous, stockez a LocalDateTimeet a ZoneId, conservés séparément. Plus tard, lors de la génération d'un planning, à la volée, déterminez un moment en appelant LocalDateTime::atZone( ZoneId )pour générer un ZonedDateTimeobjet.
ZonedDateTime zdt = ldt.atZone( z ) ; // Given a date, a time-of-day, and a time zone, determine a moment, a point on the timeline.
Si nécessaire, vous pouvez vous ajuster sur UTC. Extraire un Instantdu ZonedDateTime.
Instant instant = zdt.toInstant() ; // Adjust from some zone to UTC. Same moment, same point on the timeline, different wall-clock time.
Zone inconnue
Certaines personnes peuvent utiliser LocalDateTimedans une situation où le fuseau horaire ou le décalage est inconnu.
Je considère que ce cas est inapproprié et imprudent. Si une zone ou un décalage est prévu mais indéterminé, vous avez de mauvaises données. Ce serait comme stocker un prix d'un produit sans connaître la devise souhaitée. Pas une bonne idée.
Tous les types date-heure
Pour être complet, voici un tableau de tous les types de date-heure possibles, à la fois modernes et hérités en Java, ainsi que ceux définis par la norme SQL. Cela pourrait aider à placer les classes Instant& LocalDateTimedans un contexte plus large.

Notez les choix étranges faits par l'équipe Java lors de la conception de JDBC 4.2. Ils ont choisi de prendre en charge tous les temps java.time … à l'exception des deux classes les plus utilisées: Instant& ZonedDateTime.
Mais ne vous inquiétez pas. Nous pouvons facilement convertir dans les deux sens.
Conversion Instant.
// Storing
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
Conversion ZonedDateTime.
// Storing
OffsetDateTime odt = zdt.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;
// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZone( z ) ;
À propos de java.time
Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date, Calendar, et SimpleDateFormat.
Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .
Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*cours.
Où obtenir les classes java.time?
- Java SE 8 , Java SE 9 , Java SE 10 et versions ultérieures
- Intégré.
- Une partie de l'API Java standard avec une implémentation groupée.
- Java 9 ajoute quelques fonctionnalités et correctifs mineurs.
- Java SE 6 et Java SE 7
- Une grande partie de la fonctionnalité java.time est backportée sur Java 6 et 7 dans ThreeTen-Backport .
- Android
- Versions ultérieures des implémentations de bundles Android des classes java.time.
- Pour les versions antérieures d'Android (<26), le projet ThreeTenABP adapte ThreeTen-Backport (mentionné ci-dessus). Voir Comment utiliser ThreeTenABP… .

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval, YearWeek, YearQuarteret plus .