Get week of year in JavaScript like in PHP

后端 未结 19 1360
南方客
南方客 2020-11-22 02:38

How do I get the current weeknumber of the year, like PHP\'s date(\'W\')?

It should be the ISO-8601 week number of year, weeks starting

19条回答
  •  被撕碎了的回忆
    2020-11-22 03:01

    Here is my implementation for calculating the week number in JavaScript. corrected for summer and winter time offsets as well. I used the definition of the week from this article: ISO 8601

    Weeks are from mondays to sunday, and january 4th is always in the first week of the year.

    // add get week prototype functions
    // weeks always start from monday to sunday
    // january 4th is always in the first week of the year
    Date.prototype.getWeek = function () {
        year = this.getFullYear();
        var currentDotw = this.getWeekDay();
        if (this.getMonth() == 11 && this.getDate() - currentDotw > 28) {
            // if true, the week is part of next year 
            return this.getWeekForYear(year + 1);
        }
        if (this.getMonth() == 0 && this.getDate() + 6 - currentDotw < 4) {
            // if true, the week is part of previous year
            return this.getWeekForYear(year - 1);
        }
        return this.getWeekForYear(year);
    }
    
    // returns a zero based day, where monday = 0
    // all weeks start with monday
    Date.prototype.getWeekDay = function () {
        return  (this.getDay() + 6) % 7;
    }
    
    // corrected for summer/winter time
    Date.prototype.getWeekForYear = function (year) {
        var currentDotw = this.getWeekDay();
        var fourjan = new Date(year, 0, 4);
        var firstDotw = fourjan.getWeekDay();
        var dayTotal = this.getDaysDifferenceCorrected(fourjan) // the difference in days between the two dates.
        // correct for the days of the week
        dayTotal += firstDotw; // the difference between the current date and the first monday of the first week, 
        dayTotal -= currentDotw; // the difference between the first monday and the current week's monday
        // day total should be a multiple of 7 now
        var weeknumber = dayTotal / 7 + 1; // add one since it gives a zero based week number.
        return weeknumber;
    }
    
    // corrected for timezones and offset
    Date.prototype.getDaysDifferenceCorrected = function (other) {
        var millisecondsDifference = (this - other);
        // correct for offset difference. offsets are in minutes, the difference is in milliseconds
        millisecondsDifference += (other.getTimezoneOffset()- this.getTimezoneOffset()) * 60000;
        // return day total. 1 day is 86400000 milliseconds, floor the value to return only full days
        return Math.floor(millisecondsDifference / 86400000);
    }
    

    for testing i used the following JavaScript tests in Qunit

    var runweekcompare = function(result, expected) {
        equal(result, expected,'Week nr expected value: ' + expected + ' Actual value: ' + result);
    }
    
    test('first week number test', function () {
        expect(5);
        var temp = new Date(2016, 0, 4); // is the monday of the first week of the year
        runweekcompare(temp.getWeek(), 1);
        var temp = new Date(2016, 0, 4, 23, 50); // is the monday of the first week of the year
        runweekcompare(temp.getWeek(), 1);
        var temp = new Date(2016, 0, 10, 23, 50); // is the sunday of the first week of the year
        runweekcompare(temp.getWeek(), 1);
        var temp = new Date(2016, 0, 11, 23, 50); // is the second week of the year
        runweekcompare(temp.getWeek(), 2);
        var temp = new Date(2016, 1, 29, 23, 50); // is the 9th week of the year
        runweekcompare(temp.getWeek(), 9);
    });
    
    test('first day is part of last years last week', function () {
        expect(2);
        var temp = new Date(2016, 0, 1, 23, 50); // is the first last week of the previous year
        runweekcompare(temp.getWeek(), 53);
        var temp = new Date(2011, 0, 2, 23, 50); // is the first last week of the previous year
        runweekcompare(temp.getWeek(), 52);
    });
    
    test('last  day is part of next years first week', function () {
        var temp = new Date(2013, 11, 30); // is part of the first week of 2014
        runweekcompare(temp.getWeek(), 1);
    });
    
    test('summer winter time change', function () {
        expect(2);
        var temp = new Date(2000, 2, 26); 
        runweekcompare(temp.getWeek(), 12);
        var temp = new Date(2000, 2, 27); 
        runweekcompare(temp.getWeek(), 13);
    });
    
    test('full 20 year test', function () {
        //expect(20 * 12 * 28 * 2);
        for (i = 2000; i < 2020; i++) {
            for (month = 0; month < 12; month++) {
                for (day = 1; day < 29 ; day++) {
                    var temp = new Date(i, month, day);
                    var expectedweek = temp.getWeek();
                    var temp2 = new Date(i, month, day, 23, 50);
                    var resultweek = temp.getWeek();
                    equal(expectedweek, Math.round(expectedweek), 'week number whole number expected ' + Math.round(expectedweek) + ' resulted week nr ' + expectedweek);
                    equal(resultweek, expectedweek, 'Week nr expected value: ' + expectedweek + ' Actual value: ' + resultweek + ' for year ' + i + ' month ' + month + ' day ' + day);
                }
            }
        }
    });
    

提交回复
热议问题