SOURCE

/**
 * 计算一段时间内工作的天数。不包括周末和法定节假日,法定调休日为工作日,周末为周六、周日两天;
 * @param {*} mode 推算模式('cn'表示国人习惯【周一至周日】;'en'表示国际习惯【周日至周一】)
 * @param {*} beginDay 时间段开始日期;
 * @param {*} endDay 时间段结束日期;
 */
function getWorkDayCount(mode, beginDay, endDay) {
  // 法定节假日和调休日的设定
  var Holiday = ['2012-01-01', '2012-01-02', '2012-01-03', '2012-01-22', '2012-01-23', '2012-01-24', '2012-01-25', '2012-01-26', '2012-01-27', '2012-01-28', '2012-04-02', '2012-04-03', '2012-04-04', '2012-04-29', '2012-04-30', '2012-05-01', '2012-06-22', '2012-06-23', '2012-06-24', '2012-09-30', '2012-10-01', '2012-10-02', '2012-10-03', '2012-10-04', '2012-10-05', '2012-10-06', '2012-10-07'];

  var WeekendsOff = ['2011-12-31', '2012-01-21', '2012-01-29', '2012-03-31', '2012-04-01', '2012-04-28', '2012-09-29'];

  /**
   * 计算当前时间(或指定时间),向前推算周数(weekcount),得到结果周的第一天的时期值;
   * @param {*} mode 推算模式('cn'表示国人习惯【周一至周日】;'en'表示国际习惯【周日至周一】)
   * @param {*} weekcount 表示周数(0-表示本周, 1-前一周,2-前两周,以此推算);
   * @param {*} end 指定时间的字符串(未指定则取当前时间);
   */
  var nearlyWeeks = function(mode, weekcount, end) {
    if (typeof mode === 'undefined') mode = 'cn';
    if (typeof weekcount === 'undefined') weekcount = 0;
    if (typeof end !== 'undefined') end = new Date(new Date(end).toDateString());
    else end = new Date(new Date().toDateString());

    var days = 0;
    if (mode === 'cn') days = (end.getDay() === 0 ? 7 : end.getDay()) - 1;
    else days = end.getDay();

    return new Date(end.getTime() - (days + weekcount * 7) * 24 * 60 * 60 * 1000);
  };

  var begin = new Date(beginDay.toDateString());
  var end = new Date(endDay.toDateString());

  // 每天的毫秒总数,用于以下换算
  var daytime = 24 * 60 * 60 * 1000;
  // 两个时间段相隔的总天数
  var days = (end - begin) / daytime + 1;
  // 时间段起始时间所在周的第一天
  var beginWeekFirstDay = nearlyWeeks(mode, 0, beginDay.getTime()).getTime();
  // 时间段结束时间所在周的最后天
  var endWeekOverDay = nearlyWeeks(mode, 0, endDay.getTime()).getTime() + 6 * daytime;

  // 由beginWeekFirstDay和endWeekOverDay换算出,周末的天数
  var weekEndCount = (((endWeekOverDay - beginWeekFirstDay) / daytime + 1) / 7) * 2;
  // 根据参数mode,调整周末天数的值
  if (mode === 'cn') {
    if (endDay.getDay() > 0 && endDay.getDay() < 6) weekEndCount -= 2;
    else if (endDay.getDay() === 6) weekEndCount -= 1;

    if (beginDay.getDay() === 0) weekEndCount -= 1;
  } else {
    if (endDay.getDay() < 6) weekEndCount -= 1;

    if (beginDay.getDay() > 0) weekEndCount -= 1;
  }

  // 根据调休设置,调整周末天数(排除调休日)
  WeekendsOff.forEach(function(offitem, i) {
    var itemDay = new Date(offitem.split('-')[0] + '/' + offitem.split('-')[1] + '/' + offitem.split('-')[2]);
    // 如果调休日在时间段区间内,且为周末时间(周六或周日),周末天数值-1
    if (itemDay.getTime() >= begin.getTime() && itemDay.getTime() <= end.getTime() && (itemDay.getDay() === 0 || itemDay.getDay() === 6)) weekEndCount -= 1;
  });
  // 根据法定假日设置,计算时间段内周末的天数(包含法定假日)
  Holiday.forEach(function(itemHoliday, i) {
    var itemDay = new Date(itemHoliday.split('-')[0] + '/' + itemHoliday.split('-')[1] + '/' + itemHoliday.split('-')[2]);
    // 如果法定假日在时间段区间内,且为工作日时间(周一至周五),周末天数值+1
    if (itemDay.getTime() >= begin.getTime() && itemDay.getTime() <= end.getTime() && itemDay.getDay() > 0 && itemDay.getDay() < 6) weekEndCount += 1;
  });

  // 工作日 = 总天数 - 周末天数(包含法定假日并排除调休日)
  return days - weekEndCount;
}

document.write(`2018/09/28至2018/10/10实际工作天数为${getWorkDayCount('cn', new Date('2018/09/28'), new Date('2018/10/10'))}天`)
console 命令行工具 X clear

                    
>
console