Get weeks in year
Asked Answered
T

5

10

Moment js has a function to get the number of days in a month : http://momentjs.com/docs/#/displaying/days-in-month/

However I could not find a function to find the number of iso weeks in a year (52 or 53).

Terminator answered 28/8, 2013 at 3:7 Comment(0)
R
26

Here's an answer that isn't dependent on a library. It uses a function to calculate the week in the year that 31 December falls in for the required year. If the week is 1 (i.e. 31 December is in the first week of the following year), it moves the day number lower until it gets a different value, which will be the last week of the required year.

function getWeekNumber(d) {
  // Copy date so don't modify original
  d = new Date(+d);
  d.setHours(0, 0, 0, 0);
  // Set to nearest Thursday: current date + 4 - current day number
  // Make Sunday's day number 7
  d.setDate(d.getDate() + 4 - (d.getDay() || 7));
  // Get first day of year
  var yearStart = new Date(d.getFullYear(), 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.getFullYear(), weekNo];
}

function weeksInYear(year) {
  var month = 11,
    day = 31,
    week;

  // Find week that 31 Dec is in. If is first week, reduce date until
  // get previous week.
  do {
    d = new Date(year, month, day--);
    week = getWeekNumber(d)[1];
  } while (week == 1);

  return week;
}

[2015, 2016, 2029, new Date().getFullYear()].forEach(year =>
  console.log(`${year} has ${weeksInYear(year)} weeks`)
);

The getWeekNumber code is from here: Get week of year in JavaScript like in PHP.

Edit

Alternatively, if 31 December is in week 1 of the following year, then the subject year has 52 weeks and otherwise has 53 weeks.

function getWeekNumber(d) {
  d = new Date(+d);
  d.setHours(0, 0, 0, 0);
  d.setDate(d.getDate() + 4 - (d.getDay() || 7));
  var yearStart = new Date(d.getFullYear(), 0, 1);
  var weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7)
  return [d.getFullYear(), weekNo];
}

function weeksInYear(year) {
  var d = new Date(year, 11, 31);
  var week = getWeekNumber(d)[1];
  return week == 1 ? 52 : week;
}

[2015, 2016, 2029, new Date().getFullYear()].forEach(year =>
  console.log(`${year} has ${weeksInYear(year)} weeks`)
);
Rattlesnake answered 28/8, 2013 at 3:56 Comment(2)
Simpler than the do-loop would be to simply subtract 7.Naphtha
@ScottSauyet—simpler yet is if 31 Dec is in week 1, the year has 52 weeks, otherwise 53. :-)Rattlesnake
T
14

Use isoWeek on the last day of the year to get the number of weeks e.g. :

function weeksInYear(year) {
   return Math.max(
            moment(new Date(year, 11, 31)).isoWeek()
          , moment(new Date(year, 11, 31-7)).isoWeek()
   );
}
Terminator answered 28/8, 2013 at 3:8 Comment(2)
What happens when 31 December is in week 1 of the following year?Rattlesnake
The 28 Dec is always in the last week of a year, so you can simply get the ISO week of that date.Banshee
D
11

Feb. 4th 2014 the weeksInYear & isoWeeksInYear functions were added to moment.js

So today you can just use moment().isoWeeksInYear()or moment().weeksInYear()

For more into see the docs

Digestion answered 21/4, 2016 at 10:9 Comment(0)
C
2

Thought I would post a much simpler version that I derived from the wikipedia article. https://en.wikipedia.org/wiki/ISO_week_date

The statement in the article is:

"The number of weeks in a given year is equal to the corresponding week number of 28 December, because it is the only date that is always in the last week of the year since it is a week before 4 January which is always in the first week of the following year.

Using only the ordinal year number y, the number of weeks in that year can be determined from a function, that returns the day of the week of 31 December"

Therefore getWeekFor(new Date(2022, 11, 28) replacing the year with any year you want will always give you the number of weeks for that year.

// modified from https://mcmap.net/q/126862/-get-week-of-year-in-javascript-like-in-php 
const getWeekFor = (date) => {
    const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
    const dayNum = d.getUTCDay() || 7;
    const utc = new Date(d.setUTCDate(d.getUTCDate() + 4 - dayNum));
    const yearStart = new Date(Date.UTC(utc.getUTCFullYear(), 0, 1)).getTime();
    return Math.ceil(((d.getTime() - yearStart) / 86400000 + 1) / 7);
};

const weeks = getWeekFor(new Date(2020, 11, 28)) // 53.
console.log(weeks);
Canonicity answered 24/12, 2022 at 8:10 Comment(0)
I
-1

Get all weeks and periods of that week for a year, for whom it may interest

function getWeekPeriodsInYear(year) {
  weeks = [];

  // Get the first and last day of the year
  currentDay = moment([year, 1]).startOf('year');
  dayOfWeek = moment(currentDay).day();
  lastDay = moment([year, 1]).endOf('year');
  weeksInYear = moment(`${year}-01-01`).isoWeeksInYear();
  daysToAdd = 7 - dayOfWeek;

  for (let weekNumber = 1; weekNumber < weeksInYear + 1; weekNumber++) {
    let endOfWeek = moment(currentDay).add(daysToAdd, 'days');
    if (moment(endOfWeek).year() !== year) {
        endOfWeek = lastDay;
    }
    weeks.push({ weekNumber, start: currentDay.toDate(), end: endOfWeek.toDate() });
    currentDay = endOfWeek.add(1, 'day');
    daysToAdd = 6;
}
return weeks;
}

getWeekPeriodsInYear(new Date().getFullYear()).forEach(period =>
  document.write(`Week ${period.weekNumber} from ${moment(period.start).format('DD-MM-YYYY')} up to and including ${moment(period.end).format('DD-MM-YYYY')}<br/>`)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
Illiquid answered 19/11, 2020 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.