2011. 10. 19. 17:21

[JAVASCRIPT] 개월수 및 일수 윤년 포함 계산

윤년을 포함하여 개월수 정확하게 계산
아래 소스를 모두 복사후 시작날짜 와 끝나는 날짜를 YYYYMMDD 방식으로 던져주면된다.
함수 리턴은 재귀함수를 이용하므로 꼭 필요하다.
http://som2day.com/138

소스
/**
 * @ author : [insom*nia] (blue1769@naver.com)
 *      Homepage(BloG): http://som2day.com/
 * @ date  : 2010-01-06
 * @ descript : JavaScripts Date Functions
 */

function isLeapYear(year)
{
 // parameter가 숫자가 아니면 false
 if (isNaN(year))
  return false;
 else  {
  var nYear = eval(year);

  // 4로 나누어지고 100으로 나누어지지 않으며 400으로는 나눠지면 true(윤년)
  if (nYear % 4 == 0 && nYear % 100 != 0 || nYear % 400 == 0)
   return true;
  else
   return false;
 }
}

// start, end format: yyyymmdd
function getDifMonths(start, end)
{
 var startYear = start.substring(0, 4);
 var endYear = end.substring(0, 4);
 var startMonth = start.substring(4, 6) - 1;
 var endMonth = end.substring(4, 6) - 1;
 var startDay = start.substring(6, 8);
 var endDay = end.substring(6, 8);

 // 연도 차이가 나는 경우
 if (eval(startYear) > eval(endYear)) {
  // 종료일 월이 시작일 월보다 수치로 빠른 경우
  if (eval(startMonth) > eval(endMonth)) {
   var newEnd = startYear + "1231";
   var newStart = endYear + "0101";

   return (eval(getDifMonths(start, newEnd)) + eval(getDifMonths(newStart, end))).toFixed(2);
  // 종료일 월이 시작일 월보다 수치로 같거나 늦은 경우
  } else         {
   var formMonth = eval(startMonth) + 1;
   if (eval(formMonth) < 10) formMonth = "0" + formMonth;

   var newStart = endYear + "" + formMonth + "" + startDay;
   var addMonths = (eval(endYear) - eval(startYear)) * 12;

   return (eval(addMonths) + eval(getDifMonths(newStart, end))).toFixed(2);
  }
 } else         { 
  // 월별 일수차 (30일 기준 차이 일수)
  var difDaysOnMonth = new Array(1, -2, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1);
  var difDaysTotal = getDifDays(start, end);

  for (i = startMonth; i < endMonth; i++) {
   if (i == 1 && isLeapYear(startYear)) difDaysTotal -= (difDaysOnMonth[i] + 1);
   else         difDaysTotal -= difDaysOnMonth[i];
  }

  // because view this function
  window.alert("- run getDifMonths()\n- " + start + " ~ " + end + " => " + (difDaysTotal / 30).toFixed(2));
  
  return (difDaysTotal / 30).toFixed(2);
  }
}

// start, end format: yyyymmdd
function getDifDays(start, end)
{
 var dateStart = new Date(start.substring(0, 4), start.substring(4, 6) - 1, start.substring(6, 8));
 var dateEnd = new Date(end.substring(0, 4), end.substring(4, 6) - 1, end.substring(6, 8));
 var difDays = (dateEnd.getTime() - dateStart.getTime()) / (24 * 60 * 60 * 1000);

 // because view this function
 window.alert("- run getDifDays()\n- " + start + " ~ " + end + " => " + Math.ceil(difDays));

 return Math.ceil(difDays);
}

---------------------------------------------------------------------------------------------
다른버전
function getDiffDays(pStartDate, pEndDate, pType){
 //param : pStartDate - 시작일
 //param : pEndDate  - 마지막일
 //param : pType       - 'D':일수, 'M':개월수
 var strSDT = new Date(pStartDate.substring(0,4),pStartDate.substring(4,6)-1,pStartDate.substring(6,8));
 var strEDT = new Date(pEndDate.substring(0,4),pEndDate.substring(4,6)-1,pEndDate.substring(6,8));
 var strGapDT = 0;
 
 if(pType == 'D') {  //일수 차이
     strGapDT = (strEDT.getTime()-strSDT.getTime())/(1000*60*60*24);
 } else {            //개월수 차이
     //년도가 같으면 단순히 월을 마이너스 한다.
     if(pEndDate.substring(0,4) == pStartDate.substring(0,4)) {
         strGapDT = pEndDate.substring(4,6) * 1 - pStartDate.substring(4,6) * 1;
     } else {
         strGapDT = ((strEDT.getTime()-strSDT.getTime())/(1000*60*60*24*365.25/12)).toFixed(2);
     }
 }
 return strGapDT;
}
----------------------------------------------------------------------------------------
function getPrevDateValidate(yyyymmdd, term){
 var yyyy = yyyymmdd.substring(0, 4);
 var mm   = yyyymmdd.substring(4, 6);
 var dd   = yyyymmdd.substring(6, 8);

 myDate = new Date();
 myDate.setFullYear(yyyy);
 myDate.setMonth(mm-1);
 myDate.setDate(dd);
 

 if(term.charAt(term.length-1) == 'd'){
  term = term.substring(0, term.length-1); 
  myDate.setDate(dd - eval(term) +1 );
 }

 if(term.charAt(term.length-1) == 'm'){
  term = parseInt(term.substring(0, term.length-1), 10);

  myDate.setMonth(mm - eval(term) -1);
  myDate.setDate(myDate.getDate()+1);
 }

 yyyy = myDate.getYear();
 mm   = myDate.getMonth()+1;
 dd   = myDate.getDate();

 dd = (dd<10)?'0'+dd:dd;
 mm = (mm<10)?'0'+mm:mm;
 
 return yyyy+'-'+mm+'-'+dd;
}

function IsValidCheckDate(from_date, to_date, astr){
 if(astr != ""){
  to_date = ClearDelimit(to_date, "-");
  var temp_day   = getPrevDateValidate(to_date, astr);
  temp_day       = ClearDelimit(temp_day, "-");
  from_date = ClearDelimit(from_date, "-");
  if(astr.indexOf("m") != -1){
      var tempstring = astr.split("m");
      var tempchar   = "개월";
  }
  if(astr.indexOf("d") != -1){
      var tempstring = astr.split("d");
      var tempchar   = "일";
  }
  if(parseInt(from_date,10) < parseInt(temp_day,10)){
   alert("조회단위가 초과되었습니다. 본 서비스는 "+tempstring[0]+ tempchar +" 단위로만 조회가 가능합니다.");
   return true;
  }
 }
}

function ClearDelimit(str,serchar){
   var reStr ="";
   var seStr ="";
   var i = 0;
   seStr=str;
   reStr='';
   for (i=0;i <seStr.length; i++){
      reStr += (seStr.charAt(i) != serchar ?seStr.charAt(i) : '');
   }

   return reStr;
}