/**
 * 날짜에 대한 처리를 담당하는 자바스크립트 객체 <BR>
 *
 * @version	1.0, 2003-12-16
 * @author	namjinpark
 *@constructor
 */
function DateUtil() {
	this.isValidDate 			= isValidDate_DateUtil;
	this.getDateString			= getDateString_DateUtil;
	this.getDateInt				= getDateInt_DateUtil;
	this.dateDiff				= dateDiff_DateUtil;
	this.detachDelim			= detachDelim_DateUtil;
	this.today					= today_DateUtil;
	this.checkDateFormat 		= checkDateFormat_DateUtil;
	this.checkDateFormatString 	= checkDateFormatString_DateUtil;
	this.getCalendarParam 		= getCalendarParam_DateUtil;
	this.addDate		 		= addDate_DateUtil;
	this.addMonth		 		= addMonth_DateUtil;
} 

/**
 * 입력된 날짜가 올바를 날짜인지 체크한다.
 *@param	year	년도
 *@param	month	달
 *@param	day		일
 */
function isValidDate_DateUtil(year, month, day){
	//basic error checking
	if (year<1000)           return false;//년
	if (month<1 || month>12) return false;//월
	if (day<1 || day>31) return false;//일

	// 4,6,8,11,월 30일
	if (month==4 || month==6 || month==9 || month==11) {
		if (day==31) return false;
	}
	// 2월 윤년계산
	if (month==2) {
		// feb
		var tmp1=parseInt(year/4)
		if (isNaN(tmp1)) return false;
		if (day>29) return false;
		if (day==29 && ((year/4)!=parseInt(year/4))) return false;
	}
	return true;
}

/**
 * 입력된 년, 월, 일 값을 yyyyMMdd 형태로 반환한다.
 *@param	year	년도
 *@param	month	달
 *@param	day		일
 */
function getDateString_DateUtil(pm_iYear, pm_iMonth, pm_iDay) {
	var year = parseInt(pm_iYear);
	var month = parseInt(pm_iMonth);
	var day = parseInt(pm_iDay);
	var lm_sRet = "" + year +
		          (month < 10 ? "0" + month : month) +
				  (day < 10 ? "0" + day : day);
	return lm_sRet;
}

/**
 * 포멧처리된 날짜 문자열을 yyyyMMdd 형태로 반환한다.
 *@param	pm_sDateString	yyyy[delim]MM[delim]dd 형태의 문자열 
 *@param	pm_sDelim	딜리미터 (보통 ".", "-", "/" 사용)
 *@return	yyyyMMdd 형태의 문자열
 */
function detachDelim_DateUtil(pm_sDateString, pm_sDelim) {
	var lm_sTokens = pm_sDateString.split(pm_sDelim);
	var year = parseInt(lm_sTokens[0]);
	var month = parseInt(lm_sTokens[1], 10);
	var day = parseInt(lm_sTokens[2], 10);
	
	var lm_sRet = "" + year +
		          (month < 10 ? "0" + month : month) +
				  (day < 10 ? "0" + day : day);
	return lm_sRet;
}

/**
 * yyyyMMdd 형태의 문자열을 년, 월, 일의 배열로 반환한다.
 *@param	pm_sDateString	yyyyMMdd 형태의 문자열
 *@return	크기가 3인 배열 [년, 월, 일]
 */
function getDateInt_DateUtil(pm_sDateString) {
	var lm_sYear = pm_sDateString.substr(0, 4);
	var lm_sMonth = pm_sDateString.substr(4, 2);
	var lm_sDay = pm_sDateString.substr(6, 2);
	var lm_oArray = [parseInt(lm_sYear), parseInt(lm_sMonth, 10), parseInt(lm_sDay, 10)];
	return lm_oArray;
}

/**
 * yyyyMMdd 형태의 문자열 pm_sDateString1 과 pm_sDateString2 날짜 차이를 구한다.
 *@param	pm_sDateString1	yyyyMMdd 형태의 문자열1
 *@param	pm_sDateString2	yyyyMMdd 형태의 문자열2 
 *@return	pm_sDateString2 날짜 - pm_sDateString1 날짜 의 차이 (일수)
 */
function dateDiff_DateUtil(pm_sDateString1, pm_sDateString2) {
	var lm_oDateInts1 = this.getDateInt(pm_sDateString1);
	var lm_oDateInts2 = this.getDateInt(pm_sDateString2);
	
	var lm_oDate1 = new Date(lm_oDateInts1[0], lm_oDateInts1[1]-1, lm_oDateInts1[2]);
	var lm_oDate2 = new Date(lm_oDateInts2[0], lm_oDateInts2[1]-1, lm_oDateInts2[2]);
	
	return (lm_oDate2 - lm_oDate1) / (24 * 60 * 60 * 1000);
}

