Display time format in a running stopwatch - javascript

I'm making a stopwatch and out of esthetic reasons I want the output to display: 00:00:00:000. The problem is that when my stopwatch is running I'm having a hard time getting it to except a 0 in front when the value < 10.
window.addEventListener('load', function() {
var display = document.getElementById('display-area');
var toggle = document.getElementById('toggle-button');
var reset = document.getElementById('reset-button');
var ms,
difference,
interval,
hours,
minutes,
seconds,
timer = 0;
function start() {
difference = Date.now();
interval = window.setInterval(update, 10);
timer = 1;
};
function stopp() {
window.clearInterval(interval);
timer = 0;
};
function nullstill() {
ms = 0;
seconds = 0;
minutes = 0;
hours = 0;
display.value = '00:00:00:000';
};
function update() {
ms += elapsedTime();
if (ms >= 1000) {
seconds += 1;
ms = 0;
}
if (seconds >= 60) {
minutes += 1;
seconds = 0;
}
if (minutes >= 60) {
hours += 1;
minutes = 0;
}
display.value = hours + ':' + minutes +':' + seconds +':'+ ms;
};
function elapsedTime() {
var now = Date.now();
elapsed = now - difference;
difference = now;
return elapsed;
};
nullstill();
toggle.addEventListener('click', function() {
console.log(timer);
if (timer != 1) {
start();
} else {
stopp();
}
});
reset.addEventListener('click', function() {
nullstill();
});
});
How do I make it work?
Regards,

An integer will never hold a 0 in front of the number. This is a fairly easy fix. You will just need to use some string concatenation.
display.value = (hours < 10 ? "0"+hours : hours) + ':' + (minutes < 10 ? "0"+minutes : minutes) +':' + (seconds < 10 ? "0"+seconds: seconds) +':'+ ms;
The syntax I have used is called a ternary operator. Here is a little bit about how it works. Basically, it is a simplified if statement which can be used inline.
( condition ? {if true, run this } : {else, run this})

Here's a useful little example that shows you a convenient way to add leading zeros to numbers in Javascript. If you have a number like 53, and want 6 number places (eg 4 leading zeros in the case of 56), you just add (1e6+53+'').slice(-6) and that will give you 000053 because 1e6 means 1 with 6 zeros after it, and slice with a negative number starts from the end and chops out 6 places in this case, so 100000053 becomes 000053
hours=0,minutes=1,seconds=20,ms=7;
document.getElementById('t').innerHTML=
(1e2+hours+'').slice(-2) + ':' +
(1e2+minutes+'').slice(-2) +':' +
(1e2+seconds+'').slice(-2) +':'+
(1e3+ms+'').slice(-3);
<div id='t'></div>
Notice the 1 or 2 leading zeros in the case of ms is handled. And you can adjust the number of leading zeros easily.

This requires string concatenation when the value is less than 10. I would create three separate variables for the hours, minutes and seconds. That way the code is more clean and readable.
var displayHours = (hours >= 10) ? hours : "0" + hours;
var displayMins = (minutes >= 10) ? minutes : "0" + minutes;
var displaySeconds = (seconds >= 10) ? seconds : "0" + seconds;
display.value = displayHours + displayMins + displaySeconds + ":" + ms;

Related

Vuejs and laravel calculate hours and minutes

I have data in json from laravel backend which looks like: "03:30:00", "01:45:00", "00:15:00"
Is there an easy way to count them together in vuejs so its looks like this: "05:30:00"
So this is simple javascript.
If the time string is always going to look the same, you can do:
let times = ["03:30:00", "01:45:00", "00:15:00"]; // you can have an unlimited number of time strings
let hours = 0;
let minutes = 0;
let seconds = 0;
for (const i in times) {
const time = times[i];
let splitTime = (time + "").split(":"); // make sure it's a string
seconds += parseInt(splitTime[2]);
if(seconds > 59){ // make sure it only goes until 59
minutes++;
seconds = seconds % 60;
}
minutes += parseInt(splitTime[1]);
if(minutes > 59){ // make sure it only goes until 59
hours++;
minutes = minutes % 60;
}
hours += parseInt(splitTime[0]);
}
let totalTime = (hours < 10 ? "0" + hours : hours) + ":"
+ (minutes < 10 ? "0" + minutes : minutes) + ":"
+ (seconds < 10 ? "0" + seconds : seconds); // put the left side zeros

