views:

148

answers:

4

Hi i am using jquery-ui datepicker to select date and date.js to find difference between 2 dates.

Right now the problem is I want to exclude weekend days from calculation (saturday and sunday). How should i do that?

For example the user select start date (13/8/2010) and end date (16/8/2010). Since 14/8/2010 and 15/8/2010 is in week days, instead of 4 days total, i want it to be only 2 days.

This is the code im using right now:

<script type="text/javascript">

    $("#startdate, #enddate").change(function() {       

    var d1 = $("#startdate").val();
    var d2 = $("#enddate").val();

            var minutes = 1000*60;
            var hours = minutes*60;
            var day = hours*24;

            var startdate1 = getDateFromFormat(d1, "d-m-y");
            var enddate1 = getDateFromFormat(d2, "d-m-y");

            var days = 1 + Math.round((enddate1 - startdate1)/day);             

    if(days>0)
    { $("#noofdays").val(days);}
    else
    { $("#noofdays").val(0);}


    });

    </script>
+3  A: 

Maybe someone else can help you converting this function into JQuery's framework...

In raw javascript i will use:

Live Demo

 <script>
        function calcBusinessDays(dDate1, dDate2) { // input given as Date objects
        var iWeeks, iDateDiff, iAdjust = 0;
        if (dDate2 < dDate1) return -1; // error code if dates transposed
        var iWeekday1 = dDate1.getDay(); // day of week
        var iWeekday2 = dDate2.getDay();
        iWeekday1 = (iWeekday1 == 0) ? 7 : iWeekday1; // change Sunday from 0 to 7
        iWeekday2 = (iWeekday2 == 0) ? 7 : iWeekday2;
        if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1; // adjustment if both days on weekend
        iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
        iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;

        // calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
        iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000)

        if (iWeekday1 <= iWeekday2) {
          iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
        } else {
          iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
        }

        iDateDiff -= iAdjust // take into account both days on weekend

        return (iDateDiff + 1); // add 1 because dates are inclusive
    }
 </script>

found here

and to call that function, for example, something like:

  <script>
    alert(calcBusinessDays(new Date("August 11, 2010 11:13:00"),new Date("August 16, 2010 11:13:00")));
  </script>

## EDITED ##

If you want to use it with your that format just:

Your code will look like:

<script type="text/javascript">

    $("#startdate, #enddate").change(function() {       

    var d1 = $("#startdate").val();
    var d2 = $("#enddate").val();

            var minutes = 1000*60;
            var hours = minutes*60;
            var day = hours*24;

            var startdate1 = getDateFromFormat(d1, "d-m-y");
            var enddate1 = getDateFromFormat(d2, "d-m-y");


            var newstartdate=new Date();
            newstartdate.setFullYear(startdate1.getYear(),startdate1.getMonth(),startdate1.getDay());
            var newenddate=new Date();
            newenddate.setFullYear(enddate1.getYear(),enddate1.getMonth(),enddate1.getDay());
            var days = calcBusinessDays(newstartdate,newenddate);
      if(days>0)
      { $("#noofdays").val(days);}
      else
      { $("#noofdays").val(0);}
    });

 </script>
Garis Suero
thanks for the quick reply. will give this code a try and hope can solve my problem :)
cyberfly
To use it in your code use stardate1 and enddate1 as the parameters for the calcBusinessDays(date, date) function...
Garis Suero
the script doesnt accept this date format (11-08-2010). trying to figure out now.
cyberfly
Please see edited part...
Garis Suero
By the way, the function getDateFromFormat return a javascript Date object right?... because the function i've just posted accept Date objects as parameters
Garis Suero
thanks i get it work although the code is bit different. anyway thank very much for your help. I have been stucked by this problem for 2 days until i found stackoverflow and your great help.
cyberfly
+1 for posting a reference to the original code! I actually didn't see that when I looked at the post originally. The +1 is also because the code IS faster than my solution, but not by much :)
sberry2A
A: 

I get it work with this code. Note that the function is from date.js and businessday js (thanks to Garis Suero). Start Date 11-08-2010 End Date 16-08-2010 will result 4 days of leave.

<script type="text/javascript">

    $("#startdate, #enddate").change(function() {       

    var d1 = $("#startdate").val();
    var d2 = $("#enddate").val();

            var minutes = 1000*60;
            var hours = minutes*60;
            var day = hours*24;

            var startdate1 = getDateFromFormat(d1, "d-m-y");
            var enddate1 = getDateFromFormat(d2, "d-m-y");

            var days = calcBusinessDays(new Date(startdate1),new Date(enddate1));             

    if(days>0)
    { $("#noofdays").val(days);}
    else
    { $("#noofdays").val(0);}


    });

    </script>
cyberfly
+1  A: 

That looks like too much work to me. I'd rather let the computer do the heavy lifting- //

Date.bizdays= function(d1, d2){
    var bd= 0, dd, incr=d1.getDate();
    while(d1<d2){
        d1.setDate(++incr);
        dd= d1.getDay();
        if(dd%6)++bd;
    }
    return bd;
}

//test

var day1= new Date(2010, 7, 11), day2= new Date(2010, 7, 31);

alert(Date.bizdays(day1, day2))
kennebec
@kennebec, this is definitely a very feasible solution. However, it does mean a "fairly" high number of iterations which may or may not be significant overhead on the client's machine, but fine answer none-the-less.
sberry2A
+1  A: 

This is how I would do it

function getDays(d1, d2) {
    var one_day=1000*60*60*24;
    var d1_days = parseInt(d1.getTime()/one_day) - 1;
    var d2_days = parseInt(d2.getTime()/one_day);
    var days = (d2_days - d1_days);
    var weeks = (d2_days - d1_days) / 7;
    var day1 = d1.getDay();
    var day2 = d2.getDay();
    if (day1 == 0) {
        days--;
    } else if (day1 == 6) {
        days-=2;
    }
    if (day2 == 0) {
       days-=2;
    } else if (day2 == 6) {
       days--;
    }
    days -= parseInt(weeks) * 2;
    alert(days);
}

getDays(new Date("June 8, 2004"),new Date("February 6, 2010"));

EDIT
To clarify my comment to @keenebec...
That solution will work for small date differences quite nicely and is easy to understand. But take something as "short" as a 6 year span and you can see a remarkable difference in speed.

http://jsfiddle.net/aSvxv/

I included all 3 answers and the original answer is indeed the fastest, but not by much and the trade off for a few microseconds of execution is somewhat trivial to me in favor of readability.

sberry2A
+1 for the performance tests
Garis Suero