2

I basically just can't figure this one out and don't want to hack it.

It will look so messy if I do this for 52 weeks in a year.

Any tips?

Update

This question is not about getting the year's current week.

This question is about getting weeks elapsed since a date defined.

I want the next week's workout to show up on 6th day of the current week ;)

Example

My days since start are 99: 2018-05-30 18:39:29.

Some of your examples are showing me on week 15.

My code however shows week 16, which is right. See the caveat?

  calculateUsersCurrentWorkoutWeek: function(timestamp) {
            let daysSinceSignup = moment().diff(timestamp, "days");
            if (daysSinceSignup <= 6) {
              return 1;
            } else if (daysSinceSignup > 6 && daysSinceSignup <= 13) {
              return 2;
            } else if (daysSinceSignup > 13 && daysSinceSignup <= 20) {
              return 3;
            } else if (daysSinceSignup > 20 && daysSinceSignup <= 27) {
              return 4;
            } else if (daysSinceSignup > 27 && daysSinceSignup <= 34) {
              return 5;
            } else if (daysSinceSignup > 34 && daysSinceSignup <= 41) {
              return 6;
            } else if (daysSinceSignup > 41 && daysSinceSignup <= 48) {
              return 7;
            } else if (daysSinceSignup > 48 && daysSinceSignup <= 55) {
              return 8;
            } else if (daysSinceSignup > 55 && daysSinceSignup <= 62) {
              return 9;
            } else if (daysSinceSignup > 55 && daysSinceSignup <= 62) {
              return 10;
            } else if (daysSinceSignup > 62 && daysSinceSignup <= 69) {
              return 11;
            } else if (daysSinceSignup > 69 && daysSinceSignup <= 76) {
              return 12;
            } else if (daysSinceSignup > 76 && daysSinceSignup <= 83) {
              return 13;
            } else if (daysSinceSignup > 83 && daysSinceSignup <= 90) {
              return 14;
            } else if (daysSinceSignup > 90 && daysSinceSignup <= 97) {
              return 15;
            } else {
              return 16;
            }
          }
Ali Gajani
  • 14,762
  • 12
  • 59
  • 100
  • 8
    divide by 7 and floor? – Michel Sep 06 '18 at 06:57
  • Will that give me accurate results as shown in the if else, which precisely controls things. Actually this is for displaying week workouts and I want the next weeks workouts to show up before the 7th day of the week, so a day in advance. – Ali Gajani Sep 06 '18 at 06:58
  • @Michel This is wrong. I want to show next week on the 6th day. – Ali Gajani Sep 06 '18 at 07:14
  • Possible Duplicate: https://stackoverflow.com/questions/22859704/number-of-weeks-between-two-dates-using-javascript – Rajesh Sep 06 '18 at 07:14
  • 1
    @Rajesh Technically you are right. But looking at OPs question het wants a `workoutweek`, so I suspect the actual day doesn't matter. You just have to follow a week scheme of tedious workouts in the gym, so you can go to the pub afterwards without a guilty conscience ;-) – Michel Sep 06 '18 at 07:15
  • @Michel Yup. OP updated it later. So have added a link for a dupe. – Rajesh Sep 06 '18 at 07:18
  • Nice work, but if I run my old code, I am on Week 16. Your code shows Week 15. ;) My days since start are 99, so it should show 16th week, not 15th. My start date is 2018-05-30 18:39:29. – Ali Gajani Sep 06 '18 at 07:25
  • 1
    @Ali Gajini. No it isn't. You have an error in your code at week 9 and 10: twice the same `else if(...)` for different week numbers. – Michel Sep 06 '18 at 08:13
  • Oh my bad. You are right. – Ali Gajani Sep 06 '18 at 08:54
  • What if I want this code to start from 1 again after every 16 weeks have elapsed? So batch of 16 weeks and then start again. On and on.. – Ali Gajani Sep 07 '18 at 08:11
  • @Ali Gajani. I suggest you think about that for a moment or two, write some code and if you're stuck, ask a new question. – Michel Sep 07 '18 at 09:54
  • @Michel I noticed a problem in the answer. If the startDate=today, it gives me 0th week? – Ali Gajani Sep 18 '18 at 13:15

5 Answers5

11

Divide by 7 and ceil?

const daysSinceSignup = moment().diff(timestamp, "days");
return Math.ceil(daysSinceSignup / 7);

Did you miss out on coffee this morning? ;-)


Note: The function above will tell you "the number of the week since timestamp" which is what I understand from your text, but your code sample does not reflect it.

To get the same result of your code sample, you'll need to .floor() and add 1 instead of .ceil():

const daysSinceSignup = moment().diff(timestamp, "days");
return Math.floor(daysSinceSignup / 7) + 1;
Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
2

As @Michel said, divide by 7 and floor + 1

calculateUsersCurrentWorkoutWeek: function(timestamp) {
    let daysSinceSignup = moment().diff(timestamp, "days");
    return Math.floor(daysSinceSignup / 7) + 1;
}
Jae Woo Woo
  • 901
  • 1
  • 8
  • 19
2

The easy way could also be to create a integer array in ascending order so that the values contain the upper limit of the comparison. Then for each values of daysSinceSignup you can find the index and add 1 to it since you require the return values as 1, 2, 3, ... and so on. This will be useful if you do not have uniform interval, like currently the interval is always 7 so the division and ceil approach could also work but if the interval is not uniform then this approach could be really useful.

var indexArray = [6,13,20,27,34,41,48,55,62,69,76,83,90,97];
function calculateUsersCurrentWorkoutWeek() {
  let daysSinceSignup = 14;
  var elemIndex = indexArray.findIndex((item)=> item > daysSinceSignup);
  return elemIndex+1;
}
console.log(calculateUsersCurrentWorkoutWeek());
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62
2

What you are looking for is

return Math.ceil((daysSinceStartup + 1) / 7);

This will give the same results as your code for any real number between -1 and 62 (because around 62 you forgot to replace the copied ranges). It returns 1 for 6 days, and 2 for 6.01 days, just as the original code.

Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
0

You can put your datas in array and use array.find:

var datas = [
    { min: -Infinity, max: 6, ret: 1 },
    { min: 6, max: 13, ret: 2 },
    { min: 13, max: 20, ret: 3 },
    { min: 20, max: 27, ret: 4 }
];

function calculateUsersCurrentWorkoutWeek(daysSinceSignup) {
    return datas.find(({min, max}) => 
        daysSinceSignup > min && daysSinceSignup <= max
    ).ret;
}

console.log(calculateUsersCurrentWorkoutWeek(5));
console.log(calculateUsersCurrentWorkoutWeek(7));
console.log(calculateUsersCurrentWorkoutWeek(14));
Faly
  • 13,291
  • 2
  • 19
  • 37