Search code examples
javascriptdatecountdown

JavaScript countdown between 2 dates


I want to display a HTML countdown that takes 2 dates where dateEnd has 30 days more than dateStart. The date objects are being passed properly, but the getCountdown() function only displays the days left, while the minutes, hours and seconds don't change:

function renderCountdown(dateStart, dateEnd){

    console.log(dateStart, dateEnd); 
    // Logs 
    // Sat Dec 19 2015 11:42:04 GMT-0600 (CST) 
    // Mon Jan 18 2016 11:42:04 GMT-0600 (CST)

    let currentDate = dateStart.getTime();
    let targetDate = dateEnd.getTime(); // set the countdown date
    let days, hours, minutes, seconds; // variables for time units
    let countdown = document.getElementById("tiles"); // get tag element
    function getCountdown(){
        // find the amount of "seconds" between now and target
        let secondsLeft = (targetDate - currentDate) / 1000;
        days = pad( parseInt( secondsLeft / 86400 ) );
        secondsLeft %= 86400;
        hours = pad( parseInt( secondsLeft / 3600 ) );
        secondsLeft %= 3600;
        minutes = pad( parseInt( secondsLeft / 60 ) );
        seconds = pad( parseInt( secondsLeft % 60 ) );
        // format countdown string + set tag value
        countdown.innerHTML = "<span>" + days + "</span><span>" + hours + "</span><span>" + minutes + "</span><span>" + seconds + "</span>"; 
    }
    function pad(n) {
        return (n < 10 ? '0' : '') + n;
    }   
    getCountdown();
    setInterval(function () { getCountdown(); }, 1000);
}

Here's the HTML #tiles tag after render:

<div id="countdown">
  <div id="tiles"><span>30</span><span>00</span><span>00</span><span>00</span></div>
  <ul class="labels">
    <li>Days</li>
    <li>Hours</li>
    <li>Mins</li>
    <li>Secs</li>
  </ul>
</div>

UPDATE Working code for future reference. Thanks to @deamentiaemundi:

function renderCountdown(dateStart, dateEnd){
    let targetDate = dateEnd.getTime();
    let days, hours, minutes, seconds; 
    let countdown = document.getElementById("tiles");
    let count = 0;
    let getCountdown = function (c){
        let currentDate = new Date().getTime();
        let secondsLeft = ((targetDate - currentDate) / 1000) - c;
        days = pad( Math.floor( secondsLeft / 86400 ) );
        secondsLeft %= 86400;
        hours = pad( Math.floor( secondsLeft / 3600 ) );
        secondsLeft %= 3600;
        minutes = pad( Math.floor( secondsLeft / 60 ) );
        seconds = pad( Math.floor( secondsLeft % 60 ) );
        countdown.innerHTML = "<span>" + days + "</span><span>" + hours + "</span><span>" + minutes + "</span><span>" + seconds + "</span>"; 
    }
    function pad(n) {
        return (n < 10 ? '0' : '') + n;
    }   
    getCountdown(count++);
    setInterval(function () { getCountdown(count++ ); }, 1000);
  }

Solution

  • A little hint:

    function renderCountdown(dateStart, dateEnd){
    
        console.log(dateStart, dateEnd); 
        // Logs 
        // Sat Dec 19 2015 11:42:04 GMT-0600 (CST) 
        // Mon Jan 18 2016 11:42:04 GMT-0600 (CST)
    
        let currentDate = dateStart.getTime();
        let targetDate = dateEnd.getTime(); // set the countdown date
        let days, hours, minutes, seconds; // variables for time units
        let countdown = document.getElementById("tiles"); // get tag element
        let count = 0;
        var getCountdown = function (c){
            // find the amount of "seconds" between now and target
            let secondsLeft = ((targetDate - currentDate) / 1000) - c;
            days = pad( Math.floor( secondsLeft / 86400 ) );
            secondsLeft %= 86400;
            hours = pad( Math.floor( secondsLeft / 3600 ) );
            secondsLeft %= 3600;
            minutes = pad( Math.floor( secondsLeft / 60 ) );
            seconds = pad( Math.floor( secondsLeft % 60 ) );
            // format countdown string + set tag value
            console.log(days + ", " + hours + ", " + minutes + ", " + seconds); 
        }
        function pad(n) {
            return (n < 10 ? '0' : '') + n;
        }   
        getCountdown();
        setInterval(function () { getCountdown(count++ ); }, 1000);
    }
    
    renderCountdown(new Date("Sat Dec 19 2015 11:42:04"),new Date("Mon Jan 18 2016 11:42:04") )
    

    Output is console now, to avoid cluttering. I added a counter to actually count down and increment it every call.