javascript timer/duration giving wrong calculation after while

couple of days ago, I found a javascript code which I thought that I can use it to calculate the login time for users.. but after tested it in my application, I found that there's a difference in time after while. So, I decided to use an chrome extension called "Staying Alive for Google Chrome", it worked perfectly "or that I was hoping to.. and to be honest, it kinda good", but after that I found the same problem as picture attached.
and here's code for javscript I found:
/*===============*/
var seconds = 0;
var minutes = 0;
var hours = 0;
var t;
function add() {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
if (minutes >= 60) {
minutes = 0;
hours++;
}
}
$('#totalTime').html ( "" + (hours ? (hours > 9 ? hours : "0" + hours) : "00") + ":" + (minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") + ":" + (seconds > 9 ? seconds : "0" + seconds) );
timer();
}
function timer() {
t = setTimeout(add, 1000);
}
/*===============*/
So, I hope that someone can help me, how to make timer run decently, or has a better solution, because I have more than 6 timers in this page..
P.S. this application coded using php and javascript and I've an ajax call every 5000 milliseconds running in same page.
P.P.S. one of my friends suggested webworkers , but I really don't know a lot about it.
thanks a lot
This behaviour is expected due to the fact JavaScript is executed in a single thread in the browser. Basically, the delay amount of the setTimeout and setInterval functions should be considered a minimum.
For example, if you would execute a function resulting in heavy DOM manipulation, this could postpone the execution of the callback.
For more information on this topic, read John Resig's post on the the execution order of JavaScript timers.
Your friend's suggestion could provide a solution as WebWorkers are executed in a different thread and hence are less subjective to blocking DOM manipulation. However, I would suggest you'd handle the time calculation on the server side. For example by creating an entry for the stream in a database containing at least the start date and time of the stream. Then either:
Let your JavaScript application poll the server to sync the time
Alternatively and preferably, set up a streaming connection using a WebSocket.
The best way to measure time is to save the value of the system clock (provided by Date-Object) at start and subtract it from the current timestamp.
An example:
const totalTime = document.querySelector('#totalTime');
const startTime = Date.now();
function updateClock() {
// JS Date counts in ms, divide by 1000 to get seconds
// |0 does the same as Math.floor(value)
const elapsedTime = (Date.now() - startTime) / 1000 |0;
const seconds = elapsedTime % 60;
const minutes = Math.floor(elapsedTime / 60) % 60;
const hours = Math.floor(elapsedTime / 3600) % 24;
totalTime.textContent =
(hours < 10 ? '0' : '') + hours + ':' +
(minutes < 10 ? '0' : '') + minutes + ':' +
(seconds < 10 ? '0' : '') + seconds;
}
window.setInterval(updateClock, 1000);
<div id="totalTime"></div>
EDIT 1 "from the one who asked":
I did some edits to your code cos I needed to add some options (reset, pause and resume).
I thought it could help any one, so I post it...
class Clock {
constructor(element, offset = 0) {
if(!(element && element instanceof HTMLElement))
throw new Error('Parameter element must be a valid HTML Element');
this._startTime = 0;
this._offset = offset;
this._interval = null;
this._element = element;
}
tick() {
const elapsedTime = (Date.now() - this._startTime) / 1000 |0;
const seconds = elapsedTime % 60;
const minutes = elapsedTime / 60 % 60 |0;
const hours = elapsedTime / 3600 % 24 |0;
this._element.textContent =
(hours < 10 ? '0' : '') + hours + ':' +
(minutes < 10 ? '0' : '') + minutes + ':' +
(seconds < 10 ? '0' : '') + seconds;
}
pause () {
if(this._interval) {
this._offset = Date.now() - this._startTime;
window.clearInterval(this._interval);
this._interval = null;
}
}
resume () {
if(!this._interval) {
this._startTime = Date.now() - this._offset;
this._interval = setInterval(this.tick.bind(this), 1000);
this.tick();
}
}
reset () {
this.pause();
this._offset = 0;
this._element.textContent = '00:00:00';
}
};
let clock = new Clock(document.querySelector('#totalTime'), 30000);
document.querySelector('#pause').addEventListener('click', () => { clock.pause() });
document.querySelector('#resume').addEventListener('click', () => { clock.resume() });
document.querySelector('#reset').addEventListener('click', () => { clock.reset() });
clock.resume();
<div id="totalTime"></div>
<button id="pause">Pause</button>
<button id="resume">Resume</button>
<button id="reset">Reset</button>

Add 0's to this countdown timer

I finally managed to make my 24 hour non-date dependable countdown timer. The purpose of this is that the countdown starts every time someone visits the site. The problem is that when any unit (hours, mins, secs) reaches single digits values display them as such instead of the standard time format (9 minutes instead of 09 minutes, as it should). How can I implement a condition that if a value it's <= 9 it adds a 0 before it?
var count = 86400;
var counter = setInterval(timer, 1000); //1000 will run it every 1 second
function timer() {
count = count - 1;
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
var hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
document.getElementById("timer").innerHTML = hours + ":" + minutes + ":" + seconds; // watch for spelling
}
<span id='timer'></span>
Create one function similar to following that does the job for you:
function makeMeTwoDigits(n){
return (n < 10 ? "0" : "") + n;
}
And before printing your numbers call this function:
document.getElementById("timer").innerHTML = makeMeTwoDigits(hours) + ":" + makeMeTwoDigits(minutes) + ":" + makeMeTwoDigits(seconds);
Explanation:
Like #rfornal said, we're checking if the number is less that 10 which means single digit, add '0' and return otherwise add nothing and return.
One point to observe is this won't work if the number is negative.
You can use universal pad function from How to output integers with leading zeros in JavaScript
function pad(num, size) {
var s = num+"";
while (s.length < size) s = "0" + s;
return s;
}
and change your code to:
document.getElementById("timer").innerHTML = pad(hours,2) + ":" + pad(minutes,2) + ":" + pad(seconds,2);
Try ...
document.getElementById("timer").innerHTML
= (hours<10 ? "0" + hours : hours) + ":"
+ (minutes<10 ? "0" + minutes : minutes) + ":"
+ (seconds<10 ? "0" + seconds : seconds);
Basically, saying if the value is less than 10, place a "0"; else just the value. Another way of saying this is if condition ? then : else ...
An alternate route ... more code would be:
var t_hours, t_minutes, t_seconds;
if (hours<10) {
t_hours = "0" + hours;
} else {
t_hours = hours;
}
if (minutes<10) {
t_minutes = "0" + minutes;
} else {
t_minutes = minutes;
}
if (seconds<10) {
t_seconds = "0" + seconds;
} else {
t_seconds = seconds;
}
document.getElementById("timer").innerHTML
= t_hours + ":" t_minutes + ":" t_seconds;

javascript/jquery countdown timer with JSfiddle example?

I am building a few things and one of them is a countdown timer, the countdown will never be over an hour so all I need to do is countdown minutes and seconds.
I have it partially working, but the problem is with the leading zeros. I got it to work in the seconds but not with the minutes.
Check out my example http://jsfiddle.net/cgweb87/GHNtk/
JavaScript
setInterval(function() {
var timer = $('span').html();
timer = timer.split(':');
var minutes = timer[0];
var seconds = timer[1];
seconds -= 1;
if (minutes < 0) return;
if (minutes < 10 && length.minutes != 2) minutes = '0' + minutes;
if (seconds < 0 && minutes != 0) {
minutes -= 1;
seconds = 59;
}
else if (seconds < 10 && length.seconds != 2) seconds = '0' + seconds;
$('span').html(minutes + ':' + seconds);
}, 1000);
HTML
<span>10:10</span>
What I want to happen is the countdown timer can begin anywhere under 1 hour, it will count down with leading zeros ie in this format;
08:49
46:09
And when it reaches the countdown to simply just display:
00:00
Thanks for any input, and I don't want to use plugins, I want to learn it.
setInterval returns an identity you can use later to clearInterval:
var interval = setInterval(function() {
/* snip */
$('span').html(minutes + ':' + seconds);
if (parseInt(minutes, 10) == 0 && parseInt(seconds, 10) == 0)
clearInterval(interval);
}, 1000);
And, to avoid the ever-increasing minutes -- 00000001:42 -- either:
change length.minutes to minutes.length in your prefix test.
cast the values to Numbers when retrieving -- var minutes = parseInt(timer[0], 10); -- and just test if (minutes < 10) ....
Taking option #2, here's an update: http://jsfiddle.net/BH8q9/
to check the length of a string, it is not
length.minutes
length.seconds
it is
minutes.length
seconds.length
Made a few simple changes to your code and it works as you'd like:
setInterval(function() {
var timer = $('span').html();
timer = timer.split(':');
var minutes = timer[0];
var seconds = timer[1];
seconds -= 1;
if (minutes < 0) return;
if (seconds < 0 && minutes != 0) {
minutes -= 1;
seconds = 59;
}
else if (seconds < 10 && length.seconds != 2) seconds = '0' + seconds;
if ((minutes < 10) && ((minutes+'').length < 2)) minutes = '0' + minutes;
$('span').html(minutes + ':' + seconds);
}, 1000);
I moved the if ((minutes < 10).... line down to happen after the minutes -= 1; otherwise at 9:59, you won't get the extra 0. Also length.minutes is the wrong way around, it'd need to be minutes.length -- but to make sure it's being treated as a string (which has a length, whereas a number doesn't), I added a blank string to it and then took the length of that.. This is what ((minutes+'').length < 2 does (checks that you have the leading zero).. This is really the best way to accomplish it, but it's the closest to your existing code.
I understand that an answer has already being accepted but would like to throw in my 2c: I like to avoid extra coding whenever possible. Using Jonathan Lonowski's approach, I would improve it like:
var interval = setInterval(function() {
var timer = $('span').html().split(':');
//by parsing integer, I avoid all extra string processing
var minutes = parseInt(timer[0],10);
var seconds = parseInt(timer[1],10);
--seconds;
minutes = (seconds < 0) ? --minutes : minutes;
if (minutes < 0) clearInterval(interval);
seconds = (seconds < 0) ? 59 : seconds;
seconds = (seconds < 10) ? '0' + seconds : seconds;
minutes = (minutes < 10) ? '0' + minutes : minutes;
$('span').html(minutes + ':' + seconds);
}, 1000);

How to stop the timer once you end an exam?

I want to stop this timer when I end the exam, but before it reaches zero. Kindly help me out on scripts please. Thanks.
JavaScript code:
var cnt = 165*60; // 165 minutes (2 hours & 45 minutes) convert to seconds
function countdown() {
if (cnt < 0) {
document.f.c.value = "- : - - : - -" ;
}
else {
hour = Math.floor(cnt / 3600);
totalmin = Math.floor(cnt / 60);
min = totalmin - (hour * 60);
sec = cnt - (totalmin * 60);
if (sec < 10) { sec = "0" + sec;}
if (min < 10) {min = "0" + min;}
if (hour < 10) {hour = "0" + hour;}
document.f.c.value = hour + ":" + min + ":" + sec;
cnt--;
_timer = setTimeout("countdown()", 1000);
}
}
var _timer = setTimeout("countdown()", 1000); // tick
I assume you meant that you want to end the timer before the countdown reaches 0.
First of all, you should use setInterval instead. It should work in all major browsers (including IE). It is just a slightly nicer way to express "I want this to happen every so often." According to the MDN, it:
Calls a function repeatedly, with a fixed time delay between each call to that function.
Here's how you would use it:
var cnt = 165*60; // 165 minutes (2 hours & 45 minutes) convert to seconds
function countdown() {
if (cnt < 0) {
document.f.c.value = "- : - - : - -" ;
}
else {
hour = Math.floor(cnt / 3600);
totalmin = Math.floor(cnt / 60);
min = totalmin - (hour * 60);
sec = cnt - (totalmin * 60);
if (sec < 10) {sec = "0" + sec;}
if (min < 10) {min = "0" + min;}
if (hour < 10) {hour = "0" + hour;}
document.f.c.value = hour + ":" + min + ":" + sec;
cnt--;
if(cnt <= 0) { # Stops the timer when it reaches 0.
clearInterval(_interval);
}
}
}
var _interval = setInterval(countdown, 1000);
And somewhere in your page have a button that will stop the timer.
<input type="button" value="Done" onclick="clearInterval(_interval)">
Although to be honest, having a countdown timer freaks me out. I'd rather have a count-up timer. :-)
In your else part
check
if(current_time < total_time)
{
//Set TimeOut
}
I think your best bet here is to use setInterval rather than setTimeout.
setInterval returns a handle to the interval. clearInterval(handle) will cancel that interval. Here's some pseudo to get you started:
var global_timer;
function countdown(){
// do some countdown stuff
if([we're done]) {
window.clearInterval(global_timer);
}
}
global_timer = window.setInterval("countdown()", 1000);
In the code that you execute when user ends the exam, probably after button click, just add such line:
window.clearTimeout(_timer);
And the timer will stop ticking.

Categories