使用JavaScript获取给定月份的给定工作日

Jon*_*lem 6 javascript algorithm date

我正试图获得第n个工作日 - 例如,某个日期下降的第二个星期日.

例如,如果日期是2015年8月24日,我想这样做:

nthDayOfMonth(0, 2, new Date(2015, 7, 24))
Run Code Online (Sandbox Code Playgroud)

并获得2015年8月9日(8月的第2个星期日).然后,我希望能够添加一个月的日期,再次调用该功能,并获得2015年9月13日(9月的第2个星期日).

由于某种原因,下面的代码不起作用.

我错过了什么?

function nthDayOfMonth(day, n, date) {                                                                                              
    console.log(day);
    console.log(n);
    var count = 0; 
    var idate = new Date(date);                                                                                                       

    idate.setDate(1);                                                                                                                 

    while ((count) < n) {                                                                                                             
      idate.setDate(idate.getDate() + 1);
      if (idate.getDay() == day) {
        count++;                                                                                                                      
      }                                                                                                                               
    }                                                                                                                                 

return idate;                                                                                                                     
Run Code Online (Sandbox Code Playgroud)

}

Mic*_*zlo 8

您必须idate.getDay()在递增当月的日期前进行检查.否则,如果所需的工作日落在该月的第一天,您将得到错误的答案.

以下代码段演示了已更正的功能.

function print(s) {
  document.write(s + '<br />');
}

function nthWeekdayOfMonth(weekday, n, date) {
  var count = 0,
      idate = new Date(date.getFullYear(), date.getMonth(), 1);
  while (true) {
    if (idate.getDay() === weekday) {
      if (++count == n) {
        break;
      }
    }
    idate.setDate(idate.getDate() + 1);
  }
  return idate;
}

             // Second Sunday of the current month.
var date = new Date();
print(date = nthWeekdayOfMonth(0, 2, date)); 
             // Second Sunday of next month.
date.setMonth(date.getMonth() + 1);
print(date = nthWeekdayOfMonth(0, 2, date));

             // First Tuesday of September 2015.
print(nthWeekdayOfMonth(2, 1, new Date(2015, 8)));
             // First Wednesday of September 2015.
print(nthWeekdayOfMonth(3, 1, new Date(2015, 8)));
             // Second Tuesday of September 2015.
print(nthWeekdayOfMonth(2, 2, new Date(2015, 8)));
             // Second Wednesday of September 2015.
print(nthWeekdayOfMonth(3, 2, new Date(2015, 8)));
Run Code Online (Sandbox Code Playgroud)
body {
  font-family: sans-serif;
}
Run Code Online (Sandbox Code Playgroud)

有一种更好的方法可以计算所需的日期而不需要循环.我们首先考虑当月第一天的工作日.假设这是一个星期六,JavaScript调用6,你正在寻找一个星期天,这是0.

要到达本月的第一个星期日,您必须按这个天数推进日期:

0 - 6 + 7
Run Code Online (Sandbox Code Playgroud)

结果是1.计算如何工作?我们补充说,0 - 6从工作日6到工作日的天数0,以及将负值变为有效的工作日7.

一般来说,从工作日a到工作日的天数b是

(b - a + 7) % 7
Run Code Online (Sandbox Code Playgroud)

继续这个例子,假设我们想要这个月的第一个星期日.在那种情况下,我们到了.但是如果我们想要这个月的第二天,我们必须将日期提前7天.一般而言,如果n这n == 1意味着第一次出现给定的工作日,我们必须提前(n - 1) * 7几天.

为了把它放在一起,如果date是本月的第一天,我们可以得到在n次出现weekday通过推进

(weekday - date.getDay() + 7) % 7 + (n - 1) * 7
Run Code Online (Sandbox Code Playgroud)

这个月的第一天过去几天.

这种方法在下面实现.

function print(s) {
  document.write(s + '<br />');
}

function nthWeekdayOfMonth(weekday, n, date) {
  var date = new Date(date.getFullYear(), date.getMonth(), 1),
      add = (weekday - date.getDay() + 7) % 7 + (n - 1) * 7;
  date.setDate(1 + add);
  return date;
}

             // Second Sunday of the current month.
var date = new Date();
print(date = nthWeekdayOfMonth(0, 2, date)); 
             // Second Sunday of next month.
date.setMonth(date.getMonth() + 1);
print(date = nthWeekdayOfMonth(0, 2, date));

             // First Tuesday of September 2015.
print(nthWeekdayOfMonth(2, 1, new Date(2015, 8)));
             // First Wednesday of September 2015.
print(nthWeekdayOfMonth(3, 1, new Date(2015, 8)));
             // Second Tuesday of September 2015.
print(nthWeekdayOfMonth(2, 2, new Date(2015, 8)));
             // Second Wednesday of September 2015.
print(nthWeekdayOfMonth(3, 2, new Date(2015, 8)));
Run Code Online (Sandbox Code Playgroud)
body {
  font-family: sans-serif;
}
Run Code Online (Sandbox Code Playgroud)