Search code examples
jquerymomentjsdate-arithmetic

How do I calculate number of given weekday between range using Moment JS?


How do I find out how many of a given weekday (ex: Tuesdays) are in a date range using Moment JS and jQuery?

I can find the number of days using Difference: http://momentjs.com/docs/#/displaying/difference/

And I know the start and end date, so I feel like it should be possible?

Example: How many Tuesdays are there between March 1st and March 25th?


Solution

  • I came up with the following function that seems to work for the given handful of test cases I tried:

    function weekdaysBetween(d1, d2, isoWeekday) {
        // ensure we have valid moment instances
        d1 = moment(d1);
        d2 = moment(d2);
        // figure out how many days to advance to get to the next
        // specified weekday (might be 0 if d1 is already the 
        // specified weekday).
        var daysToAdd = ((7 + isoWeekday) - d1.isoWeekday()) % 7;
        var nextTuesday = d1.clone().add(daysToAdd, 'days');
        // if we are already passed the end date, there must not
        // be any of that day in the given period.
        if (nextTuesday.isAfter(d2)) {
            return 0;
        }
        // otherwise, just return the whole number of weeks
        // difference plus one for the day we already advanced to
        var weeksBetween = d2.diff(nextTuesday, 'weeks');
        return weeksBetween + 1;
    }
    

    You pass in the isoWeekday value for the day you are trying to count. e.g. for Tuesday, pass in 2.

    Sample invocation:

    var d1 = moment('2015-03-01');
    var d2 = moment('2015-03-25');
    
    console.log('result:', weekdaysBetween(d1, d2, 2)); // => result: 4
    

    Wolfram Alpha gives the same result.

    You should add your own tests before trusting this completely, though.