Java:日付から月の整数を取得する


157

Dateオブジェクト(java.util.Date)から整数として月を取得するにはどうすればよいですか?


23
実際には、DateのgetMonth()は永久に廃止されます;)
Mateusz Dymczyk

6
@slhck:非推奨。JDKバージョン1.1以降は、Calendar.get(Calendar.MONTH)に置き換えられました。
adarshr 2011

3
@Zenzenほとんど非推奨のクラスで非推奨のメソッドを使用する際の問題はありません。
瀬良部

1
@Muhd日付を操作している場合は、自力でjodaまたは他のライブラリを使用してください。
瀬良部

1
@Serabe:問題は、より良い解決策があることです(少なくとも非推奨ではない解決策)。また、getMonthは14年ほど前から非推奨になっており、理由により非推奨になっています。
Mateusz Dymczyk 2011

回答:


57

java.time(Java 8)

また、使用することができますjava.timeパッケージを Javaの8にして、変換java.util.Dateにオブジェクトをjava.time.LocalDateオブジェクトとそしてちょうど使用getMonthValue()方法を。

Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int month = localDate.getMonthValue();

ここで、月の値は、1から12までの範囲で与えられます cal.get(Calendar.MONTH)、0から11の値を与えるadarshrの回答とは、。

しかし、Basil Bourqueがコメントで言ったように、推奨される方法はMonthLocalDate::getMonthメソッドでenumオブジェクトを取得することです。


1
いい答えだ。読者への注意:回答に示されているデフォルトの呼び出しに依存するのではなく、タイムゾーンを指定したい場合があります。たとえば、パリではモントリオールよりも早い新しい日(および月)が始まります。あなたは、モントリオール、使用について特に気にしている場合ZoneId.of( "America/Montreal" )
バジルブルク2015年

1
java.time api の導入についての素晴らしい記事があることを追加したいだけです。oracle.com

ちなみに、読者への別の注記:単なる整数ではなくMonth列挙オブジェクトを取得することもできます。メソッドをMonth m = localDate.gotMonth();参照してくださいLocalDate::getMonth。このようなオブジェクトを使用すると、コードが自己文書化され、型の安全性が保証され、有効な値が保証されます。OracleによるEnumチュートリアルを参照してください。
バジルブルク2016

1
を使用date.toInstant()していて、たまたまjava.sql.Date(の子java.util.Date)を操作している場合は、を取得しUnsupportedOperationExceptionます。試してみるnew java.sql.Date(src.getTime()).toLocalDate()
アダム

1
@Adam java.sql.Dateその古いクラスに追加された新しい変換メソッドを使用することで、変換がはるかに簡単になります。java.sql.Date.valueOf( myLocalDate )そしてmyJavaSqlDate.toLocalDate() また、JDBCドライバは、JDBC 4.2以降不要になったのに更新java.sqlを直接アドレスすることができますタイプ、およびjava.time経由種類をResultSet::getObjectし、PreparedStatement::setObject方法。
バジルブルク2017年

287
java.util.Date date= new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int month = cal.get(Calendar.MONTH);

166
Calendar.MONTH明らかな理由がないことに注意してください。ゼロベース、つまり、January == 0。これでAPIで問題なく文書化されましたが、それでも初めてのユーザーにとっては地獄と混同しています。:多分時間を新しいSOの質問自分のために(/私は恐れているがそれにすべての偉大な背景が存在しない) -私は、彼らはそれと一緒に行った理由を教えてもらえ誰も見つけることがまだまし
VOO

5
@Voo Date.getMonth()メソッドはゼロベースでした。これが、おそらくCalendar.MONTHも主な理由です。
Muhd、2011

1
@Muhd確かに、それは取り替えでした。しかし、それだけで質問は、Date.getMonth()がゼロベースであった理由に移動しますか?特に日が1日から始まるので、恐ろしいデザインがイモです(少なくとも一貫している可能性があります!)。そもそも、特によく設計されていないAPI(日付とカレンダーの両方)の見落としだったと思います。しかし、おそらくいくつかの前例があります-それは私には奇妙に思われ、私の経験では複数の初心者に問題を引き起こしています。
Voo

2
実際、SOについては既に質問されています(それだけではありません)。要するに、APIの設計が不適切なためです。あなたが言ったように、Dateクラス全体は冗談です。おもしろいのは、Javaだけがこの問題を抱えているわけではないということです。iircJavaScriptのDate getMonth()も0で始まります。
Mateusz Dymczyk

1
@VooはgetYear()1900減算、「明白な理由のために」もある
ヘレ

17

Java 8日付API を使用している場合は、1行で直接取得できます。

LocalDate today = LocalDate.now();
int month = today.getMonthValue();

7

ジョーダタイム

または、Joda-Time DateTimeクラスを使用します。

//convert date to datetime
DateTime datetime = new DateTime(date);
int month = Integer.parseInt(datetime.toString("MM"))

…または…

int month = dateTime.getMonthOfYear();

