210

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.

3
  • 2
    Look <a href="javascript.about.com/library/blweekyear.htm"> <b>here</b></a>, which was the first link given when I googled 'javascript week of year'. Commented May 24, 2011 at 23:07
  • @Pete: That code gets 22 as the current week. While it should be 21 Commented May 24, 2011 at 23:20
  • @Pete: :D Nopez a simple -1 won't do the trick :P That wouldn't get the ISO-8601 weeknumber. A week in ISO-8601 starts on monday. The first week is the week with the year's first Thursday in it. en.wikipedia.org/wiki/ISO-8601 . PS wasn't me who downvoted you. Commented May 25, 2011 at 20:50

26 Answers 26

385

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>

Sign up to request clarification or add additional context in comments.

53 Comments

You saved my ass. Thanks. If you want to contribute to Open Source, I suggest you create a patch for the jQuery UI method: $.datepicker.iso8601Week(date) as it does only return weekNo, but no year.
Today, January 4 2016, I noticed that it was necesarry to add d.setMilliseconds(0) as well - it kept showing different week numbers for the same date depending on whether I used new Date() or new Date("1/4/2016"). Just a heads up for others who might experience the same.
Provided code does not follow ISO 8601, it's off by one
@FelipeT.—came back to this, fixed the issue. There was something going wrong with years starting on Friday during DST. Fixed by using UTC and avoiding DST entirely. I've tested against moment.js for the 50 years from 2000 to 2050 with a number of different time zones. Please let me know if there are any other issues!
Oops you're right, my typo, was supposed to be '2015-12-30' which works.
|
54

You can use momentjs library also:

moment().format('W')

2 Comments

or moment().week()
For those coming here after 2019, moment library was discontinued and the owners recommend the use of other more modern libraries like Luxon or Day.js. Here is the topic from moment.js: momentjs.com/docs/#/-project-status/recommendations
35

Not ISO-8601 week number but if the search engine pointed you here anyway.

As said above but without a class:

let now = new Date(); let onejan = new Date(now.getFullYear(), 0, 1); let week = Math.ceil((((now.getTime() - onejan.getTime()) / 86400000) + onejan.getDay() + 1) / 7); console.log(week);

5 Comments

The question asked for ISO 8601 which this ignores. As an answer to the question it is simply wrong
@havlock yeah but this is the first result on google for "get week of a year in JavaScript" so it helps a lot of people for this to be there (that don't need the complexity of the accepted answer)
There is also an answer with an identical solution posted a year before this one.
Your code has a bug and returns incorrect numbers. See my answer with a fix.
So if "where to get the best cookies in New York" got directed here, giving an answer to that question would warrant a wrong response to the actual answer?
26

Accordily http://javascript.about.com/library/blweekyear.htm

Date.prototype.getWeek = function() { var onejan = new Date(this.getFullYear(), 0, 1); var millisecsInDay = 86400000; return Math.ceil((((this - onejan) / millisecsInDay) + onejan.getDay() + 1) / 7); }; let d = new Date(2020,11,30); for (let i=0; i<14; i++) { console.log(`${d.toDateString()} is week ${d.getWeek()}`); d.setDate(d.getDate() + 1); }

4 Comments

i think since this is being added to the prototype it's what you would expect as Date treats sunday as the first day.
Won't this have problems on Daylight Saving Time days? I think it will not advance until 1am during the summer.
Also, doesn't this technically not advance the week until 0:00:00.001? Better to use Math.floor?
This answer treats Sunday as the first day of the week. If 1 Jan isn't a Sunday, then the prior days are in week 1 and the first Sunday is in week 2. That is a very different result to the OP's request.
14

The code below calculates the correct ISO 8601 week number. It matches PHP's date("W") for every week between 1/1/1970 and 1/1/2100.

/** * Get the ISO week date week number */ Date.prototype.getWeek = 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 1st 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 week number is the number of weeks between the first Thursday of the year // and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000) return 1 + Math.ceil((firstThursday - target) / 604800000); } 

Source: Taco van den Broek


If you're not into extending prototypes, then here's a function:

function getWeek(date) { if (!(date instanceof Date)) date = new Date(); // ISO week date weeks start on Monday, so correct the day number var nDay = (date.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 date.setDate(date.getDate() - nDay + 3); // Store the millisecond value of the target date var n1stThursday = date.valueOf(); // Set the target to the first Thursday of the year // First, set the target to January 1st date.setMonth(0, 1); // Not a Thursday? Correct the date to the next Thursday if (date.getDay() !== 4) { date.setMonth(0, 1 + ((4 - date.getDay()) + 7) % 7); } // The week number is the number of weeks between the first Thursday of the year // and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000) return 1 + Math.ceil((n1stThursday - date) / 604800000); } 

Sample usage:

getWeek(); // Returns 37 (or whatever the current week is) getWeek(new Date('Jan 2, 2011')); // Returns 52 getWeek(new Date('Jan 1, 2016')); // Returns 53 getWeek(new Date('Jan 4, 2016')); // Returns 1 

4 Comments

I like this function, but I have a question; What do I do if I want to put it back to sunday? I have no idea what the +6 ) % 7 part does. Thanks from a scrub!
@Babydead ISO week starts on a Monday, but JavaScript getDay() starts on a Sunday, so if you want it to start on Sunday then you can remove the correction: var nDay = date.getDay();
The function version mutates its argument (which is a bad practice). To remedy that, replace the guard at the top with: javascript date = date instanceof Date ? new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) : new Date()
Shouldn't the last line be 'n1stThursday - date.getMilliseconds()' ?
13

