Search code examples
javascriptdate

Get week of year in JavaScript like in PHP


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 on Monday.


Solution

  • You should be able to get what you want here: http://www.merlyn.demon.co.uk/js-date6.htm#YWD.

    A better link on the same site is: Working with weeks.

    Edit

    Here is some code based on the links provided and that posted eariler by Dommer. It has been lightly tested against results at http://www.merlyn.demon.co.uk/js-date6.htm#YWD. Please test thoroughly, no guarantee provided.

    Edit 2017

    There was an issue with dates during the period that daylight saving was observed and years where 1 Jan was Friday. Fixed by using all UTC methods. The following returns identical results to Moment.js.

    /* For a given date, get the ISO week number
     *
     * Based on information at:
     *
     *    THIS PAGE (DOMAIN EVEN) DOESN'T EXIST ANYMORE UNFORTUNATELY
     *    http://www.merlyn.demon.co.uk/weekcalc.htm#WNR
     *
     * Algorithm is to find nearest thursday, it's year
     * is the year of the week number. Then get weeks
     * between that date and the first day of that year.
     *
     * Note that dates in one year can be weeks of previous
     * or next year, overlap is up to 3 days.
     *
     * e.g. 2014/12/29 is Monday in week  1 of 2015
     *      2012/1/1   is Sunday in week 52 of 2011
     */
    function getWeekNumber(d) {
        // Copy date so don't modify original
        d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
        // Set to nearest Thursday: current date + 4 - current day number
        // Make Sunday's day number 7
        d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay()||7));
        // Get first day of year
        var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
        // Calculate full weeks to nearest Thursday
        var weekNo = Math.ceil(( ( (d - yearStart) / 86400000) + 1)/7);
        // Return array of year and week number
        return [d.getUTCFullYear(), weekNo];
    }
    
    var result = getWeekNumber(new Date());
    document.write('It\'s currently week ' + result[1] + ' of ' + result[0]);

    Hours are zeroed when creating the "UTC" date.

    Minimized, prototype version (returns only week-number):

    Date.prototype.getWeekNumber = function(){
      var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
      var dayNum = d.getUTCDay() || 7;
      d.setUTCDate(d.getUTCDate() + 4 - dayNum);
      var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
      return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
    };
    
    document.write('The current ISO week number is ' + new Date().getWeekNumber());

    Test section

    In this section, you can enter any date in YYYY-MM-DD format and check that this code gives the same week number as Moment.js ISO week number (tested over 50 years from 2000 to 2050).

    Date.prototype.getWeekNumber = function(){
      var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
      var dayNum = d.getUTCDay() || 7;
      d.setUTCDate(d.getUTCDate() + 4 - dayNum);
      var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
      return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
    };
    
    function checkWeek() {
      var s = document.getElementById('dString').value;
      var m = moment(s, 'YYYY-MM-DD');
      document.getElementById('momentWeek').value = m.format('W');
      document.getElementById('answerWeek').value = m.toDate().getWeekNumber();      
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
    
    Enter date  YYYY-MM-DD: <input id="dString" value="2021-02-22">
    <button onclick="checkWeek(this)">Check week number</button><br>
    Moment: <input id="momentWeek" readonly><br>
    Answer: <input id="answerWeek" readonly>