[AS3] ハッピーマンデーを求める [Edit]

ハッピーマンデーのように、ある月の何番目の曜日と指定して、日付を求めてみます。おまけに、最後の何曜日と後ろから数えられるようにもしましょう。

つぎのような関数xGetNthDay()を定義します。戻り値は指定した曜日のDateオブジェクトです。月はDateクラスと異なり1月を1から始めます。他方、序数(何番目)は第1を0とし、最後は-1から負の数で指定します。

xGetNthDay(年:uint, 月:uint, 序数:int = 0, 曜日:int = 0):Date

スクリプトの考え方は、つぎのとおりです。月内に該当する日付がないとき(たとえば第6月曜日)は、nullを返すことにします。

  1. 月初の曜日を調べる
  2. その月の求めたい曜日の最初(第1)の日付を知る
  3. 除数にしたがって7の倍数を加える
  4. その日が月の中にあるかどうかを確かめたうえで返す

関数xGetNthDay()は、以下のスクリプト001のように定義しました。上記の1〜3は、剰余演算子%を使って1行で導いています。ちょっとしたパズルの感覚で、確かめていただくとよいでしょう[*1]。なお、Dateクラスのコンストラクタメソッドに日として0を渡すと、前月末の日付が得られます。

スクリプト001■年月と除数および曜日を渡して日付が返される関数
function xGetNthDay(nYear:uint, nMonth:uint, nOrdinal:int = 0, nDay:int = 0):Date {
	var _date:Date;
	var nThisMonth:uint;
	if (nOrdinal > -1) {  // 月初から数えるとき
		_date = new Date(nYear, nMonth - 1, 1);
		nThisMonth = _date.month;
		nDay = (nDay - _date.day + 7) % 7 + nOrdinal * 7;
	} else {  // 月末から遡るとき
		_date = new Date(nYear, nMonth, 0);
		nThisMonth = _date.month;
		nDay = (nDay - _date.day - 7) % 7 + (nOrdinal + 1) * 7;
	}
	_date.date +=  nDay;
	if (_date.month != nThisMonth) {
		_date = null;
	}
	return _date;
}

2011年1月の第1月曜日と2010年12月の最後の日曜日は、つぎのように求められます。

trace(xGetNthDay(2011, 1, 0, 1));
// 出力: Mon Jan 3 00:00:00 GMT+0900 2011
trace(xGetNthDay(2010, 12, -1));
// Sun Dec 26 00:00:00 GMT+0900 2010

ついでに、2011年のハッピーマンデーも掲げておきましょう。

// [1]成人の日: 1月の第2月曜日 2011年1月10日
trace(xGetNthDay(2011, 1, 1, 1));
// 出力: Mon Jan 10 00:00:00 GMT+0900 2011
// [2]海の日: 7月の第3月曜日 2011年7月18日
trace(xGetNthDay(2011, 7, 2, 1));
// 出力: Mon Jul 18 00:00:00 GMT+0900 2011
// [3]敬老の日: 9月の第3月曜日 2011年9月19日
trace(xGetNthDay(2011, 9, 2, 1));
// 出力: Mon Sep 19 00:00:00 GMT+0900 2011
// [4]体育の日: 10月の第2月曜日 2011年10月10日
trace(xGetNthDay(2011, 10, 1, 1));
// 出力: Mon Oct 10 00:00:00 GMT+0900 2011

[2010年12月15日追記] bkzenさんがwonderflに、この関数を用いた「何年何月何週目の何曜日が何日かを求める」というカレンダーつきのサンプルをつくられました。参考に掲載させていただきます。

何年何月何週目の何曜日が何日かを求める - wonderfl build flash online


[*1] 上記の「スクリプトの考え方」にしたがうと、式はつぎのように組立てられています。ただし、求めているのは厳密には「日付」でなく、月初から数えた「日数」になります(つまり、1日が0)。

  1. 月初の曜日: _date.day
  2. その月の求めたい曜日の最初(第1)の日付: (nDay - _date.day + 7) % 7
  3. 除数にしたがって7の倍数を加える: (nDay - _date.day + 7) % 7 + nOrdinal * 7

コメント

この記事にコメントを書く

記事に対するテクニカルな質問はご遠慮ください(利用規約)。

その他の記事