Timer - javascript - javascript

I have a problem with a timer in below function. How to change seconds for a minute and seconds? In present function, the timer counting only seconds and milliseconds.
if (timer === 1) {
var startTime = Date.now();
the_timer = setInterval(function() {
var elapsedTime = Date.now() - startTime;
finished_time = (elapsedTime / 1000).toFixed(3);
$("#timer").text(finished_time);
}, 44);
}

The function getTimeStr does this. It even formats it nicely so 3 seconds will be displayed as 0:03, 32 as 0:32 and 71 seconds as 1:11.
function getTimeStr(milliseconds) {
var minutes = milliseconds / 60000;
var intMinutes = Math.floor(minutes);
var seconds = Math.floor((minutes - intMinutes) * 60);
return intMinutes + ':' + (seconds < 10 ? ('0' + seconds.toFixed(0)) : seconds.toFixed(0));
}
var startTime = new Date();
setInterval(function() {
var elapsedTime = Date.now() - startTime;
console.log(getTimeStr(elapsedTime));
}, 100);

Related

Javascript Countdown timer using SQL variable

I am new to javascript/jquery. I found the following example on the internet and I am trying to get it working with my SQL variable. But I am stuck because all it does is count down from 60 over and over again..
What I am trying to accomplish is the following. I have a variable which says how many seconds a user needs to wait before it can perform the action again $secs. What I need is to have the time and process-bar countdown with the seconds from the variable to zero. After that I will add a page reload line to it. But first the timer needs to work. I would really appreciate any help as I can not find any workable solution/explanation for my problem.
<div id='timer'></div>
<div id='progress' style='background:red; height:5px;'></div>
<script>
function started(duration) {
var TotalSeconds = "<?php echo $secs; ?>";
var documentWidth = $(document).width();
var start = Date.now();
var intervalSetted = null;
function timer() {
var diff = duration - (((Date.now() - start) / 1000) | 0);
var seconds = (diff % 60) | 0;
seconds = seconds < 10 ? "0" + seconds : seconds;
$('#timer').html("00:" + seconds);
var progresBarWidth = (seconds * documentWidth / TotalSeconds);
$('#progress').css({
width: progresBarWidth + 'px'
});
if (diff <= 0) {
clearInterval(intervalSetted);
}
}
timer();
intervalSetted = setInterval(timer, 1000);
}
started("<?php echo $secs; ?>");
</script>
You need to convert duration to time format.
<div id='timer'></div>
<div id='progress' style='background:red; height:5px;'></div>
<script>
function started(duration) {
var TotalSeconds = duration;
var documentWidth = $(document).width();
var start = Date.now();
var intervalSetted = null;
function timer() {
var diff = duration - (((Date.now() - start) / 1000) | 0);
var seconds = (diff % duration) | 0;
seconds = seconds < 10 ? "0" + seconds : seconds;
var date = new Date(0);
date.setSeconds(seconds);
var timeString = date.toISOString().substr(11, 8);
$('#timer').html(timeString);
var progresBarWidth = (seconds * documentWidth / TotalSeconds);
$('#progress').css({
width: progresBarWidth + 'px'
});
if (diff <= 0) {
clearInterval(intervalSetted);
}
}
timer();
intervalSetted = setInterval(timer, 1000);
}
started("<?php echo $secs; ?>");
</script>
function started(duration) {
var TotalSeconds = duration;
var documentWidth = $(document).width();
var start = Date.now();
var intervalSetted = null;
function timer() {
var diff = duration - (((Date.now() - start) / 1000) | 0);
var seconds = (diff % duration) | 0;
seconds = seconds < 10 ? "0" + seconds : seconds;
var date = new Date(0);
date.setSeconds(seconds);
var timeString = date.toISOString().substr(11, 8);
$('#timer').html(timeString);
var progresBarWidth = (seconds * documentWidth / TotalSeconds);
$('#progress').css({
width: progresBarWidth + 'px'
});
if (diff <= 0) {
clearInterval(intervalSetted);
}
}
timer();
intervalSetted = setInterval(timer, 1000);
}
started(60);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='timer'></div>
<div id='progress' style='background:red; height:5px;'></div>

