Jamiemcg
Jamiemcg

Reputation: 69

JavaScript Stopwatch - Trouble Displaying a Leading Digit

I've been trying to create a simple stopwatch script using JavaScript in order to display the number of seconds, minutes, and hours that have elapsed.

Ideally, I'd like to have the time displayed as follows:

hh:mm:ss

With JavaScript, I was unable to find a built-in way to format numbers such that they contain a leading zero if a number is only one digit in length. This is where my problem lies - the logic that I added to the script to add a leading "0" works for the seconds display, but not for the minutes or hours displays.

Instead of only adding a leading "0" and then the one-digit value, the code I wrote will add in a "0" for each iteration of the setInterval() function, creating a long string of "0"s and then the current minutes or hours values.

I'm having trouble understanding why that is happening for the minutes and hours sections, but not for the seconds section when the code being used is the same.

In theory, I know that I'm essentially just adding another "0" to a string that then gets displayed each time the setInterval() function executes, but I can't seem to figure out why that doesn't happen in the seconds section. And what's also interesting is that the leading "0"s don't start getting added until the timer reaches two seconds.

Please see below for the code that I wrote for this stopwatch script. I'd certainly appreciate any insight that anyone could provide to get this working as expected.

let seconds = 0;
let minutes = 0;
let hours = 0;

function stopWatch(){

//Increment seconds on each "tick" of the stopwatch
seconds++;

//Check if minutes or hours needs to be incremented (which should happen every 60 seconds or 60 minutes, resepctively)
if(seconds / 60 == 0){
	seconds = 0;
	minutes++;

	if(minutes / 60 == 0){
		minutes = 0;
		hours++;
	}

}

//If the number of elapsed seconds, minutes, or hours is less than 10, add a 0 to the front of the number.
if(seconds < 10){
	seconds = "0" + seconds;
}

if(minutes < 10){
	minutes = "0" + minutes;
}

if(hours < 10){
	hours = "0" + hours;
}

//Print the results to the "display" div in the HTML
document.getElementById("display").innerHTML = hours + ":" + minutes + ":" + seconds;

}

//Run the stopWatch() function every 1000ms
window.setInterval(stopWatch, 1000);
	<div id="display">00:00:00</div>

And for what it's worth, I kept the <script></script> tags in the HTML document for simplicity, but once I get it working, I'll likely move the script to its own script.js file and potentially add in some buttons to start, stop, and reset the stopwatch.

Upvotes: 0

Views: 234

Answers (3)

CodeMonkey
CodeMonkey

Reputation: 1156

let seconds = 0;
let minutes = 0;
let hours = 0;
let seconds_string = "0";
let minutes_string = "0";
let hours_string = "0";

function stopWatch(){

//Increment seconds on each "tick" of the stopwatch
seconds++;

//Check if minutes or hours needs to be incremented (which should happen every 60 seconds or 60 minutes, resepctively)
if(seconds / 60 === 1){
	seconds = 0;
	minutes++;

	if(minutes / 60 === 1){
		minutes = 0;
		hours++;
	}

}

//If the number of elapsed seconds, minutes, or hours is less than 10, add a 0 to the front of the number.
if(seconds < 10){
	seconds_string = "0" + seconds.toString();
} else {
    seconds_string = seconds.toString();
}

if(minutes < 10){
	minutes_string = "0" + minutes.toString();
} else {
    minutes_string = minutes.toString();
}

if(hours < 10){
	hours_string = "0" + hours.toString();
} else {
    hours_string = hours.toString();
}

//Print the results to the "display" div in the HTML
document.getElementById("display").innerHTML = hours_string + ":" + minutes_string + ":" + seconds_string;

}

//Run the stopWatch() function every 1000ms
window.setInterval(stopWatch, 1000);
	<div id="display">00:00:00</div>

Upvotes: 2

Calvin Nunes
Calvin Nunes

Reputation: 6501

Instead of test in the if if the value is less than 10, test the length of that value as a string, if it is less than 2 (which means any number less than 10 in this case), then you add another "0" as a string to the value;

Like below:

let seconds = 0;
let minutes = 0;
let hours = 0;

function stopWatch(){
  seconds++;
  
  if(seconds / 60 == 0){
    seconds = 0;
    minutes++;
    if(minutes / 60 == 0){
      minutes = 0;
      hours++;
    }
  }

  if(seconds.toString().length < 2){
    seconds = "0" + seconds;
  }
  
  if(minutes.toString().length < 2){
    minutes = "0" + minutes;
  }

  if(hours.toString().length < 2){
    hours = "0" + hours;
  }
  document.getElementById("display").innerHTML = hours + ":" + minutes + ":" + seconds;
}

window.setInterval(stopWatch, 1000);
<div id="display">00:00:00</div>

Upvotes: 1

tmdesigned
tmdesigned

Reputation: 2254

When you do "0" + minutes (and seconds, and hours) those variables get automatically converted into a string, consisting of two characters, a zero and something else.

Since the variables carry through each iteration, the next time you are adding another "0" character to the beginning of the string, and so-on.

The reason it's not happening to seconds is because you are converting seconds BACK to an int at the beginning of the loop when you do seconds++. So it becomes a string, then an int, then a string, etc.

To see this in action, try this snippet:

var test = 1;
console.log( typeof test );  //outputs "number"
test = "0" + test;
console.log( typeof test ); //outputs "string"
test++;
console.log( typeof test); //outputs number

My suggestion would be to separate counting units from display units. See if minutes is less than 10, and if so set outputMinutes to "0" + minutes. Do the same for seconds and hours. Then you just change the outputMinutes, outputSeconds, and outputHours each time, while the actual minutes, seconds, and hours variables remain as integers.

Upvotes: 2

Related Questions