-1

I have included given code in my js file

$( '.dateDisable' ).change(function() {
    calculateDays();
});

function calculateDays() {
  var first = new Date( $( '#start_date' ).val() ),
    last = new Date( $( '#end_date' ).val() ),
    daysDiff = leaveCalculation( first,last);  
}

function leaveCalculation( d1, d2 ) {
  alert(gon.holiday) // 2015-08-28,2015-09-25,2016-08-31,2016-08-07,2015-08-13,2016-08-29,2016-01-07,2015-09-08
  var weeks, dateDiff, weekDay1, weekDay2;
  if ( d2 < d1 ) return -1;
  weekDay1 = d1.getDay(),
    weekDay2 = d2.getDay();
  weeks = Math.floor( ( d2.getTime() - d1.getTime() ) / 604800000 );
  if ( weekDay1 <= weekDay2 )
    dateDiff = ( weeks * 5 ) + ( weekDay2 - weekDay1 );
  else
    dateDiff = ( ( weeks + 1 ) * 5 ) - ( weekDay1 - weekDay2 );
  return ( dateDiff + 1 );
}

I want to calculate days.

If I have selected date "27 August, 2015" - "31 August, 2015" it will calculate daysDiff = 3 but I want to take out daysDiff as if there is holiday on 28-08-2015 as I am fetching holiday disable dates in gon.holiday. In my case that would be

2015-08-28,2015-09-25,2016-08-31,2016-08-07,2015-08-13,2016-08-29,2016-01-07,2015-09-08

So if I have selected dates "27 August, 2015" - "31 August, 2015" then it will give me daysDiff as 2 because 28, 29 ,30 are already holiday. I want to exclude weekend also

How would I do that?

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Dinshaw Raje
  • 933
  • 1
  • 12
  • 33
  • Is `gon.holiday` an array or a plain string? – Jaay Aug 27 '15 at 09:23
  • @dinshaw raje : what are **dDate2** and **dDate1** ? by the way you can compare by using loop with holidays http://stackoverflow.com/questions/4428327/checking-if-two-dates-have-the-same-date-info and then subract them from **diffDays** – Muhammad Usman Aug 27 '15 at 09:23
  • its not an array it fetches simply like this 2015-08-28,2015-09-25,2016-08-31,2016-08-07,2015-08-13,2016-08-29,2016-01-07,2015-09-08 – Dinshaw Raje Aug 27 '15 at 09:27

3 Answers3

1

Like this

var gon = {};
gon["holiday"] = "2015-08-28,2015-09-25,2016-08-31,2016-08-07,2015-08-13,2016-08-29,2016-01-07,2015-09-08".split(",");

// 2 helper functions - moment.js is 35K minified so overkill in my opinion
function pad(num) { return ("0" + num).slice(-2); }
function formatDate(date) { var d = new Date(date), dArr = [d.getFullYear(), pad(d.getMonth() + 1), pad(d.getDate())];return dArr.join('-');}

function calculateDays(first,last) {
  var aDay = 24 * 60 * 60 * 1000,
  daysDiff = parseInt((last.getTime()-first.getTime())/aDay,10)+1;

  if (daysDiff>0) {  
    for (var i = first.getTime(), lst = last.getTime(); i <= lst; i += aDay) {
      var d = new Date(i);
      if (d.getDay() == 6 || d.getDay() == 0 // weekend
      || gon.holiday.indexOf(formatDate(d)) != -1) {
          daysDiff--;
      }
    }
  }
  return daysDiff;
}

// ONLY using jQuery here because OP already used it. I use 1.11 so IE8+

