45

How can I calculate the date in JavaScript knowing the week number and the year? For week number 20 and year 2013 I want to obtain 2013-05-16. I am trying it like this:

Date.prototype.dayofYear = function () {
  var d = new Date(this.getFullYear(), 0, 0)
  return Math.floor((/* enter code here */ this - d) / 8.64e + 7)
}
adius
  • 12,010
  • 6
  • 41
  • 42
user2369009
  • 495
  • 2
  • 5
  • 11
  • You should be able to find the answer here: http://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php - just Googled it. – Elle May 16 '13 at 14:45
  • 1
    i want the revers. knowing weeknumber, getting date.. – user2369009 May 16 '13 at 14:48
  • 4
    The answers below actually fulfill your request of Javascript code, but FWIW, the momentjs library handles this nicely. For ISO 8601 week numbers, `moment("2013W20")` gives: `"2013-05-13T00:00:00-06:00"`. – Rich Armstrong Dec 22 '17 at 17:02

10 Answers10

106
function getDateOfWeek(w, y) {
    var d = (1 + (w - 1) * 7); // 1st of January + 7 days for each week

    return new Date(y, 0, d);
}

This uses the simple week definition, meaning the 20th week of 2013 is May 14.

To calculate the date of the start of a given ISO8601 week (which will always be a Monday)

function getDateOfISOWeek(w, y) {
    var simple = new Date(y, 0, 1 + (w - 1) * 7);
    var dow = simple.getDay();
    var ISOweekStart = simple;
    if (dow <= 4)
        ISOweekStart.setDate(simple.getDate() - simple.getDay() + 1);
    else
        ISOweekStart.setDate(simple.getDate() + 8 - simple.getDay());
    return ISOweekStart;
}

Result: the 20th week of 2013 is May 13, which can be confirmed here.

Daniel Sokolowski
  • 11,269
  • 3
  • 65
  • 52
Elle
  • 3,495
  • 1
  • 16
  • 30
  • 2
    this is not working for e.g first week of 2009. which should start at 29.12.2008 and your method is returning 5th of January – Marcin Sep 03 '13 at 09:52
  • I believe `dow < 4` should be `dow <= 4` but I haven't thoroughly tested it. – Elle Sep 05 '13 at 07:31
  • 1
    yes, the ISO week start in year when first Thursday is in that week. So if dow is 4 means week start. <= will solve this issue. – Marcin Sep 05 '13 at 07:33
  • Still not working properly >>> getDateOfISOWeek(1,2009) Date {Mon Dec 29 2008 00:00:00 GMT+0530 (IST)} - This right >>> getDateOfISOWeek(14,2009) Date {Mon Mar 30 2009 00:00:00 GMT+0530 (IST)} - Right >>> getDateOfISOWeek(15,2009) Date {Mon Apr 06 2009 00:00:00 GMT+0530 (IST)} - Worng – Subha Apr 25 '14 at 15:25
  • 1
    @Damodharan Week 15 in 2009 DO start at Mon Apr 6. – Leif Neland May 23 '14 at 07:32
  • @Damodharan http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php?year=2009 – Elle May 24 '14 at 09:12
  • 10
    I was getting incorrect dates when dealing with parts of the year that took into consideration Daylight Saving Time, to prevent this I changed the creation of the simple variable to use the Date.UTC() constructor. `var simple = new Date(Date.UTC(y, 0, 1 + (w - 1) * 7));` – Tr1stan Jan 15 '15 at 21:23
  • @Tr1stan I don't understand, how does Daylight Savings affect the date? – Elle Jan 17 '15 at 01:54
  • @JordanTrudgett, When I was testing this last week, the `simple` var was being set as `Wed Sep 03 2014 **23:00:00** GMT+0100 (GMT Daylight Time)` - which was causing the final date to be a week out - I'll do some more testing as it is no longer doing this, but I'm on a different machine. – Tr1stan Jan 20 '15 at 17:11
  • @Tr1stan could be an interesting edge case. I wasn't aware of any time-zone considerations in this function.. They all should be midnight / timeless dates in the local timezone, but it's Javascript so.. – Elle Jan 20 '15 at 23:33
  • How would I go about getting the first day of the week, but with the weeks starting with Monday instead of Sunday? – hampani Aug 28 '21 at 08:51
8

Sorry if this is a little verbose but this solution will also return the Sunday after calculating the week number. It combines answers I've seen from a couple different places:

function getSundayFromWeekNum(weekNum, year) {
    var sunday = new Date(year, 0, (1 + (weekNum - 1) * 7));
    while (sunday.getDay() !== 0) {
        sunday.setDate(sunday.getDate() - 1);
    }
    return sunday;
}
nairys
  • 333
  • 3
  • 9
5

ISO Weeks

