Accurate and easy stopwatch Timer in JavaScript

This article shows you how to create an Accurate stopwatch in Javascript. In another article, we have already created a simple stopwatch(See here). But there is a problem you might observe the result of Stopwatch is not accurate.

The reason for the problem is we depend on setTimeout() method alone. The setTimeout() calls the callback method at the specified milliseconds only but the code execution time of the callback depends on the scheduler that may cause a delay in execution time.

To overcome the above problem, in this article we are going to use the Date.now() along with setTimeout() to make it more accurate. We will also see how to create it using the setInterval() method. There are little differences between setTimeout() and setInterval().

Accurate stopwatch javascript
Accurate stopwatch javascript

Let’s start creating a more accurate stopwatch…

How to create an accurate timer in javascript?

We will see here two app

Accurate stopwatch using setTimeout in javascript

You just need to follow the below steps:

  1. Define HTML
  2. Define CSS
  3. Javascript for timer

1. Define HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
  <head>
      <title>JavaScript StopWatch</title>
  </head>
  <body>
    <div id="stopwatch-container">
      <p id="stopwatch">00:00:00:00</p>
      <div id="buttons-container">
        <button onclick="main()" id="main-btn" class="btn">Start</button>
        <button onclick="reset()" id="reset-btn" class="btn">Reset</button>
      </div>
    </div>
  </body>
</html>

Explanation:

  • Defined an HTML <p> tag with id="stopwatch" to display the time in 00:00:00:00 format.
  • Defined two buttons with id="main-btn" and id="reset-btn" to operate stopwatch application.
  • Creating a div area as a container with id="stopwatch-container" to contain stopwatch.

2. Define CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#stopwatch-container {
  display: flex;
  justify-content: center;
  flex-direction: column;
  margin: 100px auto 0;
  width: fit-content;
  padding: 10px 20px;
  box-shadow: 1px 0px 4px 2px #9c9a9a;
  border-radius: 5px;
}
 
#stopwatch {
  margin: 0 auto;
  text-align: center;
  font-size: 60px;
}
 
#buttons-container {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}
 
#buttons-container button {
  outline: none;
  cursor: pointer;
  color: #fff;
  background-color:#000;
  border: none;
  border-radius: 5px;
  font-size: 20px;
  margin: 0 10px;
  padding: 3px 8px;
}
 
#buttons-container button:active {
  opacity: 0.7;
}

3. Javascript for Timer

Now let’s define the javascript for the timer (Stopwatch) below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//globle variables
var stopwatch = document.getElementById('stopwatch');
var mainButton = document.getElementById('main-btn');
var startTime=0;
var elapsedTime=0;
var timeoutId=null;
 
//method to operate start and stop function
function main(){
  if (mainButton.innerHTML === 'Start') {
  startTime = Date.now();
    startStopwatch();
    mainButton.innerHTML = 'Stop';
  } else {
    elapsedTime += Date.now() - startTime;
    clearTimeout(timeoutId);
    mainButton.innerHTML = 'Start';
  }
}
 
//method to reset the stopwatch
function reset() {
  elapsedTime = 0;
  startTime = Date.now();
  clearTimeout(timeoutId);
  mainButton.innerHTML = 'Start';
  displayTime(0, 0, 0, 0); 
}
 
//method to start the stopwatch
function startStopwatch() {
  
  //run setTimeout() and save id
  timeoutId = setTimeout(function(){
    //calculate elapsed time
    const time = Date.now() - startTime + elapsedTime;
     
    //calculate different time measurements based on elapsed time
    const milliseconds = parseInt((time%1000)/10)
    const seconds = parseInt((time/1000)%60)
    const minutes = parseInt((time/(1000*60))%60)
    const hour = parseInt((time/(1000*60*60))%24);
     
    //display time
    displayTime(hour, minutes, seconds, milliseconds);
     
    //calling same method again recursively 
    startStopwatch();
  }, 100);
}
 
