【问题标题】:Get next day, skip weekends第二天去,跳过周末
【发布时间】:2017-01-01 10:49:24
【问题描述】:

我想使用 JavaScript 生成下一个工作日。

这是我现在的代码

var today = new Date();
    today.setDate(today.getDate());
    var tdd = today.getDate();
    var tmm = today.getMonth()+1;
    var tyyyy = today.getYear();

    var date = new Date();

    date.setDate(date.getDate()+3);

问题是,在星期五它返回星期六的日期,而我希望它是星期一

【问题讨论】:

  • 看天(today.getDay()),如果是5(星期五)加3,如果是6(星期六)加2,否则加1。
  • 添加一个 if 语句,如果 date 的星期几是星期六,则再添加两天。添加另一个 if 语句来检查星期日。

标签: javascript date datetime weekday


【解决方案1】:

您可以一次添加 1 天,直到您到达不是周六或周日的一天:

function getNextBusinessDay(date) {
  // Copy date so don't affect original
  date = new Date(+date);
  // Add days until get not Sat or Sun
  do {
    date.setDate(date.getDate() + 1);
  } while (!(date.getDay() % 6))
  return date;
}

// today,    Friday 26 Aug 2016
[new Date(), new Date(2016,7,26)].forEach(function(d) {
  console.log(d.toLocaleString() + ' : ' + getNextBusinessDay(d).toLocaleString());
});

您还可以测试一天并添加额外的以度过周末:

// Classic Mon to Fri
function getNextWorkDay(date) {
  let d = new Date(+date);
  let day = d.getDay() || 7;
  d.setDate(d.getDate() + (day > 4? 8 - day : 1));
  return d;
}

for (let i=0, d=new Date(); i<7; i++) {
  console.log(`${d.toDateString()} -> ${getNextWorkDay(d).toDateString()}`);
  d.setDate(d.getDate() + 1);
}

这是另一种方法,可以使用 ECMAScript 工作日数字(Sun = 0、Mon = 1 等)指定工作周。超出范围的日期将移至下一个工作周的开始日期。

这在每周不是典型的周一到周五的情况下很有用,例如在周六到周三很常见的中东,或者对于可能在周五到周一(或其他任何时间)工作的人来说。

function getNext(start, end, date) {
  let d = new Date(+date);
  d.setDate(d.getDate() + 1);
  let day = d.getDay();

  // Adjust end and day if necessary
  // The order of tests and adjustment is important
  if (end < start) {
    if (day <= end) {
      day += 7;
    }
    end += 7;
  }

  // If day is before start, shift to start
  if (day < start) {
    d.setDate(d.getDate() + start - day);

    // If day is after end, shift to next start (treat Sunday as 7)
  } else if (day > end) {
    d.setDate(d.getDate() + 8 - (day || 7));
  }
  return d;
}

// Examples
let f = new Intl.DateTimeFormat('en-GB', {
  weekday:'short',day:'2-digit', month:'short'});
let d = new Date();

[{c:'Work days Mon to Fri',s:1,e:5},
 {c:'Work days Sat to Wed',s:6,e:3},
 {c:'Work days Fri to Mon',s:5,e:1}
].forEach(({c,s,e}) => {
  for (let i = 0; i < 7; i++) {
    !i? console.log(`\n${c}`) : null;
    console.log(`${f.format(d)} => ${f.format(getNext(s, e, d))}`);
    d.setDate(d.getDate() + 1);
  }
});

【讨论】:

  • 实际上您的评论似乎是一个更好的主意:)
  • @mplungjan—固定,:-)
【解决方案2】:

这将选择下一个工作日。

var today = new Date(2016, 7, 26,12,0,0,0,0); // Friday at noon
console.log("today, Monday",today,"day #"+today.getDay());
var next = new Date(today.getTime());
next.setDate(next.getDate()+1); // tomorrow
while (next.getDay() == 6 || next.getDay() == 0) next.setDate(next.getDate() + 1);
console.log("no change    ",next,"day #"+next.getDay());
console.log("-------");
// or without a loop:

function getNextWork(d) {
  d.setDate(d.getDate()+1); // tomorrow
  if (d.getDay()==0) d.setDate(d.getDate()+1);
  else if (d.getDay()==6) d.setDate(d.getDate()+2);
  return d;
}
next = getNextWork(today); // Friday
console.log("today, Friday",today);
console.log("next, Monday ",next);
console.log("-------");
today = new Date(2016, 7, 29,12,0,0,0); // Monday at noon
next = getNextWork(today);              // Still Monday at noon
console.log("today, Monday",today);
console.log("no change    ",next);
console.log("-------");

// Implementing Rob's comment

function getNextWork1(d) {
  var day = d.getDay(),add=1;
  if (day===5) add=3;
  else if (day===6) add=2;
  d.setDate(d.getDate()+add);  
  return d;
}
today = new Date(2016, 7, 26,12,0,0,0,0); // Friday at noon
next = getNextWork1(today);               // Friday
console.log("today, Friday",today);
console.log("next, Monday ",next);
console.log("-------");
today = new Date(2016, 7, 26,12,0,0,0,0); // Monday at noon
next = getNextWork1(today); // Monday
console.log("today, Monday",today);
console.log("no change    ",next);

【讨论】:

    【解决方案3】:

    接受的答案将一次跳过一天,这回答了 OP 问题,但对于希望添加可变天数同时仍跳过周末的任何人,以下功能可能会有所帮助:

    function addWorkDays(date, days) {   
      while (days > 0) {
        date.setDate(date.getDate() + 1);
        if (date.getDay() != 0 && date.getDay() != 6) {
          days -= 1;
        }
      }          
      return date;
    }
    

    【讨论】:

    • 新年有问题(12 月 31 日 -> 2 月 1 日)
    【解决方案4】:

    看看这个:https://jsfiddle.net/e9a4066r/

    function get_next_weekday (date) {
        var tomorrow = new Date(date.setDate(date.getDate() + 1))
        return tomorrow.getDay() % 6
            ? tomorrow
            : get_next_weekday(tomorrow)
    }
    

    【讨论】:

    • 这是一个很好的方法!代码只是有一些问题。一个例子:如果我们使用 2016 年 12 月 31 日的日期跳转到 2 月 2 日而不是 2017 年 1 月 2 日 - 需要处理几个月和几年的边界。
    • 这实际上只是使用递归在周末进行迭代,就像其他答案之一一样,它会修改输入日期。递归的效率通常低于顺序处理。
    猜你喜欢
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多