0

I am trying to have a function which displays the dates from today to sunday. So my function is like this:

dateSets() {
            const currentDate = new Date();
            const today = new Date();
            const sunday = new Date(
                currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 7)
            );
            const dates = [];
            for (let i = today.getDate(); i <= sunday.getDate(); i++) {
                dates.push(today);
                today.setDate(today.getDate() + 1);
            }
            console.log(dates);
            const tomorrow = new Date(today);
            tomorrow.setDate(tomorrow.getDate() + 1);
            console.log(tomorrow);
        }

But the output is like this:

[Mon Aug 09 2021 14: 16: 38 GMT + 0200(Central European Summer Time),
 Mon Aug 09 2021 14: 16: 38 GMT + 0200(Central European Summer Time),
 Mon Aug 09 2021 14: 16: 38 GMT + 0200(Central European Summer Time),
 Mon Aug 09 2021 14: 16: 38 GMT + 0200(Central European Summer Time),
 Mon Aug 09 2021 14: 16: 38 GMT + 0200(Central European Summer Time),
 Mon Aug 09 2021 14: 16: 38 GMT + 0200(Central European Summer Time),
 Mon Aug 09 2021 14: 16: 38 GMT + 0200(Central European Summer Time)]

Table.vue:203 Tue Aug 10 2021 14:16:38 GMT+0200 (Central European Summer Time)

So, it should display from today which is 2nd of August but it displays wrong.

Thanks.

pilchard
  • 12,414
  • 5
  • 11
  • 23
magic bean
  • 787
  • 12
  • 39
  • WHat if today is a sunday? – Salman A Aug 02 '21 at 12:55
  • I want so show only sunday. – magic bean Aug 02 '21 at 12:55
  • 1
    You push and update only `today`. The array contains multiple references to the same instance. – Dave Newton Aug 02 '21 at 13:01
  • @Dave Newton I didnt udnerstand though. How? – magic bean Aug 02 '21 at 13:05
  • How what? `today` is a `Date`. It gets pushed into `dates`. So (say) you have `[Date(8-1)]`. Then you `setDate` on it. You now have `[Date(8-2)]`. Then you push it into `dates`, now you have `[Date(8-2), Date(8-2)]`. Then you `setDate`, now you have `[Date(8-3), Date(8-3)]`, etc. If you want to add a *new* date, e.g., a different one, you must create that `Date`. – Dave Newton Aug 02 '21 at 13:07
  • Do `dates.push(new Date(+today))` so you get a new *Date* at each *push* rather than multiple references to the same *Date*. – RobG Aug 02 '21 at 13:14

3 Answers3

2

Refactored you code:

function dateSets() {
  const today = new Date();
  const sunday = new Date();
  sunday.setDate(sunday.getDate() - sunday.getDay() + 7);
  const dates = [];

  if (today.getDay() === 0) {
    dates.push(new Date(+today));
  } else {
    while (sunday >= today) {
      dates.push(new Date(+today));
      today.setDate(today.getDate() + 1);
    }
  }
  return dates;
}

console.log(dateSets());
.as-console-wrapper { min-height: 100%;}
Harsh Saini
  • 598
  • 4
  • 13
0

When you do:

dates.push(today);

you push a reference to today into the dates array so all the references in the array point to the same date. All you need to do is copy today and push that into the array:

dates.push(new Date(+today));

Also:

for (let i = today.getDate(); i <= sunday.getDate(); i++)

doesn't work when sunday is in the next month, e.g. if today is Mon 30 Aug 21 and sunday is Sun 5 Sep, so the test fails on the first iteration and you'll get an empty dates array.

With a couple of optimisations:

function dateSets(date = new Date()) { // Allow passing a date
  let currentDate = new Date(+date);
  currentDate.setHours(0,0,0,0); // for convenience
  let today = new Date(+currentDate);
  let sunday = new Date(
    currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 7)
  );
  let dates = [];
  while (sunday >= today) {       // While is simpler in this case
    dates.push(new Date(+today)); // Push copies into the array
    today.setDate(today.getDate() + 1);
  }
  return dates;
}

// Check ove month end
console.log(
  dateSets(new Date(2021,7,30)).map(d=>d.toDateString())
);
RobG
  • 142,382
  • 31
  • 172
  • 209
-1

You can calculate the dates for the current week by finding the offset based on the current day of the week and setting a start date n-numbers of days before.

Edit: I added a "day of week" offset so you can grab date starting with the current day of the week.

const DAY_IN_MILLIS = 864e5;

const defaultOptions = {
  weekdayOffset: 0,
  startOfWeek: false,
  includeSunday: false
};

const getDatesForCurrentWeek = (date, options) => {
  const
    result = [],
    opts = { ...defaultOptions, ...options },
    offset = (options.startOfWeek ? date.getDay() : opts.weekdayOffset) * DAY_IN_MILLIS;
  let startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  startDate.setTime(startDate.getTime() - offset);
  const limit = opts.includeSunday ? 8 : 7;
  for (let dayOfWeek = opts.weekdayOffset; dayOfWeek < limit; dayOfWeek++) {
    result.push(new Date(startDate.getTime() + (dayOfWeek * DAY_IN_MILLIS)));
  }
  return result;
};

const today = new Date();

console.log(`Day of week: ${today.toLocaleDateString('en-US', {
  weekday: 'long'
})}`);

// Today to Sunday
console.log(getDatesForCurrentWeek(today, {
  weekdayOffset: today.getDay(),
  includeSunday: true
}));

// All dates for current week
console.log(getDatesForCurrentWeek(today, {
  startOfWeek: true
}));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • Adding days by adding 24 hours is flawed in places that observe daylight saving and not all days are 24 hours long. See [*Add days to JavaScript Date*](https://stackoverflow.com/questions/563406/add-days-to-javascript-date) or any of the [many similar questions](https://stackoverflow.com/search?q=%5Bjavascript%5D+add+day+to+a+date). – RobG Aug 02 '21 at 13:13