I'm looking to run a function every 5 minutes past the hour i.e. 08:05, 08:10, 08:15 etc..all day
how do I adapt:
setTimeout(function(){
xxxxxxx()
}, 300000);
to detect the current time - if a multiple of 5 then run xxxxxx() function?
Using setInterval to call the function every second.
Then using a filter by current time having a minute divisible by 5 and seconds zero.
var timer = 0;
timer = setInterval(function(){
var currentdate = new Date();
if(currentdate.getMinutes() % 5 == 0 && currentdate.getSeconds() == 0) {
console.log("Alarm");
}
}, 1000);
//to stop: clearInterval(timer);
It is fairly straight forward:
Wait until you reach 5 minute boundary using setTimeout()
Use setInterval() to call the function every 5 minute
function dosomething() {
console.log("dosomething() called at " + new Date().toISOString());
}
var FIVEMINUTES = 5 * 60 * 1000;
var timeSincePrev = new Date() % FIVEMINUTES;
var timeUntilNext = timeSincePrev === 0 ? 0 : (FIVEMINUTES - timeSincePrev);
setTimeout(function() {
dosomething(); // execute now
setInterval(dosomething, FIVEMINUTES); // and after every 5 minutes
}, timeUntilNext);
Related
I am trying to update information from a weather service on my page. The info should be updated every hour on the hour. How exactly do I go about calling a function on the hour every hour?
I kind of had an idea but I'm not sure of how to actually refine it so it works...
What I had in mind was something like creating an if statement, such as: (pseudo code)
//get the mins of the current time
var mins = datetime.mins();
if(mins == "00"){
function();
}
You want to check out setInterval: https://developer.mozilla.org/en-US/docs/Web/API/Window.setInterval
It's a little hard to tell what you're trying to call with your code, but it would be something in the form of:
function callEveryHour() {
setInterval(yourFunction, 1000 * 60 * 60);
}
If you want it every hour, try something like:
var nextDate = new Date();
if (nextDate.getMinutes() === 0) { // You can check for seconds here too
callEveryHour()
} else {
nextDate.setHours(nextDate.getHours() + 1);
nextDate.setMinutes(0);
nextDate.setSeconds(0);// I wouldn't do milliseconds too ;)
var difference = nextDate - new Date();
setTimeout(callEveryHour, difference);
}
Now, this implementation checks the time once, sets the delay (or calls the function immediately), and then relies on setInterval to keep track after that. An alternative approach may be to poll the time every x many seconds/minutes, and fire it .getMinutes() == 0 instead (similar to the first part of the if-statement), which may sacrifice (marginal) performance for (marginal) accuracy. Depending on your exact needs, I would play around with both solutions.
Here is what should work (JSFiddle):
function tick() {
//get the mins of the current time
var mins = new Date().getMinutes();
if (mins == "00") {
alert('Do stuff');
}
console.log('Tick ' + mins);
}
setInterval(tick, 1000);
What you probably want is something like that:
var now = new Date();
var delay = 60 * 60 * 1000; // 1 hour in msec
var start = delay - (now.getMinutes() * 60 + now.getSeconds()) * 1000 + now.getMilliseconds();
setTimeout(function doSomething() {
// do the operation
// ... your code here...
// schedule the next tick
setTimeout(doSomething, delay);
}, start);
So basically the first time the user get the access, you need to know what is the delay in millisecond to the next "hour". So, if the user access to the page at 8:54 (with 56 seconds and 123 milliseconds), you have to schedule the first execution after around 3 minutes: after the first one is done, you can call it every "hour" (60 * 60 * 1000).
Repeat at specific minute past the hour
This counter is a little bit more versatile; it allows to perform a task repeatedly always at the same minute past the hour (e.g. 37 minutes past the hour), and this with up to millisecond precision.
The precision of this timer is derived from its recursion.
At every recursion, the millisecond time to the next minute gets recalculated. This prevents time lag over long periods.
The % sign refers to the modulo operator.
function minuteCount(minutesAfterHour) {
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();
const milliseconds = now.getMilliseconds();
waitUntilNextMinute = setTimeout(minuteCount, 60000 - seconds * 1000 - milliseconds);
if(minutes % 60 === minutesAfterHour) {
doSomethingHourly();
}
}
minuteCount(37);
Finally, timers are best kept away from the main thread. They are best run from within a web worker, as explained here.
This works perfectly with unfocused tabs in desktop browsers.
However, dedicated web workers on Chrome for Android are put to sleep about 5 minutes after moving the main client to the background.
EDIT: Oops, I didn't see the " o' clock" things, so I edit my answer :
var last_execution = new Date().getTime();
function doSomething(force){
var current_time = new Date().getTime();
if (force || (current_time.getMinutes() == 0)
{
last_execution = current_time;
// something
// ...
}
setTimeout(doSomething(false), 1000);
}
// force the first time
doSomething(true);
// ... call your func now
let intervalId;
let timeoutId = setTimeout(() => {
// ... call your func on end of current hour
intervalId = setInterval(() => {
// ... call your func on end of each next hours
}, 3600000);
}, ((60 − moment().minutes()) × 60 × 1000) - (moment().second() * 1000));
Here is my pair of setIntervalWithDelay and clearIntervalWithDelay that one can use like this:
let descriptor = setIntervalWithDelay(callback, 60 * 60 * 1000, nextHourDelay)
And when you are done with it:
clearIntervalWithDelay(descriptor)
Here is my implementation of the functions:
const setIntervalWithDelay = (callback, interval, delay = 0) => {
let descriptor = {}
descriptor.timeoutId = setTimeout(() => {
if(!descriptor.timeoutId){
return
}
descriptor.timeoutId = null
callback()
descriptor.intervalId = setInterval(callback, interval)
}, delay)
return descriptor
}
export const clearIntervalWithDelay = (descriptor) => {
if(!isObject(descriptor) || (!descriptor.timeoutId && !descriptor.intervalId)){
console.warn("clearIntervalWithDelay: Incorrect descriptor. Please pass an object returned by setIntervalWithDelay. Skipping this call.")
return
}
if(descriptor.timeoutId){
clearTimeout(descriptor.timeoutId)
descriptor.timeoutId = null
console.log("clearIntervalWithDelay: stopped during delay.")
}
if(descriptor.intervalId){
clearInterval(descriptor.intervalId)
descriptor.intervalId = null
console.log("clearIntervalWithDelay: stopped during interval repeat.")
}
}
One example of using dayjs to get the delay for the next hour:
let nextHour = dayjs().second(0).millisecond(0).add(1, "hour")
let nextHourDelay = nextHour.diff(dayjs())
having difficulty stopping timer outside of loop. I don't really know why the setTimeout() has been helping the function work... and i know its not the most syntactically correct.. but wondering if someone can help point me as to how to be able to call it outside the function to stop the countdown, say if an action occurs before the timer, and want to call a stopCountdown() function?
function countdown(start){
setTimeout(setCountdown, 1000);
let startingMinutes = timerEl.innerHTML;
startingMinutes = start;
let time = startingMinutes * 60;
function setCountdown(){
const minutes = Math.floor(time/60);
let seconds = time % 60;
if(seconds < 10){
seconds = '0' + seconds
} else {
seconds
}
if(minutes <=0 && seconds <=0){
clearInterval(start);
console.log('timerOver')
} else{
setTimeout(setCountdown, 1000);
timerEl.innerHTML = (minutes + ':'+seconds)
time--;
}
}}
function stopCountdown(){
document.querySelector("#countdown").innerText = '0'
setTimeout(setCountdown(start));
}
Welcome to coding, I am trying my best to explain it. First, let me point out some of my opinion on your code
function countdown(start){
setTimeout(setCountdown, 1000);
let startingMinutes = timerEl.innerHTML;
startingMinutes = start;
// I am not sure why you firstly initializing startMinutes
// to the value of timerEl.innerHTML
//and then reassign the value of startMinutes to variable start next line
let time = startingMinutes * 60;
function setCountdown(){
const minutes = Math.floor(time/60);
let seconds = time % 60;
if(seconds < 10){
seconds = '0' + seconds
} else {
seconds
}
if(minutes <=0 && seconds <=0){
clearInterval(start); // you are using setTimeout, not setInterval
console.log('timerOver')
} else{
setTimeout(setCountdown, 1000);
timerEl.innerHTML = (minutes + ':'+seconds)
time--;
}
}}
function stopCountdown(){
document.querySelector("#countdown").innerText = '0'
setTimeout(setCountdown(start));
// when calling stopCountdown(), what is the value of start?
// you can't access function setCountdown inside function stopCountdown
}
If my guess is correct, you want to make a timer and then you can make it stop when calling a stopCountdown function, right?
For a timer, it is simply asking javascript to - 1 seconds for every 1000 ms passed. So we can write a function which -1 seconds and ask JS to run it every 1000ms, right?
In this case, you should use setInterval but not setTimeout (setTimeout can also make a timer, I will also show you). The difference is that setTimeout calls a function ONCE after X milliseconds and setInterval will run a function EVERY X milliseconds.
Here is the code
let countdownIntervalId // get the countdownIntervalId outside by first declearing a variable to catch the id
function countdown(start) { // assume the unit of start is minute
console.log("countdown called, minutes =" + start)
// add code here to change the innerHTML of the timer if you want
let secondsToCount = start * 60; //Converting minutes to seconds
countdownIntervalId = setInterval(() => {
timer()
}, 1000); // starting to count down
function timer() { // run every seconds
const minutes = Math.floor(secondsToCount / 60);
let seconds = secondsToCount - minutes*60;
console.log("counter= " + minutes + ':' + `${seconds}`.padStart(2, '0'))
secondsToCount = secondsToCount-1;
if (minutes <= 0 && seconds <= 0) {
clearInterval(countdownIntervalId); // clearInterval
console.log('timerOver')
}
}
}
function stopCountdownOutside(){
if(countdownIntervalId){
clearInterval(countdownIntervalId)
}
}
countdown(2) //countdown 2 mins
You can stop the counter by calling stopCountdownOutside(), you can test on Chrome console. This is because we are passing the intervalId to the countdownIntervalId which is declare outside the function. so we can simply call clearInterval(countdownIntervalId) to stop it
For using the setTimeout
let countdownTimeoutId// get the countdownIntervalId outside by first declearing a variable to catch the id
function countdown(start) { // assume the unit of start is minute
console.log("countdown called, minutes =" + start)
// add code here to change the innerHTML of the timer if you want
let secondsToCount = start * 60; //Converting minutes to seconds
countdownTimeoutId = setTimeout(() => {
timer()
}, 1000); // starting to count down
function timer() { // run every seconds
const minutes = Math.floor(secondsToCount / 60);
let seconds = secondsToCount - minutes*60;
console.log("counter= " + minutes + ':' + `${seconds}`.padStart(2, '0'))
secondsToCount = secondsToCount-1;
if (minutes <= 0 && seconds <= 0) {
clearTimeout(countdownTimeoutId); // clearTimeout
console.log('timerOver')
}else{
countdownTimeoutId = setTimeout(timer,1000)
}
}
}
function stopCountdownOutside(){
if(countdownTimeoutId){
clearTimeout(countdownTimeoutId)
}
}
countdown(1) //countdown 2 mins
you can try to refactor my code to a more clean version, happy coding
I have the following code that will refresh the "updt" page at the minute "50" of every hour.
It only works if I refresh the page manually. How can I modify the code to sense that the minute 50 has come.
function show_hide_me () {
var myDate = new Date();
var mins = myDate.getMinutes();
if (mins == 50){
doSomething();
}
}
function doSomething() {
alert("Page will refresh now");
document.getElementById("updt").click();
}
what you are missing is that you need to check if its 50th minute, every minute.
setInterval(function(){
show_hide_me();
}, 60*1000);
This will run your function every 60000 miliseconds i.e. one minute.
https://www.w3schools.com/jsref/met_win_setinterval.asp
As other users said, what you need is a loop and a method like window.reload(true) or window.location.href = location.href to be executed when mins == 50.
For example, use setInterval:
let intervalId = window.setInterval(function() {
let myDate = new Date();
let mins = myDate.getMinutes();
if (mins == 50){
window.location.href = location.href;
}
}, 60 * 1000); // every 60 seconds
All you have to do is wrap your function in a
setInterval
So that it can be executed maybe ever minute and would continuously check if it's 50minutes into an hour already.
A sample code would be:
setInterval(show_hide_me, 60000)
The reason for this is if the user happens to refresh the page, our checker would always execute our checker.
I think you should change your doSomething function to something like:
function doSomething() {
window.location = window.location.href;
}
Try this logic. This will refresh the page at the 50th minute for every hour.
(function() {
var time = 49 - (new Date()).getMinutes();
time = time >= 0 ? time : (50 + (10 + time));
console.log("Loaded : ", time);
setTimeout(function() {
window.location.reload();
}, time*60000);
})()
i am trying to create a program that will run for X amount of minutes.
minutes was always set to 1 in testing
var minutes = $('#minutes').val();
var runtime = minutes*60; // gets the seconds
var secondsEpoch = new Date() / 1000; // Epoch time
var End = secondsEpoch + runtime; // add the minutes to the current epoch
if (secondsEpoch < End) {
window.setInterval(RunClock, 1000/10);
} else {
clearInterval(RunClock);
}
function RunClock() {
console.log(new Date() / 1000);
//my code
}
The script runs for infinity and i'm confused on why ???
When alerting variable secondsEpoch and End i always end up with a time difference of 1 minute?
Alerted the start and finish times and got
Start 1395022190.621
Finish 1395022250.621
Total difference of 60 which = 1 minute
but the console log at this minute is
1395022456.657
which is obviously greater than
1395022250.621
and the scrip is still running and not stopping
You are not clearing your interval correctly. This way it will work:
var interval;
if (secondsEpoch < End) {
interval = setInterval(RunClock, 1000/10);
} else {
clearInterval(interval);
}
I need to run a function every 16 minutes but not when user goes to page, rather at a specific time.
For example: 12:01, 12:16, 12:31, 12:46, 13:01, 13:16, 13:31 and so on...
How do I do that?
updateTodayCharts = setInterval(function () {
ajax_update( date1 , date2 );
}, 15 * 60 * 1000);
This script runs ajax_update every 15 minutes. When you visit the page at 12:20 it runs at 12:35 (12:20 + 15 minutes).
I need to run this script at 12:36 (so after 11 minutes not 15)
First i will calculate time from now to next update and then set timeinterval time.
There are two ways to do this, one is to store last date, have a shorter interval and check enough time has passed, the other is to combine setTimeout with setInterval, or some similar such construction.
var interval = (new Date().getUTCMinutes() + 59) % 15; // current position
interval = 15 - interval; // remaining til next position
interval = interval * 60e3; // to ms
interval = window.setTimeout(function () {
interval = window.setInterval(function () {
ajax_update( date1 , date2 );
}, 15 * 60e3);
}, interval);
Check each minute if the number of minutes is 1, 16, 31, 46 or whatever you want but in this case number of minutes modulo 15 must be equal to one :
updateTodayCharts = setInterval(function () {
var d = new Date(),
min = d.getMinutes();
if (min % 15 === 1) ajax_update( date1 , date2 );
}, 60 * 1000);