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現在時刻の 1 時間後に変数が設定されています。

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

この新たに発見された知識を使用して、現在の時間に 1 を追加する代わりに、現在の時間に 15 分を追加する必要があると推測できます。問題は、やみくもに 15 分を追加して、準備が整ったと考えることはできないということです。実際には、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 に答える