我正试图获得第n个工作日 - 例如,某个某个日期所在的第二个星期日 -
例如,如果日期是2015年8月24日,我想这样做:
nthDayOfMonth(0, 2, new Date(2015, 7, 24))
并获得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;
}
答案 0 :(得分: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)));
&#13;
body {
font-family: sans-serif;
}
&#13;
有一种更好的方法可以在不循环的情况下计算所需的日期。我们首先考虑当月第一天的工作日。假设它是星期六,JavaScript调用6
,并且您正在寻找一个0
的星期日。
要到达本月的第一个星期日,您必须按这个天数提前约会:
0 - 6 + 7
结果是1.计算如何运作? 0 - 6
是从工作日6
到工作日0
的天数,要将负值变为有效的工作日,我们会添加7
。
一般情况下,从工作日a
到工作日b
的天数为
(b - a + 7) % 7
继续这个例子,假设我们想要这个月的第一个星期日。在那种情况下,我们已经到了。但是如果我们想要这个月的第二天,我们必须将日期提前7天。一般来说,给定n
,n == 1
表示给定工作日的第一次出现,我们必须提前(n - 1) * 7
天。
总而言之,如果date
是该月的第一天,我们可以通过推进n
来weekday
出现
(weekday - date.getDay() + 7) % 7 + (n - 1) * 7
每月第一天过后。
此方法在下面实施。
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)));
&#13;
body {
font-family: sans-serif;
}
&#13;
答案 1 :(得分:0)
我刚刚对Michael Laszlo的优秀答案进行了调整,允许调用者提供n == 5(或任何更大的值)来表示需要该月的最后一个工作日:
function nthWeekdayOfMonth(weekday, n, date) {
var month = date.getMonth();
var date = new Date(date.getFullYear(), month, 1),
add = (weekday - date.getDay() + 7) % 7 + (n - 1) * 7;
// make sure that we stay in the same month
do {
date.setMonth(month);
date.setDate(1 + add);
add -= 7;
} while (date.getMonth() != month);
return date;
}