-1

I am trying to write a function an array of the list based on the date which means I need to have the below output as return of the function

const data = [
        {
            id: 1,
            week: 'Current Week', // Text Based on the Current year where the range lies
            displayText: '15th Mar - 21st Mar 2020', // Date Range
            rangeStart: '03/15/2020', // range start day
            rangeEnd: '03/21/2020', // range end day
        },
        {
            id: 2,
            week: 'Last Week',
            displayText: '8th Mar - 14th Mar 2020',
            rangeStart: '03/08/2020',
            rangeEnd: '03/14/2020',
        },
        {
            id: 3,
            week: 'Week 15',
            displayText: '1st Mar - 7th Mar 2020',
            rangeStart: '03/07/2020',
            rangeEnd: '03/01/2020',
        },
        {
            id: 4,
            week: 'Week 14',
            displayText: '23rd Feb - 29th Feb 2020',
            rangeStart: '02/29/2020',
            rangeEnd: '02/01/2020',
        },
    ];

So the function will take mostly three parameters

  1. Start day of the week // default value sunday
  2. End day of the week //default value saturday
  3. Weeks totally //default value 4
 getDateRangeList = (startDay = 'Sunday', endDay = 'Saturday', weeks = 4) => {
        let rangeDays = 7; // diff bw start day and end day
        let weeksToShow = Array.from({ length: weeks }, (_, i) => i + 1);
        let result = weeksToShow.map((week) => {
            let obj = {};
            obj['id'] = week;
            var startDate = new Date();
            startDate.setDate(week === 1 ? startDate.getDate() : startDate.getDate() - 7 * week);
            obj['rangeStart'] = startDate.toISOString().split('T')[0];
            var endDate = new Date();
            endDate.setDate(endDate.getDate() - 7 * week);
            obj['rangeEnd'] = endDate.toISOString().split('T')[0];
            return obj;
        });
        return result;
    };

What is the best approach to this result?

halfer
  • 19,824
  • 17
  • 99
  • 186
Learner
  • 8,379
  • 7
  • 44
  • 82
  • I think there should be only two parameters `startDate` and `weeks`. As from the startDate we can get start day and by adding 7 we can get end day.Otherwise how will function detemines on which date it should start creating data – Kiran Shinde May 05 '20 at 07:19
  • thanks kenny, but the list should limit, so thats why i added an end date. assume from may 5 to mar 12 i need to have the list so in that case i should know the end date as 12 isn't – Learner May 05 '20 at 07:22
  • But how will it determine startDate? You have only three parameters. Which is not sufficient. Also where did you specified endDate? If there is endDate, then it is sufficient. But only from that parameters you can't get what you want – Kiran Shinde May 05 '20 at 07:26
  • Also for this you should use some library like `momentjs` – Kiran Shinde May 05 '20 at 07:28
  • oh okay got it based on the weeks we can go back. so there is no custom way with using js only – Learner May 05 '20 at 07:28
  • i have added what i have tried, but there are some issues, can you check the updated question – Learner May 05 '20 at 07:39
  • @DILEEPTHOMAS It's 100% possible using pure js, however it's just much easier/quicker to use a library like `momentjs`. – Dane Brouwer May 05 '20 at 07:39
  • @DaneBrouwer thanks, I have added my base logic but i am getting stuck at the current entire week part since i am taking it as todays date and how to have the display text – Learner May 05 '20 at 07:41
  • @DILEEPTHOMAS let me know if you want comments added to the code. – Dane Brouwer May 05 '20 at 08:18

1 Answers1

1

You don't need an end date because you know the length of a week is 7 days