//method to display time in '00:00:00:00' format
function displayTime(hour, minutes, seconds, milliseconds) {
    hour = hour < 10 ? '0'+hour : hour ;
    minutes = minutes < 10 ? '0'+minutes : minutes ;
    seconds = seconds < 10 ? '0'+seconds : seconds ;
    milliseconds = milliseconds < 10 ? '0'+milliseconds : milliseconds ;
    stopwatch.innerHTML = hour+':'+minutes+':'+seconds+':'+milliseconds;
}

Explanation:

  • We have Defined some global variables here as stopwatch, mainButton, startTime, elapsedTime, and timeoutId.
  • stopwatch hold the reference of <p> tag element to display the time.
  • mainButton is used to hold the reference of main button to update the button text(start and stop).
  • startTime and elapsedTime are used to hold the start time and elapsed time respectively.
  • timeoutId hold the id returnd by setTimeout() and it is used to clear or stop the timer.
  • We have defined four method as main(), startStopwatch(), displayTime(), and reset().
  • The main() method is used to operate the start and stop functionality of the stopwatch.
  • The startStopwatch() method is used to calculate the time in hour, minute, seceond, and milliseconds. We call this method recursively to continue calculating the same.
  • Here we used setTimeout() method which executes only once, that is why we called startStopwatch() recursively to repeat the process.
  • The displayTime() method is used to display the time in 00:00:00:00 format.
  • The reset() method is used to reset the stopwatch. Here we clearTimeout() method to clear the timer by passing the timeoutId.

Stopwatch timer example in Javascript (complete source code)

Below is the complete example (putting all HTML, CSS, and Javascript code in a single file) of an accurate stopwatch application using the setTimeout() method and Date.now() method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<!DOCTYPE html>
<html>
  <head>
    <title>JavaScript StopWatch</title>
    <style>
    #stopwatch-container {
      display: flex;
      justify-content: center;
      flex-direction: column;
      margin: 100px auto 0;
      width: fit-content;
      padding: 10px 20px;
      box-shadow: 1px 0px 4px 2px #9c9a9a;
      border-radius: 5px;
    }
 
    #stopwatch {
      margin: 0 auto;
      text-align: center;
      font-size: 60px;
    }
 
    #buttons-container {
      display: flex;
      justify-content: center;
      flex-wrap: wrap;
    }
 
    #buttons-container button {
      outline: none;
      cursor: pointer;
      color: #fff;
      background-color:#000;
      border: none;
      border-radius: 5px;
      font-size: 20px;
      margin: 0 10px;
      padding: 3px 8px;
    }
 
    #buttons-container button:active {
      opacity: 0.7;
    }
  </style>
  </head>
  <body>
    <div id="stopwatch-container">
      <p id="stopwatch">00:00:00:00</p>
      <div id="buttons-container">
        <button onclick="main()" id="main-btn" class="btn">Start</button>
        <button onclick="reset()" id="reset-btn" class="btn">Reset</button>
      </div>
    </div>
    <script>
    //globle variables
    var stopwatch = document.getElementById('stopwatch');
    var mainButton = document.getElementById('main-btn');
    var startTime=0;
    var elapsedTime=0;
    var timeoutId=null;
 
    //method to operate start and stop function
    function main(){
      if (mainButton.innerHTML.trim() === 'Start') {
      startTime = Date.now();
        startStopwatch();
        mainButton.innerHTML = 'Stop';
      } else {
        elapsedTime += Date.now() - startTime;
        clearTimeout(timeoutId);
        mainButton.innerHTML = 'Start';
      }
    }
 
    //method to reset the stopwatch
    function reset() {
      elapsedTime = 0;
      startTime = Date.now();
      clearTimeout(timeoutId);
      mainButton.innerHTML = 'Start';
      displayTime(0, 0, 0, 0); 
    }
 
    //method to start the stopwatch
    function startStopwatch() {
      
      //run setTimeout() and save id
      timeoutId = setTimeout(function(){
        //calculate elapsed time
        const time = Date.now() - startTime + elapsedTime;
         
        //calculate different time measurements based on elapsed time
        const milliseconds = parseInt((time%1000)/10)
        const seconds = parseInt((time/1000)%60)
        const minutes = parseInt((time/(1000*60))%60)
        const hour = parseInt((time/(1000*60*60))%24);
         
        //display time
        displayTime(hour, minutes, seconds, milliseconds);
         
        //calling same method again recursivaly
        startStopwatch();
      }, 100);
    }
 
    //method to display time in '00:00:00:00' format
    function displayTime(hour, minutes, seconds, milliseconds) {
        hour = hour < 10 ? '0'+hour : hour ;
        minutes = minutes < 10 ? '0'+minutes : minutes ;
        seconds = seconds < 10 ? '0'+seconds : seconds ;
        milliseconds = milliseconds < 10 ? '0'+milliseconds : milliseconds ;
        stopwatch.innerHTML = hour+':'+minutes+':'+seconds+':'+milliseconds;
    }
    </script>
  </body>
