Java: pourquoi le constructeur de Date est-il déprécié, et qu'est-ce que j'utilise à la place?

je viens du monde C#, donc pas trop expérimenté avec Java encore. On vient de dire par Eclipse que le Date a été déprécié.

Person p = new Person();
p.setDateOfBirth(new Date(1985, 1, 1));

pourquoi? Et qu'est-ce (en particulier dans les cas comme ci-dessus) devrait être utilisé à la place?

171
demandé sur Raedwald 2011-04-15 17:25:15

11 réponses

le constructeur de Date spécifique est déprécié, et un calendrier devrait être utilisé à la place. Le JavaDoc pour Date décrit quels constructeurs sont dépréciés et comment les remplacer en utilisant un calendrier.

88
répondu Ruben 2011-04-15 13:27:38

la classe java.util.Date n'est pas réellement dépréciée, juste ce constructeur, ainsi que quelques autres constructeurs/méthodes sont dépréciés. Il a été déprécié parce que ce genre d'usage ne fonctionne pas bien avec l'internationalisation. La classe Calendar doit être utilisée à la place:

Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1988);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date dateRepresentation = cal.getTime();

regardez la date Javadoc:

http://download.oracle.com/javase/6/docs/api/java/util/Date.html

208
répondu BuffaloBuffalo 2014-12-15 12:41:53

tl; dr

LocalDate.of( 1985 , 1 , 1 )

... ou ...

LocalDate.of( 1985 , Month.JANUARY , 1 )

détails

les classes java.util.Date , java.util.Calendar , et java.text.SimpleDateFormat ont été précipitées trop rapidement lorsque Java a été lancé et évolué. Les cours n'ont pas été bien conçus ou mis en œuvre. Des améliorations ont été tentées, donc les dépréciations que vous avez trouvées. Malheureusement, les tentatives d'amélioration ont largement échoué. Vous devez éviter ces classes en tout. Ils sont remplacés en Java 8 par de nouvelles classes.

Problèmes Dans Votre Code

Une java.util.La Date comporte à la fois une date et une heure. Vous avez ignoré la partie du temps dans votre code. Ainsi, la classe Date prendra le début de la journée tel que défini par le fuseau horaire par défaut de votre JVM et appliquera cette heure à l'objet Date. Ainsi, les résultats de votre code varieront en fonction de la machine qu'il exécute ou du fuseau horaire qui est défini. Probablement pas ce que vous voulez.

si vous voulez juste la date, sans la portion de temps, comme pour une date de naissance, vous pouvez ne pas vouloir utiliser un objet Date . Vous pouvez vouloir stocker juste une chaîne de la date, dans ISO 8601 format de YYYY-MM-DD . Ou utilisez un objet LocalDate de Joda-Time (voir ci-dessous).

Joda-Time

première chose à apprendre en Java: éviter la notoirement gênants java.util.Date & java.util.Classes de calendrier avec Java.

comme correctement noté dans la réponse de l'utilisateur 3277382 , utiliser soit Joda-Time ou le nouveau java.temps.* paquet en Java 8.

exemple de Code dans Joda-Time 2.3

DateTimeZone timeZoneNorway = DateTimeZone.forID( "Europe/Oslo" );
DateTime birthDateTime_InNorway = new DateTime( 1985, 1, 1, 3, 2, 1, timeZoneNorway );

DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime birthDateTime_InNewYork = birthDateTime_InNorway.toDateTime( timeZoneNewYork ); 

DateTime birthDateTime_UtcGmt = birthDateTime_InNorway.toDateTime( DateTimeZone.UTC );

LocalDate birthDate = new LocalDate( 1985, 1, 1 );

Vidage de la console...

System.out.println( "birthDateTime_InNorway: " + birthDateTime_InNorway );
System.out.println( "birthDateTime_InNewYork: " + birthDateTime_InNewYork );
System.out.println( "birthDateTime_UtcGmt: " + birthDateTime_UtcGmt );
System.out.println( "birthDate: " + birthDate );

quand cours ...

birthDateTime_InNorway: 1985-01-01T03:02:01.000+01:00
birthDateTime_InNewYork: 1984-12-31T21:02:01.000-05:00
birthDateTime_UtcGmt: 1985-01-01T02:02:01.000Z
birthDate: 1985-01-01

de java.heure

dans ce cas le code pour java.le temps est presque identique à celui du Joda-Time .

nous avons un fuseau horaire( ZoneId ), et construire un objet date-heure assigné à ce fuseau horaire( ZonedDateTime ). Ensuite, en utilisant le immuable Objects motif, nous créez de nouvelles dates-heures basées sur le même instant de l'ancien objet (compte de nanosecondes depuis epoch ) mais assignez un autre fuseau horaire. Enfin, nous obtenons un LocalDate qui n'a ni heure ni fuseau horaire, bien que le fuseau horaire s'applique lors de la détermination de cette date (un nouveau jour apparaît plus tôt dans Oslo que dans New York par exemple).

ZoneId zoneId_Norway = ZoneId.of( "Europe/Oslo" );
ZonedDateTime zdt_Norway = ZonedDateTime.of( 1985 , 1 , 1 , 3 , 2 , 1 , 0 , zoneId_Norway );

