Date math

Some date math I worked out (in javascript) while improving calendar week support for bootstrap-datepicker.

Given weekstart, a weekday on which the week starts (0 for Sunday, 1 for Monday, etc), get the first day of a given date’s week:

var date = new Date();
var start = new Date(+date + (weekstart - date.getDay() - 7) % 7 * 864e5);

Given a date, you want the nearest date in the past that has start.getDay() == weekstart, inclusive of date. For the simple case of a Sunday weekstart (0), this is simply date.getDay() days in the past, or - date.getDay() “in the future”. For the sequential case of Monday (1), it’s one day after that, or - date .getDay() + 1 days “in the future”; this doesn’t work, though, for dates whose getDay is less than weekstart, such as the Sunday before a starting Monda y (this will give the following Monday as the “start of week”, instead of the previous Monday). For these cases, we subtract a week from the change and modulo it by 7 to make sure w e don’t actually go back more than one week; this allows the caculation to go back up to 6 days, but no more.

Last day of current week:

var end = new Date(+start + 6 * 864e5)

Once you have the week start, it’s just a matter of adding 6 days.

Thursday (weekday 4) of this week:

var th = new Date(+start + (4 - start.getDay() + 7) % 7 * 864e5)

Similar to finding the week start, except we now want to travel forward in time from that start. The 4 represents the day of the week we are looking for in the current week (0 for Sunday, etc), and can be changed to any other number to find the corresponding day.

First Thursday of the year, with the year from Thursday of this week:

var yth = new Date(+(yth = new Date(th.getFullYear(), 0, 1)) + (4 - yth.getDay() + 7) % 7 * 864e5)

Starting from January 1st, basically the same logic as finding the Thursday of this week.

Calendar week: milliseconds between the Thursdays we’ve found, divided by milliseconds per day to get days between Thursdays, then divided by 7 days to get number of weeks between Thursdays. This number is then 0-based, so add 1 to get the correct number.

var calWeek =  (th - yth) / 864e5 / 7 + 1;