function weekDateToDate (year, week, day) {
  const firstDayOfYear = new Date(year, 0, 1)
  const days = 2 + day + (week - 1) * 7 - firstDayOfYear.getDay()
  return new Date(year, 0, days)
}
adius
  • 12,010
  • 6
  • 41
  • 42
NoName
  • 75
  • 1
  • 1
4

Get date range according to week number

Date.prototype.getWeek = function () {
    var target  = new Date(this.valueOf());
    var dayNr   = (this.getDay() + 6) % 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);
}

function getDateRangeOfWeek(weekNo){
    var d1 = new Date();
    numOfdaysPastSinceLastMonday = eval(d1.getDay()- 1);
    d1.setDate(d1.getDate() - numOfdaysPastSinceLastMonday);
    var weekNoToday = d1.getWeek();
    var weeksInTheFuture = eval( weekNo - weekNoToday );
    d1.setDate(d1.getDate() + eval( 7 * weeksInTheFuture ));
    var rangeIsFrom = eval(d1.getMonth()+1) +"/" + d1.getDate() + "/" + d1.getFullYear();
    d1.setDate(d1.getDate() + 6);
    var rangeIsTo = eval(d1.getMonth()+1) +"/" + d1.getDate() + "/" + d1.getFullYear() ;
    return rangeIsFrom + " to "+rangeIsTo;
};

getDateRangeOfWeek(10)
"3/6/2017 to 3/12/2017"

getDateRangeOfWeek(30)
"7/24/2017 to 7/30/2017"
Aathi
  • 1,731
  • 17
  • 15
  • 2
    How do you know the required year without allowing user to pass the year? @Aathi – tharindu Jul 31 '19 at 08:18
  • I think this is more easily done with the accepted answer passed into this with `6` to get the end of the week: ```function addDays(date = new Date(), days) { var end = new Date(date); end.setDate(end.getDate() + days); return end; }``` – notsodev Apr 22 '20 at 14:34
3

