Quelqu'un pourrait-il informer la "meilleure pratique" actuelle autour des types Date
et Calendar
.
Lorsque vous écrivez un nouveau code, vaut-il mieux toujours privilégier Calendar
par rapport à Date
ou existe-t-il des circonstances dans lesquelles Date
est le type de données le plus approprié?
Date est une classe plus simple et existe principalement pour des raisons de compatibilité ascendante. Si vous devez définir des dates particulières ou effectuer un calcul arithmétique des dates, utilisez un calendrier. Les calendriers traitent également la localisation. Les fonctions de manipulation de date précédentes de Date ont depuis été déconseillé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.
Les dates et les calendriers sont modifiables, ce qui tend à présenter des problèmes lors de l'utilisation dans une API.
Date
et Calendar
sont vraiment le même concept fondamental (les deux représentent un instant dans le temps et sont des wrappers autour d'une valeur long
sous-jacente).
On pourrait soutenir que Calendar
EST EN FAIT ENCORE PLUS BRISÉ QUE Date
, car il semble offrir des faits concrets sur des choses comme le jour de la semaine et l'heure de la journée, alors que si vous changez sa propriété timeZone
, le béton se transforme en blanc ! Ni l'un ni l'autre des objets ne sont vraiment utiles en tant que magasin de année-mois-jour ou heure du jour pour cette raison.
Utilisez Calendar
uniquement comme calculatrice qui, à l'aide des objets Date
et TimeZone
, effectuera les calculs pour vous. Evitez son utilisation pour la saisie de propriétés dans une application.
Utilisez SimpleDateFormat
avec TimeZone
et Date
pour générer des chaînes d'affichage.
Si vous vous sentez aventureux, utilisez Joda-Time, bien que ce soit un IMHO inutilement compliqué et qu'il sera bientôt remplacé par l'API de date JSR-310.
J'ai déjà répondu qu'il n'était pas difficile de créer sa propre classe YearMonthDay
, qui utilise Calendar
sous le capot pour les calculs de date. La suggestion m'a été refusée, mais je crois toujours que c'est une solution valable car Joda-Time (et JSR-310 ) est vraiment trop compliqué pour la plupart des cas d'utilisation.
La date est préférable pour stocker un objet de date. C'est le persisté, le Serialized ...
Le calendrier est le meilleur pour manipuler les dates.
Remarque: nous préférons également parfois Java.lang.Long par rapport à Date, car Date est modifiable et n'est donc pas thread-safe. Sur un objet Date, utilisez setTime () et getTime () pour basculer entre les deux. Par exemple, une constante Date dans l'application (exemples: zéro 1970/01/01 ou une application END_OF_TIME que vous avez définie sur 2099/12/31; elles sont très utiles pour remplacer les valeurs nulles comme heure de début et heure de fin, notamment lorsque vous les persistez dans la base de données, SQL est si particulier avec des valeurs nulles).
J'utilise généralement Date si possible. Bien qu'il soit modifiable, les mutateurs sont en réalité déconseillés. En fin de compte, cela englobe essentiellement un long qui représenterait la date/heure. Inversement, j'utiliserais des calendriers si je devais manipuler les valeurs.
Vous pouvez penser de cette façon: vous n'utilisez StringBuffer que lorsque vous avez besoin de chaînes que vous pouvez facilement manipuler, puis vous les convertissez en chaînes à l'aide de 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 domain. Cela réduit considérablement les risques d'effets secondaires et le compilateur le fait pour vous plutôt que par un test JUnit. Vous utilisez cette technique en créant private final dans votre classe.
Et revenons à l'analogie StringBuffer. Voici un code qui vous montre comment convertir en calendrier et date
String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String
// immutable date with hard coded format. If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");
// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// mutate the value
cal.add(Calendar.YEAR, 1);
// convert back to Date
Date newDate = cal.getTime();
//
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);
Date
s devrait être utilisé comme des instants immuables dans le temps; Calendar
s sont mutables, et peuvent être échangés et modifiés si vous avez besoin de collaborer avec d'autres classes pour arriver à une date finale. Considérez-les comme analogues à String
et StringBuilder
et vous comprendrez comment, à mon avis, ils devraient être utilisés.
(Et oui, je sais que Date n’est pas techniquement immuable, mais l’intention est qu’elle ne soit pas modifiable, et si rien n’appelle les méthodes déconseillées, il en est ainsi.)
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 objet ZonedDateTime
à partir d'un ancien Java.util.Date
objet comme ceci:
Date date = new Date();
ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
Je préconise toujours Joda-time . Voici pourquoi.
EDIT: les classes de date/heure Java introduites avec Java 8 constituent désormais la solution privilégiée, si vous pouvez migrer vers Java 8.
Un peu tard à la fête, mais Java a une nouvelle API Date Time dans JDK 8. Vous voudrez peut-être mettre à niveau votre version de JDK et adopter le standard. Plus de date/calendrier en désordre, plus de pots de tiers.
Date devrait être re-développé. Au lieu d'être long, il devrait contenir l'année, le mois, la date, l'heure, les minutes et les secondes dans des champs distincts. Il peut même être utile de stocker le calendrier et le fuseau horaire associés à cette date.
Dans notre conversation naturelle, si vous définissez un rendez-vous le 1er novembre 2013 à 13h00 (heure de New York), il s'agit d'un DateTime. Ce n'est pas un calendrier. Nous devrions donc pouvoir converser comme cela en Java également.
Lorsque Date est stocké sous forme d’entier long (en millièmes de seconde depuis le 1er janvier 1970 ou quelque chose du genre), le calcul de sa date actuelle dépend du calendrier. Des calendriers différents 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 existe de nouvelles avancées en Java pour concilier ces 2 objectifs. Peut-être que ma connaissance de Java est trop ancienne.
J'utilise Calendar lorsque j'ai besoin d'opérations spécifiques sur des dates telles que le déplacement dans le temps, mais Date me semble utile lorsque vous devez formater la date pour adapter vos besoins. Récemment, j'ai découvert que Locale comportait de nombreuses opérations et méthodes utiles. J'utilise Locale en ce moment!
Btw "date" est généralement étiqueté comme "obsolète/obsolète" (je ne sais pas exactement pourquoi) - quelque chose à ce sujet y est écrit Java: Pourquoi le constructeur Date est-il déconseillé et que dois-je utiliser à la place?
Il semble que le problème concerne uniquement le constructeur via nouvelle date (int année, int mois, jour int)} [, la méthode recommandée consiste à utiliser Agenda et à définir les paramètres séparément .. (Calendar cal = Calendar.getInstance (); )