最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

settimeout - javascript run a function every quarter hour at 00, 15, 30 ,45 - Stack Overflow

programmeradmin3浏览0评论

I have the following code taken from stack overflow:

   function doSomething() {
       var d = new Date(),
       h = new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() + 1, 0, 0, 0),
       e = h - d;
       window.setTimeout(doSomething, e);

       //code to be run
       alert("On the hour")
    }
    doSomething(); 

This works perfectly and produces an alert every hour on the hour. I would like the function to run every 15 minutes, at 00, 15, 30 and 45

I have the following code taken from stack overflow:

   function doSomething() {
       var d = new Date(),
       h = new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() + 1, 0, 0, 0),
       e = h - d;
       window.setTimeout(doSomething, e);

       //code to be run
       alert("On the hour")
    }
    doSomething(); 

This works perfectly and produces an alert every hour on the hour. I would like the function to run every 15 minutes, at 00, 15, 30 and 45

Share Improve this question edited Mar 21, 2013 at 14:35 Ian 50.9k13 gold badges103 silver badges111 bronze badges asked Mar 21, 2013 at 14:25 Alex McDaidAlex McDaid 2694 silver badges13 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 14

Get the time of the next even 15 minutes by:

(d.getMinutes() - (d.getMinutes() % 15)) + 15

On example when you invoke doSomething() at 13:43, it will run next time at 13:45:

( 43 - (43 % 15) + 15 ) = ( 43 - 13 + 15 ) = 45

Then it will run as expected: 14:00, 14:15 and so on...

Complete code:

function doSomething() {
     var d = new Date(),
         h = new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), (d.getMinutes() - (d.getMinutes() % 15)) + 15, 0, 0),
         e = h - d;
     window.setTimeout(doSomething, e);

     console.log('run');
 }
 doSomething();

This is a little trickier than others presented. You don't want 15 minutes from now, you want 15 minutes on the mark, starting with the next most recent. There are lots of ways to do it, but this one is what first jumps to my mind:

function doSomething() {
   var d = new Date();
   var minutes = 15 - d.getMinutes() % 15; // the number of minutes till the next 15.
   window.setTimeout(doSomething, minutes * 60 * 1000);

   //code to be run
   alert("On the quarter-hour")
}
doSomething(); 

Give it a try. :-)

Edit

The above code is the simplest, but will have issues since it only looks at the minutes. It can drift by up to 59.999 seconds, and depending on processor load, may even show up occassionally on a 1, 16, 31, or 46. To make sure that doesn't happen, you do need to subtract:

function doSomething() {
   var d = new Date();
   var minutes = 15 - d.getMinutes() % 15; // the number of minutes till the next 15.
   var h = new Date(d.getYear(), d.getMonth(), d.getDay(), d.getHours(), d.getMinutes() + minutes, 0);
   var e = h-d;
   window.setTimeout(doSomething, e);

   //code to be run
   alert("On the quarter-hour")
}
doSomething(); 

This keeps you precise to the second, while my original post was only precise to the minute.

Look at what the function is doing. You have a variable h getting set to one hour after the current time.

//Gets the current date
var d = new Date() 

//Note the +1
h = new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() + 1, 0, 0, 0)

Each parameter in the Date constructor corresponds to a time interval

new Date(year, month, day, hours, minutes, milliseconds)

Using this newly discovered bit of knowledge we can deduce that instead of adding one to the current hour, we need to add 15 minutes to the current time. The problem is that we can't just blindly add 15 minutes and think that we are all set because what we really want is to start on a quarter hour interval and only execute again on the next quarter hour.

In order to solve this conundrum we have to find out how far away we are from the next quarter interval, and set that as our timeout value.

var d = new Date();

var currentSeconds = d.getMinutes() * 60 + d.getSeconds();

var secondsFromQuarter = 900 - currentSeconds % 900;

Now we know how many seconds we need to wait to call doSomething, but we must convert it to milliseconds.

var millisecondsFromQuarter = minutesFromQuarter * 1000;

Voila! From here we can call the setTimeout just like above with our millisecondsFromQuarter value:

window.setTimeout(doSomething, millisecondsFromQuarter);

Disclaimer

This will be accurate to the second. If accuracy is needed to the millisecond then you would simply compare the millisecond value like so:

var currentMilliseconds = d.getMinutes() * 60 * 1000 + d.getSeconds() * 1000 + d.getMilliseconds();

var MillisecondsFromQuarter = 900000 - currentSeconds % 900000;

Disclaimer #2

I up-voted @kamituel's answer because it effectively does the same thing in a much cleaner way visually. I'm not sure which is better for performance but it's probably 6:6

 function doSomething() {
   var d = new Date(),
   current_minutes = d.getMinutes(),
   current_hour = d.getHours(),
   next_min_hit = 0;

   if ( current_minutes >= 0 && current_minutes < 15 )
      next_min_hit = 15;
   if ( current_minutes >= 15 && current_minutes < 30 )
      next_min_hit = 30;
   if ( current_minutes >= 30 && current_minutes < 45 )
      next_min_hit = 45;
   if ( current_minutes >= 45 && current_minutes < 59 ){
      next_min_hit = 0;
      current_hour++;
   }
   var h = new Date(d.getFullYear(), d.getMonth(), d.getDate(), current_hour, next_min_hit , 0, 0),
   e = h - d;
   window.setTimeout(doSomething, e);

   //code to be run
   alert("On the hour")
}
doSomething(); 

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论