Javascript 检测午夜和重置数据的最佳方法

Javascript 检测午夜和重置数据的最佳方法,javascript,jquery,momentjs,Javascript,Jquery,Momentjs,我一直在开发一个web应用程序仪表板,我想知道如何检测午夜,以便使用jquery或momentjs重置一些包含前一天数据的数组。我会尝试: window.setInterval(resetAtMidnight, 1000*5) // every five seconds function resetAtMidnight() { var now = new Date(); if(now.getHours() < 1 && now.getMinutes() <

我一直在开发一个web应用程序仪表板,我想知道如何检测午夜,以便使用jquery或momentjs重置一些包含前一天数据的数组。

我会尝试:

window.setInterval(resetAtMidnight, 1000*5) // every five seconds
function resetAtMidnight() {
  var now = new Date();
  if(now.getHours() < 1
   && now.getMinutes() < 1
   && now.getSeconds() < 5 ) {
    redrawPage();
  }
};
window.setInterval(重置为午夜,1000*5)//每五秒
函数resetAtMidnight(){
var now=新日期();
如果(now.getHours()<1
&&现在。getMinutes()<1
&&现在。getSeconds()<5){
重画页();
}
};
使用
矩()格式(“h:mm:ss”)
h:mm:ss
格式返回时间

var midnight = "0:00:00";
var now = null;

setInterval(function () {
    now = moment().format("H:mm:ss");
    if (now === midnight) {
        alert("Hi");
    }
    $("#time").text(now);
}, 1000);

更好的方法是计算到午夜的秒数。使用MomentJS,这非常简单且易于阅读:

// returns the number of seconds until next midnight
moment("24:00:00", "hh:mm:ss").diff(moment(), 'seconds');
所以,只要做:

setTimeout(
   midnightTask,
   moment("24:00:00", "hh:mm:ss").diff(moment(), 'seconds')
);

function midnightTask() {
  /* do something */
}

要做到这一点,实际上只有两种方法

  • 每x秒进行一次民意调查,看看我们是否在午夜x秒以内
  • 计算从现在到午夜之间的时间,并在执行之前睡眠该时间量
  • (1) 已经在其他答案中得到证明,这里是(2)

    首先要做的是将其用作javascripts
    setTimeout
    的参数

    setTimeout(function(){
      // whatever you want to do at midnight
    }, msToMidnight);
    

    在完成该函数中的工作后,您可能希望重新计算时间,直到下一个午夜,然后重复该过程

    在今天早上午夜创建一个日期,添加86400秒,然后设置一个超时:

    new Date(Date.parse((new Date()).toString().replace(/\d\d:\d\d:\d\d/,'00:00:00')) + 86400 * 1000)
    
    以下是您如何使用它:

    var delay_to_midnight = Date.parse((new Date()).toString().replace(/\d\d:\d\d:\d\d/,'00:00:00')) + 86400 * 1000 - Date.now()
    var timeoutid = window.setTimeout(function() { alert("It's midnight!"); }, delay_to_midnight);
    

    所以我认为你走错了方向。你要找的不是午夜,你只想知道一天什么时候变了,这是一项简单得多的任务

    我要说的第一件事是不惜一切代价避免使用计时器。他们不值得。每天运行同一个函数3600次以上所带来的性能损失和额外CPU时间是荒谬的,尤其是当它在别人的计算机上运行时。你不知道它能处理多少,所以假设它根本不能处理多少。对你的用户放松点

    我建议听一个用户输入事件,假设这是你在普通计算机上会有的,而不是在没有用户输入的情况下

    如果用户输入事件是您可以依赖的,我会这样做

    var today = new Date(), lastUpdate;
    
    window.addEventListener( "mousemove", function () {
      var time = new Date();
      // If we haven't checked yet, or if it's been more than 30 seconds since the last check
      if ( !lastUpdate || ( time.getTime() - lastUpdate.getTime() ) > 30000 ) {
        // Set the last time we checked, and then check if the date has changed.
        lastUpdate = time
        if ( time.getDate() !== today.getDate() ) {
          // If the date has changed, set the date to the new date, and refresh stuff.
          today = time
    
          this_is_where_you_would_reset_stuff()
        }
      }
    } )
    
    function init() {
      var today = new Date();
      var midnight = new Date();
    
      midnight.setDate( today.getDate() + 1 )
      midnight.setHours( 0 )
      midnight.setMinutes( 0 )
    
      setTimeout( function () {
        // If the date has changed, set the date to the new date, and refresh stuff.
        today = time
    
        this_is_where_you_would_reset_stuff()
    
        init()
      }, midnight.getTime() - today.getTime() )
    }
    
    init()
    
    如果你真的需要使用计时器,那么我会这样做

    var today = new Date(), lastUpdate;
    
    window.addEventListener( "mousemove", function () {
      var time = new Date();
      // If we haven't checked yet, or if it's been more than 30 seconds since the last check
      if ( !lastUpdate || ( time.getTime() - lastUpdate.getTime() ) > 30000 ) {
        // Set the last time we checked, and then check if the date has changed.
        lastUpdate = time
        if ( time.getDate() !== today.getDate() ) {
          // If the date has changed, set the date to the new date, and refresh stuff.
          today = time
    
          this_is_where_you_would_reset_stuff()
        }
      }
    } )
    
    function init() {
      var today = new Date();
      var midnight = new Date();
    
      midnight.setDate( today.getDate() + 1 )
      midnight.setHours( 0 )
      midnight.setMinutes( 0 )
    
      setTimeout( function () {
        // If the date has changed, set the date to the new date, and refresh stuff.
        today = time
    
        this_is_where_you_would_reset_stuff()
    
        init()
      }, midnight.getTime() - today.getTime() )
    }
    
    init()
    

    请记住,第二种方法的可靠性可能要低得多。

    您说的是服务器还是客户端?我不确定你想在客户身上做……我说的是客户。我唯一不想做的就是刷新页面。例如,我想做的是:如果你有一个包含数据的数组,我想重置这个数组。我也不想每5秒检查一次(如果可能的话),如果是午夜,你如何定义午夜?这是
    0:00
    小时吗?午夜是0,但检测午夜有问题。最好的做法是重新思考您的应用程序目标,然后继续完成任务
    if(is_midnight())
    midnight返回0,逻辑上也是如此false@JuanJardim我补充了我的答案。尝试更改
    midnight
    变量并查看结果。为什么还要让CPU工作得比需要的更努力呢。1000*5=5000,为什么不直接输入5000?这会重复吗?或者在5秒延迟后只运行一次函数?@gibberish-这只会运行一次,要重复,请使用
    setInterval
    (或者再次调用
    setTimeout
    )@self我将其拼写为
    1000*5
    ,因为更容易看到发生了什么,特别是在像
    1000*60*60*4
    (4小时)这样的长时间间隔内。此外,它只需计算一次,而不是每次间隔。请不要这样做。这种方法的问题是,此仪表板将显示在监视器中,用户只看到数据更改。但是,感谢您的建议,每次鼠标移动时都会查询系统计时器。这是你最不想做的事情。即使只是因为鼠标移动了,日期对象本身的创建也比你想做的要多。如果计算机进入睡眠状态并很晚恢复,第二种解决方案(setTimeout)将不起作用。在这种情况下,触发器将延迟大约与计算机在睡眠模式下花费的时间相同。“h”提供12小时的格式,因此
    moment()。格式(“h:mm:ss”)
    将在午夜“12:00:00”。检查“HH:mm:ss”和“00:00:00”应该有效。@Dunc-Whoups!非常感谢D