2

I have an array of date-ranges from which I need to know how many people have worked in each week for the whole year.

Eg: mainArray = ['01-01-2020','31-12-2020']; //year range

dateRanges = [
  [01-01-2020, 03-01-2020], //week 1
  [03-01-2020, 06-01-2020], //week 1 and 2
  [09-01-2020, 09-01-2020], //week 2
  [10-01-2020, 11-01-2020], //week 2
  [22-01-2020, 23-01-2020], //week 4
  ....
];

//first we need to find all the weeks from the mainArray date-range 

//then calculate the weeks colliding in the dateRanges array.

the output should be =>

workLoadInWeeks = [2,3,0,1,0,0,0,0,......,0];

Explanation: Since 03-01-2020(date in week-1) is repeating in 1st and 2nd array indexes, that's why the output has 2 as the first value.

Since the dates of week-2 are repeating in dateRanges[1], dateRanges[2], dateRanges[3], that's why the output has 3 as the second value.

since nobody worked in 3rd week its 0 in the output array

Week start - Sunday, 7 days a week,
I want the week date range to start from the 1st Jan, so first week would be a partial week as 1st start is a Wednesday.

This may sound confusing. I have tried my best to explain.

Ashik Paul
  • 486
  • 4
  • 20
  • @T.J.Crowder Sorry for the confusion. I have edited the question. Please let me know if you need any further clarification. Thank you – Ashik Paul Jun 09 '20 at 11:20
  • https://www.w3resource.com/javascript-exercises/javascript-date-exercise-47.php see this can help you – Avinash Dalvi Jun 09 '20 at 11:24

2 Answers2

1

We need a function which results overall count of week:

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
}

And a function which gets week number:

function getWeek(date_string) {
    let [d, M, y] = date_string.split(/[- :]/);
    let passedDate = new Date(y, parseInt(M) - 1, d);
    let onejan = new Date(passedDate.getFullYear(), 0, 1);
    week = Math.ceil( (((passedDate - onejan) / 86400000) + onejan.getDay() + 1) / 7 );
    return week;
} 

After we having this weeks we counts of persons per Week. And then we can figure out how many people have worked in each week for the whole year.

let weeks = dateRanges.map(s => s.map(d => this.getWeek(d)));

let distinctWeeks = weeks.map(s => 
    s.filter((item, pos) => s.indexOf(item) == pos)).flatMap(s => s);

let personPerWeek = distinctWeeks.reduce((a, c)=> {
    a[c] = a[c] || 0;
    a[c] += 1;
    return a;
},{})

const weekCount = getISOWeeks(2020);
let personsPerWeeks = [];

getWorkWeeks = (workWeeks, weekCount) => {
    for (let index = 1; index <= weekCount; index++) {
        let personCount = personPerWeek[index] || 0;
        workWeeks.push(personCount);
    }
    return workWeeks;
}

An example can be seen here:

function getWeek(date_string) {
    let [d, M, y] = date_string.split(/[- :]/);
    let passedDate = new Date(y, parseInt(M) - 1, d);
    let onejan = new Date(passedDate.getFullYear(), 0, 1);
    week = Math.ceil( (((passedDate - onejan) / 86400000) + onejan.getDay() + 1) / 7 );
    return week;
}

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
}

let dateRanges = [
  ['01-01-2020', '03-01-2020'], //week 1
  ['03-01-2020', '06-01-2020'], //week 1 and 2
  ['09-01-2020', '09-01-2020'], //week 2
  ['10-01-2020', '11-01-2020'], //week 2
  ['22-01-2020', '23-01-2020'], //week 4
];

let weeks = dateRanges.map(s => s.map(d => this.getWeek(d)));
let distinctWeeks = weeks.map(s => s.filter((item, pos) => s.indexOf(item) == pos)).flatMap(s => s);
let personPerWeek = distinctWeeks.reduce((a, c)=> {
    a[c] = a[c] || 0;
    a[c] += 1;
    return a;
},{})

const weekCount = getISOWeeks(2020);
let personsPerWeeks = [];

getWorkWeeks = (workWeeks, weekCount) => {
    for (let index = 1; index <= weekCount; index++) {
        let personCount = personPerWeek[index] || 0;
        workWeeks.push(personCount);
    }
    return workWeeks;
}

getWorkWeeks(personsPerWeeks, weekCount);
console.log(personsPerWeeks)
StepUp
  • 36,391
  • 15
  • 88
  • 148
0

Check if this works for you.

dateRanges = [
 ["01-01-2020", "03-01-2020"], //week 1
  ["03-01-2020", "06-01-2020"], //week 1 and 2
  ["09-01-2020", "09-01-2020"], //week 2
  ["10-01-2020", "11-01-2020"], //week 2
  ["22-01-2020", "23-01-2020"], //week 4

];

mainArray = ['01-01-2020','31-12-2020'];
//console.log(dateRanges);
function diff_weeks(dt2, dt1) 
 {

  var diff =(dt2.getTime() - dt1.getTime()) / 1000;
  diff /= (60 * 60 * 24 * 7);
  return Math.abs(Math.round(diff));
  
 }

//for(var i = 0; i< dateRanges.length;i++){
//console.log(dateRanges[i][0]);
  var dateString1 = mainArray[0];
  var dateParts1 = dateString1.split("-"); 
  var dt1 = new Date(+dateParts1[2], dateParts1[1] - 1, +dateParts1[0]); 
  var dateString2 = mainArray[1];
  var dateParts2 = dateString2.split("-"); 
  var dt2 = new Date(+dateParts2[2], dateParts2[1] - 1, +dateParts2[0]); 
  //console.log(dt1);
  console.log(diff_weeks(dt1, dt2) + " Weeks");
//}
Avinash Dalvi
  • 8,551
  • 7
  • 27
  • 53
  • Will do, Thank you for the immediate response. I don't have permission to upvote your answer. I will check and let you know. Thank you so much. – Ashik Paul Jun 09 '20 at 11:58
  • Welcome. Once you got enough reputation do upvote. Thanks. if this works for you accept too. @AshikPaul – Avinash Dalvi Jun 09 '20 at 12:02
  • I am expecting an array as an output which is of length 52(weeks in a year). Please check the sample output. – Ashik Paul Jun 09 '20 at 12:02
  • code which i added for `mainArray` same thing you can do for other array using for lop. you want that also ? – Avinash Dalvi Jun 09 '20 at 12:04
  • I guess you have not understood the question. Your output is giving me the number of weeks between two dates. But I am expecting the dates repeating in all the week ranges(dateRanges array). I will add more details in the example. Sorry for the confusion. – Ashik Paul Jun 09 '20 at 12:13