Calendar rightNow = Calendar.getInstance();
String month = String.valueOf(rightNow.get(Calendar.MONTH));
上記のスニペットの実行後、月の値は11ではなく10になります。どうしてですか?
月は1ではなく0からインデックス化されるため、10は11月、11は12月になります。
彼らは0から始まります-チェック ドキュメント
多くの答えから明らかなように、月は0で始まります。
ヒントを次に示します。SimpleDateFormatを使用して、月の文字列表現を取得する必要があります。
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()));
出力:
11
Nov
November
注:出力は異なる場合があり、ロケール固有です。
数人が指摘したように、Javaの- Calendar および Date クラスによって返される月は、1ではなく0からインデックス付けされます。したがって、0は1月、そして今月の11月は10です。
なぜそうなのか疑問に思うかもしれません。起源は、POSIX標準関数ctime
、gmtime
、およびlocaltime
にあります。これらは、次のフィールドを持つtime_t
構造体を受け入れるか、返します(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 */
このAPIは、Java 1.0のJava Dateクラスにほぼ正確にコピーされ、そこからJava 1.1のCalendarクラスにほぼそのままコピーされました。 Sunは、Calendarを導入したときに最も目立った問題を修正しました。これは、グレゴリオ暦の2001年がDateクラスの値101で表されていたという事実です。しかし、日と月の値を少なくとも0から1のいずれかでインデックス付けの一貫性を保つように変更しなかった理由はわかりません。この矛盾と関連する混乱は、今日までJava(およびC)に残っています。
リストのインデックスのように、月はゼロから始まります。
したがって、1月= 0、2月= 1などです。
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.
他の答えは正しいですが、時代遅れです。
面倒な古い日時クラスには、多くの貧弱な設計選択と欠陥がありました。 1つは、明らかな1〜12ではなく、0〜11の月番号のカウントです。
Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、Java.util.Date
、.Calendar
、Java.text.SimpleDateFormat
などの古い厄介な日時クラスに取って代わります。
メンテナンスモード で、 Joda-Time プロジェクトもJava.timeへの移行を推奨しています。
詳細については、 Oracleチュートリアル を参照してください。また、Stack Overflowで多くの例と説明を検索してください。
Java.time機能の多くは、 ThreeTen-Backport のJava 6および7にバックポートされ、 ThreeTenABP のAndroidにさらに適合します。
ThreeTen-Extra プロジェクトは、クラスを追加してJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。
Java.timeでは、月の数は実際には1月から12月に予想される1〜12です。
LocalDate
クラスは、時刻とタイムゾーンのない日付のみの値を表します。
タイムゾーンは、日付を決定する際に重要です。どのような場合でも、日付はゾーンごとに世界中で異なります。たとえば、 Paris France の真夜中から数分後の新しい日は、 MontréalQuébec の「昨日」のままです。
continent/region
、 America/Montreal
、またはAfrica/Casablanca
など、 適切なタイムゾーン名 をPacific/Auckland
の形式で指定します。 EST
やIST
などの3〜4文字の略語をnotとして使用しないでください。真のタイムゾーンであり、標準化されておらず、一意(!)でもありません。
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
int month = today.getMonthValue(); // Returns 1-12 as values.
タイムゾーンの日付時刻が必要な場合は、ZonedDateTime
オブジェクトを同じ方法で使用します。
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
int month = now.getMonthValue(); // Returns 1-12 as values.
GregorianCalendar
オブジェクトを手に持っている場合、古いクラスに追加された新しい ZonedDateTime
メソッドを使用してtoZonedDateTime
に変換します。変換情報の詳細については、 Java.util.Dateを「Java.time」型に変換しますか? を参照してください。
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();
int month = zdt.getMonthValue(); // Returns 1-12 as values.
Month
enumちなみに、Java.timeクラスには便利な Month
enum が含まれています。単なる整数ではなくコードでこのクラスのインスタンスを使用して、コードをより自己文書化し、 type-safety を提供し、有効な値を確保します。
Month month = today.getMonth(); // Returns an instant of `Month` rather than integer.
Month
enumは、月のローカライズ名 を使用してStringを生成するなどの便利なメソッドを提供します 。
Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、 Java.util.Date
、 Calendar
、および SimpleDateFormat
などの厄介な古い legacy 日時クラスに取って代わります。
Joda-Time プロジェクトは、現在 メンテナンスモード であり、 Java.time クラスへの移行を推奨しています。
詳細については、 Oracleチュートリアル を参照してください。また、Stack Overflowで多くの例と説明を検索してください。仕様は JSR 31 です。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。 Interval
、 YearWeek
、 YearQuarter
、 more などの便利なクラスがあります。
_cal.get(Calendar.MONTH) + 1;
_
上記のステートメントは、月の正確な数を示します。 get(Calendar.Month)
は0から始まる月を返すため、結果に1を追加すると正しい出力が得られます。また、月を設定するときは1を引くことに注意してください。
_cal.set(Calendar.MONTH, (8 - 1));
_
または、提供されている定数変数を使用します。
_cal.set(Calendar.MONTH, Calendar.AUGUST);
_
使用する方が良いでしょう
Calendar.JANUARY
これはゼロです...