/**
 * 오늘날짜를 yyyyMMdd 형태로 반환한다.
 *@return 	yyyyMMdd 형태의 날짜
 */
function today_DateUtil() {
	var lm_sDate = new Date();
	var lm_iYear = lm_sDate.getYear();
	var lm_iMonth = lm_sDate.getMonth()+1;
	var lm_iDay = lm_sDate.getDate();
	return ""+lm_iYear+(lm_iMonth < 10 ? "0" + lm_iMonth : lm_iMonth) +
				  (lm_iDay < 10 ? "0" + lm_iDay : lm_iDay);
}

/** 입력된 keycode 가 숫자타입인지를 반환한다. */
function isNumber_DateUtil(pm_iKeycode) {
	var NUMBER_CODE = new Array(48,49,50,51,52,53,54,55,56,57);
	
	for(var i=0; i < NUMBER_CODE.length; i++) {
		if(pm_iKeycode == NUMBER_CODE[i]) return true;
	}
	return false;
}

/** onkeypress event handler 날짜 타입으로 포맷팅한다. (yyyy[delim]MM[delim}dd형태) */
function formatDate_DateUtil(pm_oText, pm_sDelim) {
 	var lm_iKeycode = event.keyCode;
 	window.status = lm_iKeycode;
	var lm_sText = pm_oText.value;
 	if(isNumber_DateUtil(lm_iKeycode)) {
		var lm_sStripDate = 	stripFormatDate_DateUtil(lm_sText+String.fromCharCode(lm_iKeycode), pm_sDelim);
		pm_oText.value = formatDateString_DateUtil(lm_sStripDate, pm_sDelim);
 	}
 	event.keyCode = 0;
}

/** format 된 날자 문자열을 딜리미터를 제거하고 숫자만을 반환한다. */
function stripFormatDate_DateUtil(pm_sString, pm_sDelim) {
	var lm_sReturn = "";
	for(var i=0; i < pm_sString.length; i++) {
		lm_sReturn += (pm_sString.charAt(i) == pm_sDelim ? "" : pm_sString.charAt(i));
	}
	return lm_sReturn;
}

/** 숫자로 구성된 문자열을 날짜 포멧으로 변환한다. */
function formatDateString_DateUtil(pm_sString, pm_sDelim) {
	var lm_iLength = pm_sString.length;
	var lm_sYear = "";
	var lm_sMonth = "";
	var lm_sDay = "";
	lm_sYear = pm_sString.substring(0, Math.min(4, lm_iLength));
	if(lm_iLength > 4) lm_sMonth = pm_sString.substring(4, Math.min(6, lm_iLength));
	if(lm_iLength > 6) lm_sDay = pm_sString.substring(6, Math.min(8, lm_iLength));
	
	var lm_sDate = "";
	if(lm_sDay != "") lm_sDate = pm_sDelim + lm_sDay;
	if(lm_sMonth != "") lm_sDate = pm_sDelim + lm_sMonth + lm_sDate;
	if(lm_sYear != "") lm_sDate = lm_sYear + lm_sDate;
	return lm_sDate;
}

/** 날짜 타입이 정확한지 체크한다. */
function checkDateFormat_DateUtil(pm_oText, pm_sDelim) {
	var lm_sDate = pm_oText.value;
	
	if(lm_sDate.length != 0 && lm_sDate.length != 10) {
		alert("날짜 형식(yyyy.MM.dd)이 정확하지 않습니다.");
		pm_oText.focus();
		return false;
	} else {
		var lm_sStripDate = stripFormatDate_DateUtil(lm_sDate, pm_sDelim);
		var lm_sYear = lm_sStripDate.substring(0, 4);
		var lm_sMonth = lm_sStripDate.substring(4, 6);
		var lm_sDay = lm_sStripDate.substring(6, 8);
		if(isValidDate_DateUtil(parseInt(lm_sYear), parseInt(lm_sMonth, 10), parseInt(lm_sDay, 10)) == false) {
			alert("유효하지 않는 날짜입니다.");
			pm_oText.focus();
			return false;
		}
	}
	return true;
}

/** 문자열의 날짜 타입이 정확한지 체크한다. */
function checkDateFormatString_DateUtil(pm_sText, pm_sDelim) {
	var lm_sDate = pm_sText;
	
	if(lm_sDate.length != 0 && lm_sDate.length != 10) {
		return false;
	} else {
		var lm_sStripDate = stripFormatDate_DateUtil(lm_sDate, pm_sDelim);
		var lm_sYear = lm_sStripDate.substring(0, 4);
		var lm_sMonth = lm_sStripDate.substring(4, 6);
		var lm_sDay = lm_sStripDate.substring(6, 8);
		if(isValidDate_DateUtil(parseInt(lm_sYear), parseInt(lm_sMonth, 10), parseInt(lm_sDay, 10)) == false) {
			return false;
		}
	}
	return true;
}