Minutes not quite in sync with seconds

I have a timer which I am testing, it seems there is a bit of drift between when the minute countdown goes down by 1 and seconds whenever it reaches 59 seconds ()ie every minute:-
How can I alter this so they are both in sync?
my code is the following:-
$(document).ready(function() {
function now() {
return window.performance ? window.performance.now() : Date.now();
}
function tick() {
var timeRemaining = countdown - ((now() - initTick) / 1000);
timeRemaining = timeRemaining >= 0 ? timeRemaining : 0;
var countdownMinutes = Math.floor(timeRemaining / 60);
var countdownSeconds = timeRemaining.toFixed() % 60;
countdownTimer.innerHTML = countdownMinutes + ":" + countdownSeconds;
if (countdownSeconds < 10) {
countdownTimer.innerHTML = countdownMinutes + ":" + 0 + countdownSeconds;
}
if (timeRemaining > 0) {
setTimeout(tick, delay);
}
}
var countdown = 600; // time in seconds until user may login again
var delay = 20; // time (in ms) per tick
var initTick = now(); // timestamp (in ms) when script is initialized
var countdownTimer = document.querySelector(".timer"); // element to have countdown written to
setTimeout(tick, delay);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="timer"></div>
js fiddle: https://jsfiddle.net/robbiemcmullen/cer8qemt/1/
The issue is the precision is not the same for minutes and seconds.
You need to round to the nearest second before /60 / %60.
Consider: exactly 9 mins remaining:
var x = 540;
console.log(x.toFixed() % 60, Math.floor(x / 60));`
Output is: (0,9)
Then consider the call 20 ms later:
var x = 539.980;
console.log(x.toFixed() % 60, Math.floor(x / 60));
the output is now: (0, 8).
So the seconds haven't changed (yet) but the minute does.
Here is a version using setInterval and removing the use of .toFixed ()
Why do you use an interval of 20ms and not 1 second?
//method for countdown timer
$(document).ready(function() {
function now() {
return window.performance ? window.performance.now() : Date.now();
}
function tick() {
var timeRemaining = countdown - elapsedTime;
var countdownMinutes = Math.floor(timeRemaining / 60);
var countdownSeconds = timeRemaining % 60;
countdownTimer.innerHTML = countdownMinutes + ":" + countdownSeconds;
if (countdownSeconds < 10) {
countdownTimer.innerHTML = countdownMinutes + ":" + 0 + countdownSeconds;
}
++elapsedTime;
return timeRemaining;
}
var countdown = 600;
var elapsedTime = 0;
var timeRemaining;
// countdown: time in seconds until user may login again
//var delay = 20;
// delay: time (in ms) per tick
var initTick = now(); // initTick: timestamp (in ms) when script is initialized
var countdownTimer = document.querySelector(".timer");
// countdownTimer: element to have countdown written to
var interval = setInterval(function() {
if(tick() <= 0) {
clearInterval(interval);
}
}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="timer"></div>
js fiddle https://jsfiddle.net/ud3wm8t1/

Javascript timer to use multiple times in a page

I have this Javascript count down timer that works perfectly. Only problem is i can use it for only one time in one page. I want to use it multiple times.
I think script use id ="timer" that is why i am not able to use it multiple times.
Below is the JS code:
<script>
var startTime = 60; //in Minutes
var doneClass = "done"; //optional styling applied to text when timer is done
var space = ' ';
function startTimer(duration, display) {
var timer = duration,
minutes, seconds;
var intervalLoop = setInterval(function() {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "00" + space + minutes + space + seconds;
if (--timer < 0) {
document.querySelector("#timer").classList.add(doneClass);
clearInterval(intervalLoop);
}
}, 1000);
}
window.onload = function() {
var now = new Date();
var hrs = now.getHours();
var setMinutes = 60 * (startTime - now.getMinutes() - (now.getSeconds() / 100)),
display = document.querySelector("#timer");
startTimer(setMinutes, display);
};
</script>
Just declare intervalLoop outside of the startTimer function, it'll be available globally.
var intervalLoop = null
function startTimer(duration, display) {
intervalLoop = setInterval(function() { .... }
})
function stopTimer() {
clearInterval(intervalLoop) // Also available here!
})
window.setInterval(function(){ Your function }, 1000);
Here 1000 means timer 1 sec
I think something like this could be helpful:
Timer object declaration
var timerObject = function(){
this.startTime = 60; //in Minutes
this.doneClass = "done"; //optional styling applied to text when timer is done
this.space = ' ';
return this;
};
timerObject.prototype.startTimer = function(duration, display) {
var me = this,
timer = duration,
minutes, seconds;
var intervalLoop = setInterval(function() {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "00" + me.space + minutes + me.space + seconds;
if (--timer < 0) {
// not sure about this part, because of selectors
document.querySelector("#timer").classList.add(me.doneClass);
clearInterval(intervalLoop);
}
}, 1000);
}
Use it like
var t1 = new timerObject();
var t2 = new timerObject();
t1.startTimer(a,b);
t2.startTimer(a,b);
JS Fiddle example:
UPD1 commented part so the the timer could be stopped
https://jsfiddle.net/9fjwsath/1/

Find elapsed time in javascript

I'm new to JavaScript and I'm trying to write a code which calculates the time elapsed from the time a user logged in to the current time.
Here is my code:-
function markPresent() {
window.markDate = new Date();
$(document).ready(function() {
$("div.absent").toggleClass("present");
});
updateClock();
}
function updateClock() {
var markMinutes = markDate.getMinutes();
var markSeconds = markDate.getSeconds();
var currDate = new Date();
var currMinutes = currDate.getMinutes();
var currSeconds = currDate.getSeconds();
var minutes = currMinutes - markMinutes;
if(minutes < 0) { minutes += 60; }
var seconds = currSeconds - markSeconds;
if(seconds < 0) { seconds += 60; }
if(minutes < 10) { minutes = "0" + minutes; }
if(seconds < 10) { seconds = "0" + seconds; }
var hours = 0;
if(minutes == 59 && seconds == 59) { hours++; }
if(hours < 10) { hours = "0" + hours; }
var timeElapsed = hours+':'+minutes+':'+seconds;
document.getElementById("timer").innerHTML = timeElapsed;
setTimeout(function() {updateClock()}, 1000);
}
The output is correct upto 00:59:59 but after that that O/P is:
00:59:59
01:59:59
01:59:00
01:59:01
.
.
.
.
01:59:59
01:00:00
How can I solve this and is there a more efficient way I can do this?
Thank you.
No offence, but this is massively over-enginered. Simply store the start time when the script first runs, then subtract that from the current time every time your timer fires.
There are plenty of tutorials on converting ms into a readable timestamp, so that doesn't need to be covered here.
var start = Date.now();
setInterval(function() {
document.getElementById('difference').innerHTML = Date.now() - start;
// the difference will be in ms
}, 1000);
<div id="difference"></div>
There's too much going on here.
An easier way would just be to compare markDate to the current date each time and reformat.
See Demo: http://jsfiddle.net/7e4psrzu/
function markPresent() {
window.markDate = new Date();
$(document).ready(function() {
$("div.absent").toggleClass("present");
});
updateClock();
}
function updateClock() {
var currDate = new Date();
var diff = currDate - markDate;
document.getElementById("timer").innerHTML = format(diff/1000);
setTimeout(function() {updateClock()}, 1000);
}
function format(seconds)
{
var numhours = parseInt(Math.floor(((seconds % 31536000) % 86400) / 3600),10);
var numminutes = parseInt(Math.floor((((seconds % 31536000) % 86400) % 3600) / 60),10);
var numseconds = parseInt((((seconds % 31536000) % 86400) % 3600) % 60,10);
return ((numhours<10) ? "0" + numhours : numhours)
+ ":" + ((numminutes<10) ? "0" + numminutes : numminutes)
+ ":" + ((numseconds<10) ? "0" + numseconds : numseconds);
}
markPresent();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="timer"></div>
Here is a solution I just made for my use case. I find it is quite readable. The basic premise is to simply subtract the timestamp from the current timestamp, and then divide it by the correct units:
const showElapsedTime = (timestamp) => {
if (typeof timestamp !== 'number') return 'NaN'
const SECOND = 1000
const MINUTE = 1000 * 60
const HOUR = 1000 * 60 * 60
const DAY = 1000 * 60 * 60 * 24
const MONTH = 1000 * 60 * 60 * 24 * 30
const YEAR = 1000 * 60 * 60 * 24 * 30 * 12
// const elapsed = ((new Date()).valueOf() - timestamp)
const elapsed = 1541309742360 - timestamp
if (elapsed <= MINUTE) return `${Math.round(elapsed / SECOND)}s`
if (elapsed <= HOUR) return `${Math.round(elapsed / MINUTE)}m`
if (elapsed <= DAY) return `${Math.round(elapsed / HOUR)}h`
if (elapsed <= MONTH) return `${Math.round(elapsed / DAY)}d`
if (elapsed <= YEAR) return `${Math.round(elapsed / MONTH)}mo`
return `${Math.round(elapsed / YEAR)}y`
}
const createdAt = 1541301301000
console.log(showElapsedTime(createdAt + 5000000))
console.log(showElapsedTime(createdAt))
console.log(showElapsedTime(createdAt - 500000000))
For example, if 3000 milliseconds elapsed, then 3000 is greater than SECONDS (1000) but less than MINUTES (60,000), so this function will divide 3000 by 1000 and return 3s for 3 seconds elapsed.
If you need timestamps in seconds instead of milliseconds, change all instances of 1000 to 1 (which effectively multiplies everything by 1000 to go from milliseconds to seconds (ie: because 1000ms per 1s).
Here are the scaling units in more DRY form:
const SECOND = 1000
const MINUTE = SECOND * 60
const HOUR = MINUTE * 60
const DAY = HOUR * 24
const MONTH = DAY * 30
const YEAR = MONTH * 12
We can also use console.time() and console.timeEnd() method for the same thing.
Syntax:
console.time(label);
console.timeEnd(label);
Label:
The name to give the new timer. This will identify the timer; use the same name when calling console.timeEnd() to stop the timer and get the time output to the console.
let promise = new Promise((resolve, reject) => setTimeout(resolve, 400, 'resolved'));
// Start Timer
console.time('x');
promise.then((result) => {
console.log(result);
// End Timer
console.timeEnd('x');
});
You can simply use performance.now()
Example:
start = performance.now();
elapsedTime = performance.now() - start;
var hours = 0;
if(minutes == 59 && seconds == 59)
{
hours = hours + 1;
minutes = '00';
seconds == '00';
}
I would use the getTime() method, subtract the time and then convert the result into hh:mm:ss.mmm format.
I know this is kindda old question but I'd like to apport my own solution in case anyone would like to have a JS encapsulated plugin for this. Ideally I would have: start, pause, resume, stop, reset methods. Giving the following code all of the mentioned can easily be added.
(function(w){
var timeStart,
timeEnd,
started = false,
startTimer = function (){
this.timeStart = new Date();
this.started = true;
},
getPartial = function (end) {
if (!this.started)
return 0;
else {
if (end) this.started = false;
this.timeEnd = new Date();
return (this.timeEnd - this.timeStart) / 1000;
}
},
stopTime = function () {
if (!this.started)
return 0;
else {
return this.getPartial(true);
}
},
restartTimer = function(){
this.timeStart = new Date();
};
w.Timer = {
start : startTimer,
getPartial : getPartial,
stopTime : stopTime,
restart : restartTimer
};
})(this);
Start
Partial
Stop
Restart
What I found useful is a 'port' of a C++ construct (albeit often in C++ I left show implicitly called by destructor):
var trace = console.log
function elapsed(op) {
this.op = op
this.t0 = Date.now()
}
elapsed.prototype.show = function() {
trace.apply(null, [this.op, 'msec', Date.now() - this.t0, ':'].concat(Array.from(arguments)))
}
to be used - for instance:
function debug_counters() {
const e = new elapsed('debug_counters')
const to_show = visibleProducts().length
e.show('to_show', to_show)
}

Running a Javascript Clock at 4x Speed [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript to run the Clock (date and time) 4 times speeder
I'm trying to make a clock that starts at a time value (hh:mm:ss) that I've supplied, and runs at 4x speed (for the server time of an online game that runs 4x actual time). I've modified a free clock that I found online to do this, but it only works for every other minute (try the code below to see exactly what I mean if that doesn't make sense).
var customClock = (function () {
var timeDiff;
var timeout;
function addZ(n) {
return (n < 10 ? '0' : '') + n;
}
function formatTime(d) {
t1 = d.getHours();
t2 = d.getMinutes();
t3 = d.getSeconds() * 4;
if (t3 > 59) {
t3 = t3 - 60;
t2 = t2 + 1;
}
if (t2 > 59) {
t2 = t2 - 60;
t1 = t1 + 1;
}
if (t1 > 23) {
t1 = 0;
}
return addZ(t1) + ':' + addZ(t2) + ':' + addZ(t3);
}
return function (s) {
var now = new Date();
var then;
var lag = 1015 - now.getMilliseconds();
if (s) {
s = s.split(':');
then = new Date(now);
then.setHours(+s[0], +s[1], +s[2], 0);
timeDiff = now - then;
}
now = new Date(now - timeDiff);
document.getElementById('clock').innerHTML = formatTime(now);
timeout = setTimeout(customClock, lag);
}
}());
window.onload = function () {
customClock('00:00:00');
};
Any idea why this is happening? I'm pretty new to Javascript and this is definitely a little hack-ey. Thanks
i take the orginal time and substract it from the current then multiply it by 4 and add it to the orginal time. I think that should take care or the sync problem.
(function(){
var startTime = new Date(1987,08,13).valueOf() //save the date 13. august 1987
, interval = setInterval(function() {
var diff = Date.now() - startTime
//multiply the diff by 4 and add to original time
var time = new Date(startTime + (diff*4))
console.log(time.toLocaleTimeString())
}, 1000)
}())
How to use with a custom date (use the Date object)
Date(year, month, day, hours, minutes, seconds, milliseconds)
var lag = 1015 - now.getMilliseconds(); is attempting to "run this again a smidge (15 ms) after the next clock tick". Make this value smaller (divide by 4?), and this code will run more frequently.
Next up, get it to show 4x the current clock duration. Similar problem: multiply now's details by 4 either inside or outside formatTime()
I would first create a Clock constructor as follows:
function Clock(id) {
var clock = this;
var timeout;
var time;
this.hours = 0;
this.minutes = 0;
this.seconds = 0;
this.stop = stop;
this.start = start;
var element = document.getElementById(id);
function stop() {
clearTimeout(timeout);
}
function start() {
timeout = setTimeout(tick, 0);
time = Date.now();
}
function tick() {
time += 1000;
timeout = setTimeout(tick, time - Date.now());
display();
update();
}
function display() {
var hours = clock.hours;
var minutes = clock.minutes;
var seconds = clock.seconds;
hours = hours < 10 ? "0" + hours : "" + hours;
minutes = minutes < 10 ? "0" + minutes : "" + minutes;
seconds = seconds < 10 ? "0" + seconds : "" + seconds;
element.innerHTML = hours + ":" + minutes + ":" + seconds;
}
function update() {
var seconds = clock.seconds += 4;
if (seconds === 60) {
clock.seconds = 0;
var minutes = ++clock.minutes;
if (minutes === 60) {
clock.minutes = 0;
var hours = ++clock.hours;
if (hours === 24) clock.hours = 0;
}
}
}
}
Then you can create a clock and start it like this:
var clock = new Clock("clock");
clock.start();
Here's a demo: http://jsfiddle.net/Nt5XN/

Categories