0

I'd like to know how I can work out the calendar days between 2 dates. Currently I'm converting to timestamps and working out the diff as this seems to be the most common solution as below:

let time = 1561978969653;
let now = new Date();
let uploadDate = new Date(time);

let timeDiff = Math.abs(now.getTime() - uploadDate.getTime());
let days = Math.ceil(timeDiff / (1000 * 3600 * 24));

console.log(timeDiff, days);

However this has certain drawbacks. For example 26/01/2019 @ 11:59:59 to 27/01/2019 00:00:00 should count as 1 calendar day apart, however with the method I'm using it counts as 0 because it didn't have a full 24 hours between the 2 timestamps.

I have also thought about looping through the days and incrementing a counter but that seems a little inefficient and/or inelegant.

Edit: I do not want to implement a 3rd party library for this, I'd like a programatic solution, likewise timestamp based approaches do not resolve the issue of short date intervals as stated in the question above.

Royal Wares
  • 1,192
  • 10
  • 23
  • is this not a duplicate of https://stackoverflow.com/questions/9129928/how-to-calculate-number-of-days-between-two-dates ? I would certainly recommend using momentjs and not implementing something like this yourself, it would be full of potential pitfalls! – Huw Davies Jul 01 '19 at 11:01
  • Possible duplicate of [How to calculate number of days between two dates](https://stackoverflow.com/questions/9129928/how-to-calculate-number-of-days-between-two-dates) – Matej J Jul 01 '19 at 11:02
  • @HuwDavies Nope, because that's a 3rd party library, not vanilla JS. – Royal Wares Jul 01 '19 at 11:02
  • look into how they implement their `diff` method then, and by the way, you didn't state that it *had* to be vanilla js – Huw Davies Jul 01 '19 at 11:03
  • @AlexanderDeSousa sometimes you need to look over the accepted answer. look at this answer from Matej J's link https://stackoverflow.com/a/9129976/572771 – Rafael Herscovici Jul 01 '19 at 11:03
  • P.S If you start using dates in JS, you should really consider using `moment`. – Rafael Herscovici Jul 01 '19 at 11:04
  • you should reduce each timestamp to day stamps first then subtract the result. – Stephen Quan Jul 01 '19 at 11:05
  • @StephenQuan that sounds great! Would you be happy to expand that into an answer? – Royal Wares Jul 01 '19 at 11:06
  • @HuwDavies that's right I didn't, I normally expect the default on SO to be to work with the solution programatically. – Royal Wares Jul 01 '19 at 11:09
  • If partial days should always count as a full day, just round up every time? If that's acceptable depends on what the day variable is used for. – Shilly Jul 01 '19 at 11:11
  • @StephenQuan come to think of it, that wouldn't work with daylight savings time. – Royal Wares Jul 01 '19 at 11:13

3 Answers3

1

Use Math.round on the absolute value to get the next full value of the day.

function calculateDaysBetween(now, uploadDate) {
    let timeDiff = Math.abs(now.getTime() - uploadDate.getTime());
    return Math.round(Math.abs((timeDiff)/((24*60*60*1000))));
}

let now = new Date("Jan 27, 2019 00:00:00");
let uploadDate = new Date("Jan 26, 2019 11:59:59");
console.log(calculateDaysBetween(now, uploadDate)); // 1 Day

let now2 = new Date("Jun 01, 2019 00:00:00");
let now3 = new Date("Jun 01, 2019 00:01:00");
console.log(calculateDaysBetween(now2, now3)); // 0 Days

let now4 = new Date("Jun 10, 2019 10:00:59");
let now5 = new Date("Jun 15, 2019 11:59:00");
console.log(calculateDaysBetween(now4, now5)); // 5 Days
basic
  • 3,348
  • 3
  • 21
  • 36
1

I'd suggest using the setHours method to set the hours, minutes, seconds and milliseconds to zero (giving you the start of the relevant day) for both the start and end date objects, and then calculate the difference between those.

Conveniently, the setHours method returns the number of milliseconds since Jan 1970, the same as the getTime method, so you can get rid of those calls as well.

function diff(a,b) {
  let timeDiff = Math.abs(a.setHours(0,0,0,0) - b.setHours(0,0,0,0));
  let days = Math.round(timeDiff / (1000*3600*24));
  console.log(a + " -> " + b + ": " + days + " days");
  return days;
}

diff(new Date("Jun 01, 2019 23:59:00"), new Date("Jun 02, 2019 00:01:00"));
sheltond
  • 1,877
  • 11
  • 15
1

Elaborating the idea I had in the comments, if you choose an epoch date, we just count the number of days each dates are relative to the epoch. Then, we just note the day difference. This should iron our any issues you have with hours, minutes and seconds. Choose an appropriate epoch date to cancel out local time zone issues and day light savings issues:

function countDays(srcDate, dstDate) {
    let epoch = new Date("2000-01-01 00:00:00")
    let srcDays = Math.floor((srcDate.getTime() - epoch.getTime()) / 1000 / 60 / 60 / 24)
    let dstDays = Math.floor((dstDate.getTime() - epoch.getTime()) / 1000 / 60 / 60 / 24)
    let count = dstDays - srcDays
    console.log("srcDate: ", srcDate)
    console.log("dstDate: ", dstDate)
    console.log("count: ", count)
    return count
}

countDays(new Date("2019-01-26 23:59:59"), new Date("2019-01-27 00:00:00"))
countDays(new Date("2019-01-26 11:59:59"), new Date("2019-01-27 00:00:00"))
countDays(new Date(1561978969653), new Date())
Stephen Quan
  • 21,481
  • 4
  • 88
  • 75