添加日(仅限营业日)

时间:2016-02-04 10:14:52

标签: javascript

无论如何,只考虑只有工作日而没有循环的工作日,或者是为了吗?

重要的是,功能必须灵活,不计数,不计算星期六。

我正在使用这个JS函数:

var novaData = new Date(dataBase.valueOf());
var diasUteisRemanescente;
var isFimDeSemana;
var direcao;


// Remove decimais 
if (diasSoma !== parseInt(diasSoma, 10)) { throw new TypeError('AdicionaDiaUtil utiliza apenas dias uteis.'); }

// Se zero dias, não realiza mudança 
if (diasSoma === 0) { return dataBase; }

//Decide soma ou subtração 
direcao = diasSoma > 0 ? 1 : -1;

//decide numero de iterações
diasUteisRemanescente = Math.abs(diasSoma);

//Intera até chegar zerar os dias 
while (diasUteisRemanescente) {
    // adiciona/subtrai um dia 
    novaData.setDate(novaData.getDate() + direcao);
    //Verifica se o dia é util
    if (isSabadoUtil) {
        isFimDeSemana = novaData.getDay() in { 0: 'Sunday' };
    }
    else {
        isFimDeSemana = novaData.getDay() in { 0: 'Sunday', 6: 'Saturday' };
    }
    //Se for util remove um dia 
    if (!isFimDeSemana) { diasUteisRemanescente--; }
}
return novaData;

1 个答案:

答案 0 :(得分:1)

有关于添加工作日的many questions here already,但这可能不完全重复。

您需要定义一些规则,比如应该在周六或周二添加一天?你似乎喜欢moment-business.js的方式,所以以下内容相同 - 在星期一或星期六添加一天给星期一,并且函数修改传递的日期并返回。

以下任何周末日期至周日为正数或周六为负数,然后将“营业日”添加为每组5天7天。如果开始接近星期六(正面或周日为负面)比要添加的天数(例如周四+2),则会额外(或减去)额外的2天来结束周末。

如果开始时间是星期六或星期日,则会将其移至星期日,因此星期六加一天是星期一。如果添加零天,则返回原始日期。

注意:我已经使用Date构造函数从测试数据中的字符串创建日期,但这只是为了方便,它不应该像那样使用。始终手动解析字符串或使用库。

/*  Add business days (Monday to Friday) to a date
**  If number to add is zero, the original date is returned
**  If date is on a weekend, +ve count starts from Sunday, -ve count from Saturday
**
**  e.g. Saturday + 1 => Monday
**       Sunday   + 1 => Monday
**       Friday   + 1 => Monday
**       Saturday - 1 => Friday
**       Sunday   - 1 => Friday
**       Monday   - 1 => Friday
**       Tuesday  - 3 => Thursday
**
**  @param {Date} date - Date to add days to. The original date is modified
**  @param {number} n  - Days to add (+ve to add, -ve to subtract)
**  @returns {Date}    - The original Date with days added or subtracted
*/
function addBusinessDays(date, n) {

  // If adding zero days, just return date
  if (n == 0) return date;
  
  // Setup
  var weeks   = Math[n>0? 'floor' : 'ceil'](n / 5);
  var remDays = n % 5;
  var dayNum = date.getDay();
  var daysToAdd;
  
  // Move date to Sun (+ve) or Sat (-ve) if start is on a weekend
  date.setDate(date.getDate() + (n > 0? (dayNum == 6? 1 : 0 ) : (dayNum == 0? -1 : 0)));

  // Reset dayNum in case it just moved
  dayNum = date.getDay();

  // Calculate days to add - deal with +ve and -ve and if days to add is bigger than distance
  // to a weekend
  var daysToAdd =  weeks*7 + (n > 0?(remDays > (5 - dayNum)? 2 : 0) : (-1*remDays >= dayNum? -2 : 0)) + remDays;
  
  date.setDate(date.getDate() + daysToAdd);
  return date;
}

['2016-01-01 1', // Fri 1 Jan
 '2016-01-01 2', // Fri 1 Jan
 '2016-01-02 2', // Sat 2 Jan
 '2016-01-05 1', // Tue 5 Jan
 '2016-01-05 4', // Tue 5 Jan
 '2016-01-05 14', // Tue 5 Jan
 '2016-01-02 1', // Sat 2 Jan
 '2016-01-03 1'  // Sun 3 Jan
 ].forEach(function(v){
  var b = v.split(' ');
  document.write(f(new Date(b[0])) + ' ' + b[1] + ' : ' + f(addBusinessDays(new Date(b[0]), b[1])) + '<br>');
});

document.write('<br>Negatives<br><br>');

['2016-01-04 -1',  // Mon 4 Jan
 '2016-01-04 -2',  // Mon 4 Jan
 '2016-01-02 -2',  // Sat 2 Jan
 '2016-01-05 -1',  // Tue 5 Jan
 '2016-01-05 -4',  // Tue 5 Jan
 '2016-01-05 -14', // Tue 5 Jan
 '2016-01-02 -1',  // Sat 2 Jan
 '2016-01-03 -1'   // Sun 3 Jan
 ].forEach(function(v){
  var b = v.split(' ');
  document.write(f(new Date(b[0])) + ' ' + b[1] + ' : ' + f(addBusinessDays(new Date(b[0]), b[1])) + '<br>');
});

function f(d) {
  var days = 'Sun Mon Tue Wed Thu Fri Sat'.split(' ');
  return d.getFullYear() + '-' + ('0'+(d.getMonth()+1)).slice(-2) + '-' + ('0'+d.getDate()).slice(-2) + ' ' +days[d.getDay()];
}