Jacob Wright's Date.format() library implements date formatting in the style of PHP's date() function and supports the ISO-8601 week number:

new Date().format('W'); 

It may be a bit overkill for just a week number, but it does support PHP style formatting and is quite handy if you'll be doing a lot of this.

Comments

6
getWeekOfYear: function(date) { var target = new Date(date.valueOf()), dayNumber = (date.getUTCDay() + 6) % 7, firstThursday; target.setUTCDate(target.getUTCDate() - dayNumber + 3); firstThursday = target.valueOf(); target.setUTCMonth(0, 1); if (target.getUTCDay() !== 4) { target.setUTCMonth(0, 1 + ((4 - target.getUTCDay()) + 7) % 7); } return Math.ceil((firstThursday - target) / (7 * 24 * 3600 * 1000)) + 1; } 

Following code is timezone-independent (UTC dates used) and works according to the https://en.wikipedia.org/wiki/ISO_8601

1 Comment

The posted code is not "timezone independent". For example, a system set to Australia/Sydney (UTC+11 over summer) and a date for Monday 30 Dec 2019 at 05:00 it returns week 52 (of 2019) because the UTC date is Sunday 29 Dec. It should return week 1 (of 2020).
6

Get the weeknumber of any given Date

function week(year,month,day) { function serial(days) { return 86400000*days; } function dateserial(year,month,day) { return (new Date(year,month-1,day).valueOf()); } function weekday(date) { return (new Date(date)).getDay()+1; } function yearserial(date) { return (new Date(date)).getFullYear(); } var date = year instanceof Date ? year.valueOf() : typeof year === "string" ? new Date(year).valueOf() : dateserial(year,month,day), date2 = dateserial(yearserial(date - serial(weekday(date-serial(1))) + serial(4)),1,3); return ~~((date - date2 + serial(weekday(date2) + 5))/ serial(7)); } 

Example

