无论如何,只考虑只有工作日而没有循环的工作日,或者是为了吗?
重要的是,功能必须灵活,不计数,不计算星期六。
我正在使用这个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;
答案 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()];
}