web-dev-qa-db-fra.com

Quelle est la différence entre l'ajout de DAY_OF_MONTH ou de DAY_OF_YEAR à un objet Calendar?

Je veux augmenter une date donnée d'un jour. Je crée un objet Calendar comme:

Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2012);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 31);

Ensuite, pour l’augmenter d’un jour, je peux faire deux choses:

cal.add(Calendar.DAY_OF_MONTH, 1);

OR

cal.add(Calendar.DAY_OF_YEAR, 1);

Il existe également d'autres constantes "JOUR", mais j'obtiens le même résultat en utilisant les deux méthodes ci-dessus pour augmenter le jour de 1. Dans quel cas obtiendrai-je des résultats différents pour les deux?

39
Daud

Pour l'ajouter ne fait vraiment aucune différence, mais cela

Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_YEAR));

empreintes

28
363
40
Evgeniy Dorofeev

Calendar.add Ajoute ou soustrait la durée spécifiée au champ de calendrier donné, en fonction des règles de ce dernier.

Ici vous avez une liste des champs de Calendrier que vous pouvez ajouter ou soustraire:

  • MILLISECOND est le nombre de millisecondes compris entre 0 et 999

  • SECOND est le nombre de secondes entre 0 et 59

  • MINUTE est le nombre de minutes entre 0 et 59

  • HOUR est le nombre d'heures entre 0 et 11

  • HOUR_OF_DAY est le nombre d'heures entre 0 et 23

  • DAY_OF_WEEK est le jour par rapport à la semaine entre 1 et 7

  • DAY_OF_MONTH est le jour par rapport au mois compris entre 1 et 31

  • DAY_OF_YEAR est le jour par rapport à l'année entre 1 et 365

  • WEEK_OF_MONTH est la semaine par rapport au mois à partir du 1

  • WEEK_OF_YEAR est la semaine par rapport à l'année à partir du 1

  • MONTH est le mois par rapport à l'année entre 0 et 11

  • YEAR est le nombre d'années à partir de 1

Les heures, les jours et les semaines ont plusieurs champs mais peu importe celui que vous choisissez1. Par exemple, utiliser -8 pour DAY_OF_WEEK fonctionnera.

calendar.add(Calendar.DAY_OF_MONTH, -2); // subtract 2 days
calendar.add(Calendar.DAY_OF_WEEK, -2);  // subtract 2 days
calendar.add(Calendar.DAY_OF_YEAR, -2);  // subtract 2 days

calendar.add(Calendar.YEAR, -2);         // subtract 2 year

1Peu importe seulement en utilisant Calendar.add, avec d'autres opérations, les résultats pourraient être différents.

12
Paolo Forgia

Utilisez Calendar.DATE pour vos besoins. Dans votre cas, ces trois constantes sont synonymes. 

8
Timofei

Cela ne fait aucune différence lorsque vous appelez add. Cependant les getters donnent des résultats différents: D

extrait de code de GregorianCalendar#add

case DAY_OF_MONTH: // synonym of DATE
 case DAY_OF_YEAR:
 case DAY_OF_WEEK:
    break;
7
Rahul
DAY_OF_YEAR

Numéro de champ pour get et set indiquant le numéro du jour dans l'année en cours

DAY_OF_MONTH

Numéro de champ pour get et set indiquant le jour du mois . Ceci est un synonyme pour DATE

Vous verrez la différence si le jour est supérieur à 31.

5
kosa

Vous avancez essentiellement la date de un, dans les deux cas. Donc, il n'y a pas de différence dans les deux approches.

Mais s'en tenir à une seule méthode restera cohérent sur l'ensemble de votre base de code, les responsables se sentiront comme à la maison et probablement le runtime optimisera l'appel de la méthode en le compilant également.

2

En fait, il peut y avoir une différence selon le type de champ que vous choisissez:

* http://docs.Oracle.com/javase/1.5.0/docs/api/Java/util/Calendar.html

Modèle d'utilisation. 

Pour motiver le comportement de add () et roll (), considérons un composant d'interface utilisateur avec boutons d'incrémentation et de décrémentation pour le mois, jour et année, et un calendrier grégorien sous-jacent. Si la L’interface se lit le 31 janvier 1999 et l’utilisateur appuie sur le mois bouton incrément, que doit-il lire? Si le sous-jacent implementation utilise set (), cela pourrait se lire le 3 mars 1999. Un meilleur le résultat serait le 28 février 1999. En outre, si l'utilisateur appuie sur le bouton d’incrément de mois à nouveau, il devrait se lire le 31 mars 1999, pas 28 mars 1999. En enregistrant la date d'origine et en utilisant add () ou roll (), selon que les champs plus grands doivent être affectés ou non. l'interface utilisateur peut se comporter comme la plupart des utilisateurs s'y attendent intuitivement.

1
paulsm4

tl; dr

LocalDate.of( 2012 , Month.JANUARY , 31 )
    .plusDays( 1 )

2012-02-01

…ou…

LocalDate.of( 2012 , 1 , 31 )  // Sane numbering: 1-12 for January-December, and `2012` means year 2012.
    .plusDays( 1 )

2012-02-01

Java.time

