[英]Get date of specific weekday after a specified date with Moment.js
I am trying to get the date for the next instance of a weekday after a given date. 我正在尝试获取给定日期后一个工作日的下一个实例的日期。 The weekday may be any day from Monday through Sunday.
工作日可能是星期一至星期日的任何一天。 I am using the Moment.js library but there doesn't seem to be a simple way to achieve what I am after.
我正在使用Moment.js库,但是似乎没有一种简单的方法可以实现我所追求的目标。
This is what I have so far but it's not returning the date I want: 这是到目前为止,我没有得到想要的日期:
// competition.startDate = 2016-02-10 (Wednesday)
var startDate = moment(competition.startDate);
...
for (m = 0; m < matchesPerRound; m++) {
var date;
...
// matchTime[m].day = 3 (Wednesday)
date = startDate.startOf('week').add(7, 'days').subtract(matchTime[m].day, 'days');
console.log(date.format('YYYY-MM-DD'));
// Actual Output = 2016-02-11
// Expected Output = 2016-02-10
...
}
With the example above, I need it returning 2016-02-15
as this is the next Monday after 2016-02-10
. 在上面的示例中,我需要它返回
2016-02-15
因为这是2016-02-10
之后的下一个星期一。 This is no problem, and I can get that date. 没问题,我可以得到那个日期。 My problem is that I need something more dynamic, as
matchTime[m].day
could be any weekday number. 我的问题是我需要更动态的东西,因为
matchTime[m].day
可以是任何工作日数字。 For example, if matchTime[m].day = 3 // Wednesday
, it should just return the same startDate 2016-02-10
as this is a Wednesday. 例如,如果
matchTime[m].day = 3 // Wednesday
,它应该只返回相同的startDate 2016-02-10
因为这是星期三。
I'm trying to avoid conditional statements if possible, but I am wondering if Moment.js has the functionality out of the box to produce these results. 我试图尽可能避免使用条件语句,但是我想知道Moment.js是否具有开箱即用的功能来产生这些结果。
UPDATE UPDATE
I've come up with a solution, and it's working with my requirements, but I feel it's very messy. 我想出了一个解决方案,它可以满足我的要求,但是我感到这很麻烦。 Does someone else have a cleaner, more concise solution?
别人有更清洁,更简洁的解决方案吗?
var date;
var startDate = moment(competition.startDate);
var proposedDate = moment(startDate).startOf('isoweek').add(matchTimes[0].day - 1, 'd');
if ( startDate.isAfter(proposedDate) ) {
date = startDate.startOf('isoweek').add(7 + Number(matchTimes[0].day) - 1, 'd');
} else {
date = startDate.startOf('isoweek').add(matchTimes[0].day - 1, 'd');
}
This is a pure JS version: 这是一个纯JS版本:
function claculateNextDate() { var date = new Date(); var nextDay = document.getElementById("dayOfWeek").value; var day = date.getDay(); var noOfDaysToAdd = (7 - day) + parseInt(nextDay); date.setDate(date.getDate() + noOfDaysToAdd); document.getElementById("result").innerHTML = date.toDateString(); }
<select id="dayOfWeek"> <option value="0">Sunday</option> <option value="1">Monday</option> <option value="2">Tuesday</option> <option value="3">Wednesday</option> <option value="4">Thursday</option> <option value="5">Friday</option> <option value="6">Saturday</option> </select> <button onclick="claculateNextDate()">Calculate Next Date</button> <p id="result"></p>
I don't know about moment.js, but it seems rather complex for something rather simple. 我不知道moment.js,但是对于一些简单的事情来说似乎很复杂。
function firstMatchingDayOfWeek(day, date) {
var delta = date.getDay() - day,
result = new Date(date);
if (delta) {
result.setDate(result.getDate() + ((7 - delta) % 7));
}
return result;
}
I think the code is rather self-explanatory (don't we all ;-) ), but in order to clarify the steps: 我认为代码是不言自明的(不是所有人;-)),但是为了澄清步骤:
firstMatchingDayOfWeek(day, date)
> call the function specifying the day of week (0-6) and a date object firstMatchingDayOfWeek(day, date)
>调用指定星期几(0-6)和日期对象的函数 delta = date.getDay() - day
> calculate how many days the date needs to shift in order to reach the same day of week delta = date.getDay() - day
>计算日期需要移动多少天才能到达一周的同一天 result = new Date(date)
> create a new Date instance based on the input (so you get to preserve the original date) result = new Date(date)
>根据输入创建一个新的Date实例(这样您就可以保留原始日期) result.setDate(result.getDate() + ((7 - delta) % 7))
> set the date
part (day of month) to a week minus the delta, modulo a week (as delta can be negative and you want the first occurrence of the same day) result.setDate(result.getDate() + ((7 - delta) % 7))
>将date
部分(每月的某天)设置为减去delta的一周,以一周为模(因为delta可以为负,并且您希望当天的第一次出现) function firstMatchingDayOfWeek(day, date) { var delta = date.getDay() - day, result = new Date(date); if (delta) { result.setDate(result.getDate() + ((7 - delta) % 7)); } return result; } // tests for (var i = 1; i < 28; ++i){ var check = new Date('2016-02-' + ('00' + i).substr(-2)), output = document.querySelector('#out') .appendChild(document.createElement('pre')), log = []; log.push('input: ' + check); for (var day = 0; day <= 6; ++day) { var next = firstMatchingDayOfWeek(day, check); log.push(day + ' > ' + next); } output.innerText = log.join('\\n'); }
pre { border: 1px solid gold; }
<div id="out"></div>
Here's a possible answer too using momentjs (assumes match days will be 0 (sunday) - 6): 这也是使用momentjs的可能答案(假设比赛日将为0(星期日)-6):
var startDate = moment(competition.startDate);
var matchDay = Number(matchTimes[0].day);
var daysToAdd = Math.ceil((startDate.day() - matchDay) / 7) * 7 + matchDay;
var proposedDate = moment(startDate).startOf('week').add(daysToAdd, 'd');
My solution 我的解决方案
var weekDayToFind = moment().day('Monday').weekday() //change monday to searched day name
var givenDate = moment('2016-02-10') // pass the given date
var searchDate = moment(givenDate)
while (searchDate.weekday() !== weekDayToFind){
searchDate.add(1, 'day');
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.