人間になりたい類人猿

人間以前の技術屋ブログ

javascriptで1ヶ月後(nヶ月前/後)を計算する

「ある日から1ヶ月前/後を計算したい。」
よくありそうなこんな処理。単純にsetMonthの加減だけで良いのであれば楽なのだが、
日本の一ヶ月の定義はこんな感じだったりする。

「週、月又は年の初めから期間を起算しないときは、
その期間は、最後の週、月又は年においてその起算日に応当する日の前日に満了する。
ただし、月又は年によって期間を定めた場合において、最後の月に応当する日がないときは、
その月の末日に満了する。」

民法第143条第2項(暦による期間の計算):http://www.minnpou-sousoku.com/category/article/6/143_2.html


つまり最終月に同じ日あったら前日で、もし同じ日が無ければ月末日に合わせてね。

というルール。
JRの定期券とかもこういうルールらしい。
ぶっちゃけ初めて知った。

で、これを守ろうとすると単純なsetMonthの加減では収まらなくなる。
つまり独自実装が必要。
ところがどっこい調べてみてもこれをコードとして書いている記事が特に無い。
まぁ日本にローカライズされすぎているからかもしれないし、
こんな厳密性を求めるのは交通系や契約書作成とかそういう限られた場所になるだろうから
記事にする人が少ないからかも。

そんな事をふと思ってとりあえず作ったので記事にしておく。


さっそくコード

//nヶ月前後の年月日を取得する
function getAddMonthDate(year,month,day,add){
	var addMonth = month + add;
	var endDate = getEndOfMonth(year,addMonth);//add分を加えた月の最終日を取得

	//引数で渡された日付がnヶ月後の最終日より大きければ日付を次月最終日に合わせる
	//5/31→6/30のように応当日が無い場合に必要
	if(day > endDate){
		day = endDate;
	}else{
		day = day - 1;
	}

	var addMonthDate = new Date(year,addMonth - 1,day);
	return addMonthDate;
}

//今月の月末日を取得
//※次月の0日目=今月の末日になる
function getEndOfMonth(year,month){
	var endDate = new Date(year,month,0);
	return endDate.getDate();
}

//使い方
//2016/5/31の1ヶ月後を表示したい
console.log(getAddMonthDate(2016,5,31,1))
//2016/5/31の1ヶ月前を表示したい
console.log(getAddMonthDate(2016,5,31,-1))

ま、こんな感じ。
これを使えばユーザが入力した日付が1ヶ月以内に収まっているかどうかチェックするのも楽

//開始日~終了日を入力する様なフォームだった場合
var toDate = new Date(toYear,toMonth -1 ,toDay);//入力された終了日
var limitDate = getAddMonthDate(fromYear,fromMonth,fromDay,1);//開始日から計算された上限日(一ヶ月後)
var diff = limitDate.getTime() - toDate.getTime();//差分を計算

if(diff < 0){
	alert("一ヶ月より大きいよ!!");
}

雑だけど、どこかで役に立てばうれしいな
(便利なライブラリとかありそうだけど)

以上