2

How should the getWeekNumber() prototype should be changed for Date class if I have a custom week start day instead of Monday.

Current code for finding ISO Week Number:

Date.prototype.getWeekNumber = function() {
    // Create a copy of this date object
    var target = new Date(this.valueOf());

    // ISO week date weeks start on monday
    // so correct the day number
    var dayNr = (this.getDay() + 6) % 7;

    // ISO 8601 states that week 1 is the week
    // with the first thursday of that year.
    // Set the target date to the thursday in the target week
    target.setDate(target.getDate() - dayNr + 3);

    // Store the millisecond value of the target date
    var firstThursday = target.valueOf();

    // Set the target to the first thursday of the year
    // First set the target to january first
    target.setMonth(0, 1);
    // Not a thursday? Correct the date to the next thursday
    if (target.getDay() !== 4) {
        target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
    }

    // The weeknumber is the number of weeks between the
    // first thursday of the year and the thursday in the target week
    return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000
};
Rahul
  • 47
  • 8

1 Answers1

3

Use your existing function and add an optional parameter weekstart that specifies on which weekday a week starts: 0 is Sunday, 1 is Monday and so on. The default value is Monday.

Date.prototype.getWeekNumber = function(weekstart) {
    var target = new Date(this.valueOf());

    // Set default for weekstart and clamp to useful range        
    if (weekstart === undefined) weekstart = 1;
    weekstart %= 7;

    // Replaced offset of (6) with (7 - weekstart)
    var dayNr = (this.getDay() + 7 - weekstart) % 7;
    target.setDate(target.getDate() - dayNr + 3);

    var firstThursday = target.valueOf();

    target.setMonth(0, 1);
    if (target.getDay() !== 4) {
        target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
    }

    return 1 + Math.ceil((firstThursday - target) / 604800000);
};    
M Oehm
  • 28,726
  • 3
  • 31
  • 42
  • This seems good as long as you keep the rule "week n°1 is the week of the first thursday of the year", the ISO rule can also be interpreted as "week n°1 is the week of the 4th of january", in this case you have to change a part of your code. – Pilou May 21 '14 at 12:08
  • @Pierre-LouisLaffont: The mutually equivalent rules for finding the first week are no longer equivalent when the start of the week is redefined, I can see that. The condition for the first week should be "has the first `(weekstart + 3) % 7` in it", so that it's the week with the majority of days in the current year. But a mid-week start for counting weeks is non-standard anyway, so let's see what the OP thinks. – M Oehm May 21 '14 at 12:46
  • I guess the solution is a good one. But i have no idea of the complexities it will involve for the conditions you are talking about. So i need to check it. – Rahul May 21 '14 at 13:58