8

我从堆栈溢出中获取以下代码:

   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(); 

这非常有效,并且每小时都会产生一个警报。我希望该功能每 15 分钟运行一次,时间为 00、15、30 和 45

4

4 回答 4

14

通过以下方式获取下一个偶15数分钟的时间:

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

例如,当您在 13:43 调用doSomething()时,它将在下次 13:45 运行:

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

然后它将按预期运行:14:00、14:15 等等......

完整代码:

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();
于 2013-03-21T14:34:25.317 回答
5

这比其他人提出的要棘手一些。你不想要从现在开始的 15 分钟,你想要 15 分钟,从下一个最近的开始。有很多方法可以做到这一点,但这是我首先想到的:

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(); 

试试看。:-)

编辑

上面的代码是最简单的,但会出现问题,因为它只查看分钟。它最多可以漂移 59.999 秒,并且根据处理器负载,甚至可能偶尔出现在 1、16、31 或 46 上。为确保不会发生这种情况,您需要减去:

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(); 

这使您可以精确到秒,而我的原始帖子仅精确到分钟。

于 2013-03-21T14:35:22.230 回答
4

看看函数在做什么。您有一个变量h设置为当前时间后一小时。

//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)

构造函数中的每个参数Date对应一个时间间隔

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

使用这一新发现的知识,我们可以推断出,我们需要在当前时间上增加 15 分钟,而不是在当前时间上加一。问题是我们不能盲目地添加 15 分钟并认为我们已经准备就绪,因为我们真正想要的是在一刻钟间隔开始,然后在下一刻钟再次执行。

为了解决这个难题,我们必须找出距离下一个季度间隔有多远,并将其设置为我们的超时值。

var d = new Date();

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

var secondsFromQuarter = 900 - currentSeconds % 900;

现在我们知道调用 需要等待多少秒doSomething,但我们必须将其转换为毫秒。

var millisecondsFromQuarter = minutesFromQuarter * 1000;

瞧!从这里我们可以像上面一样使用我们的millisecondsFromQuarter值调用 setTimeout:

window.setTimeout(doSomething, millisecondsFromQuarter);

免责声明

这将精确到秒。如果需要精确到毫秒,那么您只需像这样比较毫秒值:

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

var MillisecondsFromQuarter = 900000 - currentSeconds % 900000;

免责声明 #2

我对@kamituel 的回答投了赞成票,因为它在视觉上以更清晰的方式有效地做同样的事情。我不确定哪个对性能更好,但可能是 6:6

于 2013-03-21T14:30:23.317 回答
-1
 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(); 
于 2013-03-21T14:28:11.113 回答