miso_soup3 Blog

主に ASP.NET 関連について書いています。

ある期間を、月ごとに区切る

JavaScriptで、ある期間を、月ごとに期間で区切ってくれるものを作りました。

テストコード (QUnit)
test("月ごとの期間配列作成テスト。 2012/02/15 〜 2012/04/16 の場合", function () {
	expect(10);

	var startDate = new Date(2012, 2 - 1, 15);
	var endDate = new Date(2012, 4 - 1, 16);
	var span = $.dateHelper.getSpan(startDate, endDate);

	//実行
	var spans = $.dateHelper.createSpansByMonth(startDate, span);

	equal(3, spans.length);

	equal(15, spans[0].span());
	equal(31, spans[1].span());
	equal(16, spans[2].span());

	equal(new Date(2012, 2 - 1, 15).toString(), spans[0].startDate().toString());
	equal(new Date(2012, 2 - 1, 29).toString(), spans[0].endDate().toString());

	equal(new Date(2012, 3 - 1, 1).toString(), spans[1].startDate().toString());
	equal(new Date(2012, 3 - 1, 31).toString(), spans[1].endDate().toString());

	equal(new Date(2012, 4 - 1, 1).toString(), spans[2].startDate().toString());
	equal(new Date(2012, 4 - 1, 16).toString(), spans[2].endDate().toString());
});
実装コード
function createSpansByMonth(startDate, span) {
	//開始日と日数より、月毎に区切った期間の配列を返します。

	var results = [];
	var currentDate = startDate;
	var endDate = getEndDate(startDate, span);

	while (currentDate.getTime() <= endDate.getTime()) {

		var currentMonthLastDate = getMonthLastDay(currentDate); //現在の月の最後の日
		if (endDate.getTime() < currentMonthLastDate.getTime()) {
			currentMonthLastDate = endDate;
		}
		results.push(daySpanFrom(currentDate, currentMonthLastDate));

		currentDate = new Date(currentMonthLastDate.getTime() + 86400000);
	}

	return results;
}

利用モデル

function DaySpan(startDate, span) {
	//期間を表すオブジェクト startDate:開始日, span:日数

	var _startDate = startDate;
	var _span = span;

	this.startDate = function () {
		return _startDate;
	}
	this.endDate = function () {
		return getEndDate(_startDate, _span);
	}
	this.span = function () {
		return _span;
	}
}

ヘルパー(exDate利用)

function getMonthLastDay(date) {
	//date オブジェクトの保持する月の最終日を Date オブジェクト形式で返します。
	var $date = $.exDate(toShortString(date));
	return new Date($date.lastDay().getTime());
}

function getEndDate(startDate, span) {
	//開始日と日数より、終了日を取得します
	var result = new Date();
	result.setTime(startDate.getTime() + 86400000 * (span - 1));
	return result;
}

以上。

date.getTime() < date.Time() や、86400000 などが微妙ですが、
すぐに書ける処理なので書いちゃうという…