Quelqu'un pourrait-il s'il vous plaît conseiller les "meilleures pratiques" actuelles Date
et les Calendar
types?
Lors de l' écriture du nouveau code, est - il préférable de favoriser toujours Calendar
plus Date
, ou y at - il des circonstances où Date
est le type de données plus approprié?
java.util.Date
,java.util.Calendar
etjava.text.SimpleDateFormat
sont maintenant héritage, supplanté par les java.time classes. Une grande partie de la fonctionnalité java.time est rétroportée vers Java 6 et Java 7 dans le projet ThreeTen-Backport . Adapté davantage pour les versions antérieures d'Android dans le projet ThreeTenABP . Voir Comment utiliser ThreeTenABP… .Réponses:
La date est une classe plus simple et est principalement présente pour des raisons de compatibilité descendante. Si vous devez définir des dates particulières ou effectuer une arithmétique des dates, utilisez un calendrier. Les calendriers gèrent également la localisation. Les fonctions de manipulation de date précédentes de Date ont depuis été dépréciées.
Personnellement, j'ai tendance à utiliser le temps en millisecondes comme long (ou long, selon le cas) ou le calendrier lorsqu'il y a un choix.
La date et le calendrier sont mutables, ce qui tend à présenter des problèmes lors de l'utilisation de l'une ou l'autre dans une API.
la source
java.util.Date
,java.util.Calendar
etjava.text.SimpleDateFormat
sont désormais héritées , supplantées par les classes java.time intégrées à Java 8 et versions ultérieures. Voir Tutoriel par Oracle .Le meilleur moyen pour le nouveau code (si votre politique autorise le code tiers) est d'utiliser le bibliothèque Joda Time .
La date et le calendrier ont tous deux tellement de problèmes de conception que ni l'un ni l'autre ne sont de bonnes solutions pour le nouveau code.
la source
Date
etCalendar
sont vraiment le même concept fondamental (les deux représentent un instant dans le temps et sont des enveloppes autour d'unelong
valeur sous-jacente ).On pourrait dire qu'il
Calendar
est en fait encore plus cassé qu'il ne l'Date
est, car il semble offrir des faits concrets sur des choses comme le jour de la semaine et l'heure du jour, alors que si vous changez satimeZone
propriété, le béton se transforme en blancmange! Aucun des deux objets n'est vraiment utile comme magasin d' année-mois-jour ou d' heure pour cette raison.Utilisez
Calendar
uniquement comme une calculatrice qui, une fois donnéeDate
et desTimeZone
objets, fera des calculs pour vous. Évitez son utilisation pour la saisie de propriété dans une application.À utiliser
SimpleDateFormat
avecTimeZone
etDate
pour générer des chaînes d'affichage.Si vous vous sentez aventureux, utilisez Joda-Time, bien qu'il soit inutilement compliqué à mon humble avis et qu'il sera bientôt remplacé par l'API de date JSR-310 de toute façon.
J'ai déjà répondu qu'il n'est pas difficile de rouler votre propre
YearMonthDay
classe, qui utiliseCalendar
sous le capot pour les calculs de date. J'ai été rétrogradé pour la suggestion, mais je pense toujours qu'elle est valable car Joda-Time (et JSR-310 ) sont vraiment trop compliqués pour la plupart des cas d'utilisation.la source
La date est idéale pour stocker un objet de date. C'est celui qui persiste, celui qui est sérialisé ...
Le calendrier est idéal pour manipuler les dates.
la source
java.lang.Long
J'utilise généralement Date si possible. Bien qu'il soit mutable, les mutateurs sont en fait obsolètes. En fin de compte, il enveloppe essentiellement un long qui représenterait la date / heure. Inversement, j'utiliserais des calendriers si je dois manipuler les valeurs.
Vous pouvez y penser de cette façon: vous n'utilisez StringBuffer que lorsque vous avez besoin d'avoir des chaînes que vous pouvez facilement manipuler puis les convertir en chaînes en utilisant la méthode toString (). De la même manière, je n'utilise Calendar que si j'ai besoin de manipuler des données temporelles.
Pour les meilleures pratiques, j'ai tendance à utiliser autant que possible des objets immuables en dehors du modèle de domaine . Cela réduit considérablement les risques d'effets secondaires et cela est fait pour vous par le compilateur, plutôt que par un test JUnit. Vous utilisez cette technique en créant des champs finaux privés dans votre classe.
Et revenons à l'analogie StringBuffer. Voici un code qui vous montre comment convertir entre le calendrier et la date
la source
Date
/Calendar
utilisé le modèle d'objets immuables.Date
s doivent être utilisés comme des points immuables dans le temps;Calendar
Les s sont modifiables et peuvent être transmis et modifiés si vous avez besoin de collaborer avec d'autres classes pour trouver une date finale. Considérez-les comme analoguesString
etStringBuilder
et vous comprendrez comment je considère qu'ils devraient être utilisés.(Et oui, je sais que la date n'est pas réellement immuable techniquement, mais l'intention est qu'elle ne devrait pas être modifiable, et si rien n'appelle les méthodes obsolètes, alors c'est le cas.)
la source
Date
/Calendar
utilisé le modèle d'objets immuables. Spécifiquement,Instant
remplacejava.util.Date
etZonedDateTime
remplaceCalendar
/GregorianCalendar
.tl; dr
Évitez complètement ces classes héritées . Utilisez plutôt des classes java.time .
Instant
Date
)ZonedDateTime
GregorianCalendar
OffsetDateTime
LocalDateTime
Détails
La réponse par Ortomala Lokni a raison de suggérer d' utiliser les modernes java.time les classes plutôt que les classes date du temps de l' héritage vieux gênants (
Date
,Calendar
, etc.). Mais cette réponse suggère la mauvaise classe comme équivalente (voir mon commentaire sur cette réponse).Utilisation de java.time
Les classes de java.time sont une grande amélioration par rapport à la classe date temps anciens, la différence nuit et jour. Les anciennes classes sont mal conçues, déroutantes et gênantes. Vous devriez éviter les anciennes classes autant que possible. Mais lorsque vous avez besoin de convertir vers / à partir de l'ancien / nouveau, vous pouvez le faire en appelant de nouvelles méthodes à ajouter aux anciennes classes.
Pour plus d'informations sur la conversion, voir ma réponse et le diagramme astucieux vers une autre question, Convertir java.util.Date en quel type «java.time»? .
La recherche de débordement de pile donne plusieurs centaines d'exemples de questions et réponses sur l'utilisation de java.time. Mais voici un bref résumé.
Instant
Obtenez le moment actuel avec un
Instant
. LaInstant
classe représente un moment sur la chronologie en UTC avec une résolution de nanosecondes (jusqu'à neuf (9) chiffres d'une fraction décimale).ZonedDateTime
Pour voir ce même moment simultané à travers l'objectif de l' heure d'une horloge murale d'une région particulière , appliquez un fuseau horaire (
ZoneId
) pour obtenir unZonedDateTime
.Fuseau horaire
Indiquez un nom de fuseau horaire approprié dans le format
continent/region
, tels queAmerica/Montreal
,Africa/Casablanca
ouPacific/Auckland
. N'utilisez jamais l'abréviation de 3 à 4 lettres telles queEST
ouIST
car ce ne sont pas de véritables fuseaux horaires, ni standardisés, ni même uniques (!).Décalage
Un fuseau horaire est l'histoire d'une région dans laquelle son décalage par rapport à l'UTC a changé . Mais parfois, vous ne recevez qu'un décalage sans la zone complète. Dans ce cas, utilisez la
OffsetDateTime
classe.L'utilisation d'un fuseau horaire est préférable à l'utilisation d'un simple décalage.
LocalDateTime
Le «Local» dans les
Local…
classes signifie n'importe quelle localité, pas une localité particulière. Le nom peut donc être contre-intuitif.LocalDateTime
,LocalDate
EtLocalTime
délibérément manque aucune information sur la zone de décalage ou de temps. Ils ne représentent donc pas des moments réels, ce ne sont pas des points sur la chronologie. En cas de doute ou de confusion, utilisezZonedDateTime
plutôt queLocalDateTime
. Search Stack Overflow pour plus de discussion.Cordes
Ne confondez pas les objets date-heure avec des chaînes qui représentent leur valeur. Vous pouvez analyser une chaîne pour obtenir un objet date-heure et vous pouvez générer une chaîne à partir d'un objet date-heure. Mais la chaîne n'est jamais la date-heure elle-même.
Découvrez les formats ISO 8601 standard, utilisés par défaut dans les classes java.time.
À 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
, &SimpleDateFormat
.Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers java.time classes .
Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Utilisant un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure, vous pouvez échanger des objets java.time directement avec votre base de données. Pas besoin de chaînes ni de classes java.sql. *.
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 de futurs ajouts possibles à java.time. Vous trouverez peut - être des classes utiles ici, comme
Interval
,YearWeek
,YearQuarter
et plus .la source
Avec Java 8, le nouveau package java.time doit être utilisé.
Les objets sont immuables, les fuseaux horaires et l'heure d'été sont pris en compte.
Vous pouvez créer un
ZonedDateTime
objet à partir d'un ancienjava.util.Date
objet comme ceci:la source
LocalDateTime
. Cette classe perd volontairement toute information sur le décalage par rapport à l'UTC et le fuseau horaire. Cette classe n'est donc pas équivalente commeDate
en UTC etCalendar
a un fuseau horaire attribué. Voir ma réponse et le diagramme astucieux à une autre question, convertir java.util.Date en quel type "java.time"? .Je préconise toujours Joda-time . Voici pourquoi.
EDIT: Les classes de date / heure Java introduites avec Java 8 sont maintenant la solution préférée, si vous pouvez migrer vers Java 8
la source
Un peu en retard à la fête, mais Java a une nouvelle API Date Time dans JDK 8. Vous pouvez mettre à niveau votre version JDK et adopter la norme. Plus de date / calendrier en désordre, plus de pots tiers.
la source
La date devrait être re-développée. Au lieu d'être un entier long, il devrait contenir l'année, le mois, la date, l'heure, la minute, la seconde, comme des champs séparés. Il peut même être utile de stocker le calendrier et le fuseau horaire auxquels cette date est associée.
Dans notre conversation naturelle, si vous fixez un rendez-vous le 1er novembre 2013 à 13 h, heure de New York, il s'agit d'un DateTime. Ce n'est PAS un calendrier. Nous devrions donc pouvoir converser comme ça en Java également.
Lorsque la date est stockée sous la forme d'un entier long (en mili secondes depuis le 1er janvier 1970 ou quelque chose comme ça), le calcul de sa date actuelle dépend du calendrier. Différents calendriers donneront une date différente. C'est dans la perspective de donner un temps absolu (par exemple 1 billion de secondes après le Big Bang). Mais souvent, nous avons également besoin d'un moyen de conversation pratique, comme un objet encapsulant l'année, le mois, etc.
Je me demande s'il y a de nouvelles avancées en Java pour concilier ces 2 objectifs. Peut-être que mes connaissances en java sont trop anciennes.
la source
Date
a été re-développé; remplacé par lajava.time.Instant
classe. EtCalendar
/ aGregorianCalendar
été remplacé par lajava.time.ZonedDateTime
classe.Btw "date" est généralement étiqueté comme "obsolète / obsolète" (je ne sais pas exactement pourquoi) - quelque chose à ce sujet est écrit ici Java: Pourquoi le constructeur Date est-il obsolète, et que dois-je utiliser à la place?
Il semble que ce soit un problème du constructeur uniquement via la nouvelle date (année int, mois int, jour int) , la manière recommandée est via Calendrier et définir les paramètres séparément .. ( Calendrier cal = Calendar.getInstance (); )
la source
J'utilise Calendrier lorsque j'ai besoin d'opérations spécifiques sur les dates comme le déplacement dans le temps, mais Date, je trouve cela utile lorsque vous devez formater la date pour adapter vos besoins, récemment j'ai découvert que Locale a beaucoup d'opérations et de méthodes utiles. J'utilise Locale en ce moment!
la source
Calendar
et lesDate
classes ont été supplanté il y a quelques années par les java.time classes. Pas besoin de jamais utiliserDate
ouCalendar
. EtLocale
n'a rien à voir avec la signification des objets date-heure. ALocale
est uniquement utilisé pour spécifier le langage humain et les normes culturelles à utiliser pour la localisation tout en générant du texte pour représenter la valeur d'un objet date-heure.