javascript timer error - javascript

I started working on a timer to show how long people have been on my page. The problem is that instead of counting the seconds, it just keeps adding zeros to the end. Can anyone show me where I went wrong?
<script language="javascript">
<!--
var seconds = 0
var minutes = 0
document.getElementById('timer').innerHTML = '0'
function Timer() {
if ( seconds < 10 ) {
seconds = "0" + seconds
}
else if ( minutes < 10 ) {
minutes = "0" + minutes
}
else if ( seconds >= 59 ){
seconds = 0
minutes += 1
}
else
seconds += 1
document.getElementById('timer').innerHTML = "You've been on my blog for "+minutes+" : "+seconds+" minutes."
setTimeout("Timer()",1000)
}
//-->
</script>

Well yes, because you're concatenating a string. The + operator does both concatenation and addition.
"0" + foo // concatenate the string "0" and foo
0 + foo // add foo to 0 (given that both are numbers)
You're going about the timer the wrong way though. Your script is not guaranteed to execute on time, any slight delay in execution will give you accumulative the wrong value. The right way to do a timer is to take a fixed start time and use that as the base to calculate the difference every second or so.
var start = Date.now();
function timer() {
alert(((Date.now() - start) / 1000) + ' seconds elapsed');
}
setInterval(timer, 1000);

You're switching the variable type for seconds from being:
var seconds = 0 // integer type
....
seconds = "0" + seconds // now seconds is holding a string!
seconds (and minutes) should only be integers.
Also, just focus on the seconds. Later, divide it by 60 to display number of minutes. seconds % 60 will be the remaining number of sec.

Related

How can I show the audio duration and subtracting one second each second?

I made this function, I want every second audio duration to minus one but it returns NaN, Then I tried to delete " : " so it's fully numbers but setInterval is executed only once for example if audio duration is 0524 after clicking .button it only returns 0523.
<button class="button"></button>
<p class="demo"></p>
var playng= new Audio();
playng.src = audio.mp3;
$('.button').click(function(){
playng.play()
songDur()
})
function songDur(){
var audiod = playng.duration;
var minutes = "0" + Math.floor(audiod / 60);
var seconds = Math.floor(audiod - minutes * 60);
var songTime = minutes + " : " + seconds;
console.log(songTime);
setInterval(function(){
$('.demo').text(songTime - 1)},1000);
}
NaN stands for "Not a Number" and two numbers with a colon in the middle is indeed not a number.
The reason why it only appears to run once if you remove the colon, is because you never update the value of songTime. You only set the text to songTime -1, but songTime is never updated so songTime -1 will also always output the same number.
It is also worth mentioning that setInterval is not very accurate and can shift over time.
The best way to get a countdown timer that accurately counts down how much time is left in a song, is to subtract the currentTime from the duration. This will give you the seconds left so you can convert that into minutes and seconds. (Be sure to do the calculation inside the setInterval so it is recalculated for every interval.)
var playng = new Audio();
playng.src = 'audio.mp3';
$('.button').click(function() {
playng.play()
songDur()
});
function songDur() {
setInterval(function() {
var timeRemaining = playng.duration - playng.currentTime;
var minutes = Math.floor(timeRemaining / 60);
var seconds = Math.floor(timeRemaining % 60);
var secondsWithLeadingZero = seconds < 10 ? '0' + seconds : seconds;
$('.demo').text(minutes + ':' + secondsWithLeadingZero);
}, 500);
}
<button class="button">Play</button>
<p class="demo"></p>
Working example: https://jsfiddle.net/qgp8k7bf/

Countdown timer every hour but on 30 minute marks

