Javascrip count down timer: prevent reseting on page reload - javascript

I have a minute timer which counts from 15 to 0. I don't want to reset (= restart) the timer on page reload. but I can't figure out how to prevent the timer from resetting on a page reload. I'm using javascript with php. I have tried to add the timer time on load to php session but that didn't work for me. any suggestions? thank you :)
function startTimer() {
setTimeout('timer()', 60);
}
var continueMins = localStorage.getItem("continueMins");
var continueSecs = localStorage.getItem("continueSecs");
if (continueMins == 'true') {
mins = continueMins;
} else {
mins = 15;
}
if (continueSecs == 'true') {
secs = continueSecs;
} else {
secs = mins * 60;
}
function timer() {
if (document.getElementById) {
minutes = document.getElementById("minutes");
seconds = document.getElementById("seconds");
progressBar = document.getElementById("progressBar");
timerContainer = document.getElementById("timer-container");
expired = document.getElementById("expired");
btcAmount = document.getElementById("btcAmount");
btcAddress = document.getElementById("btcAddress");
window.onbeforeunload = function() {
localStorage.setItem("continueMins", getMinutes());
localStorage.setItem("continueSecs", getSeconds());
}
var totalSeconds = 15 * 60, remainingSeconds = getMinutes() * 60 + getSeconds();
progressBar.style.width = (remainingSeconds * 100 / totalSeconds) + "%";
minutes.innerHTML = getMinutes() < 10 ? "0" + getMinutes() : getMinutes();
seconds.innerHTML = getSeconds() < 10 ? "0" + getSeconds() : getSeconds();
if (mins < 1) {
minutes.classList.add("text-danger");
seconds.classList.add("text-danger");
}
if (mins < 0) {
expired.style.display = 'block';
timerContainer.style.display = 'none';
btcAmount.text = 'Expired';
btcAddress.text = 'Payment Window Expired';
localStorage.removeItem("continueMins");
localStorage.removeItem("continueSecs");
} else {
secs--;
setTimeout('timer()', 1000);
}
}
}
function getMinutes() {
mins = Math.floor(secs / 60);
return mins;
}
function getSeconds() {
return secs - Math.round(mins * 60);
}
startTimer();
<p class="font-18 font-500"><span id="minutes"></span> : <span id="seconds"></span></p>

