2

I have a javascript function which calculates the date range from the week number

Date.prototype.getWeek = function weekCalc() {
  const date = new Date(this.getTime());
  date.setHours(0, 0, 0, 0);
  date.setDate((date.getDate() + 3 - (date.getDay() + 6)) % 7);
  const week1 = new Date(date.getFullYear(), 0, 4);

  return 1 + Math.round((((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6)) % 7) / 7);
};

const getDateRangeOfWeek = (weekNo, y) => {
  const d1 = new Date(`${y}`);
  const pastDays = d1.getDay() - 1;
  d1.setDate(d1.getDate() - pastDays);
  d1.setDate(d1.getDate() + 7 * (weekNo - d1.getWeek()));
  const rangeIsFrom = `${`0${d1.getDate()}`.slice(-2)}/${`0${d1.getMonth() + 1}`.slice(-2)}/${d1.getFullYear().toString().substring(2)}`;
  d1.setDate(d1.getDate() + 6);
  const rangeIsTo = `${`0${d1.getDate()}`.slice(-2)}/${`0${d1.getMonth() + 1}`.slice(-2)}/${d1.getFullYear().toString().substring(2)}`;
  return `${rangeIsFrom}-${rangeIsTo}`;
};

console.log(getDateRangeOfWeek(52, 2016));

When you test it for the week number 52 of year 2016 according to ISO 8061 it gives

getDateRangeOfWeek(52, 2016);
"19/12/16-25/12/16"

which is somehow incorrect, check here https://www.calendar-week.org/2016/52

I'm not sure what's going wrong in the above implementation?

Evaldas Buinauskas
  • 13,739
  • 11
  • 55
  • 107
Ashish Bairwa
  • 757
  • 1
  • 6
  • 19

1 Answers1

1

I didn't bother digging through your code, but I did cobble together a solution that will retrieve the desired result:

function addDays(date, days) {
  let newDate = new Date(date);
  newDate.setDate(newDate.getDate() + days)
  return newDate;
}

let locale = new Intl.DateTimeFormat('en-GB',{ dateStyle: 'short'});

function formatDate(date) {
  return locale.format(date)
}

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

  //let dateSpanLong = `${ISOweekStart} to ${ISOweekEnd}`; // date objects to do with what you please;
  let dateSpanShort = `${formatDate(ISOweekStart)} to ${formatDate(ISOweekEnd)}`;
  return dateSpanShort;
}

console.log(getDateOfISOWeek(52,2016)) // returns '26/12/2016 to 01/01/2017'

Here's a great reference for the Intl.DateTimeFormat options...

And another StackOverflow post I borrowed from for adding the 6 days...

And I used this to get the correct start of the week

Doomd
  • 1,271
  • 1
  • 16
  • 27
  • I'm sorry but I can't see how that is helping him. He wanted to know why his code isn't working, not for a working solution. And since we are indeed returning a date range, his naming was better. – jperl Nov 09 '20 at 08:58
  • You may be right. But just in case he needed a working solution, I thought I'd provide it since it only took a few minutes to compile... – Doomd Nov 09 '20 at 09:33
  • 1
    @Doomd That's why I upvoted your answer but haven't accepted it. Because I want to know the reason of why is it failing at some cases. Thanks for the references and the answer btw. – Ashish Bairwa Nov 09 '20 at 09:45