getDateRangeList = (startDay = 1, weeks = 18, startDate = new Date()) => {
  let weeksToShow = Array.from({
    length: weeks
  }, (_, i) =>i);

  if (startDate.getDay() !== startDay) {
    startDate.setDate(startDate.getDate() - (startDate.getDay() - startDay))
  }

  return weeksToShow.map(week => {
    let [rangeStart, rangeEnd] = [new Date(startDate.getTime()), new Date(startDate.getTime())];
    rangeStart = new Date(rangeStart.setDate(rangeStart.getDate() - (7 * week)));
    rangeEnd = new Date(rangeEnd.setDate(rangeEnd.getDate() - (7 * (week - 1))));

    return {
      id: week,
      week: week === 1 ? 'Current Week' : week === 2 ? 'Last Week' : getWeekNumber(rangeStart),
      displayText: `${getDisplayTest(rangeStart)} - ${getDisplayTest(rangeEnd)}`,
      rangeStart: rangeStart.toISOString().split('T')[0].split('-').join('/'),
      rangeEnd: rangeEnd.toISOString().split('T')[0].split('-').join('/'),
    }
  });
};

// Copied from https://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php
function getWeekNumber(d) {
  d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
  const dayNum = d.getUTCDay() || 7;
  d.setUTCDate(d.getUTCDate() + 4 - dayNum);
  const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
  return Math.ceil((((d - yearStart) / 86400000) + 1) / 7)
}

function getDisplayTest(d) {
  const [day, month, [firstDateChar, secondDateChar], year] = d.toDateString().split(" ");
  const suffix = !secondDateChar ?
    +firstDateChar === 1 ? 'st' : +firstDateChar === 2 ? 'nd' : +firstDateChar === 3 ? 'rd' : 'th' :
    +firstDateChar === 1 ?
    'th' :
    +secondDateChar === 1 ? 'st' : +secondDateChar === 2 ? 'nd' : +secondDateChar === 3 ? 'rd' : 'th'
  return `${secondDateChar? +(firstDateChar+secondDateChar) : +firstDateChar}${suffix} ${month}`
}

console.log(getDateRangeList());
Community
  • 1
  • 1
Dane Brouwer
  • 2,827
  • 1
  • 22
  • 30
  • Thanks Dane, but somethings are missing, week and displayText properties are not there and instead of plus it should be minus – Learner May 05 '20 at 08:18
  • @DILEEPTHOMAS Ah, apologies - I didn't see that the above output was what you wanted. Will add that in. – Dane Brouwer May 05 '20 at 08:20
  • check this one getWeekNumber = (passedDate) => { var d = new Date(Date.UTC(passedDate.getFullYear(), passedDate.getMonth(), passedDate.getDate())); var dayNum = d.getUTCDay() || 7; d.setUTCDate(d.getUTCDate() + 4 - dayNum); var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)); return Math.ceil(((d - yearStart) / 86400000 + 1) / 7); }; getWeekNumber(new Date('2020-05-10')) this will give the week number. I thought this will help to complete the answer – Learner May 05 '20 at 08:38
  • displayText us comming as empty – Learner May 05 '20 at 08:41
  • @DILEEPTHOMAS If this answers your question. Please mark is as the answer. – Dane Brouwer May 05 '20 at 09:18
  • i have found out the way for display text will add that part and test it one more time if any other issuse so it will be a complete solution, Thanks Dane Sure will do it once i test it – Learner May 05 '20 at 09:18
  • if you give the week as 17 in getDateRangeList instead of 4, 5th Jan to 12th Jan is the week 1, isn't wrong, – Learner May 05 '20 at 09:31
  • have you seen that issue @Dane – Learner May 05 '20 at 09:35
  • also why do we need to have the if condiiton, can you explain the case may be i missed it – Learner May 05 '20 at 09:40
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/213147/discussion-between-dane-brouwer-and-dileep-thomas). – Dane Brouwer May 05 '20 at 09:44
  • just one doubt i change the params startDay = 0 and weeks = 4, the 53 week shows but we have 52 weeks isn't instead of 53 it should show 1 isn't, what can be the issue – Learner Jan 29 '21 at 09:57
  • Some years have more than 52 weeks exactly - so those extra days will likely be displayed as the 53rd week. [further reading](https://www.quora.com/What-year-will-have-53-weeks) – Dane Brouwer Jan 29 '21 at 11:50