ZoneId zoneId_NewYork = ZonedId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt_Norway.withZoneSameInstant( zoneId_NewYork );

ZonedDateTime zdt_Utc = zdt_Norway.withZoneSameInstant( ZoneOffset.UTC );  // Or, next line is similar.
Instant instant = zdt_Norway.toInstant();  // Instant is always in UTC.

LocalDate localDate_Norway = zdt_Norway.toLocalDate();

à propos de java.heure

Le de java.time framework est construit dans Java 8 et plus tard. Ces classes remplacent les anciennes héritées classes de date-heure telles que java.util.Date , Calendar , & SimpleDateFormat .

Le Joda-Time project, maintenant en mode maintenance , conseille la migration vers le java.temps classes.

pour en savoir plus, voir le Oracle Tutorial . Et rechercher le débordement de la pile pour de nombreux exemples et explications. La spécification est JSR 310 .

vous pouvez échanger java.temps les objets directement avec votre base de données. Utiliser un JDBC driver conforme à JDBC 4.2 ou plus tard. Pas besoin de Chaînes, pas besoin de classes java.sql.* .

où obtenir le java.les classes de temps?

Le ThreeTen-Extra le projet s'étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'expérimentation pour d'éventuelles futures additions à java.temps. Vous pouvez trouvez ici quelques classes utiles telles que: Interval , YearWeek , YearQuarter , et plus .

55
répondu Basil Bourque 2018-04-28 06:27:21

je suis tombé sur cette question comme un duplicata de une nouvelle question qui a demandé ce que la façon non-dépréciée d'obtenir un Date à une année, mois, et jour était.

les réponses ici jusqu'à présent disent d'utiliser la classe Calendar , et c'était vrai jusqu'à ce que Java 8 soit sorti. Mais à partir de Java 8, la manière standard de faire ceci est:

LocalDate localDate = LocalDate.of(1985, 1, 1);

et puis si vous avez vraiment besoin d'un java.util.Date , vous pouvez utiliser le suggestions dans cette question .

pour plus d'informations, consultez L'API ou les tutoriels pour Java 8.

10
répondu Kevin Workman 2017-10-18 16:25:07

une des raisons pour lesquelles le constructeur est déprécié est que la signification du paramètre année n'est pas ce que vous attendez. Le javadoc dit:

dans la version 1.1 de JDK, remplacé par Calendar.set(year + 1900, month, date) .

notez que le champ de l'année est le nombre d'années depuis 1900 , donc votre code d'échantillon ne fera probablement pas ce que vous attendez qu'il fasse. Et c'est le point.

en général, le Date API supporte uniquement le calendrier occidental moderne, a des composants spécifiés idiosyncratiquement, et se comporte de manière incohérente si vous définissez des champs.

les API Calendar et GregorianCalendar sont meilleures que Date , et les API tiers Joda-time étaient généralement considérées comme les meilleures. En Java 8, Ils ont introduit les paquets java.time , et ceux-ci sont maintenant l'alternative recommandée.

8
répondu Stephen C 2017-03-01 22:41:52

veuillez noter que Calendar.getTime() est non déterministe dans le sens que la heure du jour partie par défaut à l'heure actuelle.

pour reproduire, essayez d'exécuter le code suivant plusieurs fois:

Calendar c = Calendar.getInstance();
c.set(2010, 2, 7); // NB: 2 means March, not February!
System.err.println(c.getTime());

sortie eg.:

Sun Mar 07 10:46:21 CET 2010

exécutant exactement le même code quelques minutes plus tard donne:

Sun Mar 07 10:57:51 CET 2010

ainsi, tandis que set() forces correspondant aux valeurs correctes, il fuit le temps du système pour les autres champs. (Testé ci-dessus avec Sun jdk6 & jdk7)

7
répondu Tijn Porcelijn 2014-11-14 21:02:01

Date lui-même n'est pas déprécié. C'est juste beaucoup de ses méthodes. voir ici pour plus de détails .

utiliser java.util.Calendar à la place.

6
répondu Mike Thomsen 2012-05-09 10:40:15

la plupart des développeurs Java utilisent actuellement le paquet tiers Joda-Time . Il est largement considéré comme une bien meilleure mise en œuvre.

Java 8 cependant aura un nouveau java.temps.* paquet . Voir cet article, introduisant la nouvelle API Date et heure pour JDK 8 .

4
répondu davesbrain 2014-02-06 08:45:36

similaire à ce que binnyb a suggéré, vous pourriez envisager d'utiliser le calendrier plus récent > méthode GregorianCalendar. Voir ces documents plus récents:

http://download.oracle.com/javase/6/docs/api/java/util/GregorianCalendar.html

1
répondu Joshua 2011-04-15 13:30:13

vous pouvez faire une méthode comme new Date(year,month,date) dans votre code en utilisant la classe Calendar .

private Date getDate(int year,int month,int date){
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month-1);
    cal.set(Calendar.DAY_OF_MONTH, day);
    return cal.getTime();
}

il fonctionnera tout comme le constructeur déprécié de Date

0
répondu Sudhanshu Dubey 2018-07-11 07:36:24
new GregorianCalendar(1985, Calendar.JANUARY, 1).getTime();

(le pré-Java-8)

0
répondu Curtis Yallop 2018-10-05 20:12:36