Home > Net >  Why is there an extra 1/4 of a day in this time calculation?
Why is there an extra 1/4 of a day in this time calculation?

Time:03-29

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

CodePudding user response:

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

CodePudding user response:

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);
}

CodePudding user response:

There are some strange things happening with Date object. It is not always returning time as 00:00:00 thats why you are getting extra 1/4 in the answer.

This is a simple example how to fix it.

new Date("2011-09-24");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF AS BEFORE.

new Date("2011/09/24"); // change from "-" to "/".
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

For more information refer to this question - this question

  • Related