Firstly, your code is buggy. You take a day
argument, but you never use it for anything. You always return mondays.
But worse, you're incrementing dates like so:
new Date(today.getFullYear(), today.getMonth(), today.getDay()+x);
Spot the error? You're passing getDay()+x
as the date argument. But getDay()
returns the weekday number (0-6) - not the day-in-month.
So today, Thursday the 5th of November 20151, you're in effect saying:
new Date(2015, 10, 4 + x);
The year's correct, and the month's correct (January is zero), but the date is 1 day off. Thursday is day #4 in the 0-6 weekday scheme - but really, today's the 5th of November.
So if you were to run this on the, say, the 30th of November, you'd actually be using the 1st of November as your start date, since the 30th's a Monday. If you run it on a Sunday, getDay
will return zero, meaning your start date will be the last of the previous month. And so on.
I also have to wonder why you've created a function, which builds an array just to hold a list of incrementing numbers, which you then map
to dates. The simpler way of looping through incrementing numbers is a plain old for
-loop.
Anyway, while calendars are complex, there's one thing that thankfully doesn't change: There are 7 days in a week. So you're creating 7 times more dates than you need, and filtering most of them away. You could consider simply skipping 7 dates at a time from the first occurrence.
Edit: The only thing in the above paragraph that holds true is that calendars are complex. As RobH points out in the comments, some pacific nations have been known to jump across the dateline. Presumably just to mess with programmers the world over!
Thirdly, don't mix calendar dates and raw time calculations like your division by milliseconds in a day. Switching back and forth between daylight savings time (aka winter/summer time) can cause all sorts of nonsense when mixing raw time and dates. Some calendar days are 25 hours long, some are 23. And since a date constructed from only year, month, and date sets its time to midnight, you risk skipping over a date, or repeating the same date twice.
Anyway, here's a simple solution that adds 1 day at a time until the year rolls over, storing dates that match what you're looking for:
function remainingDays(weekday) {
var current = new Date,
year = current.getFullYear(),
dates = [];
// a simple helper function
function nextDay(date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
}
// as long we're in the same year, keep adding 1 day,
// and store the ones that match the weekday we're looking for
while(current.getFullYear() === year) {
if(current.getDay() === weekday) {
dates.push(current);
}
current = nextDay(current);
}
return dates;
}
No need to build ranges, map, and filter them. Just a while
loop and push
.
Incidentally, if you want to learn more about why programming calendar and time things are just hideously complex, check out this video on youtube
1) Happy Guy Fawkes day everyone