/** Calendar 에 팝업처리를 위한 초기 파라미터를 얻는다. 
  * year=2005&month=10&day=1 와 같은 식이 된다.
  */
function getCalendarParam_DateUtil(pm_sText, pm_sDelim) {
	var lm_sDate = pm_sText;
	var lm_sReturn = "";
	if(lm_sDate.length != 0 && lm_sDate.length != 10) {
		return "";
	} else {
		var lm_sStripDate = stripFormatDate_DateUtil(lm_sDate, pm_sDelim);
		var lm_sYear = lm_sStripDate.substring(0, 4);
		var lm_sMonth = lm_sStripDate.substring(4, 6);
		var lm_sDay = lm_sStripDate.substring(6, 8);
		if(isValidDate_DateUtil(parseInt(lm_sYear), parseInt(lm_sMonth, 10), parseInt(lm_sDay, 10)) == false) {
			return "";
		} else {
			lm_sReturn += "year="+lm_sYear;
			lm_sReturn += "&month="+lm_sMonth;
			lm_sReturn += "&day="+lm_sDay;
		}
	}
	return lm_sReturn;	
}

/**
 * yyyy[pm_sDelim]MM[pm_sDelim}dd(예. 2004.01.01 형태의 날짜 문자열을 Date 객체로 전환하여
 * 날짜값을 pm_iAdded 만큼 더한 Date를 pm_sDelim 로 포맷팅하여 반환한다.
 *@param	pm_sText	포맷처리된 날짜 문자열
 *@param	pm_sDelim	딜리미터
 *@param	pm_iAdded	숫자값 (양수이면 날자가 더해지고 음수이면 날짜를 빼주게 된다.)
 *@return	pm_iAdded 만큼 더한 Date를 pm_sDelim 로 포맷팅하여 반환
 */
function addDate_DateUtil(pm_sText, pm_sDelim, pm_iAdded) {
	//날짜 형식이 올바르지 않으면 null을 반환
	if(checkDateFormatString_DateUtil(pm_sText, pm_sDelim) == false) return null; 
	var lm_sDetachDate = detachDelim_DateUtil(pm_sText, pm_sDelim);
	var lm_oDateArray = getDateInt_DateUtil(lm_sDetachDate);
	var lm_oDate = new Date(lm_oDateArray[0], lm_oDateArray[1]-1, lm_oDateArray[2]+pm_iAdded);
	var lm_iYear = lm_oDate.getYear();
	var lm_iMonth = lm_oDate.getMonth() + 1;
	var lm_iDate = lm_oDate.getDate();
	var lm_sReturn = "" + lm_iYear + pm_sDelim +
		          (lm_iMonth < 10 ? "0" + lm_iMonth : lm_iMonth) + pm_sDelim +
				  (lm_iDate < 10 ? "0" + lm_iDate : lm_iDate);
	return lm_sReturn;
}

/**
 * yyyy[pm_sDelim]MM[pm_sDelim}dd(예. 2004.01.01 형태의 날짜 문자열을 Date 객체로 전환하여
 * 월값을 pm_iAdded 만큼 더한 Date를 pm_sDelim 로 포맷팅하여 반환한다.
 *@param	pm_sText	포맷처리된 날짜 문자열
 *@param	pm_sDelim	딜리미터
 *@param	pm_iAdded	숫자값 (양수이면 월이 더해지고 음수이면 월을 빼주게 된다.)
 *@return	pm_iAdded 만큼 더한 Date를 pm_sDelim 로 포맷팅하여 반환
 */
function addMonth_DateUtil(pm_sText, pm_sDelim, pm_iAdded) {
	//날짜 형식이 올바르지 않으면 null을 반환
	if(checkDateFormatString_DateUtil(pm_sText, pm_sDelim) == false) return null; 
	var lm_sDetachDate = detachDelim_DateUtil(pm_sText, pm_sDelim);
	var lm_oDateArray = getDateInt_DateUtil(lm_sDetachDate);
	var lm_oDate = new Date(lm_oDateArray[0], lm_oDateArray[1]-1+pm_iAdded, lm_oDateArray[2]);
	var lm_iYear = lm_oDate.getYear();
	var lm_iMonth = lm_oDate.getMonth() + 1;
	var lm_iDate = lm_oDate.getDate();
	var lm_sReturn = "" + lm_iYear + pm_sDelim +
		          (lm_iMonth < 10 ? "0" + lm_iMonth : lm_iMonth) + pm_sDelim +
				  (lm_iDate < 10 ? "0" + lm_iDate : lm_iDate);
	return lm_sReturn;
}