Difficulty Showing Leading Digit on JavaScript Timepiece

Recently, I've been dabbling in creating a basic stopwatch script using JavaScript to showcase the elapsed seconds, minutes, and hours.

The desired time format is:

hh:mm:ss

In my quest to achieve this with JavaScript, I encountered a roadblock. The challenge I faced was formatting numbers to include a leading zero for single-digit values. While I managed to add a leading "0" for the seconds, I struggled to do the same for minutes and hours.

The issue stemmed from inadvertently adding multiple "0"s within each iteration of the setInterval() function, resulting in extended strings of "0"s before the actual minutes or hours values.

I'm puzzled as to why this occurred selectively for the minutes and hours sections while it didn't affect the seconds. Despite utilizing the same logic across all three sections, the discrepancy remains elusive.

The anomaly gets more intriguing as the surplus "0"s only start appearing after two seconds into the timer. Here's the snippet of code I drafted for the stopwatch script. Any insights on rectifying this deviation would be greatly appreciated.

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

function stopWatch(){

//Increment seconds per tick of the stopwatch
seconds++;

//Check for necessary increment in minutes or hours (every 60 seconds or 60 minutes)
if(seconds % 60 == 0){
seconds = 0;
minutes++;

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

}

//Add a leading 0 if seconds, minutes, or hours are less than 10
if(seconds < 10){
seconds = "0" + seconds;
}

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

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

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

}

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

For simplicity, I retained the <script></script> tags within the HTML document. Once I streamline the functionality, I intend to transfer the script to a separate script.js file and perhaps introduce buttons for starting, stopping, and resetting the stopwatch.

Answer №1

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

function runTimer(){

//Increment seconds on each tick of the timer
seconds++;

//Check if minutes or hours need to be incremented (should occur every 60 seconds or 60 minutes, respectively)
if(seconds / 60 === 1){
seconds = 0;
minutes++;

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

}

//Add a leading zero if seconds, minutes, or hours is less than 10.
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();
}

//Display the time in the HTML element with id "display"
document.getElementById("display").innerHTML = hours_string + ":" + minutes_string + ":" + seconds_string;

}

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

Answer №2

When you concatenate "0" with minutes (as well as seconds and hours), the variables are automatically converted into strings with two characters, a zero and another character.

Since the variables persist through each iteration, adding another "0" character at the beginning of the string occurs in the subsequent iterations.

The reason this does not happen with seconds is because seconds are converted back to an integer at the start of the loop when using seconds++. This results in a cycle of conversion between string and integer for seconds.

To witness this process, try running the following code 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 recommendation is to separate counting units from display units. Check if minutes is less than 10, and if it is, set outputMinutes to "0" + minutes. Repeat this process for seconds and hours. By doing so, you can update the outputMinutes, outputSeconds, and outputHours variables while keeping the actual minutes, seconds, and hours integers intact.

Answer №3

Instead of checking if the value in the if statement is less than 10, you should check the length of the value as a string. If the length is less than 2 (indicating any number less than 10), then append another "0" as a string to the value;

Here is an example:

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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I transfer a particular data value from a div to JavaScript within Laravel 5.0?

Displaying separate square divs based on integers retrieved from the database. This is the front-end view. I want to pass the room ID (code) to a JavaScript function when clicking on these div elements. https://i.stack.imgur.com/aIYTr.png Below is my cur ...

Leaving the Node Environment after Completing All Promises

Just a heads up, this is a cronjob, so I'll have to exit using a process.exit command once the processing is done. In this unique scenario, I'm going to illustrate the problem with some placeholder code because pasting the exact script could lea ...

When the JavaScript string retrieved from the database is null, it will be displayed as an empty string

Currently, my Ajax setup involves querying a database on the server with SELECT someColumn FROM someTable. The returned value of someColumn is then updated on the client side by using $('#someElement').text(someColumn); Everything works perfectl ...

Conceal the Ipad keyboard while still retaining the ability to input text using a customized keyboard

I need to create an input field where users can enter numbers using a custom "keyboard" created with CSS/HTML on the page. This means I don't want the iPad's keyboard to pop up. Most of the solutions I've come across involve removing focus f ...

