Friday, February 19, 2010

Get Business Day in JavaScript

Often required in web application is to obtain the next business day or a business day in future.
Normally, a business day excludes national holiday and business defined non-business day of week (usually Saturday and Sunday).

National Holidays are defined in a comma delimited string such as
D01012010,D02152010,D12252010
where D12252010 refer to Dec 25th, 2010, the Christmas Day.

Non-business day of week are defined also in a comma delimited string such as
D1,D7
where D1 is to Sunday, D7 is Saturday.

Holiday and Non-business days can be defined either in properties or database, here just simply the problem by handwriting them in the strings.

Also, assuming user pass in the date as string in mm/dd/yyyy format.

The following JavaScript code can calculate a business day that is N business days from a specific date:

parameters:

fromWhen - the start date
bizDays - N business days from the start date (+ value for future date, - value for previous date)


function getBusinessDate(fromWhen, bizDays) {  
     var maxWindow = 365 ; // Business day cannot exceed this window
     var fdate;
     var forward = true;
     // list of days that are holidays
     var holidays = "D01012010,D02152010,D12252010";
     // list of days of week that's non-business day
     var nonBizDays = "D1,D7";

     if(isValiddate(fromWhen)){
         fdate = new Date(parseInt(fromWhen.split('/')[2],10), parseInt(fromWhen.split('/')[0],10) - 1, parseInt(fromWhen.split('/')[1],10), 0,0,0,0);
     }else{
         fdate = new Date();
     }
     
     if(bizDays < bizdays =" -bizDays;" forward =" false;" daysskipped =" 0;" i="0;i maxWindow){
                 alert("Cannot find any business day within " + maxWindow + " days !");
                 return false;
             }
             if(holidays.indexOf(getDateStr(fdate))<0 dayfound =" true;" day =" date.getDate();" day = "0" month =" date.getMonth()+1;" month = "0" year =" date.getFullYear();" datestr = "D" indate =" inDateObj;" slashcnt =" 0;" validdate =" true;" indate ="="" i =" 0;" onechar =" inDate.charAt(i);" onechar ="="" slashcnt ="="" slash1index =" i" slashcnt ="="" slash2index =" i"> '9')
       {
         validdate = false;
       }
 }
 if (!validdate) {
   return false;
 }

 if (slashcnt != 2) {
   return false;
 }

 monthStr = inDate.substring(0,slash1Index);
 if (monthStr.length == 0) monthStr = "0";
 dayStr = inDate.substring(slash1Index+1,slash2Index);
 if (dayStr.length == 0) dayStr = "0";
 yearStr = inDate.substring(slash2Index+1,inDate.length);
 month = parseInt(monthStr, 10);
 day = parseInt(dayStr, 10);
 year = parseInt(yearStr, 10);
 if ((yearStr.length != 2) && (yearStr.length != 4)) {
   return false;
 }

 if (month > 12 || month < daysinmonth =" getDaysInMonth(month,"> daysInMonth)) {
   return false;
 }
 return true;
}


function getDaysInMonth(month,year)  {
   var days = 0;
   if (month==1 || month==3 || month==5 || month==7 || month==8 ||
       month==10 || month==12)  days=31;
   else if (month==4 || month==6 || month==9 || month==11) days=30;
   else if (month==2)  {
       if (isLeapYear(year)) {
           days=29;
       } else {
           days=28;
       }
   }
   return (days);
}


function isLeapYear (Year) {
   if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) {
       return (true);
   } else {
       return (false);
   }
}


Examples:

To get the next business day: getBusinessDate(null,1);

To get the date that's 10 business day from today: getBusinessDate(null,10);

To get the date that's 10 business day from March 1st, 2010: getBusinessDate('03/01/2010',10);

Wednesday, February 3, 2010

Get Only Date from DateTime in T-SQL

I need to sort the records based entrydate, transferType, then amount.
So I wrote something like
SELECT entrydate
FROM mytable
ORDER BY groupvalue, transfertype, amout
The result is not correct because the entrydate column is date time column so when doing the sort, records on the same date but different time are considered different group, so the later transfertype and amount sort is not grouped correctly.
I need to sort the entrydate only by the date part. I google around and find a solution at Anatoly Lubarsky's blog on T-SQL: Get only Date from DateTime.

To get the date part, we can use:
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
So my previous t-sql statement becomes:
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, entrydate )) 'groupvalue'
FROM mytable
ORDER BY groupvalue, transfertype, amout
Now everything is working correctly.