【问题标题】:Get date of specific weekday after a specified date with Moment.js使用 Moment.js 在指定日期之后获取特定工作日的日期
【发布时间】:2016-01-24 06:35:34
【问题描述】:

我正在尝试获取给定日期之后下一个工作日的日期。工作日可以是从星期一到星期日的任何一天。我正在使用 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');
}

【问题讨论】:

    标签: javascript date momentjs


    【解决方案1】:

    我不知道 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) > 调用指定星期几(0-6)和日期对象的函数
    • delta = date.getDay() - day > 计算日期需要移动多少天才能到达一周中的同一天
    • result = new Date(date) > 根据输入创建一个新的 Date 实例(这样您就可以保留原始日期)
    • 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;
    }
    &lt;div id="out"&gt;&lt;/div&gt;

    【讨论】:

    • 谢谢。这很有帮助。
    【解决方案2】:

    这也是使用 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');
    

    【讨论】:

    • 这就是我一直在寻找的东西,我正在使用 Moment.js 和 startDate 来处理其他事情,因此使用 Moment.js 找到一个简洁的解决方案很有帮助
    【解决方案3】:

    这是纯JS版本:

    逻辑

    1. 查找当前日期。
    2. 找出要添加的日子,以便下周开始。
    3. 获取当天的日期编号以查找日期。
    4. 用这个日期计算日期。

    JSFiddle.

    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>

    【讨论】:

      【解决方案4】:

      我的解决方案

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-01
        相关资源
        最近更新 更多