3

I am getting an array of day dates from an API:

0:{date: "2016-11-17T00:00:00",…}
1:{date: "2016-11-18T00:00:00",…}
2:{date: "2016-11-19T00:00:00",…}
3:{date: "2016-11-21T00:00:00",…}
4:{date: "2016-11-22T00:00:00",…}
5:{date: "2016-11-23T00:00:00",…}

In this example the array is missing this date:

{date: "2016-11-20T00:00:00",…}

What is the best way to find a missing day from an array of dates in Javascript or Angular?

So that I later would be able to pass it to a datepicker as a disabled day.

7
  • What (working) algorithm did you try so far? Commented Nov 17, 2016 at 12:18
  • what is ... meaning ?? Commented Nov 17, 2016 at 12:22
  • I am in the process of thinking about it: Using two for loops Commented Nov 17, 2016 at 12:22
  • ... means unnecessary information Commented Nov 17, 2016 at 12:23
  • is the data sorted? Commented Nov 17, 2016 at 12:23

4 Answers 4

2

Check this out:

  1. First you can sort the array (in case it is not so) using Array.prototype.sort

  2. Then use Array.prototype.reduce and a hash table to find the missing dates

Demo given in snippet below:

var array=[
  {date:"2016-11-17T00:00:00"},
  {date:"2016-11-19T00:00:00"},
  {date:"2016-11-18T00:00:00"},
  {date:"2016-11-21T00:00:00"},
  {date:"2016-11-22T00:00:00"},
  {date:"2016-11-23T00:00:00"},
  {date:"2016-11-27T00:00:00"}
];

var result = array.sort(function(a,b){
   return Date.parse(a.date) - Date.parse(b.date);
}).reduce(function(hash){
  return function(p,c){
    var missingDaysNo = (Date.parse(c.date) - hash.prev) / (1000 * 3600 * 24);
    if(hash.prev && missingDaysNo > 1) {
      for(var i=1;i<missingDaysNo;i++)
        p.push(new Date(hash.prev+i*(1000 * 3600 * 24)));
    }
    hash.prev = Date.parse(c.date);
    return p;
  };
}(Object.create(null)),[]);

console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}

Sign up to request clarification or add additional context in comments.

1 Comment

@alereisan let me know your thoughts on this... This works if the dates are not in order and also if more than one date is skipped... Note that if more than one days are skipped in succession, that will be handled too...
1

Create a new array missingDates[]

Iterate over the array (from your API) using a for loop

for (i = 0; i < array.length; i++){
    var date1 = convert your array item (with index i) to a date
    var date2 = convert your array item (with index i + 1) to a date (keep in mind, index i + 1 cant be > than array.length)

    //calculate diffDays between the 2 dates, if diff is > 1, you have a missing date
    var missingDate = create your missing date (use your date1 variable + 1Day)

    //add misingDate to missingDates[] array
    missingDates.push(missingDate)
}

Comments

1

You can do a method getMissingDate to return null if there is not missing date or return the Date object if there is a difference between to dates bigger than one day:

var arr1 = [{date: "2016-11-17T00:00:00"}, {date: "2016-11-18T00:00:00"}, {date: "2016-11-19T00:00:00"}, {date: "2016-11-21T00:00:00"}, {date: "2016-11-22T00:00:00"}, {date: "2016-11-23T00:00:00"}],
    arr2 = [{date: "2016-11-17T00:00:00"}, {date: "2016-11-18T00:00:00"}, {date: "2016-11-19T00:00:00"}, {date: "2016-11-20T00:00:00"}, {date: "2016-11-21T00:00:00"}, {date: "2016-11-22T00:00:00"}, {date: "2016-11-23T00:00:00"}],
    getMissingDate = function(arr) {
      var result = null;
      for (var i = 0, l = arr.length - 1; i < l; i++) {
        var current = new Date(arr[i].date),
            next = new Date(arr[i + 1].date);

        if (1 < Math.ceil(Math.abs(next.getTime() - current.getTime()) / (1000 * 3600 * 24))) {
          result = new Date(current.setDate(current.getDate() + 1));
          break;
        } 
      }

      return result;
    };

console.log('arr1:', getMissingDate(arr1));
console.log('arr2:', getMissingDate(arr2));

Comments

0

var array=[
  {date:"2016-01-01T00:00:00"},
  {date:"2016-03-01T00:00:00"},
  {date:"2016-04-01T00:00:00"},
  {date:"2016-07-01T00:00:00"},
  {date:"2016-09-01T00:00:00"},
  {date:"2016-11-01T00:00:00"},
  {date:"2016-12-01T00:00:00"}
];

var result = array.sort(function(a,b){
   return Date.parse(a.date) - Date.parse(b.date);
}).reduce(function(hash){
  return function(p,c){
    var missingMonthsNo= (Date.parse(c.date) - hash.prev) / (1000 * 3600 * 24);
    if(hash.prev && missingMonthsNo> 1) {
      for(var i=1;i<missingMonthsNo;i++)
        p.push(new Date(hash.prev+i*(1000 * 3600 * 24)));
    }
    hash.prev = Date.parse(c.date);
    return p;
  };
}(Object.create(null)),[]);

console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.