Javaで月末日を取得する方法

こんにちは、さるまりんです。

以前、PHPで月末日を取得するというのをやりました。

今回はJavaでやってみたいと思います。

Javaでは日時にはDateクラスやCalendarクラスを使います。

これらを用いて月末日を取得してみます。

月末日の取得

以下簡単ですがメソッドにしてみました。

Date getLastOfTheMonth(Date dt) {
	// 渡された日付がnullならnullを返却
	if (dt == null) return null;

	// 渡された日時のCalendarを作成
	Calendar c = getCalendar(dt);
	// その月に日の最大を取得
	int lastDay = c.getActualMaximum(Calendar.DATE);
	c.set(Calendar.DATE, lastDay); // 最大日を設定
		
	// その日の最後の瞬間にする
	c.set(Calendar.HOUR_OF_DAY, 23);
	c.set(Calendar.MINUTE, 59);
	c.set(Calendar.SECOND, 59);
	c.set(Calendar.MILLISECOND, 999);
	
	return c.getTime(); // Dateクラスのオブジェクトとして返却
}

キモはCalendarオブジェクトのgetActualMaximum()です。Calendar.DATE (日)を単位として渡すことで、Calendarオブジェクトの持つ日時の年月の日数を返します。例えば4月ならば30、5月ならば31、うるう年の2月なら29という数字を取得することができます。それで取得できた数値をCalendarオブジェクトのset()で日の部分として設定しています。

c.set(Calendar.HOUR_OF_DAY, 23);
c.set(Calendar.MINUTE, 59);
c.set(Calendar.SECOND, 59);
c.set(Calendar.MILLISECOND, 999);

続いて同じようにset()で設定しているのが時分秒とミリ秒の単位です。Calendarは日時を表すので日よりも小さな単位も持っています。その部分を23:59:59.999に設定しています。

最後にCalendarオブジェクトのgetTime()メソッドを呼び出してDateオブジェクトを取得。これには渡されたDateオブジェクトの月末日の23:59:59.999が設定されています。

月初日の取得

同じ方法で月初日を取得してみます。こちらもメソッドにしてみました。

Date getFirstOfTheMonth(Date dt) {
	// 渡された日付がnullならnullを返却
	if (dt == null) return null;

	// 渡された日時のCalendarを作成
	Calendar c = getCalendar(dt); 
	c.set(Calendar.DATE, 1); // 1日を設定
		
	// その日の最初の瞬間にする
	c.set(Calendar.HOUR_OF_DAY, 0);
	c.set(Calendar.MINUTE, 0);
	c.set(Calendar.SECOND, 0);
	c.set(Calendar.MILLISECOND, 0);
	
	return c.getTime(); // Dateクラスのオブジェクトとして返却
}

こちらはgetActual..のメソッドを呼ぶことはありません。月初日はいつも1日ですね。違ったら異世界かな。日よりも小さい単位には00:00:00.000を設定しています。

月初日を取得 (文字列操作で)

月初日はこんな方法でも取得することができます。

DateFormatを使って文字列を操作することで月初日を取得してみます。

Date getFirstOfTheMonth(Date dt) {
	// 渡された日付がnullならnullを返却
	if (dt == null) return null;
	// 日付を"yyyy-MM-01 00:00:00.000"の文字列に変換
	DateFormat df = new SimpleDateFormat("yyyy-MM-01 00:00:00.000");
	String firstStr= df.format(dt);

	Date first = null;
	try {
		// できた文字列をDateオブジェクトに戻す
		first = df.parse(firstStr);
	} catch (ParseException e) {
		// 変換できない文字列でした (起こることはないです)
		e.printStackTrace();
	}
	// 返却
	return first;
}

Dateオブジェクトで日時をもらい、その日を文字列経由で日の部分を1に、時間部分を00:00:00.000にして、Dateオブジェクトに戻しています。これだとCalendarを使わずにできました。

JavaのDateクラスにも年月日を数値で指定するコンストラクタや時分秒を数値で設定するメソッドがあるのですがそれらは非推奨なため別の方法をとるために考えてみました。

どうやったらできるだろうって考えるのはパズルのようで楽しいですね。

読んでくださってありがとうございます。

それではまた!