2

I have an issue where I am not sure how to calculate if it is one hour or less between a dispatch date and the current time using the JS Date object. what I have done so far is I converted the entity.dispatchDate string into a Date object, however this case that I have written so far returns true whenever todaysDate date object is equal to or greater than the dispatch date. What I think I have to do is first of all, not use 1 hour but instead use minutes, as I need to account for every scenario that is within that hour - e.g. if its one hour before, 15 minutes, or 30 minutes to return true. What I have written so far:

// OPTIONS
const hoursBeforeSendout = 1;
// END OF OPTIONS

if(!entity.dispatchDate) {
    return false;
}
var sendDate = new Date(Date.parse(entity.dispatchDate));

Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}

var todaysDate = new Date();
todaysDate.addHours(hoursBeforeSendout);

if(todaysDate >= sendDate) {
    return true;
}

return false;

I would appreciate any input here on what the best approach would be

Kristaps L
  • 45
  • 4
  • 1
    The Date prototype already has a `.setHours()` function, you don't need to add one. – Pointy Jan 18 '22 at 13:47
  • The use of *Date.parse* in `new Date(Date.parse(entity.dispatchDate))` is redundant. The format of *dispatchDate* is not shown, see [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG Jan 18 '22 at 20:37

2 Answers2

2

I'd suggest simply subtracting the current date (using Date.now()) from the dispatch date.

If this is under the threshold duration, it's 'due' or 'close':

function isDispatchDateClose(dispatchDate, thresholdMs = 3600 * 1000) {
    if (!dispatchDate) {
        return false;
    }
    const timeToDispatchDateMilliseconds = Date.parse(dispatchDate) - Date.now();
    return (timeToDispatchDateMilliseconds <= thresholdMs);
}

let dispatchDates = [0, 30, 45, 90, 120].map(offsetMinutes => new Date(Date.now() + offsetMinutes * 60000).toLocaleString('sv'));
console.log('Dispatch Date', '\t\t', 'Is Close ( < 1 hr to go)');
for(let dispatchDate of dispatchDates) {
    console.log(dispatchDate, '\t', isDispatchDateClose(dispatchDate))
}
        
.as-console-wrapper { max-height: 100% !important; top: 0; }
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
0

If all you are wanting is to know if the dispatchDate value is within (less than) 1 hour from now, there are a few ways to do this that are fairly simple.

The simplest method would probably be (updated based on comment by RobG:

return new Date() - sendDate.getTime() >= 3600000;

Depending on whether or not you need any additional flexibility, you could also get the time remaining in a few different forms and decide what to do from there:

// OPTIONS
const hoursBeforeSendout = 1;
// END OF OPTIONS

if(!entity.dispatchDate) {
    return false;
}
var sendDate = new Date(Date.parse(entity.dispatchDate));

let _TimeRemaining = function(d) {
  let timeRemaining = Math.floor((d.getTime() - new Date().getTime()) / 1000);
  return {"hours": Math.floor(timeRemaining / 60 / 60), "minutes": Math.floor(timeRemaining / 60), "seconds": timeRemaining}
}

console.log(_TimeRemaining(sendDate)["hours"]); // returns the hours remaining
console.log(_TimeRemaining(sendDate)["minutes"]); // returns the minutes remaining
console.log(_TimeRemaining(sendDate)["seconds"]); // returns the seconds remaining

return _TimeRemaining(sendDate)["hours"] <= 0; // returns true if less than 1 hour
EssXTee
  • 1,783
  • 1
  • 13
  • 18
  • 1
    The use of `true : false` in ternary expressions is unnecessary. E.g. the first example can be `return new Date() - sendDate.getTime >= 3.6e6`. – RobG Jan 18 '22 at 20:40
  • That is definitely right and I'm not sure why that didn't occur to me before. I'm not sure what sort of performance differences there are, but it definitely makes for cleaner/simpler code. – EssXTee Jan 18 '22 at 20:52