2019 version (if anyone wants to calculate the date of week's start)

The answer of Elle is pretty much right, but there is one exception: if you want to get a date of start of the week - it won't help you because Elle's algorithm doesn't mind the day, from which the week starts of, at all.

And here is why:

Elle's solution

function getDateOfWeek(w, y) {
  var d = (1 + (w - 1) * 7); // 1st of January + 7 days for each week

  return new Date(y, 0, d);
}

Here you basically just calculating the amount of days from the start of the year (1st January). This means that it doesn't matter from which day your year starts of: Monday, Sunday or Friday - it will not make any difference.

To set the day, from which your week will start of (let's say Monday, for example), you just need to:

function getDateOfWeek(w, y) {
  let date = new Date(y, 0, (1 + (w - 1) * 7)); // Elle's method
  date.setDate(date.getDate() + (1 - date.getDay())); // 0 - Sunday, 1 - Monday etc
  return date
}
Andrew
  • 71
  • 6
2
function getDateOfWeek(weekNumber,year){
    //Create a date object starting january first of chosen year, plus the number of days in a week multiplied by the week number to get the right date.
    return new Date(year, 0, 1+((weekNumber-1)*7));
}
var myDate = getDateOfWeek(20,2013);
Salketer
  • 12,278
  • 2
  • 27
  • 57
  • 1
    Month needs to start from 0: http://stackoverflow.com/questions/1208519/javascript-date-objects-month-index-begins-with-0 – Elle May 16 '13 at 15:04
1

ISO week date (e.g. 2017-W32-3) to normal date:

const getZeroBasedIsoWeekDay = date => (date.getDay() + 6) % 7
const getIsoWeekDay = date => getZeroBasedIsoWeekDay(date) + 1

function weekDateToDate(year, week, weekDay) {
  const zeroBasedWeek = week - 1
  const zeroBasedWeekDay = weekDay - 1
  let days = (zeroBasedWeek * 7) + zeroBasedWeekDay

  // Dates start at 2017-01-01 and not 2017-01-00
  days += 1

  const firstDayOfYear = new Date(year, 0, 1)
  const firstIsoWeekDay = getIsoWeekDay(firstDayOfYear)
  const zeroBasedFirstIsoWeekDay = getZeroBasedIsoWeekDay(firstDayOfYear)

  // If year begins with W52 or W53
  if (firstIsoWeekDay > 4) days += 8 - firstIsoWeekDay
  // Else begins with W01
  else days -= zeroBasedFirstIsoWeekDay

  return new Date(year, 0, days)
}

const expectedAndActual = [
  [new Date('2007-01-01'), weekDateToDate(2007,  1, 1)],
  [new Date('2015-11-24'), weekDateToDate(2015, 48, 2)],
  [new Date('2015-12-31'), weekDateToDate(2015, 53, 4)],
  [new Date('2016-01-03'), weekDateToDate(2015, 53, 7)],
  [new Date('2017-01-01'), weekDateToDate(2016, 52, 7)],
  [new Date('2017-01-02'), weekDateToDate(2017,  1, 1)],
  [new Date('2017-05-07'), weekDateToDate(2017, 18, 7)],
  [new Date('2018-12-31'), weekDateToDate(2019,  1, 1)],
]

expectedAndActual
  .forEach(value => {
    const expected = value[0].toISOString()
    const actual = value[1].toISOString()
    const isEqual = actual === expected
    console.assert(isEqual, '%s !== %s', actual, expected)
    console.log(actual, '===', expected)
  })
adius
  • 12,010
  • 6
  • 41
  • 42
  • This one was the one that worked best for me. Strange that it was downvoted. Only change I did was const zeroBasedWeekDay = weekDay; – Johansrk Jan 19 '21 at 21:53
1

@adius function worked for me but I made some improvements for people who are looking for a simple copy paste solution:

/**
 * get date by week number
 * @param  {Number} year 
 * @param  {Number} week 
 * @param  {Number} day of week (optional; default = 0 (Sunday)) 
 * @return {Date}      
 */

  function weekToDate(year, week, weekDay = 0) {
    const getZeroBasedIsoWeekDay = date => (date.getDay() + 6) % 7;
    const getIsoWeekDay = date => getZeroBasedIsoWeekDay(date) + 1;
    const zeroBasedWeek = week - 1;
    const zeroBasedWeekDay = weekDay - 1;
    let days = (zeroBasedWeek * 7) + zeroBasedWeekDay;
        // Dates start at 2017-01-01 and not 2017-01-00
        days += 1;
  
    const firstDayOfYear = new Date(year, 0, 1);
    const firstIsoWeekDay = getIsoWeekDay(firstDayOfYear);
    const zeroBasedFirstIsoWeekDay = getZeroBasedIsoWeekDay(firstDayOfYear);
  
    // If year begins with W52 or W53
    if (firstIsoWeekDay > 4) {
      days += 8 - firstIsoWeekDay; 
    // Else begins with W01
    } else {
      days -= zeroBasedFirstIsoWeekDay;
    }
    
    return new Date(year, 0, days);
  }


// test: 
const x = [
  {year: 2001, week: 10},
  {year: 2019, week: 7},
  {year: 2020, week: 5},
  {year: 2020, week: 1},
  {year: 2020, week: 12}, 
  {year: 2020, week: 2},
  {year: 2020, week: 40},
  {year: 2021, week: 4},
  {year: 2021, week: 3},
  {year: 2021, week: 2},
  {year: 2032, week: 1}
]

for (let i = 0; i < x.length; i++) {
  let date = weekToDate(x[i].year, x[i].week, 0);
  let d = new Date(date).toLocaleDateString('en-US', { 
    year: 'numeric',
    month: 'long',
    day: 'numeric' 
  })

  console.log(d);
}
Dorbn
  • 97
  • 2
  • 10
0

This is for getting the first monday of a week in the current year (ISO 8601):

function getFirstMondayOfWeek(weekNo) {
    var firstMonday = new Date(new Date().getFullYear(), 0, 4, 0, 0, 0, 0);

    while (firstMonday.getDay() != 1) {
        firstMonday.setDate(firstMonday.getDate() - 1);
    }
    if (1 <= weekNo && weekNo <= 52)
        return firstMonday.setDate(firstMonday.getDate() + 7 * (weekNo - 1));

    firstMonday.setDate(firstMonday.getDate() + 7 * (weekNo - 1));
    if (weekNo = 53 && firstMonday.getDate() >= 22 && firstMonday.getDate() <= 28)
        return firstMonday;
    return null;
}
Stephen Rauch
  • 44,696
  • 30
  • 102
  • 125
Up Gxy
  • 31
  • 2
0

I just created this one:

//Returns monday and saturday of the week
function getWeekRange(weekNo,YearNo) {
    let firstDayofYear = new Date(yearNo, 0, 1);

    if (firstDayofYear.getDay() > 4)  {
        let weekStart = new Date(yearNo, 0, 1 + (weekNo - 1) * 7 - firstDayofYear.getDay() + 8);
        let weekEnd = new Date(yearNo, 0, 1 + (weekNo - 1) * 7 - firstDayofYear.getDay() + 8 + 5);
        return { startDay: weekStart, endDay: weekEnd }
    }
    else {
        let weekStart = new Date(yearNo, 0, 1 + (weekNo - 1) * 7 - firstDayofYear.getDay() + 1);
        let weekEnd = new Date(yearNo, 0, 1 + (weekNo - 1) * 7 - firstDayofYear.getDay() + 1 + 5);
        return { startDay: weekStart, endDay: weekEnd }
    }
}