исключить выходные дни в расчете даты javascript

у меня есть два набора кодов, которые работают. Нужна помощь, чтобы объединить их в одно целое.

этот код дает мне разницу между двумя датами. отлично работает:

function test(){
var date1 = new Date(txtbox_1.value);    
var date2 = new Date(txtbox_2.value);

var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));

var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;

var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;

var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;

txtbox_3.value = days + "." + hrs; }

источник для вышеуказанного кода

код ниже @cyberfly, похоже, имеет ответ на исключение sat и sun, который мне нужен. источник. Однако его в jquery и вышеуказанный код находятся в JS. Поэтому нужна была помощь, так как мне не хватало этих знаний :(

<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>

редактировать Сделал попытку комбинирования кодов. вот мой образец. получение объект ожидаемая ошибка.

function test(){
var date1 = new Date(startdate.value);    
var date2 = new Date(enddate.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff)); 
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;

var startdate1 = getDateFromFormat(startdate, "dd/mm/yyyy hh:mm");
var enddate1 = getDateFromFormat(enddate, "dd/mm/yyyy hh:mm");
days = calcBusinessDays(new Date(startdate1),new Date(enddate1));           
noofdays.value = days + "." + hrs; }

start: <input type="text" id="startdate" name="startdate" value="02/03/2015 00:00">
end: <input type="text" id="enddate" name="enddate" value="02/03/2015 00:01">
<input type="text" id="noofdays" name="noofdays" value="">

4 ответов


при определении количества дней между двумя датами необходимо принять множество решений о том, что такое День. Например, период с 1 февраля по 2 февраля обычно составляет один день, поэтому с 1 февраля по 1 февраля-ноль дней.

при добавлении сложности подсчета только рабочих дней, все становится намного сложнее. Например. С понедельника 2 февраля 2015 по пятницу 6 февраля-4 прошедших дня (с понедельника по вторник-1, с понедельника по среду-2 и т. д.), однако выражение "с понедельника по пятницу" вообще рассматриваемый как 5 рабочих дней, а продолжительность Пн 2 февраля по сб 7 февраля также должна быть 4 рабочих дня, но с воскресенья по субботу должно быть 5.

вот мой алгоритм:

  1. получить общее количество целых дней между двумя датами
  2. разделить на 7, чтобы получить количество целых недель
  3. умножить количество недель на два, чтобы получить количество выходных дней
  4. вычесть количество выходных дней из целого, чтобы получить бизнес дни
  5. если общее количество дней не является четным числом недель, добавьте число недель * 7 к дате начала, чтобы получить временную дату
  6. пока дата temp чем дата конца:
    • если дата temp не суббота или воскресенье, добавьте один рабочих дней
    • добавить один в дату temp
  7. вот и все.

шагающая часть в конце, вероятно, может быть заменена каким-то другим алгоритмом, но она никогда не будет петлять более 6 дней, поэтому это простое и разумно эффективное решение проблемы неравномерных недель.

некоторые последствия вышеизложенного:

  1. С понедельника по пятницу-4 рабочих дня
  2. любой день в тот же день в другой неделе четное количество недель и, следовательно, четный mutiple 5, например, понедельник 2 февраля в понедельник 9 февраля и воскресенье 1 февраля в воскресенье 8 февраля 5 рабочих дней
  3. пятница 6 февраля до воскресенья 7 февраля-ноль рабочие дни
  4. пятница 6 февраля до понедельника 9 февраля-один рабочий день
  5. воскресенье 8 февраля: воскресенье 15 февраля, СБ 14 февраля и пт 13 февраля все 5 рабочих дней

вот код:

// Expects start date to be before end date
// start and end are Date objects
function dateDifference(start, end) {

  // Copy date objects so don't modify originals
  var s = new Date(+start);
  var e = new Date(+end);

  // Set time to midday to avoid dalight saving and browser quirks
  s.setHours(12,0,0,0);
  e.setHours(12,0,0,0);

  // Get the difference in whole days
  var totalDays = Math.round((e - s) / 8.64e7);

  // Get the difference in whole weeks
  var wholeWeeks = totalDays / 7 | 0;

  // Estimate business days as number of whole weeks * 5
  var days = wholeWeeks * 5;

  // If not even number of weeks, calc remaining weekend days
  if (totalDays % 7) {
    s.setDate(s.getDate() + wholeWeeks * 7);

    while (s < e) {
      s.setDate(s.getDate() + 1);

      // If day isn't a Sunday or Saturday, add to business days
      if (s.getDay() != 0 && s.getDay() != 6) {
        ++days;
      }
    }
  }
  return days;
}