You could use the localStorage (sessionStorage is also an option but more prone to restart your timer if the user e.g. reconnects in a new tab or restarts the browser)
How to do it to be on the save side (crashes, unexpected bahaviour e.g.you should update the elapsed time in your local storage from time to time. The "normal" situations are handled by checking for the respective event:
var aTimer, bool;
window.onbeforeunload = function (e) {
if (bool) return;
aTimer = setTimeout(function () {
bool = true;
localStorage.setItem("resetTimer", "false");
localStorage.setItem("currentTimer", MY_TIMER_VAR);
localStorage.setItem("sessionDate", MY_NEW_SESSION_VAR);
}, 500);
return ;
};
EDIT If you want that an elapsed timer is valid for lets say 24 hours you have also to place MY_NEW_SESSION_VAR which is a Date.now() converted in hours when reloading you check against TODAY_DATETIME_IN_HOURS which is a Date.now() converted in hours (This was my use case, if you do not need it just leave it out)
The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings).
When starting your program (loading js) you should check for the vars with:
var resetTimer = localStorage.getItem("resetTimer");
var sessionDate = localStorage.getItem("sessionDate");
if (resetTimer == "true" || sessionDate > (TODAY_DATETIME_IN_HOURS - 24) ){ // start timer }
To delete a single item
localStorage.removeItem("sessionDate");
If you want to use sessionStorage just replace localStorage with sessionStorage
EDIT full code for the OP tested and working as asked
var countDownTarget;
if (document.readyState!="loading") docReady();
/* Modern browsers */
else document.addEventListener("DOMContentLoaded", docReady);
function docReady() {
countDownTarget = parseInt(localStorage.getItem("countDownTarget"));
console.debug("Initvalue: " + countDownTarget);
if (isNaN(countDownTarget) == true || countDownTarget == "" || countDownTarget <= 0){ // If not defined
countDownTarget = new Date().getTime() + 15 * 60 * 1000;
console.debug("is NaN sInitvalue: " + countDownTarget);
//Update the count down every 1 second
setInterval(countDown, 1000);
} else {
console.debug("else Initvalue: " + countDownTarget);
setInterval(countDown, 1000);
}
}
window.onbeforeunload = function() {
localStorage.setItem("countDownTarget", countDownTarget);
};
// Functions you call
function countDown(){
var now = new Date().getTime();
//console.debug("now " + now);
var distance = countDownTarget - now;
console.debug("distance " + distance);
var mins = distance < 0 ? 0 : Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var secs = distance < 0 ? 0 : Math.floor((distance % (1000 * 60)) / 1000);
/** Add a zero in front of numbers<10 */
mins = prependZero(mins);
secs = prependZero(secs);
// Output the results
document.getElementById("minutes").innerHTML = mins;
document.getElementById("seconds").innerHTML = secs;
if (distance <= 0) {
// clearInterval(x);
localStorage.removeItem("countDownTarget");
clearInterval(countDown);
}
}
function prependZero(i){
if (i < 10) {
i = "0" + i;
}
return i;
}
Copy between your script tags or load as *.js file

Related

Javascript countdown timer add 7 days

I'm trying to add 7 days when the timer reaches 0.
Can you help?
It currently reaches negative values, but I want it to restart every Tuesdays for example.
Also, I found some solutions, but the timer was countdown was reset also on page refresh, and I don't want that.
// Countdown timer
function makeTimer() {
var endTime = new Date("October 18, 2020 08:00:00 EST");
var endTime = (Date.parse(endTime)) / 1000;
var now = new Date();
var now = (Date.parse(now) / 1000);
var timeLeft = endTime - now;
var days = Math.floor(timeLeft / 86400);
var hours = Math.floor((timeLeft - (days * 86400)) / 3600);
var minutes = Math.floor((timeLeft - (days * 86400) - (hours * 3600 )) / 60);
var seconds = Math.floor((timeLeft - (days * 86400) - (hours * 3600) - (minutes * 60)));
if (hours < "10") { hours = "0" + hours; }
if (minutes < "10") { minutes = "0" + minutes; }
if (seconds < "10") { seconds = "0" + seconds; }
$("#days").html(days + '<span class="camp">Days</span>');
$("#hours").html(hours + '<span class="camp">Hours</span>');
$("#minutes").html(minutes + '<span class="camp">Minutes</span>');
$("#seconds").html(seconds + '<span class="camp">Seconds</span>');
}
setInterval(function() { makeTimer();
}, 1000);
You have to give the browser a way to know what your end time is or it will go back to the original hardcoded value every time. Either store the data you need to start and end the calculations for a user on the server or use localStorage to do it in the browser only.
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
So I've added a function called add7Days and I've got a check to see if the time left is less than 0.
This will add extra days to your variable each time it runs out.
I've also created an object as a global variable because if you are running this presumably for weeks you will start to run into memory leak issue if you are re-declaring the variables every second.
var countDownObject = {
'endDate': new Date('2020-10-19 23:45')
,'now': undefined
,'days': 0
,'hours': 0
,'minutes': 0
,'seconds': 0
,'timeLeft': 0
};
function countDown(){
countDownObject.now = new Date();
countDownObject.timeLeft = countDownObject.endDate - countDownObject.now;
if(timeLeft < 0) add7Days(); /* Function to change time left */
countDownObject.days = Math.floor(timeLeft / 86400);
countDownObject.hours = Math.floor((timeLeft - (days * 86400)) / 3600);
countDownObject.minutes = Math.floor((timeLeft - (days * 86400) - (hours * 3600 )) / 60);
countDownObject.seconds = Math.floor((timeLeft - (days * 86400) - (hours * 3600) - (minutes * 60)));
if(hours < 10) countDownObject.hours = "0" + hours;
if(minutes < 10) countDownObject.minutes = "0" + minutes;
if(seconds < 10) countDownObject.seconds = "0" + seconds;
$("#days").html(countDownObject.days + '<span class="camp">Days</span>');
$("#hours").html(countDownObject.hours + '<span class="camp">Hours</span>');
$("#minutes").html(countDownObject.minutes + '<span class="camp">Minutes</span>');
$("#seconds").html(countDownObject.seconds + '<span class="camp">Seconds</span>');
};
function add7Days(){
countDownObject.endDate.setDate(countDownObject.endDate.getDate() + 7);
countDownObject.timeLeft = countDownObject.endDate - countDownObject.now;
};
setInterval(function(){makeTimer();}, 1000);
[Edit]
If you are refreshing the browser you may want to store the object countDownObject as either local storage
//Set Object
localStorage.setItem("countDownObject", JSON.stringify(countDownObject));
//Get Object
var countDownObject = JSON.parse(localStorage.getItem("countDownObject"));
or as its own json file on the server.
An alternate approach for counting down to a specific day of the week and time, based on a specific time zone (Tuesday at 8AM, east coast time in your case) would be to use a third-party time API that you could access using an XMLHttpRequest (or fetch if you don’t need to support Internet Explorer).
The third-party time API would give you a JSON object with GMT time with the current offset for eastern time (I used New York for my JSFiddle example) for standard time or daylight savings time, and it would also note if daylight savings was in effect or not. This could be better than depending on the visitor’s computer time, which could be set to a different time zone (e.g. Phoenix, Arizona uses Mountain Standard Time year round).
Having access to a third party time API would let you resync your timer every so often, so the countdown timer wouldn’t drift too far from the actual end time. setInterval can be slow by around 0.3%, which over a 6 day period would be around 30 minutes.
XMLHttpRequest has an onerror event handler that could be used to connect to an alternative time API if the primary one is offline for some reason. IE10 and 11 support the onerror event handler.
// padStart polyfill for IE
if (!String.prototype.padStart) {
String.prototype.padStart = function padStart(targetLength, padString) {
//floor if number or convert non-number to 0;
targetLength = targetLength >> 0;
padString = String(typeof padString !== 'undefined' ? padString : ' ');
if (this.length > targetLength) {
return String(this);
} else {
targetLength = targetLength - this.length;
if (targetLength > padString.length) {
//append to original to ensure we are longer than needed
padString += padString.repeat(targetLength / padString.length);
}
return padString.slice(0, targetLength) + String(this);
}
};
}
function countdownTime (endDay, endTimeStr, reachedZero) {
var oReq;
var endingTimeObj;
var currentDateObj;
var countdownDisplay = document.getElementById("countdown");
var timeDisplay = document.getElementById("time");
var intervalID = null;
var endTime = {};
var numbers = endTimeStr.split(",").map(Number);
var cycleCount = 0;
endTime.hr = numbers[0];
endTime.min = numbers[1];
endTime.sec = numbers[2];
endTime.ms = numbers[3];
function countdown () {
var remainingDays;
var remainingHours;
var remainingMin;
var remainingSec;
var delta = endingTimeObj - currentDateObj;
if (delta <= 0) {
reachedZero(); // call the passed in function
endingTimeObj.setUTCDate(endingTimeObj.getUTCDate() + 7);
delta = endingTimeObj - currentDateObj;
}
remainingDays = Math.floor(delta / 86400000);
delta = delta - remainingDays * 86400000;
remainingHours = Math.floor(delta / 3600000);
delta = delta - remainingHours * 3600000;
remainingMin = Math.floor(delta / 60000);
delta = delta - remainingMin * 60000;
remainingSec = Math.floor(delta / 1000);
timeDisplay.innerHTML = remainingDays + ":" +
remainingHours.toString().padStart(2, "0") + ":" +
remainingMin.toString().padStart(2, "0") + "." +
remainingSec.toString().padStart(2, "0");
currentDateObj.setSeconds(currentDateObj.getSeconds() + 1);
// Sync the countdown after an hour to prevent too much drift
cycleCount += 1;
if (cycleCount >= 3600) {
load();
}
}
function reqListener () {
if(this.readyState === 4 && this.status === 200) {
// Stop the existing timer - will create a new timer in a moment
if (intervalID !== null) {
window.clearInterval(intervalID);
intervalID = null;
}
var obj = JSON.parse(this.responseText);
currentDateObj = new Date(obj.datetime);
endingTimeObj = new Date(obj.datetime);
console.log("GMT: " + currentDateObj.toUTCString());
currentDateObj.setHours(currentDateObj.getHours()
+ parseInt(obj.utc_offset,10));
console.log("ET: " + currentDateObj.toUTCString());
// Time to the next countdown finish
endingTimeObj.setUTCDate(currentDateObj.getUTCDate()
+ (7 + endDay - currentDateObj.getUTCDay()) % 7);
endingTimeObj.setUTCHours(endTime.hr, endTime.min, endTime.sec, endTime.ms);
if (currentDateObj > endingTimeObj) {
endingTimeObj.setUTCDate(endingTimeObj.getUTCDate() + 7);
}
console.log("End: " + endingTimeObj.toUTCString());
// display is initially hidden when first loaded
countdownDisplay.style.display = "block";
countdown();
intervalID = window.setInterval(countdown, 1000);
}
}
function load() {
cycleCount = 0;
oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
if (oReq.onerror !== undefined) {
// A function to connect to a different time API could go
// here (IE9 doesn't support onerror)
}
oReq.open("GET", "https://worldtimeapi.org/api/timezone/America/New_York");
oReq.send();
}
window.onload = load;
if ("visibilityState" in document) {
document.addEventListener("visibilitychange", function() {
if (document.visibilityState === "visible") {
load();
}
});
}
}
function reachedZeroAlert () {
document.body.style.backgroundColor = "red";
alert("Done");
document.body.style.backgroundColor = "white";
}
// Pass in the day (Sunday = 0),
// a string for the time of day the countdown should finish,
// an the function to execute when the countdown reaches zero
countdownTime(2, "08,0,0,0", reachedZeroAlert);
body {
background-color: white;
}
span {
margin: 0;
padding: 0;
}
#countdown {
font-family: monospace;
display: none;
}
.values {
font-size: 2rem;
margin-left: 0.625rem;
}
.labels {
font-size: 0.8rem;
}
.days {
margin-left: 0.1875rem;
}
.hours {
margin-left: 1.0625rem;
}
.minutes {
margin-left: 1.875rem;
}
.seconds {
margin-left: 1.5625rem;
}
<div id="countdown">
<div class="values">
<span id="time">5:22:43.04</span>
</div>
<div class="labels">
<span class="days">Days</span>
<span class="hours">Hr</span>
<span class="minutes">Min</span>
<span class="seconds">Sec</span>
</div>
</div>