I need a simple countdown timer, but it is really bugging me that I can't seem to get it for some reason, and I think it's because of the special way I need it done, it has to adhere to these rules:
Must be every hour
Must be on the 30 minute mark
Must use UTC time
So for instance, it is 07:22 UTC, it would be 8 minutes till the next one.
If it were say, 07:30, it would say 1 hour till the next one.
And last but not least, if it were 07:31, it would say 59 minutes till the next one.
I was able to do this very easily for other countdowns I made, but those were for on the hour type things, it wasn't this complicated... I'm just stumped big time, please help me.
EDIT
Added sample code
var d = new Date();
var hoursUntil = 2 - d.getUTCHours() % 3;
var minutesUntil = 60 - d.getUTCMinutes();
var timestr = "";
if (minutesUntil === 60) {
hoursUntil++;
minutesUntil = 0;
}
if (hoursUntil > 0) {
timestr += hoursUntil + " hour" + (hoursUntil > 1 ? "s" : "");
}
if (hoursUntil >= 1 && minutesUntil > 1) {
timestr += " and " + minutesUntil + " minute" + (minutesUntil > 1 ? "s" : "");
}
if (minutesUntil > 1 && hoursUntil < 1) {
timestr += minutesUntil + " minute" + (minutesUntil > 0 && minutesUntil < 2 ? "" : "s");
}
bot.sendMessage(msg, "Next event will be in " + timestr + ".");
Let's do some thoughts. What we want to know is, when the minute hand next time shows 30. If we wanted to know only every half hour, we could just take the rest of division by 30 as you did with d.getUTCHours() % 3.
However, we want to get every 60 minutes, so we have do do somethingInMinutes % 60. The mark must be on shift from 60 to 0, so just add 30 minutes.
To have seconds precision, calculate that into seconds, add the current seconds and subtract both from 60 minutes (3600 seconds).
We want a timer that triggers on every second shift. Calculate the difference of 1000 and milliseconds.
<div>Seconds remaining until next 30 minutes mark: <span id="min-total"></span></div>
<div>minutes:seconds remaining: <span id="min-part"></span>:<span id="sec-part"></span></div>
<script>
var byId = document.getElementById.bind(document);
function updateTime()
{
var
time = new Date(),
// take 1800 seconds (30 minutes) and substract the remaining minutes and seconds
// 30 minutes mark is rest of (+30 divided by 60); *60 in seconds; substract both, mins & secs
secsRemaining = 3600 - (time.getUTCMinutes()+30)%60 * 60 - time.getUTCSeconds(),
// integer division
mins = Math.floor(secsRemaining / 60),
secs = secsRemaining % 60
;
byId('min-total').textContent = secsRemaining;
byId('min-part').textContent = mins;
byId('sec-part').textContent = secs;
// let's be sophisticated and get a fresh time object
// to calculate the next seconds shift of the clock
setTimeout( updateTime, 1000 - (new Date()).getUTCMilliseconds() );
}
updateTime();
</script>
Maybe I am missing something but as far as I can see, UTC and in fact hours in general are not relevant to this. It should be as simple as just calculating where the current minute is.
Maybe something like
now = new Date();
minutes = now.getMinutes();
if(minutes > 30) {
minutes_until = (60 - minutes) + 30;
}
else {
minutes_until = 30 - minutes;
}

Countdown timer with milliseconds

I'm new to JS and I'm stuck trying to figure out what's causing my countdown timer not to countdown. The user enters the time in 00:00:00 format minutes, seconds, and milliseconds. Afterwards, I convert that format to seconds to begin the process of counting down. I think the calculations is fine, but something is not causing it not to behave as it should be. I've tested and see that the code runs in terms of entering the time and showing up in the output. I see the countdown decrementing, for both seconds and milliseconds at the same time but it should go from 10:00:00 to 09:59:99.. 09:59:98... Basically seconds won't change until milliseconds reaches zero. so 09:59:00 will be 09:58:99... Please any help is greatly appreciated. I've been going at this and been stuck.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
var running = 0; //Glob variable for starting/pausing timer
function startPause(){
var time = document.getElementById("timeEntered").value; //Not sure if needed but I just have the time entered be converted to seconds.
var a = time.split(":");
var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);
if(running == 0){ //If off, turn it on.
running = 1;
countDown();
document.getElementById("startPause").innerHTML = "Start/Stop";
}else{
running = 0;
document.getElementById("startPause").innerHTML = "Resume";
}
}
function countDown() {
var time = document.getElementById("timeEntered").value; //Take user input and convert 00:00:00 format to seconds.
var a = time.split(":");
if(!timeToSeconds)
var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);
if(running == 1){ //When user clicks start it will calculate the minutes, seconds, and milliseconds.
var minutes = Math.floor(timeToSeconds / 60);
var seconds = timeToSeconds % 60;
var milli = timeToSeconds % 100;
if(minutes <= 9) { //Add leading zeroes to display countdown in 00:00:00 format.
minutes = "0" + minutes;
}
if(seconds <= 9) {
seconds = "0" + seconds;
}
if(milli <= 9) {
milli = "0" + milli;
}
timeToSeconds--; //Decrement the time entered.
console.log(timeToSeconds);
document.getElementById("output").innerHTML = minutes + ":" + seconds + ":" + milli //Display the time 00:00:00 format.
if(timeToSeconds !== -1){
setTimeout('countDown()',100);
}
if(timeToSeconds == 0){ //When time is 00:00:00 the message will show.
document.getElementById("output").innerHTML = "The time is over."
}
}
}
</script>
</head>
<body>
<h1>Countdown Timer</h1>
<div id="mainCont">
<input type="text" id="timeEntered">
<p>
<button id="startPause" onclick="startPause()">Start/Stop</button>
</p>
<div id="output">00:00:00</div>
</div>
</body>
</html>
There are a handful of problem here, so I will go over each one and show you the solution. The first problem is that the value of timeToSeconds is the same on each iteration. The reason for this is because you are getting the value from the same unchanging source, decrementing does nothing as the value is lost on the next function call. To fix this have your function take a parameter in which you pass the remaining seconds off after you modified it:
function countDown(timeToSeconds) {
...
timeToSeconds-=0.1; //Decrement the time entered.
if(timeToSeconds <= 0){ //When time is 00:00:00 the message will show.
document.getElementById("output").innerHTML = "The time is over."
return;
}
else if(timeToSeconds !== -1){
setTimeout(function(){countDown(timeToSeconds)},100);
}
Notice I only subtracted 0.1 because our setTimeout is called after 100 milliseconds (0.1 seconds). I've also switched around the checks, as before hand you would call the timer even if timeToSeconds was 0.
The next thing was you conversion to seconds was off, in your code here:
var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);
Both minutes and seconds are calculated in the same way, a[1] is the seconds value and should not be multiplied. And a[2] is actually 10*milliseconds (1 seconds = 1000 milliseconds). That value should be divide by 100:
if(!timeToSeconds)
var timeToSeconds = (+a[0]) * 60 + (+a[1]) + (Math.floor(+a[2]/100));
The if-statement is a basic check if the value is true (being any number). In our case it can work as a "Does this value exist" check, since we are only dealing with positive numbers. And the following conversions should be:
var minutes = Math.floor(timeToSeconds / 60) % 60;
var seconds = Math.floor(timeToSeconds) % 60;
var milli = Math.floor(timeToSeconds*100) % 100;
For the most part, your values for minutes and seconds where correct. Although the reason why milli and seconds appeared the same was because you never converted milli to it's correct value, as such they will have the same value apart from the % applied.
Here is the final result
One last thing I would like to point out is that this timer will not be exact. As it takes some time between the computation and the setTimeout call. For a more accuracy value you will want to use Date.now() and find the different between the start time and the current timer. This question uses such a method to do so, which can be applied to the countdown timer in the same fashion.

