0

So I have an array of dates and want to get the current date and put it into a countdown clock I have this code atm:

 <script>
    var dates = [
      '24/5/2017',
      '12/6/2017',
      '14/6/2017',
      '16/6/2017',
      '20/6/2017',
      '20/6/2017',
      '22/6/2017',
      '23/6/2017',
      '26/6/2017'

    ];

    function sortDates(dates) {
      return dates.map(function(date) {
        return new Date(date).getTime();
      }).sort(function(a, b) {
        return a - b;
      });
    }

    var orderedDates = sortDates(dates);
    document.getElementById("demoo").innerHTML = orderedDates

    var nextDate = orderedDates.filter(function(date) {
      return (var now = new Date().getTime(); - date) > 0;
    })[0];
    document.getElementById("demo").innerHTML = nextDate

    var x = setInterval(function() {

        // Get todays date and time
        var now = new Date().getTime();

        // Find the distance between now an the count down date
        var distance = nextDate - now;

        // Time calculations for days, hours, minutes and seconds
        var days = Math.floor(distance / (1000 * 60 * 60 * 24));
        var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        var seconds = Math.floor((distance % (1000 * 60)) / 1000);

        // Output the result in an element with id="demo"
        document.getElementById("demo").innerHTML = days + "d " + hours + "h "
        + minutes + "m " + seconds + "s ";

        // If the count down is over, write some text 
        if (distance < 0) {
            clearInterval(x);
            document.getElementById("demo").innerHTML = "EXPIRED";
        }
    }, 1000);
    </script>
    <center><h2>Core Maths 2</h2><center>

This doesn't seem to do anything, so I don't really know what to do. at the moment it just comes up with NAN for the countdown

Kenan Jasim
  • 27
  • 1
  • 5
  • Please see [*Why does Date.parse give incorrect results?*](http://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG May 19 '17 at 11:43

2 Answers2

4

One problem is, that, for instance, new Date('24/5/2017') yields Invalid Date. I don't think this is a valid Date format recognized by new Date().

If you really need the format like this, you can do something like:

var dates = [
    '24/5/2017', // past Date for testing
    '12/6/2017',
    '14/6/2017',
    '16/6/2017',
    '20/6/2017',
    '20/6/2017',
    '22/6/2017',
    '23/6/2017',
    '26/6/2017'
  ].map(function (d) {
    var parts = d.split('/');
    return new Date(parts[2], parts[1] - 1 /* january = 0 */, parts[0]);
  });

so you end up having actual Date objects instead of strings by passing the parameters in a order to the Date constructor which it understands.

Another point: Since you can interpret a Date object as a Number (which yields the same as new Date().getTime(), namely the milliseconds since January 1, 1970), you can simply get the minimum using: Math.min.apply(Math, dates). So, your "next Date" (smallest timestamp which is not in the past) can simply been retrieved by var nextDate = new Date(Math.min.apply(Math, dates.filter(x => +x > Date.now())));

Below is a working snipppet which should do what you wanted.

var dates = [
  '20/4/2017',
  '24/5/2017',
  '12/6/2017',
  '14/6/2017',
  '16/6/2017',
  '20/6/2017',
  '20/6/2017',
  '22/6/2017',
  '23/6/2017',
  '26/6/2017'
].map(function (d) {
  var parts = d.split('/');
  return new Date(parts[2], parts[1] - 1 /* january = 0 */, parts[0]);
});

var nextDate = new Date(Math.min.apply(Math, dates.filter(x => +x > Date.now())));

var x = setInterval(function() {

    // Get todays date and time
    var now = new Date().getTime();

    // Find the distance between now an the count down date
    var distance = nextDate - now;

    // Time calculations for days, hours, minutes and seconds
    var days = Math.floor(distance / (1000 * 60 * 60 * 24));
    var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);

    // Output the result in an element with id="demo"
    document.getElementById("demo").innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";

    // If the count down is over, write some text 
    if (distance < 0) {
        clearInterval(x);
        document.getElementById("demo").innerHTML = "EXPIRED";
    }
}, 1000);
<center><h2>Core Maths 2</h2><center>

<div id="demo"></div>
SVSchmidt
  • 6,269
  • 2
  • 26
  • 37
0

So I did your dirty work for you, all you needed to do is some debugging, putting some console logs here and there to find out what was going wrong, which was a couple of things.

1. Your date formats are messed up (at least for me).

Instead of typing '24/5/2017', type '5/24/2017' if you want it to go right when you pass it into a Date() constructor. You can validate this by doing this: console.log(new Date('24/5/2017'));

2. Your filter function was bad

You want the next date, though you check for now - date > 0 which means that only dates that were in past will work. Either use date - now > 0 or now - date < 0.

3. You made a typo

document.getElementById("demoo").innerHTML = orderedDates

Notice the extra 'o' in 'demoo'.

4. You used invalid syntax

var nextDate = orderedDates.filter(function(date) {
  return (var now = new Date().getTime(); - date) > 0;
})[0];

This doesn't work because you cannot declare now like this. Extract the declaration of now to a line above the return statement as follows:

var nextDate = orderedDates.filter(function(date) {
  var now = new Date().getTime();
  return (now - date) < 0;
})[0];

If you apply all these corrections your countdown should work.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Glubus
  • 2,819
  • 1
  • 12
  • 26
  • Regarding date format, please see [*Why does Date.parse give incorrect results?*](http://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG May 19 '17 at 11:46