2

In javascript, how can I find out how many weeks a given year has? Getting the weeknumber from year-dec-31 will fail since that can result in week 1.

This question calculate number of weeks in a given year sort of answers it, but is there any neat way of calculating this in JS?

Community
  • 1
  • 1
Roger Johansson
  • 22,764
  • 18
  • 97
  • 193

3 Answers3

9

For the ISO 8601 Standard Weeks

function getISOWeeks(y) {
  var d,
    isLeap;

  d = new Date(y, 0, 1);
  isLeap = new Date(y, 1, 29).getMonth() === 1;

  //check for a Jan 1 that's a Thursday or a leap year that has a 
  //Wednesday jan 1. Otherwise it's 52
  return d.getDay() === 4 || isLeap && d.getDay() === 3 ? 53 : 52
}
console.log(getISOWeeks(2019))
console.log(getISOWeeks(2020))
console.log(getISOWeeks(2021))

I put this together from the two following posts.

Calculating the number of weeks in a year with Ruby

javascript to find leap year

mplungjan
  • 169,008
  • 28
  • 173
  • 236
rwilliams
  • 21,188
  • 6
  • 49
  • 55
  • for the placement of the brackets: `return (d.getDay() === 4 || (isLeap && d.getDay() === 3)) ? 53 : 52` – zerbene Apr 28 '21 at 09:08
1

This should do it =)

function getWeeks(d) {
 var first = new Date(d.getFullYear(),0,1);
 var dayms = 1000 * 60 * 60 * 24;
 var numday = ((d - first)/dayms)
 var weeks = Math.ceil((numday + first.getDay()+1) / 7) ; 
 return weeks


}

console.log(getWeeks(new Date("31 Dec 2012"))) // 53
  • This will first get the First Jan of the year you want to get the Weeks of
  • Then substracts the first Jan from date given (results in the ms since that day)
  • Divides it by 86400000 to get the number of day
  • Adds the days since the sunday of the week from the first Jan
  • Divides it all by 7
  • Which should work regardless of Leap Years because it takes ms

If you want to stick to the Iso 8601 Week numbering which state for the first year in a week

  • the week with the year's first Thursday in it (the formal ISO definition),
  • the week with 4 January in it,
  • the first week with the majority (four or more) of its days in the starting year, and
  • the week starting with the Monday in the period 29 December – 4 January.

You can adjust it slightly to this

function getIsoWeeks(d) {
 var first = new Date(d.getFullYear(),0,4);
 var dayms = 1000 * 60 * 60 * 24;
 var numday = ((d - first)/dayms)
 var weeks = Math.ceil((numday + first.getDay()+1) / 7) ; 
 return weeks   
}

console.log(getWeeks(new Date("31 Dec 2016"))) // 53
console.log(getIsoWeeks(new Date("31 Dec 2016")) //52

You could of course short the code and squeeze it all together, but for readability i declared the used vars like dayms

You can also take a look at this JSBin example

Moritz Roessler
  • 8,542
  • 26
  • 51
  • This appears to fail for 1st Sep 2013 although it corrects for later dates. It puts Sunday 1st September in the 36th week of the year, incorrectly. i.e. console.log(getWeeks(new Date("1 Sep2013"))) // 36 – alimack Sep 04 '13 at 09:39
  • @alimack Thanks for the comment :) i'll give it a look when i'm back from Mobile – Moritz Roessler Sep 04 '13 at 10:09
0

For ISO-8601 years :

Approach # 1 :

function FunctionP(y) {
    return (y + Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400)) % 7;
}

function WeekCount(y) {
    var additionalWeek = (FunctionP(y) == 4 || FunctionP(y-1) == 3) ? 1 : 0;
    return weekCount = 52 + additionalWeek;
}

Approach # 2 : Logic for GetISO8601Week prototype from https://www.w3resource.com/javascript-exercises/javascript-date-exercise-24.php

function GetMaxWeekCountOfISOYear(yyyy) {
  var dec31YYYY = (new Date(yyyy, 11, 31));
  var dec31Day = dec31YYYY.getDay();

  return dec31Day >= 1 && dec31Day <= 3 ?
    Number(GetSunday(dec31YYYY).GetISO8601Week()) :
    Number(dec31YYYY.GetISO8601Week());
}

Date.prototype.GetISO8601Week = 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 GetSunday(requestDate) {
  requestDate = new Date(requestDate.setHours(0, 0, 0, 0));
  var day = requestDate.getDay(),
    diff = requestDate.getDate() - day;
  return new Date(requestDate.setDate(diff));
}
Nitish
  • 776
  • 3
  • 13