La classe Calendar est déroutante, délicate et mal conçue. Parmi ses nombreux problèmes, citons ces méthodes de pass-the-units-flag. Heureusement, vous pouvez maintenant tout oublier de cette classe. 

Les classes Java.time intégrées à Java 8 et versions ultérieures supplantent maintenant les classes héritées date-heure.

LocalDate

La classe LocalDate représente une valeur de date uniquement sans heure et sans fuseau horaire.

Un fuseau horaire est crucial pour déterminer une date. Pour un moment donné, la date varie dans le monde entier par zone. Par exemple, quelques minutes après minuit dans Paris France est un nouveau jour alors qu’il est encore «hier» dans Montréal Québec .

Si aucun fuseau horaire n'est spécifié, la machine virtuelle Java applique implicitement son fuseau horaire par défaut actuel. Ce défaut peut changer à tout moment, vos résultats peuvent donc varier. Il est préférable de spécifier explicitement votre fuseau horaire souhaité/attendu en tant qu'argument.

Spécifiez un nom du fuseau horaire } au format continent/region, tel que America/Montreal , Africa/Casablanca ou Pacific/Auckland. N'utilisez jamais les abréviations de 3-4 lettres telles que EST ou IST car elles sont pas des fuseaux horaires véritables, non standardisés et même pas uniques (!). 

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Si vous souhaitez utiliser le fuseau horaire actuel par défaut de la JVM, demandez-le et transmettez-le en tant qu’argument. Si cette option est omise, la valeur par défaut actuelle de la machine virtuelle Java est appliquée implicitement. Mieux vaut être explicite, car la valeur par défaut peut être changée à tout moment pendant l'exécution par n'importe quel code de n'importe quel fil de n'importe quelle application de la JVM.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Ou spécifiez une date. Vous pouvez régler le mois par un numéro, avec un numéro de 1 à 12 pour janvier à décembre. 

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Ou mieux, utilisez les objets Month enum prédéfinis, un pour chaque mois de l'année. Conseil: Utilisez ces objets Month dans votre base de code plutôt qu'un simple nombre entier pour que votre code s'auto-documente davantage, garantisse des valeurs valides et fournit type-safety .

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

Les pièces

Avec une LocalDate en main, vous pouvez interroger pour ses parties.

Pour obtenir le jour du mois, c'est-à-dire la "date" telle que 23 à partir du 23 janvier 2018:

int dayOfMonth = ld.getDayOfMonth() ; // 1-31, depending on length of month.

Pour obtenir le nième jour de l'année, de 1 à 365, ou dans une année bissextile, de 1 à 366:

int dayOfYear = ld.getDayOfYear() ;

Math

Ajouter ou soustraire des jours est assez simple et intuitif en Java.time. Les méthodes de commodité et les objets de durée rendent le code beaucoup plus clair.

LocalDate dayLater = ld.plusDays( 1 ) ;

Donc, être demain serait:

LocalDate tomorrow = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ).plusDays( 1 ) ;

Sinon, vous pouvez représenter une plage de temps non attachée à la chronologie. Pendant des années, des mois, des jours, utilisez Period. Pendant heures-minutes-secondes, utilisez Duration.

Period p = Period.ofDays( 1 ) ;
LocalDate dayLater = ld.plus( p ) ;

Notez que Java.time utilise la numérotation sane, contrairement aux classes héritées. Le numéro 2018 est l'année 2018. Les mois sont numérotés de 1 à 12 pour les mois de janvier à décembre. Les jours de la semaine sont numérotés de 1 à 7 pour les lundi à dimanche, selon la norme ISO 8601 .


À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes gênantes héritées _ date-heure telles que Java.util.Date , Calendar _, & SimpleDateFormat .

Le projet Joda-Time , désormais en mode { mode maintenance }, conseille la migration vers les classes Java.time .

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

Où obtenir les classes Java.time? 

  • Java SE 8 , Java SE 9 et versions ultérieures
    • Intégré. 
    • Une partie de l'API Java standard avec une implémentation fournie.
    • Java 9 ajoute quelques fonctionnalités et corrections mineures.
  • Java SE 6 et Java SE 7
    • Une grande partie de la fonctionnalité Java.time est rétroportée vers Java 6 et 7 dans ThreeTen-Backport .
  • Android
    • Les versions ultérieures d'Android regroupent des implémentations des classes Java.time.
    • Pour les versions antérieures d'Android, le projet ThreeTenABP s'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 d'éventuels ajouts à Java.time. Vous pouvez y trouver des classes utiles telles que Interval _, YearWeek , YearQuarter _ et plus _.

1
Basil Bourque

En plus de la date, peu importe que vous utilisiez DAY_OF_MONTH ou DAY_OF_YEAR. Cependant, il est logique que vous obteniez un appelant et que vous en passiez un. 

0
Rais Alam

Use DATE ou DAY_OF_MONTH sont identiques

Voici la différence: 

DATE or DAY_OF_MONTH : Get and Set indicating the day of the month
DAY_OF_WEEK          : get and set indicating the week number within the current month
DAY_OF_YEAR          : get and set indicating the day number within the current ye

Source: https://docs.Oracle.com/javase/7/docs/api/Java/util/Calendar.html

0
Ashraful Islam