I am trying to display the time remaining for the next 5 minutes (snapped to the full 5 minutes of the current time e.g., 15:05, 15:10..)
I was able to achieve the same for the time remaining for next Hour (Not minutes):
<span class="timer"></span>
<script>
function secondPassed() {
var cur_date = new Date();
var hour = cur_date.getHours();
var minutes = cur_date.getMinutes();
var seconds = cur_date.getSeconds();
var minutes_remain = parseInt(59 - parseInt(minutes));
var seconds_remain = parseInt(60 - parseInt(seconds));
var timers = document.getElementsByClassName('timer');
for (var i = 0; i < timers.length; i++) {
timers[i].innerHTML = minutes_remain+":"+seconds_remain;
}
}
var countdownTimer = setInterval(secondPassed, 1000);
</script>
JSfiddle : http://jsfiddle.net/ov0oo5f7/
Something like this?
function secondPassed() {
var cur_date = new Date();
var minutes = cur_date.getMinutes();
var seconds = cur_date.getSeconds();
var timers = document.getElementsByClassName('timer');
for (var i = 0; i < timers.length; i++) {
timers[i].innerHTML = (4 - minutes % 5) + ":" + (seconds >= 50 ? "0" : "") + (59 - seconds);
}
}
var countdownTimer = setInterval(secondPassed, 1000);
<span class="timer"></span>
You can reduce the code a bit and to make it more accurate, use setTimeout and call the function as close as reasonable to the next full second. setInterval will slowly drift.
// Return the time to next 5 minutes as m:ss
function toNext5Min() {
// Get the current time
var secs = (new Date() / 1000 | 0) % 300;
// Function to add leading zero to single digit numbers
function z(n){return (n < 10? '0' : '') + n;}
// Return m:ss
return (5 - secs/60 | 0) + ':' + z(60 - (secs%60 || 60));
}
// Call the function just after the next full second
function runTimer() {
console.log(toNext5Min());
var now = new Date();
setTimeout(runTimer, 1020 - now % 1000);
}
The above ticks over on the full minute so that at say 10:00:00 it shows 5:00. If you'd rather is showed 0:00, then the last line of toNext5Min should be:
return (5 - (secs? secs/60 : 5) | 0) + ':' + z(60 - (secs%60 || 60));
This is what you need to change to get it to work the way you want:
var minutes = cur_date.getMinutes();
var seconds = cur_date.getSeconds();
try change it to this:
var minutes_remain = 5 - minutes%5 - 1;
var seconds_remain = 59 - seconds;
Try it out here: jsFiddle
Change your minutes remain to following line. It calculates current minute mod by 5 subtracted from 5, which is what you need.
function secondPassed() {
var cur_date = new Date();
var hour = cur_date.getHours();
var minutes = cur_date.getMinutes();
var seconds = cur_date.getSeconds();
var minutes_remain = parseInt(5 - parseInt(minutes%5));
var seconds_remain = parseInt(60 - parseInt(seconds));
var timers = document.getElementsByClassName('timer');
for (var i = 0; i < timers.length; i++) {
timers[i].innerHTML = minutes_remain+":"+seconds_remain;
}
}
var countdownTimer = setInterval(secondPassed, 1000);
Updated fiddle http://jsfiddle.net/ov0oo5f7/2/
You can work out what the next 5 minutes interval will be if you divide by 5, round it up, and multiply by 5 again.
You need to handle if you are on an exact minute otherwise minutes_remain will show as 1 minute less.
In terms of being accurate, you don't need to parseInt everywhere as they are all numbers already. I've tried to make it as efficient as possible. In any case, you are only checking it once a second, so you can't guarantee accuracy.
http://jsfiddle.net/ov0oo5f7/6/
function secondPassed() {
var cur_date = new Date();
var hour = cur_date.getHours();
// handle 0 seconds - would be 60 otherwise
var seconds_remain = 60 - (cur_date.getSeconds() || 60);
// handle ceil on 0 seconds - otherwise out by a minute
var minutes = cur_date.getMinutes() + (seconds_remain == 0 ? 0 : 1);
var minutes_remain = Math.ceil(minutes/5) * 5 - minutes;
var timers = document.getElementsByClassName('timer');
for (var i = 0; i < timers.length; i++) {
timers[i].innerHTML = minutes_remain+":"+seconds_remain;
}
}
var countdownTimer = setInterval(secondPassed, 1000);
If you are looking for the mechine time and counting it down for 5 minutes , then this might help -
var startTime = new Date();
function secondPassed() {
var cur_date = new Date();
if(parseInt((cur_date - startTime)/1000) >300 ){
window.clearInterval(countdownTimer);
}
var hour = cur_date.getHours();
var minutes = cur_date.getMinutes();
var seconds = cur_date.getSeconds();
var minutes_remain = parseInt(59 - parseInt(minutes));
var seconds_remain = parseInt(60 - parseInt(seconds));
var timers = document.getElementsByClassName('timer');
for (var i = 0; i < timers.length; i++) {
timers[i].innerHTML = minutes_remain+":"+seconds_remain;
}
}
var countdownTimer = setInterval(secondPassed, 1000);
A simple approach is nothing that 5 minutes are 5*60*1000 milliseconds, thus
var k = 5*60*1000;
var next5 = new Date(Math.ceil((new Date).getTime()/k)*k);
Related
I want to create a countdown timer which looks like an fps counter for webpage...
after hours of time spent i m not able to find out what is wrong.....help
<script>
var myvar = setInterval(function () { startTimer() }, 1000);
function startTimer() {
var presentTime = 17 + ":" + 00;
var timeArray = presentTime.split(/[:]+/);
var m = timeArray[0];
var s = checkSecond((timeArray[1] - 1));
if (s == 59) {
m = m - 1
}
//if(m<0){alert('timer completed')}
var button2 = document.createElement("Button2");
var interval = m + s;
button2.innerHTML = Math.round(interval);
button2.style = "top:0; left:0rem; height:10% ;color: black; background-color: #ffffff;position:fixed;padding:20px;font-size:large;font-weight: bold;";
setTimeout(startTimer, 1000);
document.body.appendChild(button2);
}
function checkSecond(sec) {
if (sec < 10 && sec >= 0) {
sec = "0" + sec
}; // add zero in front of numbers < 10
if (sec < 0) {
sec = "59"
};
return sec;
}
</script>
I can find three errors that hinder your code from performing correctly.
Multiple timers
First off since you invoke both a setInterval in outer scope, and then a setTimeout after each performed iteration, you will end up getting many unwanted timer instances that will do some crazy counting for you.
I recommend you to scrap either one of these and stick with just one of them.
For my example i happend to stick with the setInterval since you're executing the very same method over and over any way.
The initialization
Since the presentTime is declared inside the startTimer-function it will be constantly overwritten with 17 + ":" + 00 (resulting in "17:0" btw).
This is solved by declaring it in the outer scope instead.
Remembering the changes
Finally you need to save the current state of presentTime after modifications. Just adding a presentTime = [m,s].join(":"); at the end of startTimer() solves this.
var presentTime = "17:00";
function startTimer() {
var timeArray = presentTime.split(/[:]+/);
var m = timeArray[0];
var s = checkSecond((timeArray[1] - 1));
if (s == 59) {
m = m - 1
}
var button2 = document.createElement("Button2");
var interval = s;
button2.innerHTML = m + ":" + s;
button2.style = "top:0; left:0rem; height:10% ;color: black; background-color: #ffffff;position:fixed;padding:20px;font-size:large;font-weight: bold;";
document.body.appendChild(button2);
presentTime = [m,s].join(":");
}
function checkSecond(sec) {
if (sec < 10 && sec >= 0) {
sec = "0" + sec
}; // add zero in front of numbers < 10
if (sec < 0) {
sec = "59"
};
return sec;
}
var interval = setInterval(startTimer, 1000);
I'm currently using this function to calculate 2 fields and the results are good but sometimes missing a zero. sample
10:20 + 10:30 current output 0.10
10:20 + 10:30 I want the output to be 00.10
$(function () {
function calculate() {
time1 = $("#start").val().split(':'),
time2 = $("#end").val().split(':');
hours1 = parseInt(time1[0], 10),
hours2 = parseInt(time2[0], 10),
mins1 = parseInt(time1[1], 10),
mins2 = parseInt(time2[1], 10);
hours = hours2 - hours1,
mins = 0;
if(hours < 0) hours = 24 + hours;
if(mins2 >= mins1) {
mins = mins2 - mins1;
} else {
mins = (mins2 + 60) - mins1;
}
// the result
$("#hours").val(hours + ':' + mins);
}
});
also when there is an invalid character I keep getting a nan message is possible to change this to 00 instead?
Instead of dealing with the strings and each value independently, you can use the javascript Date object to calculate the difference...
function calculate() {
// Get time values and convert them to javascript Date objects.
var time1 = new Date('01/01/2017 ' + $('#start').val());
var time2 = new Date('01/01/2017 ' + $('#end').val());
// Get the time difference in minutes. If is negative, add 24 hours.
var hourDiff = (time2 - time1) / 60000;
hourDiff = (hourDiff < 0) ? hourDiff+1440 : hourDiff;
// Calculate hours and minutes.
var hours = Math.floor(hourDiff/60);
var minutes = Math.floor(hourDiff%60);
// Set the result adding '0' to the left if needed
$("#hours").val((hours<10 ? '0'+hours : hours) + ':' + (minutes<10 ? '0'+minutes : minutes));
}
Or even better, you can make the function independent of the DOM elements, so you can reuse it...
function calculate(startTime,endTime) {
// Get time values and convert them to javascript Date objects.
var time1 = new Date('01/01/2017 ' + startTime);
var time2 = new Date('01/01/2017 ' + endTime);
// Get the time difference in minutes. If is negative, add 24 hours.
var hourDiff = (time2 - time1) / 60000;
hourDiff = (hourDiff < 0) ? hourDiff+1440 : hourDiff;
// Calculate hours and minutes.
var hours = Math.floor(hourDiff/60);
var minutes = Math.floor(hourDiff%60);
// Return the response, adding '0' to the left of each field if needed.
return (hours<10 ? '0'+hours : hours) + ':' + (minutes<10 ? '0'+minutes : minutes);
}
// Now you can use the function.
$("#hours").val(calculate($('#start').val(),$('#end').val()));
Add a function
function checkTime(i) {
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
and call this function before displaying result
I propose you that :
$(".calculator").on("change",function(){
var isNegative = false;
var hours = "00:00";
var inputStart = $("#start").val();
var inputEnd = $("#end").val();
if(inputStart!="" && inputEnd != ""){
// calculate only if the 2 fields have inputs
// convert to seconds (more convenient)
var seconds1 = stringToSeconds(inputStart);
var seconds2 = stringToSeconds(inputEnd);
var secondsDiff = seconds2 - seconds1;
var milliDiffs = secondsDiff * 1000;
if(milliDiffs < 0){
milliDiffs = milliDiffs *-1;
isNegative = true;
}
// Convert the difference to date
var diff = new Date(milliDiffs);
// convert the date to string
hours = diff.toUTCString();
// extract the time information in the string 00:00:00
var regex = new RegExp(/[0-9]{2}:[0-9]{2}:[0-9]{2}/);
var arr = hours.match(regex);
hours = arr[0];
// Take only hours and minutes and leave the seconds
arr = hours.split(":");
hours=arr[0]+":"+arr[1];
// put minus in front if negative
if(isNegative){
hours = "-"+hours;
}
// Show the result
$("#hours").val(hours);
// Put back the inputs times in case there were somehow wrong
// (it's the same process)
var date1 = new Date(seconds1*1000);
var str1 = date1.toUTCString();
arr = str1.match(regex);
hours = arr[0];
arr = hours.split(":");
hours=arr[0]+":"+arr[1];
$("#start").val(hours);
// idem for time 2
var date2 = new Date(seconds2*1000);
var str2 = date2.toUTCString();
arr = str2.match(regex);
hours = arr[0];
arr = hours.split(":");
hours=arr[0]+":"+arr[1];
$("#end").val(hours);
}
});
function timeElementToString(timeElement){
var output = timeElement.toString();
if(timeElement < 10 && timeElement >=0)
output = "0"+output;
else if(timeElement < 0 && timeElement >=-10)
output = "-0"+Math.abs(output);
return output;
}
function stringToSeconds(input){
var hours = 0;
var arr=input.split(":");
if(arr.length==2){
hours=parseInt(arr[0]);
minutes=parseInt(arr[1]);
if(isNaN(hours)){
hours = 0;
}
if(isNaN(minutes)){
minutes = 0;
}
}
return hours*3600+60*minutes;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<label for="start">Start</label><input type="text" id="start" class="calculator"></input><br />
<label for="end">End</label><input type="text" id="end" class="calculator"></input><br />
<label for="hours">Hours</label><input type="text" id="hours" readonly="readonly"></input>
</form>
This question already has answers here:
Current time formatting with Javascript
(16 answers)
Closed 8 years ago.
The following JS shows the time in HH:MM:SS format while I need it to show HH:MM only
setInterval(function() {
var d = new Date();
var t = d.getTime();
var interval = 5*60*1000;
var last = t - t % interval;
var next = last + interval + 10*60000;
d.setTime(next);
var time = d.toLocaleTimeString();
$(".clock").html(time);
}, 1000);
Any idea on how to achieve that?
Fiddle: http://jsfiddle.net/7z9boag8/
There's getHours() and getMinuets() methods available.
example:
http://jsfiddle.net/0todu2y7/
jQuery(function($) {
setInterval(function() {
var d = new Date();
var t = d.getTime();
var interval = 5*60*1000;
var last = t - t % interval;
var nextt = last + interval + 5*60000;
d.setTime(nextt);
var hours = d.getHours();
var min = d.getMinutes();
$(".clock").html(hours+":"+min);
}, 1000);
});
i am sorry . i m not edit your code . i just give you another procedure
String.prototype.toHHMMSS = function () {
var sec_num = parseInt(this, 10); // don't forget the second param
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
var time = hours+':'+minutes+':'+seconds;
return time;
}
Second Formula is
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
function yourTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
// add a zero in front of numbers<10
m = checkTime(m);
s = checkTime(s);
document.getElementById('time').innerHTML = h + ":" + m + ":" + s;
t = setTimeout(function () {
startTime()
}, 500);
}
yourTime();
Try this:
var time = d.toLocaleTimeString().match(/(\d+:\d+):\d+( \w{2})*/);
var time = time[1] + (time[2] ? time[2] : "");
setInterval(function() {
var d = new Date();
var t = d.getTime();
var interval = 5*60*1000;
var last = t - t % interval;
var next = last + interval + 10*60000;
d.setTime(next);
var time = d.toLocaleTimeString().split(':')
time.pop()
time.join(':')
$(".clock").html(time);
}, 60000);
I don't think that u shuold run tins function every second. U may do it once in minute.
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/
I have a countdown like this one:
var countdown = {
startInterval: function() {
var count = 600
var countorig = 600;
var currentId = setInterval(function() {
var min = (count - (count % 60)) / 60;
var sec = count % 60;
if (sec < 10) {
$('#timer').html(min + ':0' + sec);
} else {
$('#timer').html(min + ':' + sec);
}
$('#time').val(countorig - count);
if (count == 0) {
$('#form').submit();
}--count;
}, 1000);
countdown.intervalId = currentId;
}
};
It works. But if I load the page, the countdown starts but it stutter it is not "round" like a clock is.
JSFiddle.
setInterval isn’t exact. You should use Dates instead, to get an accurate time, and then choose an interval of less than one second to get a smoother clock. Here’s a demo!
var countdown = {
startInterval: function() {
var count = 600;
var start = new Date(); // The current date!
var currentId = setInterval(function() {
var difference = Math.max(0, count - (new Date() - start) / 1000 | 0);
var min = difference / 60 | 0;
var sec = difference % 60;
$('#timer').text(min + ':' + (sec < 10 ? '0' : '') + sec);
$('#time').val(difference);
if(count === 0) {
$('#form').submit();
}
}, 200);
countdown.intervalId = currentId;
}
};
It's never a good idea to assume your timers are exact. Instead, use delta timing.
var startTime = new Date().getTime();
setInterval(function() {
var elapsed = new Date().getTime()-startTime;
console.log("Been running for "+Math.floor(elapsed/1000)+" seconds");
},25);
That is because setInterval is not meant to be a high resolution timer. It will NOT hit every 1000 milliseconds on the dot. You might have swings as much as 20 to 30 milliseconds in either direction, resulting in a clock that is off.
Using Date.now(), this is a quick example of a countdown function ( x is milliseconds )
function countdown(x){
var o = {future: Date.now()+x, last:-1, i:null}; // object so we can pass by-ref if req.
o.i = setInterval( function() { // use o.i so we can clear interval
var remain = o.future - Date.now(),
secs = Math.floor( remain / 1000 ),
mins = 0;
if( remain < 0 ){ // finished, do whatever
return clearInterval(o.i); // then clear & exit
}
if( secs === o.last ) return; // skip this iteration if it's not been a second
o.last = secs; // else update last time
// do whatever you want for this new second
if( secs > 59 ) mins = Math.floor( secs / 60 ), secs = secs % 60;
console.log(
(mins < 10 ? '0'+mins : mins) + ':' +
(secs < 10 ? '0'+secs : secs) + ' remain.'
);
}, 100);
}
If you know it wont be used in IE, consider adding o as an argument to the callback function in the interval and also as the last argument to setInterval (so it is passed to the callback as first arg), which means closure is independent => callback can be defined anywhere.