Calendar rightNow = Calendar.getInstance();
String month = String.valueOf(rightNow.get(Calendar.MONTH));
Après l'exécution de l'extrait ci-dessus, le mois obtient une valeur de 10 au lieu de 11. Comment se fait-il?
Les mois sont indexés de 0 à 1, donc 10 correspond à novembre et 11 à décembre.
Ils commencent à partir de 0 - vérifiez les documents
Comme en témoignent les nombreuses réponses: le mois commence par 0.
Voici un conseil: vous devriez utiliser SimpleDateFormat pour obtenir la représentation String du mois:
Calendar rightNow = Calendar.getInstance();
Java.text.SimpleDateFormat df1 = new Java.text.SimpleDateFormat("MM");
Java.text.SimpleDateFormat df2 = new Java.text.SimpleDateFormat("MMM");
Java.text.SimpleDateFormat df3 = new Java.text.SimpleDateFormat("MMMM");
System.out.println(df1.format(rightNow.getTime()));
System.out.println(df2.format(rightNow.getTime()));
System.out.println(df3.format(rightNow.getTime()));
Sortie:
11
Nov
November
Remarque: la sortie peut varier, elle est spécifique aux paramètres régionaux.
Comme plusieurs personnes l'ont souligné, les mois retournés par les classes Calendar et Date dans Java sont indexés de 0 au lieu de 1. Donc 0 est janvier et le mois en cours, novembre, est 10.
Vous vous demandez peut-être pourquoi c'est le cas. Les origines résident dans les fonctions standard POSIX ctime
, gmtime
et localtime
, qui acceptent ou renvoient un time_t
structure avec les champs suivants (from man 3 ctime ):
int tm_mday; /* day of month (1 - 31) */
int tm_mon; /* month of year (0 - 11) */
int tm_year; /* year - 1900 */
Cette API a été copiée à peu près exactement dans la classe Java Date dans Java 1.0, et à partir de là, presque intacte dans la classe Calendar dans Java 1.1. Sun a résolu le problème le plus flagrant lors de l'introduction de Calendar - le fait que l'année 2001 dans le calendrier grégorien était représentée par la valeur 101 dans leur classe Date. Mais je ne sais pas pourquoi ils n'ont pas changé les valeurs du jour et du mois pour au moins les deux soient cohérentes dans leur indexation, à partir de zéro ou de 1. Cette incohérence et la confusion associée existent toujours dans Java (et C) à ce jour.
Les mois commencent à zéro, comme les index des listes.
Par conséquent, Jan = 0, Feb = 1, etc.
Depuis l'API:
Le premier mois de l'année est JANVIER qui est 0; le dernier dépend du nombre de mois dans une année.
http://Java.Sun.com/j2se/1.5.0/docs/api/Java/util/Calendar.html
LocalDate.now() // Returns a date-only `LocalDate` object for the current month of the JVM’s current default time zone.
.getMonthValue() // Returns 1-12 for January-December.
Les autres réponses sont correctes mais obsolètes.
Les anciennes classes de date et heure gênantes présentaient de nombreux choix de conception et défauts. L'un était le comptage à base zéro des numéros de mois 0-11 plutôt que le 1-12 évident.
Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes de date-heure gênantes telles que Java.util.Date
, .Calendar
, & Java.text.SimpleDateFormat
.
Désormais en mode maintenance , le projet Joda-Time conseille également la migration vers Java.time.
Pour en savoir plus, consultez le Oracle Tutorial . Et recherchez Stack Overflow pour de nombreux exemples et explications.
Une grande partie de la fonctionnalité Java.time est back-portée vers Java 6 & 7 in ThreeTen-Backport et plus adaptée à Android dans ThreeTenABP .
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.
Dans Java.time, le numéro du mois est en effet le 1-12 attendu pour janvier-décembre.
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 par zone. Par exemple, quelques minutes après minuit à Paris France est un nouveau jour alors qu'encore "hier" à Montréal Québec .
Spécifiez un nom de fuseau horaire correct au format continent/region
, tel que America/Montreal
, Africa/Casablanca
ou Pacific/Auckland
. N'utilisez jamais l'abréviation de 3-4 lettres telle que EST
ou IST
car ils sont pas vrais fuseaux horaires, non standardisés, ni même uniques (!) .
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
int month = today.getMonthValue(); // Returns 1-12 as values.
Si vous voulez une date-heure pour un fuseau horaire, utilisez l'objet ZonedDateTime
de la même manière.
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
int month = now.getMonthValue(); // Returns 1-12 as values.
Si vous avez un objet GregorianCalendar
en main, convertissez-le en ZonedDateTime
en utilisant la nouvelle méthode toZonedDateTime
ajoutée à l'ancienne classe . Pour plus d'informations sur la conversion, voir Convertir Java.util.Date en quel type "Java.time"?
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();
int month = zdt.getMonthValue(); // Returns 1-12 as values.
Month
enumLes classes Java.time incluent la pratique Month
enum , soit dit en passant. Utilisez des instances de cette classe dans votre code plutôt que de simples entiers pour rendre votre code plus auto-documenté, fournissez type-safety et garantissez des valeurs valides.
Month month = today.getMonth(); // Returns an instant of `Month` rather than integer.
L'énumération Month
propose des méthodes utiles telles que la génération d'une chaîne avec le nom localisé du mois .
Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes --- héritées date-heure telles que - Java.util.Date
, Calendar
, & SimpleDateFormat
.
Le projet Joda-Time , maintenant en 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 31 .
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 pouvez trouver ici des classes utiles telles que Interval
, YearWeek
, YearQuarter
, et plus .
cal.get(Calendar.MONTH) + 1;
La déclaration ci-dessus donne le numéro exact du mois. Comme get(Calendar.Month)
renvoie le mois à partir de 0, l'ajout de 1 au résultat donnerait la sortie correcte. Et n'oubliez pas de soustraire 1 lors du réglage du mois.
cal.set(Calendar.MONTH, (8 - 1));
Ou utilisez les variables constantes fournies.
cal.set(Calendar.MONTH, Calendar.AUGUST);
Il vaudrait mieux utiliser
Calendar.JANUARY
ce qui est nul ...