</html>

Javascript stopwatch Timer Live Demo

00:00:00:00

Accurate stopwatch using setInterval in javascript

The setInterval() method in JavaScript is used to repeat a specified function at every given time interval. The setInterval() method continues calling the function until clearInterval() is called, or the window is closed.

Here we use the same HTML and CSS code from the above example, only we need to modify the javascript logic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//globle variables
var stopwatch = document.getElementById('stopwatch');
var mainButton = document.getElementById('main-btn');
var startTime=0;
var elapsedTime=0;
var intervalId=null;
 
//method to operate start and stop function
function main(){
  if (mainButton.innerHTML === 'Start') {
  startTime = Date.now();
    startStopwatch();
    mainButton.innerHTML = 'Stop';
  } else {
    elapsedTime += Date.now() - startTime;
    clearInterval(intervalId);
    mainButton.innerHTML = 'Start';
  }
}
 
//method to reset the stopwatch
function reset() {
  elapsedTime = 0;
  startTime = Date.now();
  clearInterval(intervalId);
  mainButton.innerHTML = 'Start';
  displayTime(0, 0, 0, 0); 
}
 
//method to start the stopwatch
function startStopwatch() {
  
  //run setInterval() and save id
  intervalId = setInterval(function(){
    //calculate elapsed time
    const time = Date.now() - startTime + elapsedTime;
     
    //calculate different time measurements based on elapsed time
    const milliseconds = parseInt((time%1000)/10)
    const seconds = parseInt((time/1000)%60)
    const minutes = parseInt((time/(1000*60))%60)
    const hour = parseInt((time/(1000*60*60))%24);
     
    //display time
    displayTime(hour, minutes, seconds, milliseconds);     
     
  }, 100);
}
 
//method to display time in '00:00:00:00' format
function displayTime(hour, minutes, seconds, milliseconds) {
    hour = hour < 10 ? '0'+hour : hour ;
    minutes = minutes < 10 ? '0'+minutes : minutes ;
    seconds = seconds < 10 ? '0'+seconds : seconds ;
    milliseconds = milliseconds < 10 ? '0'+milliseconds : milliseconds ;
    stopwatch.innerHTML = hour+':'+minutes+':'+seconds+':'+milliseconds;
}

NOTE: Here you may notice we are not calling the startStopwatch() method recursively because we used setInterval() method and it calls the callback method every time after the specified interval by default.

Conclusion

Here you have seen creating an accurate stopwatch timer application using the setTimeout() as well as the setInterval(). You have also seen we use Date.now() method to make it more accurate.

Hope you like it. If you have any queries related to this article, write them down in the comment section below.

You may also like:

Share with friends

Leave a Comment

Your email address will not be published. Required fields are marked *