javascript每四分之一小时在00、15、30、45运行一个函数

javascript每四分之一小时在00、15、30、45运行一个函数,javascript,settimeout,Javascript,Settimeout,我从堆栈溢出中获取了以下代码: 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

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

   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(); 
这项功能工作正常,每小时都会发出警报。 我希望函数在00、15、30和45时每15分钟运行一次{
 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(); 
var d=新日期(), 当前分钟数=d.getMinutes(), 当前小时=d.getHours(), next_min_hit=0; 如果(当前分钟数>=0和当前分钟数<15) next_min_hit=15; 如果(当前分钟数>=15和当前分钟数<30) next_min_hit=30; 如果(当前分钟数>=30和当前分钟数<45) next_min_hit=45; 如果(当前分钟数>=45和当前分钟数<59){ next_min_hit=0; 当前_小时++; } var h=新日期(d.getFullYear(),d.getMonth(),d.getDate(),当前时间,下一个时间,0,0), e=h-d; 设置超时(doSomething,e); //要运行的代码 警报(“准时”) } doSomething();
看看函数在做什么。将变量
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分钟,而不是在当前时间上增加1分钟。问题是,我们不能盲目地增加15分钟,以为我们都准备好了,因为我们真正想要的是在每四分之一小时开始,然后在下一个四分之一小时再次执行

为了解决这个难题,我们必须找出距离下一个四分之一间隔的距离,并将其设置为超时值

var d = new Date();

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

var secondsFromQuarter = 900 - currentSeconds % 900;
现在我们知道需要等待多少秒才能调用
doSomething
,但我们必须将其转换为毫秒

var millisecondsFromQuarter = minutesFromQuarter * 1000;
瞧!从这里,我们可以像上面一样使用
毫秒fromQuarter
值调用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,通过以下方式获得下一个偶数
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();

这比其他介绍的要复杂一些。从现在开始你不需要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(); 

这可以让你精确到第二分钟,而我原来的帖子只精确到一分钟。

如果我在12:22打开,它将在12:37运行,我想从sec u运行,你希望每15分钟运行一次。现在应该可以了,如果是45分钟或更高,日期设置为小时+1。如果它在46分钟内,你会有问题。。。否?@IdanHen-我添加了一部分来解释这背后的数学;)@如果您传递的分钟值大于,IdanHen
new Date()
将处理它59@awbergs-是的。我总是试着用OP的密码回答。我认为这(通常)是最好的,因为OP可以看出他的尝试和解决方案之间的区别——这有助于学习。@awbergs你的解决方案是什么?我很想看看。只是看起来不坏——但是你的警报/闹钟会迟到一分钟,因为你只数分钟。i、 在09:14:59-你将在一分钟内让闹钟响。嗯。。。最多延迟59.999秒。:-)我想处理器速度足够快,我们可以始终保持在正确的时间。不过,我想我还是应该解释一下。