使用Moment.js获取指定日期之后的特定工作日的日期

时间:2016-01-24 06:35:35

标签: javascript date momentjs

我想在给定日期之后获取工作日的下一个实例的日期。工作日可以是周一至周日的任何一天。我正在使用Moment.js库,但似乎并不是一种简单的方法来实现我的目标。

这是我到目前为止所得到的,但它没有返回我想要的日期:

// 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
    ...

}

通过上面的示例,我需要它返回2016-02-15,因为这是2016-02-10之后的下一个星期一。这没问题,我可以得到那个日期。我的问题是我需要一些更有活力的东西,因为matchTime[m].day可能是任何工作日的数字。例如,如果是matchTime[m].day = 3 // Wednesday,它应该返回相同的startDate 2016-02-10,因为这是星期三。

我试图尽可能避免使用条件语句,但我想知道Moment.js是否具有开箱即用的功能来产生这些结果。

更新

我提出了一个解决方案,它正在按照我的要求工作,但我觉得它非常混乱。其他人是否有更清洁,更简洁的解决方案?

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');
}

4 个答案:

答案 0 :(得分:0)

这是一个纯JS版本:

逻辑

  1. 查找当天。
  2. 找到要添加到下周开始的日子。
  3. 获取当天的日期以查找日期。
  4. 使用此日期计算日期。
  5. JSFiddle

    &#13;
    &#13;
    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();
    }
    &#13;
    <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>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:0)

我不知道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;
}

我认为代码是相当不言自明的(不是我们所有人;-)),但为了澄清步骤:

  • firstMatchingDayOfWeek(day, date)&gt;调用指定星期几(0-6)和日期对象
  • 的函数
  • delta = date.getDay() - day&gt;计算日期需要转换多少天才能达到一周的同一天
  • result = new Date(date)&gt;根据输入创建一个新的Date实例(这样就可以保留原始日期)
  • result.setDate(result.getDate() + ((7 - delta) % 7))&gt;将date部分(月中的某一天)设置为一周减去增量,以一周为模(因为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>

答案 2 :(得分:0)

这里也是一个可能的答案,使用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');

答案 3 :(得分:0)

我的解决方案

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'); 
}