如何计算';工作日';在Javascript中使用moment.js的两个日期之间?

如何计算';工作日';在Javascript中使用moment.js的两个日期之间?,javascript,date,formula,momentjs,Javascript,Date,Formula,Momentjs,如何使用moment.js在JavaScript中计算两个日期之间的工作日数。我有一个计算这些天的工作公式,但该公式并不满足所有条件: 这是我的密码: var start= moment(data[x].start_date); var end= moment(data[x].est_end_date); var difference= end.diff(start, 'days'); var wor

如何使用moment.js在JavaScript中计算两个日期之间的工作日数。我有一个计算这些天的工作公式,但该公式并不满足所有条件:

这是我的密码:

var start= moment(data[x].start_date);
                var end= moment(data[x].est_end_date);
                var difference= end.diff(start, 'days');
                var workingDays= Math.round((difference/7)*5);
//data[x] is for iterating over a loop
我在这里每7天有5天,因为周六和周日被视为非工作日,但如果从周日或周六开始计算天数,这个公式将失败


请任何人在这方面提供帮助,为避免此问题,必须进行哪些必要的更改。

只需将其分为三部分。。第一周、最后一周以及其间,类似这样的事情:

function workday_count(start,end) {
  var first = start.clone().endOf('week'); // end of first week
  var last = end.clone().startOf('week'); // start of last week
  var days = last.diff(first,'days') * 5 / 7; // this will always multiply of 7
  var wfirst = first.day() - start.day(); // check first week
  if(start.day() == 0) --wfirst; // -1 if start with sunday 
  var wlast = end.day() - last.day(); // check last week
  if(end.day() == 6) --wlast; // -1 if end with saturday
  return wfirst + Math.floor(days) + wlast; // get the total
} //              ^ EDIT: if days count less than 7 so no decimal point
测试代码

var ftest = {date:'2015-02-0',start:1,end:7};
var ltest = {date:'2015-02-2',start:2,end:8};
var f = 'YYYY-MM-DD';
for(var z=ftest.start; z<=ftest.end; ++z) {
  var start = moment(ftest.date + z);
  for(var y=ltest.start; y<=ltest.end; ++y) {
    var end = moment(ltest.date + y);
    var wd = workday_count(start,end);
    console.log('from: '+start.format(f),'to: '+end.format(f),'is '+wd+' workday(s)');
  }
}

我发现如果几天在同一周内(例如,从太阳到周六),kokizzu的回答就不起作用,所以我决定改为:

    function calcBusinessDays(startDate, endDate) { 
      var day = moment(startDate);
      var businessDays = 0;

      while (day.isSameOrBefore(endDate,'day')) {
        if (day.day()!=0 && day.day()!=6) businessDays++;
        day.add(1,'d');
      }
      return businessDays;
    }

我对Kokizzu的答案进行了修改,以解决夏季的问题。在巴西时区(GMT-3),2017年10月17日和2017年10月18日之间的差值为-2.71,而不是2

本周开始时间为UTC 2017年10月15日00:00或2017年10月14日21:00-03:00

本周结束时间为UTC 2017年10月22日00:00或2017年10月21日22:00-02:00(夏季)

因此,与7不同的是,“first”和“last”变量在几天内的差值是6(或8,取决于您所在的时区)

修正代码如下:

start = moment(start).utc().add(start.utcOffset(), 'm'); // Ignore timezones
end = moment(end).utc().add(end.utcOffset(), 'm'); // Ignore timezones

var first = start.clone().endOf('week'); // end of first week
var last = end.clone().startOf('week'); // start of last week

// Fixing Summer Time problems
firstCorrection = moment(first).utc().add(60, 'm').toDate(); //
var days = last.diff(firstCorrection,'days') * 5 / 7; // this will always multiply of 7

var wfirst = first.day() - start.day(); // check first week
if(start.day() == 0) --wfirst; // -1 if start with sunday
var wlast = end.day() - last.day(); // check last week
if(end.day() == 6) --wlast; // -1 if end with saturday
return wfirst + days + wlast; // get the total (subtract holidays if needed)

我使用一个简单的函数来实现这一点。也许这不是最有效的,但它确实有效。它不需要Moment.js。它只是Javascript

function getNumWorkDays(startDate, endDate) {
    var numWorkDays = 0;
    var currentDate = new Date(startDate);
    while (currentDate <= endDate) {
        // Skips Sunday and Saturday
        if (currentDate.getDay() !== 0 && currentDate.getDay() !== 6) {
            numWorkDays++;
        }
        currentDate = currentDate.addDays(1);
    }
    return numWorkDays;
}
您可以尝试以下方法(无循环):

通过使用,可以采用以下方式:

private calculateWorkdays(startDate: Date, endDate: Date): number {
// + 1 cause diff returns the difference between two moments, in this case the day itself should be included.

const totalDays: number = moment(endDate).diff(moment(startDate), 'days') + 1;
const dayOfWeek = moment(startDate).isoWeekday();
let totalWorkdays = 0;

for (let i = dayOfWeek; i < totalDays + dayOfWeek; i++) {
    if (i % 7 !== 6 && i % 7 !== 0) {
      totalWorkdays++;
    }
  }
  return totalWorkdays;
}
private calculateWorkdays(开始日期:日期,结束日期:日期):数字{
//+1 cause diff返回两个时刻之间的差值,在这种情况下,应包括当天本身。
const totalDays:number=时刻(endDate).diff(时刻(startDate),'days')+1;
const dayOfWeek=时刻(startDate).isoWeekday();
总工作日=0;
for(设i=dayOfWeek;i
我在《工作日》和《时刻》中使用了一个有用的库

之间的工作日数示例
const diff=moment('05-15-2017','MM-DD-YYYY')。businessDiff(moment('05-08-2017','MM-DD-YYYY');
//差异=5

对于5天的日期范围,它给出了5.7天。事实上,对于小于7天的日期范围,该值是十进制数字。我也有同样的问题。这是由于一周开始和结束之间的夏季时间差异造成的。修复方法如下。只需添加
Math。floor(days)
将解决问题“\uuuuu”),感谢您发现了这一点,我们终于做到了!在stackoverflow.com上只允许使用英语回答。要了解更多信息,请阅读我几个月的作品。。。也许你可以分享你的代码/错误?
Date.prototype.addDays = function (days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
};
  function getBusinessDays(endDate, startDate) {
    var lastDay = moment(endDate);
    var firstDay = moment(startDate);
    let calcBusinessDays = 1 + (lastDay.diff(firstDay, 'days') * 5 -
      (firstDay.day() - lastDay.day()) * 2) / 7;

    if (lastDay.day() == 6) calcBusinessDays--;//SAT
    if (firstDay.day() == 0) calcBusinessDays--;//SUN

    return calcBusinessDays;
  }
private calculateWorkdays(startDate: Date, endDate: Date): number {
// + 1 cause diff returns the difference between two moments, in this case the day itself should be included.

const totalDays: number = moment(endDate).diff(moment(startDate), 'days') + 1;
const dayOfWeek = moment(startDate).isoWeekday();
let totalWorkdays = 0;

for (let i = dayOfWeek; i < totalDays + dayOfWeek; i++) {
    if (i % 7 !== 6 && i % 7 !== 0) {
      totalWorkdays++;
    }
  }
  return totalWorkdays;
}