Moving from one page to another

I am attempting to create a transition effect between sections within a single-page application. All the sections are contained on the same page, with only one section displayed at a time while the rest are set to display none. When a specific event is tri ...

Update the specific component according to the identified modifications

In my project, I have two simple components: parent and child. The parent component contains an Array and for each element in the array, it renders the child component. parent.component.ts export class parent implements OnInit { data: CustomType[] = [ ...

Tips for incorporating a plugin and utilizing an external module or file on RT

My node.js application/module is currently functioning well with a plug-in concept. This means that my module acts like a proxy with additional capabilities, such as adding new functionality to the existing methods. To achieve this, follow these steps: Cl ...

Angular ERROR: Trying to access rating property of an undefined value

I'm encountering an issue on a website where users can vote for their favorite animal. Whenever I try to select an animal to vote for, I receive an unclear error message that has been difficult to resolve even after searching online for a solution. A ...

Utilizing JavaScript event handlers on dynamically appended elements after the document has finished loading

One issue I am facing is with a javasript function that needs to change the value of an element appended after the document has loaded. The problem arises when trying to intercept actions on a newly appended DIV, such as: <div class="new-div"></d ...

How to use jQuery Animate to create a step-by-step animation with image sprites?

I'm working on creating an image sprite using jQuery and I'm curious if it's feasible to animate it in steps rather than a linear motion. I initially tried using CSS3 animations, but since IE9 is a requirement, the animations didn't wor ...

When using AngularJS and Require together, there may be instances where the r.js

There seems to be a ongoing discussion about whether or not to use require.js with AngularJS, however, I have decided to implement it in my project. Currently, the project is set up and running with require, and my next step is to optimize and minify using ...

The previous successful execution of req.body is now yielding an undefined value

My req.body is suddenly undefined, even though it was working fine a few days ago. I've tried using the deprecated body-parser module, but no luck. Here's my code: JS: var express = require("express"); var router = express(); require(& ...

Getting information from MySQL database with just HTML and JavaScript

Looking to securely access a MySQL database on my localhost using only HTML and JavaScript. No need for server-side scripting or web servers. Any tips on how to make this happen? ...

StopPropagation() method in Ng-class not functioning properly in Angular for parent element

I am facing an issue with 2 nested ng-repeats. The parent one is supposed to add a class based on ng-click, but even when I click the child, it still triggers when I don't want it to. <div class="add-filter-tags" data-filter="{{f1}}" ng-class="{&a ...

AngularJS ng-disabled not functioning properly when multiple conditions are used with && (and) and || (or) operators in the view

I'm in need of some assistance. I've tried various methods to solve this issue, but I just can't seem to get both parameters working together. Using a single parameter works fine for me. This is my desired outcome: If the selection in my ...

Vue - Retrieve the id of the specific post that was clicked

My main objective is to track the number of clicks for each post. So far, I have only been able to retrieve the number of clicks per post in the console: https://i.sstatic.net/YyIdw.png However, I need to identify which post was clicked. To distinguish ...

Automatically redirect users on page refresh using jQuery

I am attempting to use jQuery to detect when the user refreshes the page in order to redirect, but I can't seem to get it working. Can someone help me figure out what is wrong with this code? <?php include 'instagram.php'; ?> <! ...

Chat application using Node.js without the need for Socket.IO

Recently delving into the world of Node.js, I stumbled upon the fs.watchFile() method. It got me thinking - could a chat website be effectively constructed using this method (along with fs.writeFile()) in comparison to Socket.IO? While Socket.IO is reliabl ...

What is the best way to create an `isHook` function in my code?

Is there a way to determine if a function passed is a React Hook? isHook(useState); // returns true isHook(() => {}); // returns false; I am looking for a method to distinguish whether a function attached to an object property is a hook or not. In cas ...

What causes the issue of undefined destructured environment variables in Next.js?

Within my application built with Next.js, I have configured a .env file containing a variable labeled API_KEY. When attempting to destructure the value of this variable, I am consistently met with undefined, as shown below: const { API_KEY } = process.env ...