Не знаю, как он сравнивается с ответом jfriend00 или кодом, на который вы ссылались, если вы хотите, чтобы период был включительным, просто добавьте его, если дата начала или окончания-рабочий день.


вот простая функция для вычисления количества рабочих дней между двумя объектами. Как и планировалось, он не учитывает начальный день, но считает конечный день, поэтому, если вы дадите ему дату во вторник одной недели и вторник следующей недели, он вернет 5 рабочих дней. Это не учитывает праздники, но работает должным образом во всех изменениях летнего времени.

function calcBusinessDays(start, end) {
    // This makes no effort to account for holidays
    // Counts end day, does not count start day

    // make copies we can normalize without changing passed in objects    
    var start = new Date(start);
    var end = new Date(end);

    // initial total
    var totalBusinessDays = 0;

    // normalize both start and end to beginning of the day
    start.setHours(0,0,0,0);
    end.setHours(0,0,0,0);

    var current = new Date(start);
    current.setDate(current.getDate() + 1);
    var day;
    // loop through each day, checking
    while (current <= end) {
        day = current.getDay();
        if (day >= 1 && day <= 5) {
            ++totalBusinessDays;
        }
        current.setDate(current.getDate() + 1);
    }
    return totalBusinessDays;
}

и, код jQuery + jQueryUI для демо:

// make both input fields into date pickers
$("#startDate, #endDate").datepicker();

// process click to calculate the difference between the two days
$("#calc").click(function(e) {
    var diff = calcBusinessDays(
        $("#startDate").datepicker("getDate"), 
        $("#endDate").datepicker("getDate")
    );
    $("#diff").html(diff);
});

и вот простой демо построен с выбора даты в jQueryUI: http://jsfiddle.net/jfriend00/z1txs10d/


@RobG дал отличный алгоритм для отделения рабочих дней от выходных. Я думаю, что единственная проблема заключается в том, что если начальные дни-выходные, суббота или воскресенье, то нет рабочих дней/выходных будет одним меньше.

исправленный код ниже.

function dateDifference(start, end) {

  // Copy date objects so don't modify originals

  var s = new Date(start);
  var e = new Date(end);

    var addOneMoreDay = 0;
    if( s.getDay() == 0 || s.getDay() == 6 ) {
    addOneMoreDay = 1;
  }

  // Set time to midday to avoid dalight saving and browser quirks
  s.setHours(12,0,0,0);
  e.setHours(12,0,0,0);

  // Get the difference in whole days
  var totalDays = Math.round((e - s) / 8.64e7);

  // Get the difference in whole weeks
  var wholeWeeks = totalDays / 7 | 0;

  // Estimate business days as number of whole weeks * 5
  var days = wholeWeeks * 5;

  // If not even number of weeks, calc remaining weekend days
  if (totalDays % 7) {
    s.setDate(s.getDate() + wholeWeeks * 7);

    while (s < e) {
      s.setDate(s.getDate() + 1);

      // If day isn't a Sunday or Saturday, add to business days
      if (s.getDay() != 0 && s.getDay() != 6) {
        ++days;
      }
      //s.setDate(s.getDate() + 1);
    }
  }
  var weekEndDays = totalDays - days + addOneMoreDay;
  return weekEndDays;
}

ссылка JSFiddle-этоhttps://jsfiddle.net/ykxj4k09/2/


сначала получить количество дней в месяц

     totalDays(month, year) {
        return new Date(year, month, 0).getDate();
     }

тогда не получите рабочих дней в месяц, удалив субботу и воскресенье

  totalWorkdays() {
     var d = new Date(); // to know present date
     var m = d.getMonth() + 1; // to know present month
     var y = d.getFullYear(); // to knoow present year
     var td = this.totalDays(m, y);// to get no of days in a month
     for (var i = 1; i <= td; i++) {  
        var s = new Date(y, m - 1, i);
        if (s.getDay() != 0 && s.getDay() != 6) {
           this.workDays.push(s.getDate());// working days
        }else {
           this.totalWeekDays.push(s.getDate());//week days
         }
      }
      this.totalWorkingDays = this.workDays.length;
 }