web-dev-qa-db-fra.com

Devrais-je utiliser Java.util.Date ou passer à Java.time.LocalDate

Edit: Eh bien, apparemment c'était trop basé sur l'opinion, alors laissez-moi essayer de le reformuler plus précisément -

Existe-t-il des mises en garde ou des inconvénients évidents à l’utilisation de LocalDate, LocalTime, etc. dans un code Java qui n’a pas besoin de compatibilité ascendante, et si oui - de quoi s'agit-il?

Je cherche des choses comme "Les bibliothèques EE actuelles X et Y ne fonctionnent pas correctement avec LocalDate" ou "Ce modèle très utile est rompu avec LocalTime", etc.


(voici la question initiale pour référence)

Avec Java 8, une nouvelle API d'heure est introduite, à savoir Java.time.LocalDate etc., mais Java.util.Date n'est pas marqué comme obsolète.

J'écris un nouveau projet, qui n'a pas besoin d'être compatible avec les versions antérieures. Devrais-je utiliser uniquement LocalDate, LocalDateTime, etc.? L'utilisation de cette nouvelle API présente-t-elle des inconvénients par rapport au bon vieux Java.util.Date?

En particulier, je vais travailler principalement avec JDBC. D'après ce que j'ai vu, JDBC gère bien Java.util.Date. Est-ce aussi bien adapté à LocalDate?

La recherche a révélé que de nombreux sites expliquaient comment convertir un format à l’autre, sans donner de réponse définitive quant au nouveau code utilisant l’ancienne API.

Merci.

47
Itai

Malgré son nom, Java.util.Date peut être utilisé pour stocker la date et l’heure (il stocke le décalage UTC en millisecondes depuis Epoch).

J'utiliserais certainement la nouvelle API en raison de fonctionnalités améliorées:

  • Format/analyse simplifié. L'API a ses propres méthodes de format/analyse
  • L'API comprend une opération d'addition/soustraction (minusminutes, plus jours, etc.)

Aucune de ces réponses n’est disponible sur Java.util.Date

Old Date peut également être convertie en LocalDateTime comme ceci:

Date oldDate = ...
LocalDateTime newDateTime = 
  LocalDateTime.from(Instant.ofEpochMilli(oldDate.getTime()));
36
gerrytan

J'ajoute au réponse correcte de Ole V.V.

JDBC 4.2

En particulier, je vais travailler principalement avec JDBC.

JDBC 4.2 ajout de la prise en charge de l'échange d'objets Java.time avec la base de données. Voir le PreparedStatement::setObject et ResultSet::getObject méthodes.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
myPreparedStatement.setObject( … , today ) ;

Récupération.

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

Pour des raisons qui m'échappent, la spécification JDBC ne n'exige pas de prendre en charge les deux classes les plus utilisées: Instant et ZonedDateTime . Votre base de données et pilote JDBC peuvent ou non ajouter un support pour ceux-ci.

Sinon, vous pouvez facilement convertir. Commencez par OffsetDateTime , avec l'assistance requise dans JDBC.

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

Pour voir ce moment dans l'horloge murale utilisée par les habitants d'une région particulière (un fuseau horaire), appliquez un ZoneId pour obtenir un objet ZonedDateTime.

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant() ;

Pour ajuster en UTC, extrayez un Instant. Un Instant est toujours en UTC, par définition.

Instant instant = odt.toInstant() ;

Vous pouvez convertir dans l'autre sens, pour écrire dans une base de données.

myPreparedStatement.setObject( … , zdt.toOffsetDateTime() ;  // Converting from `ZonedDateTime` to `OffsetDateTime`. Same moment, same point on the timeline, different wall-clock time.

…et:

myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ;  // Converting from `Instant` to `OffsetDateTime`. Same moment, same point on the timeline, and even the same offset. `OffsetDateTime` is a more flexible class with abilities such as (a) applying various offsets and (b) flexible formatting when generating text, while `Instant` is meant to be a more basic building-block class. 

Notez la convention de dénomination utilisée dans Java.time : at, from, to, with, et ainsi de suite.

Table of date-time types in Java (both modern and legacy) and in standard SQL.


À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancien problème - legacy classes date-heure telles que Java.util.Date , Calendar , & SimpleDateFormat .

Pour en savoir plus, consultez le Oracle Tutorial . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 31 .

Le projet Joda-Time , actuellement en mode de maintenance , conseille de migrer vers le Java.time = cours.

Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou une version ultérieure. Pas besoin de chaînes, pas besoin de Java.sql.* Des classes.

Où obtenir les classes Java.time?

Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez trouver ici quelques classes utiles telles que Interval , YearWeek , YearQuarter , et plus .

3
Basil Bourque

Java 8 et ultérieur: pas de soucis

Non, il n'y a aucune raison pour que vous ne vouliez pas utiliser Java.time, l'API moderne pour la date et l'heure Java si vous êtes sur Java 8 ou plus tard (où il est intégré).

La seule chose que l’on peut considérer brièvement est celle que vous avez déjà exclue.

J'écris un nouveau projet, qui n'a pas besoin d'être compatible avec les versions antérieures.

Et même pour des raisons de compatibilité ascendante, vous pouvez utiliser Java.time en toute sécurité, car les méthodes de conversion sont intégrées aux anciennes classes de Java 8.

Java 6 et 7: peser

Si vous êtes sur Java 6 ou 7, vous devrez utiliser le ThreeTen-Backport pour Java.time, encore adapté pour Android inférieur au niveau de l'API 26 dans ThreeTenABP . Si vous ne travaillez que très peu sur la date et l'heure et que la compatibilité en aval n'est pas un problème, vous pouvez vous demander si la dépendance externe en vaut la peine. Veuillez prendre en compte le fait que votre dépendance externe n'est qu'un backport de ce qui est construit dans Java 8 et ultérieur, donc solide comme un roc, et donc que vous en aurez besoin uniquement jusqu'à ce que vous migriez vers Java 8 ou ultérieur. À ce moment, vous pouvez modifier vos importations, effectuer un nouveau test et supprimer le backport.

Vos exemples de passifs pensables

Les bibliothèques EE actuelles X et Y ne fonctionnent pas correctement avec LocalDate

Il existe quelques exemples, ainsi que des classes de bibliothèque dans le JDK. Mon choix serait d’utiliser Java.time dans mon propre code et de ne convertir que juste avant d’appeler dans l’API qui n’accepte pas encore un type Java.time. Et inversement, si je récupère une instance d'une classe obsolète à partir de l'API, convertissez-la d'abord et utilisez Java.time pour le reste.

Ce modèle très utile est cassé avec LocalTime

Je ne connais pas un tel modèle. Au contraire, Java.time utilise des modèles , des objets immuables et de la méthode de la fabrique , contrairement à la plupart des anciennes classes.

1
Ole V.V.