I'm trying to create something similar to a stop watch in an AngularJS app.
I've got a 'start' button that when clicked, the app will set a startTime variable which gets the current time and then I want another variable which updates every second and calculates the difference in seconds between the startTime variable and the current time which I can use as the stop watch value that's displayed to the user.
I'll also need to be able to stop and restart the timer so I'd like the stop watch value to be stored in seconds so that I can easily start the timer at any number of seconds and resume the timer.
What's the simplest way of doing this?
Expanding on my comments above, something like this...
var startTime = new Date();
$scope.stopwatch = 0;
$interval(function() {
$scope.stopwatch = (new Date() - startTime) / 1000;
}, 1000);
and in your template
<p>Seconds: {{ stopwatch }}</p>
Bonus points for creating a filter for formatting the seconds in hh:mm:ss format.
The best way to accomplish this, is by using $interval like so:
var stop, seconds=0;
stop = $interval(updatingFunc, 1000);
function updatingFunc(){
seconds++;
console.log(seconds);
if(seconds === 4){ // Here you set whatever condition to cancel the interval
$interval.stop(stop);
}
}
Related
I am trying to make a cookie clicker game, and one item that you can get in shop is a bot where it adds x amount of credits to your current amount of credits every second. I want to be able to make multiple of these bots with variations, so not sure if setInterval would be usable in this case. How can I make this?
Note: The timer only starts when a variable is turned to false, so the timer shouldn't start when the app is opened.
P.S. I am using React
let bought = false
const [credits, setCredits] = useState
if (bought) {
For every second {
setCredits(credits+1)
}
}
I think you have to calculate seconds after each reaction on click,
you should use setInterval() in JavaScript function.
Example --
let time = document.getElementById("time");
function clock(){
let date = new Date();
let clocktime = (date.toString().split('G')[0]);
time.innerHTML = `${clocktime}`;
}
setInterval(clock, 1000);
First target an element then change its text to this function's output, and give time here in setInterval() function, for how many seconds you want to repeat that function (for how many seconds)
I am creating a countdown in Typescript that will set an alarm.
I have taken input from the time attribute and then converted it by using .getTime and subtracted the current .getTime and displayed the result in console. When the time passes, the difference is not zero. Difference on console
var timer = (<HTMLInputElement>document.getElementById("time")).valueAsNumber; //getting input of time element and
console.log(timer);
console.log(new Date().getTime())
setInterval(function () { //a timer
var duration = (timer - (new Date().getTime()))/1000;
console.log(duration);
if (duration=0){
document.querySelector("audio").play();//plays audio
clearInterval();
}
}, 1000);
setInterval is not going to be exact, and also there is some small amount of time needed for executing new Date().getTime()).
To get the timer to work as intended, you can check if it's within a tolerance: if (duration < 10) instead of checking if it's exactly 0.
Alternatively, you can use setTimeout since you're only executing the function once.
I want to check if 2hours passed then do some steps. This is what I've tried so far
var d = new Date();
var time = d.getHours() + d.getMinutes();
if(time >= 120) {
// Do something
}
You can use setTimeout function to do stuffs in 2 hours. To cancel the timeout task, simply use clearTimeout to stop it.
var timeoutId = setTimeout( function(){
alert( '2 hours passed' );
}, 2*60*60*1000 );
// clearTimeout( timeoutId );
I like momentjs
let twoHoursLater = moment().add({hours: 2})
after some time passes, this check will return true when 2 hours passes
moment().isAfter(twoHoursLater)
-> true
Oh, and a plugin "timer" based on moment, here
npm install moment-timer
then in javascript, use the duration and timer, like so
let timer = new moment.duration(2, 'hours').timer(callback);
timer.start();
function callback() {
/* magic happens */
}
Another simple way is to just use javascript's native timeout, in this example, a callback is invoked after 2 hours.
setTimeout(callback, 2 * 60 * 60 * 1000)
Your approach is not clear. #Thum Choon Tat answer is fine if you just want to do stuff without page refresh.Every page refresh will calculate the time from 0 second.If You want to check weather 2 hours passed or not ignoring page refresh, you have to set a reference time from which you will calculate how much time have been passed. You can use https://plugins.jquery.com/cookie/
This is Jquery Cookie to set reference time. then get current time as you are doing. now compare this current time with your reference time.
I'm trying to decrement a variable once a day. I have written the following code for that.
var counter = 10; //any value
setInterval(function() {
counter = counter - 1;
}, 86400000);
Is there a better or efficient way to achieve the same thing ?
P.S : - I do not wish to use any libraries.
The only thing I see you miss is to set the initial value of counter variable.
I would write:
var counter = 1000; // or any useful value
setInterval(function() {
--counter;
}, 24 * 60 * 60 * 1000); // this is more self-explanatory than 86400000, and, being evaluated just once, it will have a tiny effect on the performace of the script
I don't see any problem in the way you write it. You use interval, ok, but this is not the worst evil you may do to set up the variable value.
You may think of another solution with a function which returns you the current counter.
var initialValue = 20000;
function getCounter() {
return initialValue - Math.floor(Date.now() / 1000 / 60 / 60 / 24);
}
console.log(getCounter());
The difference is that it takes the current day number starting from the UNIX time beginning. Every day the day number will be increased, so the result of the function will be decreased by 1.
But still I don't see how this solution can be better than yours.
I'm not totally sure why, but using setInterval like this makes me uncomfortable.
If I were to require this, I would use something like this approach:
var counter = 10;
var timeout = new Date();
setInterval(function(){
if(new Date() >= timeout)
{
--counter; // the action to perform
timeout = new Date(timeout.getTime() + 86400000); // update the timeout to the next time you want the action performed
}
console.log(counter);
},1000); // every second is probably way more frequent than necessary for this scenario but I think is a decent default in general
One thing that this allows is to, for example, set the next timeout to midnight of tomorrow rather than being locked in to "X seconds since the previous execution". The key is the inversion of control - the action itself can now dictate when it should next run.
Though I would probably abstract away the details behind an interface accepting a start, interval, and action.
The biggest problem in my eyes is that you have to keep this one JS process running consistently for days at a time to have it do what you need. The world is not so perfect that things don't need an occasional reboot...including the average JS process.
Personally I would store a timestamp of my starting point, then (whenever I need to know how much time has elapsed) grab a new timestamp and use it to calculate how many days it has been. That way even if something interrupts my process I can still be right where I started.
Maybe use window.localStorage to save the last time, and if it is greater than 60*60*24 (seconds in a day) set the last time to this morning/now/1:00 and then decrease the value and save it.
Example:
var d = new Date();
var mins = -(1+d.getHours())*60+d.getMinutes();
var secs = mins*60+d.getSeconds(); // total seconds passed today from 1:00
var now = d.getCurrentTime():
var lastCheck = localStorage.getItem("lastCheck");
if (!lastCheck)
{
localStorage.saveItem("lastCheck",now-secs); // beginning of today
}
var dayPassed = now - lastCheck > 24*60*60; // change to see if a day has passed
if (dayPassed)
{
// save seconds
localStorage.setItem("counter",localStorage.getItem("counter")-1);
localStorage.saveItem("lastCheck",now-secs); // beginning of today
}
It makes more sense to me to check how many days have passed since a specific date and decrement that number of days from the counter. Mostly just because I wouldn't expect anybody to leave the same page open without the need or want to reload for days on end. I would do something like this:
counter = 365; // original counter
var start = new Date(2016, 03, 20); // original date
var now = new Date();
var days = Math.floor(Math.abs(start.getTime()-now.getTime())/(24*60*60*1000))
counter -= days;
That way every time you visited the page, it would be decremented correctly. Note that this ignores any issues with leap days or time zones. The example above would have a counter of 360 for me. And then if you did expect it to be open for days, reload it automatically with:
self.setTimeout(function(){document.location.reload()}, 86400000);
I saw a Javascript milliseconds timer demo HERE
However, I found it very inaccurate because it uses setInterval to increase one ms per time.
Does anyone have ideas about how to implement an accurate milliseconds timer in JS easily? Does it has to be done using Date object?
An accurate timer uses setTimeout() or setInterval() to regularly update a display, but NEVER to count the actual time. Because of Javascript's single threaded nature and event driven system, a timer event may not occur exactly at the right time interval, but a call to Date.now() will always give you the exact current system time.
So, instead, you always use something like Date.now() to get the current time and compare it to some previous time to calculate the actual elapsed time. This will be as accurate as the system clock on the computer is.
For example, here's a working timer display:
var startTime = Date.now();
var interval = setInterval(function() {
var elapsedTime = Date.now() - startTime;
document.getElementById("timer").innerHTML = (elapsedTime / 1000).toFixed(3);
}, 100);
<span id="timer"></span> s
Yes. Using Date will be much more accurate. setInterval will not be triggered 'exactly' each milliseconds.
var startTime, interval;
function start(){
startTime = Date.now();
interval = setInterval(function(){
updateDisplay(Date.now() - startTime);
});
}
function stop(){
clearInterval(interval);
}
function updateDisplay(currentTime){
// do your stuff
}
setInterval could be switchet with
var x = 100; //ms time
var incrementFunction = function(){
//increment the watch/clock code
setTimeout(incrementFunction,x);
};
incrementFunction();
this will make a setTimeout function to be endless called, and set again.
It seems that setTimeout, has bigger priority than setInterval, which could be delayed.