user1964234
user1964234

Reputation: 129

Comparing js dates ... what week is it?

Thanks for looking at this. Javascript dates always mess me over.

I am running a time defined event and each week define new functionality. In my js I have the following;

var challenge_start = new Date(2018,03,14);
var today = new Date(2018,4,1)
var int = new Date();
var weekNo = 0;
		
	if(today<=int.setDate(challenge_start.getDate() + 7)) {
		weekNo = 1;
	}
	if(today>int.setDate(challenge_start.getDate() + 7) && today< int.setDate(challenge_start.getDate() + 15)) {
		weekNo = 2;
	}
	if(today>int.setDate(challenge_start.getDate() + 14) && today< int.setDate(challenge_start.getDate() + 22)) {
		weekNo = 3;
	}
	if(today>int.setDate(challenge_start.getDate() + 21) && today< int.setDate(challenge_start.getDate() + 29)) {
		weekNo = 4;
	}
	if(today>int.setDate(challenge_start.getDate() + 28) && today< int.setDate(challenge_start.getDate() + 36)) {
		weekNo = 5;
	}
	if(today>int.setDate(challenge_start.getDate() + 35) && today< int.setDate(challenge_start.getDate() + 43)) {
		weekNo = 6;
	}
	if(today>int.setDate(challenge_start.getDate() + 42) && today< int.setDate(challenge_start.getDate() + 49)) {
		weekNo = 7;
	}
 console.log(weekNo);

Today, I would expect weekNo=3 but instead I get weekNo=1. What am I missing here? There must be a better way to do this?

Thanks for looking at it,

Upvotes: 2

Views: 72

Answers (4)

Delvian
Delvian

Reputation: 185

.getDate() simply returns the nth of the month - today, it returns 1.

It seems like you want to know how many weeks have passed since the challenge_start date. Try the following:

function getWeeksSince(date)
{
   return Math.floor((new Date() - date) / 604800000); //604800000 is the amount of ms in a week
}
getWeeksSince(challenge_start); //2

This will return 2 when anywhere between 2-3 weeks have passed. As soon as 3 full weeks have passed since April 14th (which will be on May 5th) it will return 3.

Upvotes: 1

theGleep
theGleep

Reputation: 1187

TL;DR; - you're comparing "ticks" instead of days.

Since today is a Date object, where int.setDate() returns a number - the number of ticks since epoch, to be exact. To do the comparison, the language converts today to a number of ticks, based on "00:00:00".

When I ran my test version, I got int.setDate(challenge_start.getDate() + 7) == 1526912465737, where today.valueOf() == 1525154400000

As suggested elsewhere, you could use a secondary library like moment (I'm a particular fan of sugar.js). Or if you want to stay with "pure" javascript, you could convert those ticks to days using a bunch of math.

Upvotes: -2

T.J. Crowder
T.J. Crowder

Reputation: 1074178

I have to admit that I have trouble following your logic and what it is you ultimately want to know, but one thing jumped out at me: You're setting the day-of-month (setDate) on int based on getDate from challenge_start when they are in different months entirely (because int was initialized with just new Date()).

If I change it so int and challenge_start are initially the same date:

var int = new Date(challenge_start.getTime());

...your code returns 3 as you seem to expect:

var challenge_start = new Date(2018,03,14);
var today = new Date(2018,4,1)
var int = new Date(challenge_start.getTime());
var weekNo = 0;
		
	if(today<=int.setDate(challenge_start.getDate() + 7)) {
		weekNo = 1;
	}
	if(today>int.setDate(challenge_start.getDate() + 7) && today< int.setDate(challenge_start.getDate() + 15)) {
		weekNo = 2;
	}
	if(today>int.setDate(challenge_start.getDate() + 14) && today< int.setDate(challenge_start.getDate() + 22)) {
		weekNo = 3;
	}
	if(today>int.setDate(challenge_start.getDate() + 21) && today< int.setDate(challenge_start.getDate() + 29)) {
		weekNo = 4;
	}
	if(today>int.setDate(challenge_start.getDate() + 28) && today< int.setDate(challenge_start.getDate() + 36)) {
		weekNo = 5;
	}
	if(today>int.setDate(challenge_start.getDate() + 35) && today< int.setDate(challenge_start.getDate() + 43)) {
		weekNo = 6;
	}
	if(today>int.setDate(challenge_start.getDate() + 42) && today< int.setDate(challenge_start.getDate() + 49)) {
		weekNo = 7;
	}
 console.log(weekNo);

If weekNo is meant to be "how many weeks between the challenge start and now?" then the simplest thing is probably just to get the milliseconds between the two dates and divide by a week's worth of milliseconds, rounding up (as you appear to count partial weeks):

var challenge_start = new Date(2018,03,14);
var today = new Date(2018,4,1); // I assume this is a stand-in for just `new Date()`

today.setHours(0, 0, 0);            // Note making sure to get rid of the time (well, using midnight)
challenge_start.setHours(0, 0, 0);  // Note the midnight thing again
var weekNo = Math.ceil((today - challenge_start) / (7 * 24 * 60 * 60 * 1000));
console.log(weekNo);

That works because JavaScript's Date treats a day as exactly 86400000 (24 * 60 * 60 * 1000) milliseconds.

Upvotes: 4

phuzi
phuzi

Reputation: 13060

This should be fairly easy to calculate, no need for look ups.

Subtracting one date from another will get you the difference in ms between the two dates. Divide this by the number of milliseconds per week (1000*60*60*24*7 = 604,800,000) will get you the number of weeks since the start date.

This is not the same as week number so round it down and add 1.

var challengeStart = new Date(2018,03,14);
var today = new Date(2018,4,1)

const weeksSince = (start, date) => {
  
  const msPerWeek = 604800000;
  
  return Math.floor((date - start) / msPerWeek) + 1
};

var weekNo = weeksSince(challengeStart, today);

console.log("Week No. " + weekNo);

Upvotes: 1

Related Questions