console.log( week(2016, 06, 11),//23 week(2015, 9, 26),//39 week(2016, 1, 1),//53 week(2016, 1, 4),//1 week(new Date(2016, 0, 4)),//1 week("11 january 2016")//2 ); 

3 Comments

I cannot believe it, but this function is the only one that worked all the time! The accepted answer played up when it went past daylight savings, others said '0' as the week number on certain years. - and some relied on UTC functions that sometimes returned the previous day therefore assigning it week '53' or '54'. Unfortunately I need the week to begin on a Sunday and this code is very hard to understand...
@MelissaZachariadis said I need the week to begin on a Sunday; I think the only needed change is in function weekday()'s .getDay()+1 to be changed to .getDay()
This is what i need, but this code is kinda messy and hard to read
5

I found useful the Java SE's SimpleDateFormat class described on Oracle's specification. In my case in Google Apps Script it worked like this:

function getWeekNumber() { var weekNum = parseInt(Utilities.formatDate(new Date(), "GMT", "w")); Logger.log(weekNum); } 

For example in a spreadsheet macro you can retrieve the actual timezone of the file:

function getWeekNumber() { var weekNum = parseInt(Utilities.formatDate(new Date(), SpreadsheetApp.getActiveSpreadsheet().getSpreadsheetTimeZone(), "w")); Logger.log(weekNum); } 

Comments

4

This adds "getWeek" method to Date.prototype which returns number of week from the beginning of the year. The argument defines which day of the week to consider the first. If no argument passed, first day is assumed Sunday.

/** * Get week number in the year. * @param {Integer} [weekStart=0] First day of the week. 0-based. 0 for Sunday, 6 for Saturday. * @return {Integer} 0-based number of week. */ Date.prototype.getWeek = function(weekStart) { var januaryFirst = new Date(this.getFullYear(), 0, 1); if(weekStart !== undefined && (typeof weekStart !== 'number' || weekStart % 1 !== 0 || weekStart < 0 || weekStart > 6)) { throw new Error('Wrong argument. Must be an integer between 0 and 6.'); } weekStart = weekStart || 0; return Math.floor((((this - januaryFirst) / 86400000) + januaryFirst.getDay() - weekStart) / 7); }; 

3 Comments

The first calendar week of 2016 starts at the 4th of January in Germany, but your function starts counting again from 0 from the 1st January on. It also returns wrong numbers at the end of the year, e.g. 52 for 2018-11-31 (53rd week), although it's already the 1st calendar week of 2019: new Date(Date.UTC(2018,11, 31)).getWeek(1)+1 (Monday is the 1st day of week in Germany).
That's how it was intended, and that's, I believe, the most likely use case. Otherwise the first 3 days of 2016 would fall out. First days of the month are considered to comprise the first week for that month, no-matter which and how many days there are. If you need the function to work differently, you can tweak it according to your needs. Likewise, if a week falls into both the given year and the following year, it can be called the last week of that year, as well as the first week of the following year (according to current logic).
Thanks for the info. I ended up using RobG's solution, which implements ISO8601 week dates correctly (last days in December and the first days in January may belong to week 52, 53 or 1: en.m.wikipedia.org/wiki/ISO_week_date
4

this code fixes a bug in answer by nvd

function getWeek(param) { let onejan = new Date(param.getFullYear(), 0, 1); return Math.ceil((((param.getTime() - onejan.getTime()) / 86400000) + onejan.getDay()) / 7); } 

3 Comments

please define what you are explaining
@jaibalaji this code fixes a bug in answer by nvd
This is for Sunday being the first day of the week and fixes nvd's stackoverflow.com/a/27125580/4953663 which doesn't handle a non-Sunday first day of the year correctly. This is what I needed, thanks!
3

If you are already in an Angular project you could use $filter('date').

For example:

var myDate = new Date(); var myWeek = $filter('date')(myDate, 'ww'); 

Comments

3

This week number thing has been a real pain in the a**. Most trivial solutions around the web didn't really work for me as they worked most of the time but all of them broke at some point, especially when year changed and last week of the year was suddenly next year's first week etc. Even Angular's date filter showed incorrect data (it was the 1st week of next year, Angular gave week 53).

Note: The examples are designed to work with European weeks (Mon first)!

getWeek()

Date.prototype.getWeek = function(){ // current week's Thursday var curWeek = new Date(this.getTime()); curWeek.setDay(4); // current year's first week's Thursday var firstWeek = new Date(curWeek.getFullYear(), 0, 4); firstWeek.setDay(4); return (curWeek.getDayIndex() - firstWeek.getDayIndex()) / 7 + 1; }; 

setDay()

/** * Make a setDay() prototype for Date * Sets week day for the date */ Date.prototype.setDay = function(day){ // Get day and make Sunday to 7 var weekDay = this.getDay() || 7; var distance = day - weekDay; this.setDate(this.getDate() + distance); return this; } 

getDayIndex()

/* * Returns index of given date (from Jan 1st) */ Date.prototype.getDayIndex = function(){ var start = new Date(this.getFullYear(), 0, 0); var diff = this - start; var oneDay = 86400000; return Math.floor(diff / oneDay); }; 

I have tested this and it seems to be working very well but if you notice a flaw in it, please let me know.

1 Comment

This looks better because you are NOT dividing the date, by milliseconds in a day. This is a big mistake because the calculation will fail during a leap year
2

The code snippet which works pretty well for me is this one:

var yearStart = +new Date(d.getFullYear(), 0, 1); var today = +new Date(d.getFullYear(),d.getMonth(),d.getDate()); var dayOfYear = ((today - yearStart + 1) / 86400000); return Math.ceil(dayOfYear / 7).toString(); 

Note:
d is my Date for which I want the current week number.
The + converts the Dates into numbers (working with TypeScript).

Comments

2

With Luxon (https://github.com/moment/luxon) :

import { DateTime } from 'luxon'; const week: number = DateTime.fromJSDate(new Date()).weekNumber; 

1 Comment

Just a note: Luxon has so many options to create a given date; the fromJSDate() is just one of many. Luxon was created by one of the maintainers of MomentJS, and is expected to be maintained indefinitely. At this point in time, either this or Moment are really the best ways to accomplish this task.
1

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

Comments

1

Here is a slight adaptation for Typescript that will also return the dates for the week start and week end. I think it's common to have to display those in a user interface, since people don't usually remember week numbers.

function getWeekNumber(d: Date) { // 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 const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)); // Calculate full weeks to nearest Thursday const weekNo = Math.ceil( ((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7 ); const weekStartDate = new Date(d.getTime()); weekStartDate.setUTCDate(weekStartDate.getUTCDate() - 3); const weekEndDate = new Date(d.getTime()); weekEndDate.setUTCDate(weekEndDate.getUTCDate() + 3); return [d.getUTCFullYear(), weekNo, weekStartDate, weekEndDate] as const; }

Comments

1

This is my typescript implementation which I tested against some dates. This implementation allows you to set the first day of the week to any day.

//sunday = 0, monday = 1, ... static getWeekNumber(date: Date, firstDay = 1): number { const d = new Date(date.getTime()); d.setHours(0, 0, 0, 0); //Set to first day of the week since it is the same weeknumber while(d.getDay() != firstDay){ d.setDate(d.getDate() - 1); } const dayOfYear = this.getDayOfYear(d); let weken = Math.floor(dayOfYear/7); // add an extra week if 4 or more days are in this year. const daysBefore = ((dayOfYear % 7) - 1); if(daysBefore >= 4){ weken += 1; } //if the last 3 days onf the year,it is the first week const t = new Date(d.getTime()); t.setDate(t.getDate() + 3); if(t.getFullYear() > d.getFullYear()){ return 1; } weken += 1; return weken; } private static getDayOfYear(date: Date){ const start = new Date(date.getFullYear(), 0, 0); const diff = (date.getTime() - start.getTime()) + ((start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000); const oneDay = 1000 * 60 * 60 * 24; const day = Math.floor(diff / oneDay); return day; } 

Tests:

describe('getWeeknumber', () => { it('should be ok for 0 sunday', () => { expect(DateUtils.getWeekNumber(new Date(2015, 0, 4), 0)).toBe(1); expect(DateUtils.getWeekNumber(new Date(2017, 0, 1), 0)).toBe(1); expect(DateUtils.getWeekNumber(new Date(2017, 0, 2), 0)).toBe(1); expect(DateUtils.getWeekNumber(new Date(2017, 0, 8), 0)).toBe(2); expect(DateUtils.getWeekNumber(new Date(2017, 0, 9), 0)).toBe(2); expect(DateUtils.getWeekNumber(new Date(2020, 11, 28), 0)).toBe(53); expect(DateUtils.getWeekNumber(new Date(2020, 11, 29), 0)).toBe(53); expect(DateUtils.getWeekNumber(new Date(2020, 11, 30), 0)).toBe(53); expect(DateUtils.getWeekNumber(new Date(2020, 11, 31), 0)).toBe(53); expect(DateUtils.getWeekNumber(new Date(2022, 0, 3), 0)).toBe(1); }); it('should be ok for monday 1 default', () => { expect(DateUtils.getWeekNumber(new Date(2015, 0, 4), 1)).toBe(1); expect(DateUtils.getWeekNumber(new Date(2017, 0, 1), 1)).toBe(52); expect(DateUtils.getWeekNumber(new Date(2017, 0, 2), 1)).toBe(1); expect(DateUtils.getWeekNumber(new Date(2017, 0, 8), 1)).toBe(1); expect(DateUtils.getWeekNumber(new Date(2017, 0, 9), 1)).toBe(2); expect(DateUtils.getWeekNumber(new Date(2020, 11, 28), 1)).toBe(53); expect(DateUtils.getWeekNumber(new Date(2020, 11, 29), 1)).toBe(53); expect(DateUtils.getWeekNumber(new Date(2020, 11, 30), 1)).toBe(53); expect(DateUtils.getWeekNumber(new Date(2020, 11, 31), 1)).toBe(53); expect(DateUtils.getWeekNumber(new Date(2022, 0, 3), 1)).toBe(1); }); }); 

Comments

0

I tried a lot to get the shortest code to get the weeknumber ISO-conform.

Date.prototype.getWeek=function(){ var date=new Date(this); date.setHours(0,0,0,0); return Math.round(((date.setDate(this.getDate()+2-(this.getDay()||7))-date.setMonth(0,4))/8.64e7+3+(date.getDay()||7))/7)+"/"+date.getFullYear();} 

The variable date is necessary to avoid to alter the original this. I used the return values of setDate() and setMonth() to dispense with getTime() to save code length and I used an expontial number for milliseconds of a day instead of a multiplication of single elements or a number with five zeros. this is Date or Number of milliseconds, return value is String e.g. "49/2017".

1 Comment

This doesn't work at all in 2020. Jan 5th returns as 53rd week of 2019 (ok, but not great). Jan 6th returns as 2nd week of 2020. Effectively, there's no first week of 2020...
0

Another library-based option: use d3-time-format:

const formatter = d3.timeFormat('%U'); const weekNum = formatter(new Date()); 

Comments

0

Shortest workaround for Angular2+ DatePipe, adjusted for ISO-8601:

import {DatePipe} from "@angular/common"; public rightWeekNum: number = 0; constructor(private datePipe: DatePipe) { } calcWeekOfTheYear(dateInput: Date) { let falseWeekNum = parseInt(this.datePipe.transform(dateInput, 'ww')); this.rightWeekNum = (dateInput.getDay() == 0) ? falseWeekNumber-1 : falseWeekNumber; } 

Comments

0

Inspired from RobG's answer.

What I wanted is the day of the week of a given date. So my answer is simply based on the day of the week Sunday. But you can choose the other day (i.e. Monday, Tuesday...);

First I find the Sunday in a given date and then calculate the week.

function getStartWeekDate(d = null) { const now = d || new Date(); now.setHours(0, 0, 0, 0); const sunday = new Date(now); sunday.setDate(sunday.getDate() - sunday.getDay()); return sunday; } function getWeek(date) { const sunday = getStartWeekDate(date); const yearStart = new Date(Date.UTC(2021, 0, 1)); const weekNo = Math.ceil((((sunday - yearStart) / 86400000) + 1) / 7); return weekNo; } // tests for (let i = 0; i < 7; i++) { let m = 14 + i; let x = getWeek(new Date(2021, 2, m)); console.log('week num: ' + x, x + ' == ' + 11, x == 11, m); } for (let i = 0; i < 7; i++) { let m = 21 + i; let x = getWeek(new Date(2021, 2, m)); console.log('week num: ' + x, x + ' == ' + 12, x == 12, 'date day: ' + m); } for (let i = 0; i < 4; i++) { let m = 28 + i; let x = getWeek(new Date(2021, 2, m)); console.log('week num: ' + x, x + ' == ' + 13, x == 13, 'date day: ' + m); } for (let i = 0; i < 3; i++) { let m = 1 + i; let x = getWeek(new Date(2021, 3, m)); console.log('week num: ' + x, x + ' == ' + 13, x == 13, 'date day: ' + m); } for (let i = 0; i < 7; i++) { let m = 4 + i; let x = getWeek(new Date(2021, 3, m)); console.log('week num: ' + x, x + ' == ' + 14, x == 14, 'date day: ' + m); }

Comments

0
import dayJs from 'dayjs'; import isoWeek from 'dayjs/plugin/isoWeek'; dayJs.extend(isoWeek); /** * Get the current week number based on date. * * @return {number} * @param date */ export const getWeekNumberByDate = (date) => dayJs(date).isoWeek(); 

Comments

0

According to https://en.wikipedia.org/wiki/ISO_week_date

Weeks start with Monday and end on Sunday. Each week's year is the Gregorian year in which the Thursday falls. The first week of the year, hence, always contains 4 January.

date-fns getWeek does this.

It can be tested according to wiki's "Examples of contemporary dates around New Year's Day" table as following:

in jsfiddle

// html <script src="https://cdn.jsdelivr.net/npm/[email protected]/cdn.min.js"></script> result1: <span id="result1"></span><br> result2: <span id="result2"></span><br> result3: <span id="result3"></span><br> result4: <span id="result4"></span><br> result5: <span id="result5"></span><br> result6: <span id="result6"></span><br> result7: <span id="result7"></span><br> result8: <span id="result8"></span><br> 
// js function getWeek (date) { return dateFns.getWeek(date, { weekStartsOn: 1, firstWeekContainsDate: 4 }) } document.getElementById('result1').innerHTML = getWeek('1977-01-01') document.getElementById('result2').innerHTML = getWeek('1977-01-02') document.getElementById('result3').innerHTML = getWeek('1978-01-01') document.getElementById('result4').innerHTML = getWeek('1978-01-02') document.getElementById('result5').innerHTML = getWeek('1979-01-01') document.getElementById('result6').innerHTML = getWeek('1979-01-02') document.getElementById('result7').innerHTML = getWeek('1980-12-28') document.getElementById('result8').innerHTML = getWeek('1980-12-29') 

results:

  • result1: 53
  • result2: 53
  • result3: 52
  • result4: 1
  • result5: 1
  • result6: 1
  • result7: 52
  • result8: 1

Comments

0

As of April 2025, The TC39 Temporal Proposal is in stage 3, and currently being worked on by being worked on the JS engine implementers. BUT it can be accessed now by using a polyfill.

It has a built-in function to get ISO 8601 weekOfYear

const date = Temporal.PlainDate.from("2019-12-31"); console.log(date4.weekOfYear); // 1 

Based on the explanation on Wikipedia, I made a simpler implementation that's easy to understand.

/** * Returns the ISO 8601 week number * @param {Date} target */ function getWeek(target) { const targetYear = target.getFullYear(); const Dec31 = new Date(targetYear, 11, 31); const dec31WeekDay = getISOWeekDay(Dec31.getDay()); // if Dec 31 is Monday(1), Tuesday(2) or Wednesday(3), last few days would be in week 1 of next year if ( dec31WeekDay < 4 && target.getMonth() === 11 && target.getDate() > 31 - dec31WeekDay ) { return 1; } const Jan1 = new Date(targetYear, 0, 1); const jan1WeekDay = getISOWeekDay(Jan1.getDay()); // If Jan 1 is on a Monday(1), Tuesday(2), Wednesday(3) or Thursday(4), it is in W01. // If it is on a Friday(5), it is part of W53 of the previous year. // If it is on a Saturday(6), it is part of the last week of the previous year, // which is numbered W52 in a common year and W53 in a leap year. // If it is on a Sunday(7), it is part of W52 of the previous year. if ( jan1WeekDay > 4 && target.getMonth() === 0 && target.getDate() <= 7 - jan1WeekDay + 1 ) { return jan1WeekDay === 5 || (jan1WeekDay === 6 && isLeapYear(targetYear - 1)) ? 53 : 52; } // 1-based days into the year (1-366) const dayOfYear = Math.floor((target.getTime() - Jan1.getTime()) / (1000 * 60 * 60 * 24)) + 1; // The offset is the number of days till the *second* Monday when Jan 1 is in W01, // and, number of days till the *first* Monday otherwise, i.e. when Jan 1 lies in the last week of previous year // Both happen to have the same formula. const offset = 7 - jan1WeekDay + 1; return Math.ceil((dayOfYear - offset) / 7) + (jan1WeekDay > 4 ? 0 : 1); } /** @param {number} year 4-digit year */ function isLeapYear(year) { return year % 4 === 0 && !(year % 100 === 0 && year % 400 !== 0); } /** * Converts JS week day to ISO 8601 week year day. * - JS Week: starts on Sunday, 0-6 * - ISO 8601 Week: Starts on Monday (1-7) * * @param {number} day Week Day from Date object method */ function getISOWeekDay(day) { return ((6 + day) % 7) + 1; } 

Comments

-1
now = new Date(); today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); firstOfYear = new Date(now.getFullYear(), 0, 1); numOfWeek = Math.ceil((((today - firstOfYear) / 86400000)-1)/7); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.