memo.xight.org

日々のメモ

JavaScriptでビルトインオブジェクトハック (Dateクラス編)

Summary

最速インターフェース研究会の「実践JavaScriptリファクタリング」に触発されてDateクラスに手を加えてみた.

IEとMozilla系でgetYear(),setYear()の仕様が異なるため,
getFullYear(),setFullYear()を使うことで,年の扱いを4ケタで統一.

Source

/*
連想配列を返す
return Array
*/
Date.prototype.toHashArray = function(){
	var dateArray = new Object();
	dateArray["year"]	= this.getFullYear();
	dateArray["month"]	= this.getMonth();
	dateArray["date"]	= this.getDate();
	dateArray["day"]	= this.getDay();
	dateArray["hour"]	= this.getHours();
	dateArray["minute"]	= this.getMinutes();
	dateArray["second"]	= this.getSeconds();

	return dateArray;
}

/*
その年が閏年かどうか
return boolean
*/
Date.prototype.isLeapYear = function(){
	var year = this.getFullYear();
	return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
}

/*
その日が引数と同じ日付かどうか
return boolean
*/
Date.prototype.isSameDate = function(d){
	var arr		= this.toHashArray();
	var arr2	= d.toHashArray();

	return ((arr["year"] == arr2["year"]) && (arr["month"] == arr2["month"]) && (arr["date"] == arr2["date"]));
}
/*
その時間が引数と同じ時間かどうか
return boolean
*/
Date.prototype.isSameTime = function(d){
	var arr		= this.toHashArray();
	var arr2	= d.toHashArray();

	return ((arr["hour"] == arr2["hour"]) && (arr["minute"] == arr2["minute"]) && (arr["second"] == arr2["second"]));
}
/*
その時間が引数と同じ日付、同じ時間かどうか
return boolean
*/
Date.prototype.equals = function(d){
	return (this.isSameDate(d) && this.isSameTime(d));
}

/*
その日が今日と同じ日付かどうか
return boolean
*/
Date.prototype.isToday = function(){
	return this.isSameDate(new Date());
}

/*
時間を 00:00:00に設定
*/
Date.prototype.resetTime = function(){
	this.setHours(0);
	this.setMinutes(0);
	this.setSeconds(0);

	return;
}

/*
その月の日数を取得
return int
*/
Date.prototype.getDayNumber = function(){
	var year = this.getFullYear();
	var month = this.getMonth();

	var dayNumber = 
		(month == 0 || month == 2 || month == 4 || month == 6 || month == 7 || month == 9 || month == 11) ? 31 :
		(month == 3 || month == 5 || month == 8 || month == 10) ? 30 :
		(this.isLeapYear()) ? 29 :
		28;

	return dayNumber;
}

/*
その月の週の数を取得
return int
*/
Date.prototype.getWeekNumber = function(){
	var dayNumber = this.getDayNumber();
	var weekOfTheDay = this.getDay();

	var weekNumber = Math.ceil((weekOfTheDay + dayNumber) / 7);

	return weekNumber;
}

/*
閏年を考慮して前の月のDateを返す
(3月29日,30日,31日の前の月は2月28日 or 29日)
return Date
*/
Date.prototype.getPreviousMonth = function(){
	var year      = this.getFullYear();
	var month     = this.getMonth();
	var date      = this.getDate();

	var prevYear  = year;
	var prevMonth = month;
	var prevDate  = date;

	if (month == 0){
		prevMonth = 11;
		prevYear--;
	} else if (month == 1 || date > 28){
		prevDate = (this.isLeapYear()) ? 29 : 28;
		prevMonth--;
	} else {
		prevMonth--;
	}
	var retDate = new Date(prevYear,prevMonth,prevDate);
	retDate.resetTime();

	return retDate;
}

/*
閏年を考慮して次の月のDateを返す
(1月29日,30日,31日の次の月は2月28日 or 29日)
return Date
*/
Date.prototype.getNextMonth = function(){
	var year      = this.getFullYear();
	var month     = this.getMonth();
	var date      = this.getDate();

	var nextYear  = year;
	var nextMonth = month;
	var nextDate  = date;

	if (month == 11){
		nextMonth = 0;
		nextYear++;
	} else if (month == 0 || date > 28){
		nextDate = (this.isLeapYear()) ? 29 : 28;
		nextMonth++;
	} else {
		nextMonth++;
	}
	var retDate = new Date(nextYear,nextMonth,nextDate);
	retDate.resetTime();

	return retDate;
}

/*
その月の最初の日付を返す。時間は00:00:00にリセット。
return Date
*/
Date.prototype.getFirstDate = function(){
	var year      = this.getFullYear();
	var month     = this.getMonth();

	var retDate = new Date(year,month,1);
	retDate.resetTime();

	return retDate;
}

/*
読みやすい形式で日付の文字列を出力
return String
*/
Date.prototype.toReadableString = function(){
	var dateArray = this.toHashArray();
	var displayMonth = dateArray["month"] + 1;

	var ret = '';
	ret += dateArray["year"] + '/' + displayMonth + '/' + dateArray["date"];
	return ret;
}

/*
読みやすい形式で日付と時刻の文字列を出力
return String;
*/
Date.prototype.toLongReadableString = function(){
	var dateArray = this.toHashArray();
	var day		= this.getWeekOfTheDay();

	var ret = '';
	ret += this.toReadableString();
	ret += '(' + day + ')' + dateArray["hour"] + ':' + dateArray["minute"] + ':' + dateArray["second"];

	return ret;
}

/*
読みやすい曜日を返す
return String;
*/
Date.prototype.getWeekOfTheDay = function(){
	var day = this.getDay();
	var ret = this.weekOfTheDay[day];
	return ret;
}

/*
読みやすい曜日表示の設定
引数は "7つの要素を持つArray"
return boolean;
*/
Date.prototype.setWeekOfTheDayArray = function(arr){
	var state = (arr.length == 7) ? true : false;
	if (state){
		this.weekOfTheDay = arr;
	}
	
	return state;
}

Date.prototype.weekOfTheDay = new Array("日","月","火","水","木","金","土");
// Date.prototype.weekOfTheDay = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat");


Reference

最速インターフェース研究会 - 2005-10-06 - 実践JavaScriptリファクタリング
http://la.ma.la/blog/diary_200510060733.htm
最速インターフェース研究会 - 2005-10-06 - 実践JavaScriptリファクタリング、その2
http://la.ma.la/blog/diary_200510062243.htm