1

I've got a textbox and a button. Pressing it will calculate the time left based on the textbox value.

For example, for a value of 3600 (=seconds), it will calculate the left time : 0 days, 0 hours, 59 minutes 59 seconds.

Running the timer for the first time works greats, but I need it to reset and calculate time again from the second button pressing - and it's not working well. How can I stop the timer and run it again for new input values? The code based on w3schhol example and another web example (you can test it):

 // Set the date we're counting down to

    function setTimer()
    {

    var timeSpan = convert();
    //var countDownDate = new Date("Jan 5, 2021 15:37:25").getTime();
    var countDownDate = new Date(timeSpan).getTime();

    // Update the count down every 1 second
    var x = setInterval(function() 
    {
 
  
      // Get today's date and time
      var now = new Date().getTime();
    
      // Find the distance between now and the count down date
      var distance = countDownDate - 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);


    }

    function convert()
    {
    var now = new Date()  
    var secondsSinceEpoch = Math.round(now.getTime() / 1000)  

     // Unixtimestamp
     var unixtimestamp = document.getElementById('timestamp').value;
     unixtimestamp = parseInt(unixtimestamp);
     secondsSinceEpoch = parseInt(secondsSinceEpoch);
     unixtimestamp = unixtimestamp +  secondsSinceEpoch;
     // Months array
     var months_arr = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

     // Convert timestamp to milliseconds
     var date = new Date(unixtimestamp*1000);

     // Year
     var year = date.getFullYear();

     // Month
     var month = months_arr[date.getMonth()];

     // Day
     var day = date.getDate();

     // Hours
     var hours = date.getHours();

     // Minutes
     var minutes = "0" + date.getMinutes();

    // Seconds
     var seconds = "0" + date.getSeconds();

     // Display date time in MM-dd-yyyy h:m:s format
     var convdataTime = month+' '+day+', '+year+' '+hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
     //"Jan 5, 2021 15:37:25"
     document.getElementById('datetime').innerHTML = convdataTime;
     return convdataTime;
    }
 <!DOCTYPE HTML>
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    p {
      text-align: center;
      font-size: 60px;
      margin-top: 0px;
    }
    </style>
    </head>
    <body>
    <input type='text' value='1490028077' id='timestamp'>&nbsp;
    <input type='button' id='convert' value='Convert' onclick='setTimer()'>

    <br><br>
    <span id='datetime'></span>
    <p id="demo"></p>

    </body>
    </html>

I tried to put a counter variable, and call return once the variable == 2 (return from

var x = setInterval(function() 

) But it didn`t work...

Here is an example:

The timer freaks out from the second button press

Hitesh Tripathi
  • 856
  • 1
  • 11
  • 23
חיים חדד
  • 512
  • 5
  • 17
  • You can run the code and see the problem – חיים חדד Dec 19 '19 at 10:56
  • Does this answer your question? [How do I clear this setInterval inside a function?](https://stackoverflow.com/questions/2901108/how-do-i-clear-this-setinterval-inside-a-function) – Liam Dec 19 '19 at 10:57
  • Declare `var x` outside your `setTimer` function, then instead of `var x = setInterval..` just do `x = setInterval ...` . Basically what is happening is that when you try to `clearInterval` is possible that `x` is no longer the same property since you've declared inside your function. – gugateider Dec 19 '19 at 11:20

2 Answers2

1

var interval;
function setTimer()
    {

clearInterval(interval)

    var timeSpan = convert();
    //var countDownDate = new Date("Jan 5, 2021 15:37:25").getTime();
    var countDownDate = new Date(timeSpan).getTime();

    // Update the count down every 1 second
    interval = setInterval(function() 
    {
 
  
      // Get today's date and time
      var now = new Date().getTime();
    
      // Find the distance between now and the count down date
      var distance = countDownDate - 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(interval);
        document.getElementById("demo").innerHTML = "EXPIRED";
          }
        }, 1000);


    }

    function convert()
    {
    var now = new Date()  
    var secondsSinceEpoch = Math.round(now.getTime() / 1000)  

     // Unixtimestamp
     var unixtimestamp = document.getElementById('timestamp').value;
     unixtimestamp = parseInt(unixtimestamp);
     secondsSinceEpoch = parseInt(secondsSinceEpoch);
     unixtimestamp = unixtimestamp +  secondsSinceEpoch;
     // Months array
     var months_arr = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

     // Convert timestamp to milliseconds
     var date = new Date(unixtimestamp*1000);

     // Year
     var year = date.getFullYear();

     // Month
     var month = months_arr[date.getMonth()];

     // Day
     var day = date.getDate();

     // Hours
     var hours = date.getHours();

     // Minutes
     var minutes = "0" + date.getMinutes();

    // Seconds
     var seconds = "0" + date.getSeconds();

     // Display date time in MM-dd-yyyy h:m:s format
     var convdataTime = month+' '+day+', '+year+' '+hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
     //"Jan 5, 2021 15:37:25"
     document.getElementById('datetime').innerHTML = convdataTime;
     return convdataTime;
    }
<!DOCTYPE HTML>
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    p {
      text-align: center;
      font-size: 60px;
      margin-top: 0px;
    }
    </style>
    </head>
    <body>
    <input type='text' value='1490028077' id='timestamp'>&nbsp;
    <input type='button' id='convert' value='Convert' onclick='setTimer()'>

    <br><br>
    <span id='datetime'></span>
    <p id="demo"></p>

    </body>
    </html>
Ajay
  • 444
  • 2
  • 9
  • clearInterval(interval); in the code when counter end was still clearInterval(x); that thing is edited. – Ajay Dec 20 '19 at 00:41
1

Here's an example of a class-based approach (so you don't need a global variable);

class Timer {
  constructor(logTicks = false) {
    this.interval = null;
    this.logTicks = logTicks;
  }
  start() {
    this.interval = setInterval( () => {
      if (this.logTicks) { console.log('Tick'); }
    }, 1000);
  }
  stop() {
    if (this.interval) { clearInterval(this.interval); }
  }
}


// Usage
const timer = new Timer(true);
timer.start();

setTimeout( () => { timer.stop(); }, 10000);
mwilson
  • 12,295
  • 7
  • 55
  • 95