javascript - 添加日期(仅限工作日)

标签 javascript

有没有办法只考虑工作日而不需要像 while 或 for 这样的循环来添加日期?

重要的是,该功能必须灵活地工作,不计算周六。

我正在使用这个 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;

最佳答案

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()];
}

关于javascript - 添加日期(仅限工作日),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35198187/

相关文章:

javascript - 无法在 ASP.NET 中集成 reCAPTCHA v2(服务器端)

javascript - 使用 AJAX 提交表单 PHP JQuery 将我带到操作页面

javascript - CSS 过渡、绝对定位和 React 过渡组的问题

javascript - 如何为Each() 类创建点击监听器

javascript - Android 4.4.2 原生浏览器选择和上传文件的网页

javascript - 在 PHP 中转义 Javascript 中的引号

javascript - YouTube API : How to grab video ID? JQuery/Json

javascript - 使用lookarounds来查找匹配的javascript

javascript - 我如何将下拉列表 html/css 附加到 jquery 1 行正文

javascript - 如何在ionic 2的下拉列表中动态添加值