$(function() {
    var days = calculateDays(new Date($('#start_date').val()),
                             new Date($('#end_date').val()));
    if (days <= 0) {
      alert("Please enter an end date after the begin date");
    }
    else {
      alert(days +" working days found");
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="start_date" value="27 August, 2015" />
<input id="end_date" value="31 August, 2015" />
mplungjan
  • 169,008
  • 28
  • 173
  • 236
1

This can be implemented rather easily with Moment.js:

var startString = "2015-01-01";
var endString = "2015-02-20";
var holidaysString = "2015-01-03, 2015-01-15, 2015-02-05, 2015-03-01";

var start = moment(startString);
var end = moment(endString);
var holidays = holidaysString.split(',').map(function(str) {
  return moment(str);
});

var getDuration = function getDuration(start, end, holidays) {
  var overlappingDays = holidays.reduce(function(count, holiday) {
    return count + ~~(holiday.isAfter(start) && holiday.isBefore(end));
  }, 0);
  var diff = end.diff(start, 'days');
  return diff - overlappingDays;
};

output.innerHTML = getDuration(start, end, holidays);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<span id="output"></span> days.
Etheryte
  • 24,589
  • 11
  • 71
  • 116
  • Its not working as per my requirement I if I have dates between "27 August, 2015" - "31 August, 2015" then the no of days differ is 5 but I dont want to count sat and sun so it remains 3 but if there is some other holiday on 28 aug i.e on friday then it will not count holiday and output I want is 2 . – Dinshaw Raje Aug 27 '15 at 11:25
  • @dinshawraje If you wanted to exclude weekends as well, you should've started by writing that down in your question. – Etheryte Aug 27 '15 at 11:42
  • I have mentioned in my code that I am fetching days and then subtracting them – Dinshaw Raje Aug 27 '15 at 11:59
  • I would not call your code easy, readable or very understandable for beginners – mplungjan Aug 27 '15 at 12:49
  • @mplungjan What exactly are you having a hard time with? Using standard array methods or understanding a bitwise not? – Etheryte Aug 27 '15 at 13:04
  • I can read your code, but adding moment and ~~ and map and reduce and calling it easy? – mplungjan Aug 27 '15 at 14:37
  • @mplungjan Both map and reduce are standard array methods that are a core part of the language. Moment is the most commonly used Javascript date-time library. I don't see you making a point. – Etheryte Aug 27 '15 at 14:59
  • My point is to help a beginner. Map, reduce are standard (but quite new and unsupported in some browsers), ~~ are not standard usage but "clever". Moment.js is 35K unnecessary code in this case my opinion. Obviously others disagree since I got voted down and you got voted up – mplungjan Aug 27 '15 at 15:01
  • @mplungjan To be fair, you used jQuery, 82K of _"unnecessary code"_, just to get text from inputs for a small example so you're really building a straw-man argument here. Both map and reduce are supported by IE9+, the same browser support you get when using jQuery 2.x, just so you know. – Etheryte Aug 27 '15 at 15:07
  • Nope. OP already used that. My main code does not need jQuery and I use 1.11 in my snippet – mplungjan Aug 27 '15 at 15:11
0

You can calculate the days between the days

Then split the string of dates that are coming in at gon.holiday into an array

Then loop through this array subtracting days if they are between the two dates

function calculateDays(){
 var first = new Date( '27 August, 2015'),
    last = new Date('31 August, 2015'),
    daysDiff = leaveCalculation( first,last);
}
function leaveCalculation( d1, d2 ) {
  var holidayArr = [];
  var holiday = gon.holiday; //"2015-08-28,2015-09-25,2016-08-31,2016-08-07,2015-08-13,2016-08-29,2016-01-07,2015-09-08";
  if ( d2 < d1 ) return -1;
    
    var oneDay = 24*60*60*1000;
    var difDays = Math.round(Math.abs((d1.getTime() - d2.getTime())/(oneDay))); //find the number of days between the two dates
    var holidayArr = holiday.split(','); //split at ,
    for(var i=0; i<holidayArr.length;i++){ //loop through array
     if(new Date(holidayArr[i]) <= d2 && new Date(holidayArr[i]) >= d1){ //check if two dates are between the given dates
            difDays-=1;
        }
    }
  return difDays;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Pindo
  • 1,585
  • 5
  • 16
  • 32