I was trying to do a basic date calculation as seen below. I want to find the remaining days in the month given the arguments below.
I thought I determined a solution, but there appears to be an extra 1/4 in the answer.
// returns last day of month
function lastDayOfMonth(date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0)
}
let day_start = new Date('2018-11-04');
let day_end = new Date('2019-01-10');
let day_last = lastDayOfMonth(day_start);
let total = 0;
if (day_end <= day_last) {
total = day_end - day_start;
} else {
total = day_last - day_start;
}
console.log(total / (1000 * 60 * 60 * 24)); // returns 26.25
The Date constructor using the format, new Date(year, month, day) is evaluated using your local time zone. The Date constructor for the ISO 8601 string, YYYY-MM-DD is evaluated in UTC.
You can resolve this by printing your local date in ISO 8601 format and passing that into a newly constructed Date object.
function lastDayOfMonth(date) {
let localDate=new Date(date.getFullYear(), date.getMonth()+1, 0);
let m=localDate.getMonth();
let d=localDate.getDate();
return new Date(localDate.getFullYear()+'-'+(m<10?'0':'')+m+'-'+ (d<10?'0':'')+d);
}
The difference comes from the UTC offset, since as you have it written, day_start and day_end are midnight UTC, but day_last is midnight in your local timezone.
To fix, just do all calculations in UTC. Since day_last is the only one that is local, this is the only one you need to adjust. In order to produce this in UTC, you could use the setUTCFullYear and related methods (sadly I don't believe there is a way to do it with the Date constructor):
// returns last day of month
function lastDayOfMonth(date) {
// Set correct date in UTC:
let last_date = new Date();
last_date.setUTCFullYear(date.getFullYear());
last_date.setUTCMonth(date.getMonth() + 1);
last_date.setUTCDate(0);
// Zero out the time so that this will end up as midnight:
last_date.setUTCHours(0);
last_date.setUTCMinutes(0);
last_date.setUTCSeconds(0);
last_date.setUTCMilliseconds(0);
return last_date;
}
let day_start = new Date('2018-11-04');
let day_end = new Date('2019-01-10');
let day_last = lastDayOfMonth(day_start);
let total = 0;
if (day_end <= day_last) {
total = day_end - day_start;
} else {
total = day_last - day_start;
}
console.log(total / (1000 * 60 * 60 * 24)); // returns 26 flat