JavaScript calculate time and seconds

I was having some problem when trying to perform some calculation logic using JavaScript. Basically along a route there is 80 steps and it took around 9 minutes to finish up the entire route.
So I was trying to do an auto route which will tell you the minutes left to destination. My logic is as below:
9 * 60 / 80 = 6.75
So basically for each step is 6.75 seconds but I wanted to show a round number like 9 instead of 8.4 minutes. Here is the code:
getAllBusLoc(function(busList) {
var totalBusLoc = busList.length;
var busLeftPct = Math.round(parseFloat(busList.length) * 40 / 100)
document.getElementById("busStopLeft").innerHTML = totalBusLoc;
pointArr.forEach(function(coord,index){
setTimeout(function(){
var travelTime = document.getElementById(travelDistMin").value;
moveNext(coord.x, coord.y);
}, 1000* index);
});
});
I got the travel time as variable travelTime which in this case is 9 minutes. For each point, I wanted to minus 6.75 seconds from the 9 minutes and display a round number instead of 8.2.
Any ideas?
Thanks in advance.
Use Math.round() for subtracting 6.75 from travelTime.
This is will round to the nearest whole number.
An idea that I could suggest is to write a generic function that transforms a decimal time interval (for example, 8.25 minutes) into its equivalent 'mm:ss' value instead of rounding so that you display the precise time representation:
Number.prototype.toMMSS = function () {
d = this;
var sign = d < 0 ? "-" : "";
var min = Math.floor(Math.abs(d))
var sec = Math.floor((Math.abs(d) * 60) % 60);
return sign + (min < 10 ? "0" : "") + min + ":" + (sec < 10 ? "0" : "") + sec;
};
Example:
8.25.toMMSS() // "08:15"
JSFiddle
Or, you could try the moment plugin duration function like:
moment.duration(8.25, 'minutes').minutes(); // 8
Or, the humanize method to round off:
console.log(moment.duration(8.51, "minutes").humanize()); // "9 minutes"
console.log(moment.duration(8.15, "minutes").humanize()); // "8 minutes"

for loop milliseconds converted to seconds and minutes

This appears in the middle of a function, I wrote it myself and im stuck.
What it does it make a call for the time in milliseconds, (countStart) and then it makes a call for the time when it completes (countEnd). When this is activated, it looks at the countStart countEnd and does the math to determine if it has run long enough to run again.
All of this is successful, except, it displays everything in seconds, so 3 minutes is 180 seconds. I am trying to figure a way to make it count down 3 minutes correctly.
Is this a feasible thing? I have done hours of research and I can find 50 ways to supposedly do this, and all of them are HTML based and massively large. I tried to add a if this goes above 60 function then add 1 to minutes and subtract 60 from seconds, but that locked up the counter.
So anyway any help or guidance would be appreciated
var countStart = 100000000000000;
var countStop = 100000000000020;
var countDelay = 180000;
alert(parseInt((factor * -1) / 1000, 10) + " s)");
for (var factor = countStop - (countStart + countDelay) + 1; factor > 0; factor--){
countStart = 0;
countStop = 0;
countDelay = 0;
}
Do the math:
var time_in_seconds = ...;
var minutes = (time_in_seconds / 60) | 0; // divide by 60 and truncate to an integer.
var seconds = time_in_seconds % 60; // this is the modulo operator
If you don't like the modulo operator for no obvious reason, then you can do further math:
var minutes = (time_in_seconds / 60) | 0;
var seconds = time_in_seconds - minutes * 60;
To format the two integers:
var string = minutes + "m" + (seconds < 10 ? "0" + seconds : seconds);
condition ? then_expr : else_expr is the ternary operator. If the condition is true, then then_expr gets evaluated, otherwise else_expr.

Categories