How to fix javascript timer so that seconds run up to 60 and then reset to zero

I'm setting up a timer, but currently the seconds run into the thousands instead of resetting to zero after 60 seconds. Is there a quick fix for this?
This is the code I'm using:
var running = 0;
function startPause(){
if(running == 0){
running = 1;
increment();
document.getElementById("start").innerHTML = "Pause";
}else{
running = 0;
document.getElementById("start").innerHTML = "Resume";
}
};
function reset(){
running = 0;
time = 0;
document.getElementById("output").innerHTML = "00:00";
document.getElementById("start").innerHTML = "Start";
};
function increment(){
if(running == 1){
setTimeout(function(){
time++;
var mins = Math.floor(time / 10 / 60);
if(mins <= 9){
mins = "0" + mins;
}
var secs = Math.floor(time / 10);
if(secs <= 9){
secs = "0" + secs;
}
document.getElementById("output").innerHTML = mins + ":" + secs;
increment();
}, 100);
}};
You can use modulo % 60.
It gives the Rest of the division by 60
example 127 % 60 = 7
I made a custom audio player and this helped me.
if (seconds != 0 && seconds % 60 == 0) {
seconds = 0;
minutes++;
}

How to initialize a countdown timer to reflect the user input

I'm creating a countdown timer based on a users input. When the user pauses and resumes, the timer restarts at the initial inputed value and fails to resume from the current interval. I've uploaded the code into Codepen.
http://codepen.io/alivera/pen/JGpvRx
//Timer
var myTimer;
var duration = sessionCounter * 60;
var startTimer = function() {
minutes = parseInt(duration / 60);
seconds = parseInt(duration % 60);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById("clockTimer").innerHTML = minutes + ":" + seconds;
if (--duration < 0) {
document.getElementById("toggleStatus").innerHTML = "<br>Break!";
}
};
//Start Timer
var go = function() {
myTimer = setInterval(startTimer, 1000);
document.getElementById('start').innerHTML = "Stop";
document.getElementById('start').className = "btn btn-danger";
document.getElementById("start").onclick = stop;
};
//Stop Timer
var stop = function() {
clearInterval(myTimer);
document.getElementById('start').innerHTML = "Start";
document.getElementById('start').className = "btn btn-success";
document.getElementById("start").onclick = go;
};
duration.onload = stop();
You're loading the time to count down from from the #clockTimer element:
var sessionCounter = document.getElementById("clockTimer").innerHTML;
This is bad because the contents of that element are changing. Often.
And parseInt on the next line only is only giving you the number before the colon. Your best bet for solving this problem would be storing the current time remaining and the previously set time in separate variables, as I have done below.
Your code was a little difficult to work with, so while correcting the error(s), I ended up almost completely rewriting it.
Here's my version; I'll explain it line-by-line (or section-by-section, or whatever):
First, put all of our elements in to easy-to-use (and type) variables:
var subBreakButton = document.getElementById("subBreakButton"),
breakTimer = document.getElementById("breakTimer"),
addBreakButton = document.getElementById("addBreakButton"),
subSessionButton = document.getElementById("subSessionButton"),
sessionTimer = document.getElementById("sessionTimer"),
addSessionButton = document.getElementById("addSessionButton"),
breakSession = document.getElementById("breakSession"),
clockTimer = document.getElementById("clockTimer"),
These variables are in seconds (thus m * s):
breakLength = 5 * 60, // Minutes to seconds
sessionLength = 25 * 60, // Minutes to seconds
sessionTimeLeft = sessionLength;
Next, a helper method that formats times into a mm:ss ... format:
function timeString (seconds) {
var minutes = parseInt(seconds / 60) + "",
seconds = parseInt(seconds % 60) + "";
if (minutes.length === 1)
minutes = "0" + minutes;
if (seconds.length === 1)
seconds = "0" + seconds;
return minutes + ":" + seconds;
}
Third, event listeners for the plus and minus buttons:
// Event Listeners
addBreakButton.addEventListener("click", function () {
breakLength += 1 * 60;
breakTimer.innerHTML = timeString(breakLength);
});
subBreakButton.addEventListener("click", function () {
breakLength -= 1 * 60;
if (breakLength < 0)
breakLength = 0;
breakTimer.innerHTML = timeString(breakLength);
});
addSessionButton.addEventListener("click", function () {
sessionLength += 1 * 60;
sessionTimer.innerHTML = timeString(sessionLength);
});
subSessionButton.addEventListener("click", function () {
sessionLength -= 1 * 60;
if (sessionLength < 0)
sessionLength = 0;
sessionTimer.innerHTML = timeString(sessionLength);
});
And, the fun part:
// Timer
var myTimer;
function startTimer () {
if (myTimer) // Check to see if a timer was already running, and if so, stop it
stopTimer();
sessionTimeLeft = sessionLength;
myTimer = setInterval(function () {
sessionTimeLeft--;
if (sessionTimeLeft <= 0) {
sessionTimeLeft = 0;
stopTimer();
}
clockTimer.innerHTML = (sessionTimeLeft <= 0? "Break!": timeString(sessionTimeLeft));
}, 1000);
}
function stopTimer () {
clearInterval(myTimer);
myTimer = 0;
}
Lastly, wrappers:
// Start Timer
function go() {
startTimer();
}
//Pause Timer
function stop() {
stopTimer();
}
Codepen: http://codepen.io/anon/pen/ZQjLZE?editors=1010

