5

I'm looking for a way to get "tomorrow" and "the day after tomorrow" returned from a function that receives to dates:

The current date:

"2015/04/24 18:15:00"

The date in the future:

"2015/04/25 02:40:00"

The function should return "tomorrow" here. I tried looking up some functions but they all return 0 not 1.

function days_between(date1, date2) {

    // The number of milliseconds in one day
    var ONE_DAY = 1000 * 60 * 60 * 24

    // Convert both dates to milliseconds
    var date1_ms = date1.getTime()
    var date2_ms = date2.getTime()

    // Calculate the difference in milliseconds
    var difference_ms = Math.abs(date1_ms - date2_ms)

    // Convert back to days and return
    return Math.round(difference_ms/ONE_DAY)

}

Any ideas?

kevinius
  • 4,232
  • 7
  • 48
  • 79

3 Answers3

6

First, here's the documentation on the Javascript Date object and its prototype.

So, how can you determine if a particular day (date2) is one day after another (date1)? Well, add one day to date1 and see if the dates match:

var date1_tomorrow = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate() + 1);
if (date1_tomorrow.getFullYear() == date2.getFullYear() && date1_tomorrow.getMonth() == date2.getMonth() && date1_tomorrow.getDate() == date2.getDate()) {
    return "tomorrow"; // date2 is one day after date1.
}

If you want to determine if date2 is two days after date1, you can use the same logic as above but add 2 days instead of 1:

var date1_overmorrow = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate() + 2);
if (date1_overmorrow.getFullYear() == date2.getFullYear() && date1_overmorrow.getMonth() == date2.getMonth() && date1_overmorrow.getDate() == date2.getDate()) {
    return "the day after tomorrow"; // date2 is two days after date1.
}

If the dates are not 1 or 2 days apart, the final bit would be to just return the date in your desired format:

return date2.toLocaleString(); // Firefox 29+, Chrome 24+, IE 11+
// OR
return date2.getFullYear() + '/' + (date2.getMonth() + 1) + '/' + date2.getDate() + ' ' + date2.getHours() + ':' + date2.getMinutes() + ':' + date2.getSeconds(); // Et al.

Test

function incrementDate(date, n) {
  return new Date(date.getFullYear(), date.getMonth(), date.getDate() + n);
}

function compareDates(date1, date2) {
  return date1.getFullYear() == date2.getFullYear() && date1.getMonth() == date2.getMonth() && date1.getDate() == date2.getDate();
}

function formatDate(date) {
  var year = date.getFullYear();
  var month = date.getMonth() + 1;
  var day = date.getDate();
  return year + '-' + (month < 10 ? '0' : '') + month + '-' + (day < 10 ? '0' : '') + day;
}

$(function() {
  var $output = $('#output');
  
  var comparisons = [
    {'start': new Date(2016, 6 - 1, 1), 'inc': 1, 'target': new Date(2016, 6 - 1, 2)},
    {'start': new Date(2016, 6 - 1, 30), 'inc': 1, 'target': new Date(2016, 7 - 1, 1)},
    {'start': new Date(2016, 12 - 1, 31), 'inc': 1, 'target': new Date(2017, 1 - 1, 1)}
  ];
  for (var i = 0, len = comparisons.length; i < len; i += 1) {
    var comp = comparisons[i];
    var $row = $('<tr>');
    
    $('<td>').text(formatDate(comp.start)).appendTo($row);
    $('<td>').text(comp.inc).appendTo($row);
    $('<td>').text(formatDate(comp.target)).appendTo($row);
    $('<td>').text(compareDates(comp.target, incrementDate(comp.start, comp.inc)) ? 'yes' : 'no').appendTo($row);
    
    $output.append($row);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th>Start</th>
      <th>Inc</th>
      <th>Target</th>
      <th>Equal</th>
    </tr>
  </thead>
  <tbody id="output">
  </tbody>
</table>
Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
  • 6
    This does not work if tomorrow is a new month or a new year. – marchaos Mar 21 '16 at 08:38
  • @marchaos Rollover on a new month and new year work for me. Can you provide an example or link? – Uyghur Lives Matter Mar 21 '16 at 14:08
  • Yeah sorry it's actually fine, I think I must have done something different, somehow! Will delete my comment and down-vote :) – dan richardson Jun 23 '16 at 14:02
  • I'd actually use `Date.UTC` though instead and compare the time values == 0, much easier – dan richardson Jun 23 '16 at 14:04
  • 2
    @danrichardson I'm comparing only the date portion specifically to make it time agnostic because it looked like the OP wanted to determine "tomorrow" without respect to time. – Uyghur Lives Matter Jun 23 '16 at 14:23
  • Point taken. Creating a date via it's constructor without time parameters will always result it being time agnostic anyway so it's then safe to compare the milliseconds anyway, as UTC is time agnostic essentially in this instance. – dan richardson Jun 24 '16 at 10:57
  • I'm having a array off feature times. I want to pick the next available time from the array. Can I use this logic to find the next time? – reegan29 Oct 23 '18 at 11:58
  • @reegan29 This will not help you pick a date/time from an array. What this does is tell you if a date/time occurs the day after. – Uyghur Lives Matter Oct 23 '18 at 14:44
1

I would create two date objects. One that represents midnight of today's date and another that represents midnight of tomorrow. If the date I'm comparing is between those two dates then I know it falls under the umbrella of "tomorrow." If I want to do two days in advance the idea is the same but the date objects would represent an extra date in the future.

For example:

const oneDay = 1000 * 60 * 60 * 24;

function getMidnight(day){
  const date = new Date(day);
  date.setMilliseconds(999);
  date.setSeconds(59);
  date.setMinutes(59);
  date.setHours(23);
  return date;
}

function isTomorrow(date){
  const midnightTonight = getMidnight(new Date());
  const midnightTomorrow = new Date(midnightTonight.getTime() + oneDay);

  return date > midnightTonight && date < midnightTomorrow;
}

function isDayAfterTomorrow(date){
  const midnightTomorrow = getMidnight(new Date(Date.now() + oneDay));
  const midnightDayAfterTomorrow = new Date(midnightTomorrow + oneDay);

  return date > midnightTomorrow && date < midnightDayAfterTomorrow;
}
Abir Taheer
  • 2,502
  • 3
  • 12
  • 34
0

This actually worked for me: Generally, we retrieve UNIX time of tomorrow start and end as well. Then we just check, if our date gets to the interval between them.

const isTomorrow = (date: Date): boolean => {
  const today = new Date();
  const tomorrow = new Date(today);
  tomorrow.setDate(tomorrow.getDate() + 1);
  tomorrow.setHours(0, 0, 0, 0);
  const tomorrowStart = tomorrow.valueOf();
  tomorrow.setHours(23, 59, 59, 999);
  const tomorrowEnd = tomorrow.valueOf();
  return date.valueOf() >= tomorrowStart && date.valueOf() <= tomorrowEnd;
};
Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34
  • Why do you do `const today = new Date();, const tomorrow = new Date(today)`? Isn't that the same as ` const tomorrow = new Date()`? – Moritz Ringler Feb 21 '23 at 17:49