2
さらに簡単に言えば、DateTimeオブジェクトの月を尋ねるだけです。int month = dateTime.getMonthOfYear();
バジルブルク2014

バジルよろしくお願いします。コードを更新しました。ただし、.toString("MM")「MM」以外にも可能性があることを示しているので、私は好きです。
ssoward 14

1
この回答は、タイムゾーンの重要な問題を無視しています。質問と兄弟の回答に関する私のコメントを参照してください。DateTimeZoneオブジェクトをそのDateTimeコンストラクターに渡すことをお勧めします:DateTimeZone.forID( "America/Montreal" )
バジルブルク2015年

6

tl; dr

myUtilDate.toInstant()                          // Convert from legacy class to modern. `Instant` is a point on the timeline in UTC.
          .atZone(                              // Adjust from UTC to a particular time zone to determine date. Renders a `ZonedDateTime` object. 
              ZoneId.of( "America/Montreal" )   // Better to specify desired/expected zone explicitly than rely implicitly on the JVM’s current default time zone.
          )                                     // Returns a `ZonedDateTime` object.
          .getMonthValue()                      // Extract a month number. Returns a `int` number.

java.time 細部

回答使用するためのOrtomala Lokniによってjava.timeは正しいです。また、java.timeは古いjava.util.Date/.Calendarクラスに比べて大幅に改善されているため、使用する必要があります。Oracleチュートリアルを見るjava.timeを。

新しいコードから始める場合のために、java.util.Dateに関係なくjava.timeを使用する方法を示すコードをいくつか追加します。

簡単に言えば、java.timeの使用… Instantは、UTCのタイムライン上の瞬間です。タイムゾーン(ZoneId)を適用してZonedDateTimeます。

Monthクラスは、洗練された列挙型、一般的に月を表現します。その列挙には、ローカライズされた名前を取得するなどの便利なメソッドがあります。また、java.timeの月数は、java.util.Date / .Calendarにあるゼロベースのナンセンス(0-11)ではなく、1〜12の正気なものであることを確認してください。

現在の日時を取得するには、タイムゾーンが重要です。いつでも日付は世界中で同じではありません。したがって、月の終わり/初めに近い場合、月は世界中で同じではありません。

ZoneId zoneId = ZoneId.of( "America/Montreal" );  // Or 'ZoneOffset.UTC'.
ZonedDateTime now = ZonedDateTime.now( zoneId );
Month month = now.getMonth(); 
int monthNumber = month.getValue(); // Answer to the Question.
String monthName = month.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH );

java.timeについて

java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスjava.util.DateCalendar&を、SimpleDateFormat

ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。

詳細については、Oracleチュートリアルを参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。

java.timeオブジェクトをデータベースと直接交換することができます。JDBC 4.2以降に準拠したJDBCドライバーを使用します。文字列もクラスも必要ありません。java.sql.*

java.timeクラスはどこで入手できますか?

  • Java SE 8 Java SE 9 Java SE 10以降
    • 内蔵。
    • 実装がバンドルされた標準Java APIの一部。
    • Java 9では、いくつかのマイナーな機能と修正が追加されています。
  • Java SE 6および Java SE 7
    • java.time機能の多くは、ThreeTen-BackportでJava 6および7にバックポートされています。
  • アンドロイド
    • Androidの新しいバージョンには、java.timeクラスの実装がバンドルされています。
    • 以前のAndroid(<26)では、ThreeTenABPプロジェクトはThreeTen-Backport(上記)を採用しています。ThreeTenABPの使用方法…を参照してください。

ThreeTen-エクストラプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、java.timeに将来追加される可能性があることを証明する場です。あなたはここにいくつかの有用なクラスのような見つけることがIntervalYearWeekYearQuarter、および多くを


4

Joda時間を使用できず、まだ暗い世界に住んでいる場合:)(Java 5以下)これを楽しむことができます:

注:日付が次の形式で作成されていることを確認してください:dd / MM / YYYY

/**
Make an int Month from a date
*/
public static int getMonthInt(Date date) {

    SimpleDateFormat dateFormat = new SimpleDateFormat("MM");
    return Integer.parseInt(dateFormat.format(date));
}

/**
Make an int Year from a date
*/
public static int getYearInt(Date date) {

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
    return Integer.parseInt(dateFormat.format(date));
}

あなたは母親です!/Είσαιημάνα!
Tzegenos

0
Date mDate = new Date(System.currentTimeMillis());
mDate.getMonth() + 1

戻り値は0から始まるため、結果に1を追加する必要があります。


6
答えに関する2つの問題:1つは、をnew Date()使わずに現在の日付を作成できることSystem.currentTimeMillisです。もう1つは、getMonthが非推奨であることです。
Muhd

@Muhdでは、最善の解決策は何ですか?
twlkyao

@Muhdここに追加したSystem.currentTimeMillis()は、ここがlong型であることを示すためのものであり、日付を指定できます。
twlkyao

4
日:: getMonthはすでにJavaの1.1(で廃止されましたcs.mun.ca/~michael/java/jdk1.1-beta2-docs/api/...
Ortomala Lokni
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.