Countdown timer with hundredths?

I'm trying to create a countdown timer in the format of 00:00:00 (minutes, seconds, and hundredths). Right the now the way I set up my countdown timer, is to make sure the user inputs in the format of 00:00:00 (which has to be). From there the countdown time should commence when they click the start button. I see that it does somewhat of a countdown, but I'm not sure what could be the problem with my implementation. The hundredths is not decrementing correctly for some reason. It should start of as 10:00:00 (10 mins) and go to 09:59:99.. 09:59:98, etc.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Countdown Timer</title>
<script type="text/javascript">
var running = 0;
var hundreds = 0;
function validTime() {
var setTime = document.getElementById("timeEntered").value;
var regex = /^\d{2}:\d{2}:\d{2}$/;
if (regex.test(setTime)) {
document.getElementById("timeAlert").innerHTML = "<span class='valid'>Valid</span>";
return (true);
} else {
document.getElementById("timeAlert").innerHTML = "<span class='error'>Invalid time entered. Please make sure it's in the format 00:00:00</span>";
return (false);
}
}
function correctTime(){
if (validTime()){
countdownTimer();
return true;
}else{
alert("Please correct your inputted time.");
return false;
}
}
function countdownTimer() {
var time = document.getElementById("timeEntered").value;
var a = time.split(":");
var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);
if(parseInt(timeToSeconds) <= 600 ) {
startPause();
}else{
document.getElementById("output").innerHTML = "Sorry. Time range cannot exceed 10 mins.";
}
}
function startPause(){
var time = document.getElementById("timeEntered").value;
var a = time.split(":");
var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);
if(running == 0){
running = 1;
decrement();
document.getElementById("startPause").innerHTML = "Start/Stop";
}else{
running = 0;
document.getElementById("startPause").innerHTML = "Resume";
}
}
var hundreds = 0;
function decrement(){
var time = document.getElementById("timeEntered").value;
var a = time.split(":");
var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);
if(running == 1){
var mins = Math.round((timeToSeconds - 30)/60);
var secs = timeToSeconds % 60;
//var hundredths = timeToSeconds % 100;
if(mins < 10) {
mins = "0" + mins;
}
if(secs < 10) {
secs = "0" + secs;
}
document.getElementById("output").innerHTML = mins + ":" + secs + ":" + hundreds;
if (hundreds === 0){
if(timeToSeconds ===0){
clearInterval(countdownTimer);
document.getElementById("output").innerHTML = "Time's Up.";
}else{
timeToSeconds--;
hundreds = 100;
}
}else{
hundreds--;
}
var countdownTimer = setInterval('decrement()', 10)
}
}
</script>
</head>
<body>
<h1>Countdown Timer</h1>
<div id="mainCont">
<p>Please enter the desired time:
<input type="text" id="timeEntered" onblur="validTime();"> <span id="timeAlert"></span>
</p>
<p>
<button id="startPause" onclick="correctTime()">Start/Stop</button>
</p>
<div id="output">00:00:00</div>
</div>
</body>
</html>
I think #bholagabbar's code needs rewriting into hundreths of a second rather than in seconds.
function startTimer(duration, display) {
var timer = duration, minutes, seconds, dispms;
setInterval(function () {
dispms=parseInt(timer % 100,10);
seconds = parseInt(timer / 100, 10);
minutes = parseInt(seconds / 60, 10);
seconds = parseInt(seconds % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
dispms = dispms < 10 ? "0" + dispms : dispms;
display.textContent = minutes + ":" + seconds+":"+dispms;
if (--timer < 0) {
timer = duration;
}
}, 10); //hundreths of a second - 1000 would be 1 second
}
window.onload = function () {
var fiveMinutes = 60 * 5 * 100, //hundreths of second
display = document.querySelector('#time');
startTimer(fiveMinutes, display);
};
I'm not sure if this is what you wanted but I have some working code for a timer that counts up to the given input (in seconds) which includes the 1/100th of a second. If you want to include ms as you mentioned, you will need 3 0's or ':000' for the display int the end. Here is the code. How will of course, have to mod it for your scenario but the timer is implemented perfe
function startTimer(duration, display) {
var timer = duration, minutes, seconds, dispms;
setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
dispms=parseInt((timer)%100,10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
dispms = dispms < 10 ? "0" + dispms : dispms;
display.textContent = minutes + ":" + seconds+":"+dispms;
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
window.onload = function () {
var fiveMinutes = 60 * 5,
display = document.querySelector('#time');
startTimer(fiveMinutes, display);
};
<body>
<div>Registration closes in <span id="time"></span> minutes!</div>
</body>
I think you will have to make changes only in the HTML part. Rest of the logic in my code is fine for a general timer. You will have to pass in the seconds as an argument, that is all

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)
}

Categories