MomentJS countdown with diff - javascript

I am constructing a session timeout as part of a web application using the MomentJS library. What I have so far (below) is the timeToExpire difference (in seconds) from when the user logged in and when the session will expire. However when displaying a countdown clock using setInterval, the diff is NOT recalculated each second and instead the clock is never updated.
Could someone point me in the right direction to what is going wrong?
const access_ttl = 3600;
const now = moment();
const login_timestamp = moment('2017-02-19 17:31:58+00:00');
const expire_timestamp = login_timestamp.add(access_ttl, 's');
const timeToExpire = expire_timestamp.diff(now, 'seconds');
function displayClock(inputSeconds) {
const sec_num = parseInt(inputSeconds.toString(), 10);
const hours = Math.floor(sec_num / 3600);
const minutes = Math.floor((sec_num - (hours * 3600)) / 60);
const seconds = sec_num - (hours * 3600) - (minutes * 60);
let hoursString = '';
let minutesString = '';
let secondsString = '';
hoursString = (hours < 10) ? "0" + hours : hours.toString();
minutesString = (minutes < 10) ? "0" + minutes : minutes.toString();
secondsString = (seconds < 10) ? "0" + seconds : seconds.toString();
return hoursString + ':' + minutesString + ':' + secondsString;
}
function timer() {
$('.output').html(`Expires in: ${displayClock(timeToExpire)}`)
}
setInterval(timer, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<div class="output"></div>

You are not updating the now() or timeToExpire values and so the value you are passing to displayClock is always the same.
Link to complete JS Fiddle: https://jsfiddle.net/xzyjdb1g/2/
var now, timeToExpire;
function updateTime() {
now = moment();
timeToExpire = expire_timestamp.diff(now, 'seconds');
}
function timer() {
updateTime();
$('.output').html(`Expires in: ${displayClock(timeToExpire)}`)
}

Related

.blur() causes my stopwatch to lag pretty significantly

Hi I have a stopwatch here that works pretty great except that I wanted to add .blur() method to the buttons so that when I click them, the space bar doesn't re-trigger a button when it is pressed.
I got this idea from a bpm counter I was making that integrated the stopwatch and where the space bar thing was a much bigger issue.
I'm just curious, why does simply adding .blur() to my event listener cause the stopwatch to noticeably lag when hitting start/stop? Is there a better alternative I could be using instead? Will this method negatively affect my bpm counter as well? Am I using .blur() correctly?
This is my first post on Stack Overflow so please let me know if I formatted this question wrong in any way.
// initialize variables
const STARTSTOP = document.querySelector('.start-stop');
const RESET = document.querySelector('.reset');
const STOPWATCH = document.querySelector('.stopwatch');
const DISPLAY = document.querySelector('.display');
let stopwatchIsActive = false;
let elapsedTime = 0;
var myInterval;
// stopwatch functions
function convertElapsedTimeToString() {
let milliseconds = Math.floor((elapsedTime % 1000) / 10),
seconds = Math.floor((elapsedTime / 1000) % 60),
minutes = Math.floor((elapsedTime / (1000 * 60)) % 60),
hours = Math.floor((elapsedTime / (1000 * 60 * 60)) % 24);
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
milliseconds = (milliseconds < 10) ? "0" + milliseconds : milliseconds;
STOPWATCH.innerHTML = minutes + ":" + seconds + ":" + milliseconds;
if (hours >= 1) {
hours = (hours < 10) ? "0" + hours : hours;
STOPWATCH.innerHTML = hours + ":" + minutes + ":" + seconds;
};
}
function resetStopwatch() {
STOPWATCH.innerHTML = "00:00:00";
stopwatchIsActive = false;
elapsedTime = 0;
clearInterval(myInterval);
};
function startStopStopwatch() {
if (stopwatchIsActive) {
clearInterval(myInterval);
convertElapsedTimeToString();
stopwatchIsActive = false;
} else if (elapsedTime > 0) {
startTime = Date.now() - elapsedTime;
clearInterval(myInterval);
myInterval = setInterval(function() {
elapsedTime = Date.now() - startTime;
convertElapsedTimeToString();
}, 10);
stopwatchIsActive = true;
} else {
startTime = Date.now();
myInterval = setInterval(function() {
elapsedTime = Date.now() - startTime;
convertElapsedTimeToString();
}, 10);
stopwatchIsActive = true;
}
};
// executes stopwatch functions
RESET.addEventListener("click", () => {
resetStopwatch();
RESET.blur();
});
STARTSTOP.addEventListener("click", () => {
startStopStopwatch();
STARTSTOP.blur();
});
DISPLAY.addEventListener("click", () => {
startStopStopwatch();
});
<div class="container">
<header class="header">This is a Stopwatch.</header>
<div class="display">
<h2 class="stopwatch">00:00:00</h2>
</div>
<div class="stats">
<button class="start-stop">Start/Stop</button>
</div>
<button class="reset">RESET</button>
</div>

Subtract time and show difference in mins:secs format

I want to accurately display the difference between two times. The different should be displayed in a format such as mm:ss
methods: {
calcuateTimeDifference: function (startTime, endTime) {
let result = 0;
if (startTime && endTime) {
let start = startTime.split(":");
let end = endTime.split(':');
let startTimeInHrs = (parseFloat(start[0]/3600) + parseFloat(start[1]/60) + parseFloat(start[2]/3600));
let endTimeInHrs = (parseFloat(end[0]/3600) + parseFloat(end[1]/60) + parseFloat(end[2] /3600));
result = endTimeInHrs - startTimeInHrs;
}
return result.toFixed(2);
},
Using this function - the difference between the following times: 16:03:01 - 16:04:01 - I get the result as -32.00.
split the strings on : to get the hours, minutes, and seconds
convert all to seconds and add them to get the total seconds from each time
subtract the two to get the difference in seconds
convert the difference seconds to hours, minutes and seconds using the modules operator(%)
format the result for appropriate display
let start = "16:03:01";
let end = "16:04:05";
let time = calcuateTimeDifference(start, end);
console.log(time);
function calcuateTimeDifference(startTime, endTime) {
let result = 0;
if (startTime && endTime) {
const start = startTime.split(':').map(Number);
const end = endTime.split(':').map(Number);
const startSeconds = (60*60) * start[0] + 60*start[1] + start[2];
const endSeconds = (60*60) * end[0] + 60*end[1] + end[2];
const diffSeconds = endSeconds - startSeconds;
seconds = parseInt((diffSeconds) % 60);
minutes = parseInt((diffSeconds/60) % 60);
hours = parseInt((diffSeconds/(60*60)) % 24);
//append `0` infront if a single digit
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return `${hours}:${minutes}:${seconds}`;
}
console.log("Invalid Input");
}
function calcuateTimeDifference(startTime, endTime) {
let toSeconds = (time) => {
let [h, m, s] = time.split(':');
return h * 360 + m * 60 + +s;
};
let d = Math.abs(toSeconds(startTime) - toSeconds(endTime));
let mm = String(Math.floor(d / 60));
if (mm.length == 1) mm = '0' + mm;
let ss = String(d % 60);
if (ss.length == 1) ss = '0' + ss;
return `${mm}:${ss}`;
}

Add milliseconds to JavaScript

I created a simple game for which I need a countdown. Now everything is fine, but I need to add a millisecond to the timer. I used the code found on the internet, but it lacks just those milliseconds. My attempts have not been successful, so I am asking you for help.
var seconds;
var temp;
function countdown() {
time = document.getElementById('countdown').innerHTML;
timeArray = time.split(':')
seconds = timeToSeconds(timeArray);
if (seconds == '') {
temp = document.getElementById('countdown');
temp.innerHTML = '00:00:00';
return;
}
seconds--;
temp = document.getElementById('countdown');
temp.innerHTML = secondsToTime(seconds);
timeoutMyOswego = setTimeout(countdown, 1000);
}
function timeToSeconds(timeArray) {
var minutes = (timeArray[0] * 1);
var seconds = (minutes * 60) + (timeArray[1] * 1);
return seconds;
}
function secondsToTime(secs) {
var divisor_for_minutes = secs % (60 * 60);
var minutes = Math.floor(divisor_for_minutes / 60);
minutes = minutes < 10 ? '0' + minutes : minutes;
var divisor_for_seconds = divisor_for_minutes % 60;
var seconds = Math.ceil(divisor_for_seconds);
seconds = seconds < 10 ? '0' + seconds : seconds;
return minutes + ':' + seconds;
}
countdown();

javascript countdown from d:h:m:s

I'm new in javascript.
My PHP script returns a value in this format
d:h:m:s
Now I would like to have a countdown which is able to countdown each second from this.
I modified a countdown. This works once a time, after the countdown "ticks" each second it returns NaN all the time. Any idea what I do wrong?
$(document).ready(function() {
setInterval(function() {
$('.countdown').each(function() {
var time = $(this).data("time").split(':');
var timestamp = time[0] * 86400 + time[1] * 3600 + time[2] * 60 + time[3] * 1;
var days = Math.floor(timestamp / 86400);
console.log(time,timestamp);
var hours = Math.floor((timestamp - days * 86400) / 3600);
var minutes = Math.floor((timestamp - hours * 3600) / 60);
var seconds = timestamp - ((days * 86400) + (hours * 3600) + (minutes * 60))-1;
$(this).data("time",""+days+":"+hours+":"+minutes+":"+seconds);
if (hours < 10) {
hours = '0' + hours;
}
if (minutes < 10) {
minutes = '0' + minutes;
}
if (seconds < 10) {
seconds = '0' + seconds;
}
$(this).text(days + ':' + hours + ':' + minutes + ':' + seconds);
});
}, 1000);
})
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1 class="countdown">02:03:05:59</h1>
As far as I can see you have 2 problems here:
after the first execution you change the pattern of the text you display in the h1. First you have 02:03:05:59. Then you want to write 02 days 03:05:58 into the tag. Next time you parse it, you get the error because you split at : and that does not work anymore as you have days instead of : as the seperator for the first part.
When calculating the minutes, you should also substract the days and not just the hours.
When you wan to keep the dd:hh:mm:ss format, you could do it like this:
$(document).ready(function() {
setInterval(function() {
$('.countdown').each(function() {
var time = $(this).text().split(':');
var timestamp = time[0] * 86400 + time[1] * 3600 + time[2] * 60 + time[3] * 1;
timestamp -= timestamp > 0;
var days = Math.floor(timestamp / 86400);
console.log(days);
var hours = Math.floor((timestamp - days * 86400) / 3600);
var minutes = Math.floor((timestamp - days * 86400 - hours * 3600) / 60);
var seconds = timestamp - days * 86400 - hours * 3600 - minutes * 60;
if (days < 10) {
days = '0' + days;
}
if (hours < 10) {
hours = '0' + hours;
}
if (minutes < 10) {
minutes = '0' + minutes;
}
if (seconds < 10) {
seconds = '0' + seconds;
}
$(this).text(days + ':' + hours + ':' + minutes + ':' + seconds);
});
}, 1000);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1 class="countdown">02:03:05:59</h1>
Your snippet goes from dd:hh:mm:ss to dd days, hh hours. So second time around, your tag contains non-parsable text.
I have changed it to something more precise. Something even MORE precise would be to give a timestamp in milliseconds in the future instead of something with seconds since it will take several seconds to render the page. If you round on minutes from the server, it would likely be better.
var aDay = 24*60*60*1000, anHour = 60*60*1000, aMin = 60*1000, aSec = 1000;
$(document).ready(function() {
$('.countdown').each(function() {
var time = $(this).data("time").split(':');
var date = new Date();
date.setDate(date.getDate()+parseInt(time[0],10))
date.setHours(date.getHours()+parseInt(time[1],10),date.getMinutes()+parseInt(time[2],10),date.getSeconds()+parseInt(time[3],10),0)
$(this).data("when",date.getTime());
});
setInterval(function() {
$('.countdown').each(function() {
var diff = new Date(+$(this).data("when"))-new Date().getTime();
var seconds, minutes, hours, days, x = diff / 1000;
seconds = Math.floor(x%60); x=(x/60|0); minutes = x % 60; x= (x/60|0); hours = x % 24; x=(x/24|0); days = x;
$(this).text(
days + ' day' +(days==1?", ":"s, ") +
hours + ' hour' +(hours==1?", ":"s, ") +
minutes + ' minute'+(minutes==1?", ":"s, ") +
seconds + ' second'+(seconds==1?".":"s.")
);
});
}, 500);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1 class="countdown" data-time="02:03:05:59"></h1>

Javasciript custom video player current time / total time

I'm making a html5 video player and am using javascript to update the current time out of the total time. So far my script is
function updateTime() {
var curTime = mediaPlayer.currentTime;
var totTime = mediaPlayer.duration;
timePlayed.innerHTML = curTime + '/' + totTime;
}
I have an eventlistener at the start. So the script works, but it outputs it like 23.703/285.067513 How would I get it to output something like 00:00 / 00:00 Just like the youtube video player, so it would be like minute minute:second second / minute minute:second second. For my html, I just have a span <span id="timePlayed">00:00/00:00</span>
If anyone can help me with this, thanks in advance!
I think, you can use an another function for it.Look what I found.
function formatSeconds(seconds) {
var date = new Date(1970,0,1);
date.setSeconds(seconds);
return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1"); }
https://stackoverflow.com/a/17781037/2500784
You can do the following and solve your issues
video.addEventListener("timeupdate", function() {
function formatTime(seconds) {
var minutes = Math.floor(seconds / 60);
minutes = (minutes >= 10) ? minutes : minutes;
var hours = Math.floor(minutes / 60);
hours = (minutes >= 10) ? hours : hours;
var seconds = Math.floor(seconds % 60);
seconds = (seconds >= 10) ? seconds : seconds;
return hours + ":" + minutes + ":" + seconds;
}
var seconds = video.currentTime;
currentTime.innerHTML = formatTime(seconds);
});
video.addEventListener("timeupdate", function() {
function formatTime(seconds) {
var minutes = Math.floor(seconds / 60);
minutes = (minutes >= 10) ? minutes : minutes;
var seconds = Math.floor(seconds % 60);
seconds = (seconds >= 10) ? seconds : seconds;
return minutes + ":" + seconds;
}
var seconds = video.duration;
durationTime.innerHTML = formatTime(seconds);
});
Then you must have this HTML Markup as defined
<span id="currentTime">00:00:00</span> / <span id="durationTime">00:00:00</span>

Categories

Resources