0

I need to compare two dates in Javascript, considering only the day (ie. not the time), but I don't want to mutate the original date objects.

I've come up with:

_isDayGreaterOrEqualThan(date1, date2) {
    const dayDate1 = new Date(date1).setHours(0,0,0,0);
    const comparableDate1 = new Date(dayDate1).getTime();
    const dayDate2 = new Date(date2).setHours(0,0,0,0);
    const comparableDate2 = new Date(dayDate2).getTime();
    return comparableDate1 >= comparableDate2;
}

Is there any more efficient way to do this, without using external libraries?

  • 1
    Creating another Date-Objects for `comparableDate1` and `comparableDate2` are not necessary because `setHours` also returns the timestamps you are calling with `new Date(dayDate1).getTime()` and `new Date(dayDate2).getTime()` – Blauharley May 15 '18 at 10:31
  • As Blauharley says, *dayDate1* and *comparableDate1* will be identical values (millisecond offsets from 1970-01-01). – RobG May 16 '18 at 08:13
  • You could do the same operation as a single line of code: `return new Date(date1).setHours(0,0,0,0) >= new Date(date2).setHours(0,0,0,0)`. Hopefully *date1* and *date2* are Dates. If they're strings, see [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG May 16 '18 at 08:25

2 Answers2

1

This is maybe not more efficient, but more elegant:

Date.prototype.onlyDate = function () {
    var d = new Date(this);
    d.setHours(0, 0, 0, 0);
    return d;
}

and then you can ask:

date1.onlyDate() > date2.onlyDate()
MikeSpiris
  • 73
  • 6
0

You can take the timestamp and truncate it to multiples of 1000 * 60 * 60 * 24, i.e. days in milliseconds.

_isDayGreaterOrEqualThan(date1, date2) {
    const comp1 = Math.trunc(date1.getTime() / (1000 * 60 * 60 * 24));
    const comp2 = Math.trunc(date2.getTime() / (1000 * 60 * 60 * 24));
    return comp1 >= comp2;
}

As a side note: by convention, comparator functions return a negative number if the left argument is less than the right, a positive number if the right argument is less than the left, and zero if they're equal (this is the convention that e.g. Array.sort() uses if you pass a function as an argument). So you might want to consider this:

_compareDay(date1, date2) {
    const comp1 = Math.trunc(date1.getTime() / (1000 * 60 * 60 * 24));
    const comp2 = Math.trunc(date2.getTime() / (1000 * 60 * 60 * 24));
    return comp1 - comp2;
}
Máté Safranka
  • 4,081
  • 1
  • 10
  • 22
  • That will compare UTC dates since *getTime* returns the internal time value, which is a UTC offset. The OP seems to be comparing local dates. – RobG May 16 '18 at 08:11
  • Does that matter, though? The end result is still that one date is before the other. Timezone doesn't really make a difference, especially if we use UTC which is zone independent. – Máté Safranka May 16 '18 at 08:12
  • Yes. For someone in timezone UTC -08:00, 2018-05-15 12:00 is the same date UTC, but 2018-05-15 20:00 (i.e. the same local day) is 2018-05-16 04:00 UTC (i.e. the next day). Some places also apply daylight saving changes at midnight, which can also shift Dates using this method. – RobG May 16 '18 at 08:20
  • Ahhh, okay I see what you mean. Local dates do make more sense in this case. – Máté Safranka May 16 '18 at 08:27