0

I am trying to make a small question/answer quiz game using react, and I want to show a timer that counts down every second. Each game will last 10, 15, or 30 minutes at most, so I want to show a timer that updates every second in the bottom of the screen (in big font, of course!), something like 15:00, 14:59, 14:58, and so on until it hits 00:00.

So, given a start time such as 2016-04-25T08:00:00Z, and an end time after adding 15 min of 2016-04-25T08:15:00Z, I want to start the countdown.

My issue is that I am not understanding how to use setIntervals to keep calling my method to find the remaining time.

timeLeft = Math.round(timeLeft/1000) * 1000;
const timer = new Date(timeLeft);
return timer.getUTCMinutes() + ':' + timer.getUTCSeconds();
user1354934
  • 8,139
  • 15
  • 50
  • 80
  • I didn't completely understand you, but you should take a look at [moment.js](http://momentjs.com/docs) a very powerful JS lib for dealing with dates & time. For what you're describing you need to look at the "displaying" section of their docs – ChicoDelaBarrio Apr 25 '16 at 06:24
  • @RaybanM can you see my updated question? I'm stuck on using setInterval to call my method that does the above every 1 second. Thanks, and I will be check out moment.js! – user1354934 Apr 25 '16 at 06:25
  • I'm too lazy to write out an answer, but I "solved" this problem some time ago in a project of my own. Relevant code is https://github.com/jwronline/dashboard/blob/gh-pages/src/js/main.js#L238-L292 – Haroen Viaene Apr 25 '16 at 06:27
  • [Code to format time](http://stackoverflow.com/questions/6312993/javascript-seconds-to-time-string-with-format-hhmmss) And this is how I used it: timerInterval = setInterval(function() { var timeStringHHMMSS = (++timeInSeconds+"").toHHMMSS(); gameTimerElement.text(timeStringHHMMSS); }, 1000); and you can turn it off like this: clearInterval(timerInterval); – ChicoDelaBarrio Apr 25 '16 at 06:30

1 Answers1

1

EDIT: You've edited your question. You will need the time padding, and the method below will be faster than what you are using, but to answer your question about setInterval:

First, define your function to run your timer and decrement each time it's called:

var timeLeft; // this is the time left
var elem; // DOM element where your timer text goes
var interval = null; // the interval pointer will be stored in this variable

function tick() {
  timeLeft = Math.round(timeLeft / 1000) * 1000;
  const timer = new Date(timeLeft);
  var time = timer.getUTCMinutes() + ':' + timer.getUTCSeconds();
  elem.innerHTML = time;

  timeLeft -= 1000; // decrement one second

  if (timeLeft < 0) {
    clearInterval(interval);
  }
}

interval = setInterval(tick, 1000);

OG Answer:

No, I do not believe there is a built-in way to display time differences.

Let's say you have two date objects:

var start = Date.now();
var end = Date.now() + 15 * 60 * 1000; // 15 minutes

Then you can subtract the two Date objects to get a number of milliseconds between them:

var diff = (end - start) / 1000; // difference in seconds

To get the number of minutes, you take diff and divide it by 60 and floor that result:

var minutes = Math.floor(diff / 60);

To get the number of seconds, you take the modulus to get the remainder after the minutes are removed:

var seconds = diff % 60;

But you want these two padded by zeros, so to do that, you convert to Strings and check if they are two characters long. If not, you prepend a zero:

// assumes num is a whole number
function pad2Digits(num) {
  var str = num.toString();
  if (str.length === 1) {
    str = '0' + str;
  }
  return str;
}

var time = pad2Digits(minutes) + ':' + pad2Digits(seconds);

Now you have the time in minutes and seconds.

PitaJ
  • 12,969
  • 6
  • 36
  • 55
  • Thanks @PitaJ. I am actually logging the start/end times because I save this to the user's profile in case they decide to pause the game. The only value I really use is the milliseconds between their end - start times. I have a function right now that returns me the min:sec, but how can I refresh that each second using setInterval? – user1354934 Apr 25 '16 at 06:28
  • @user1354934 - I've edited the answer. Hopefully this will help you. You will be needing the padding with zeros. – PitaJ Apr 25 '16 at 06:37
  • thanks! just one question -- i am having some trouble putting this into my react component logic. basically, I am just trying to get the countdown to show up in my `
    {this.timer()}
    ` but not sure how to use the setInterval with that :(
    – user1354934 Apr 25 '16 at 07:00
  • If you're using React, you should be saving the `timeLeft` in your component state, and using `setState` in the `setInterval` callback so the component is updated. – PitaJ Apr 25 '16 at 07:08