【问题标题】:How to run a function at specific time & date?如何在特定时间和日期运行功能?
【发布时间】:2013-10-05 22:50:12
【问题描述】:

如何在给定的时间和日期运行函数?

示例:我有一个函数需要在每月 12 日上午 10 点运行。

如果这很重要,此页面将 24/7 全天候运行。

显然我必须与当前日期进行比较,但我不确定如何检查当前日期和时间是否匹配。

香农

【问题讨论】:

  • 你怎么知道他们会在那个时间和日期出现在你的特定网页上?
  • 查看new Date().getDate() 的当天和new Date().getHours() 的小时。我希望您不要指望其他人为您编写整个代码。
  • @Alnitak,通过将其与当前日期进行比较?
  • 不,我不@JoeSimmons,我只是不知道如何开始这个..
  • @ShannonHochkins 你错过了我的观点。您要求提供 JS 代码。 JS 代码在浏览器中运行。这意味着您希望这个特定 页面如果不是 24x7 运行,那么至少在您的“惊喜”应该发生的时候。这似乎是一个,嗯,不寻常的网页应用程序。

标签: javascript jquery date time


【解决方案1】:

您可以实例化两个 Date 对象。一个用于现在,一个用于事件的下一个实例。现在很简单:new Date()。对于下一个实例,您可以遍历选项,直到找到比现在更大的选项。或者做一些更复杂的日期时间魔法。比较两者的getTime(),然后为alert做一个setTimeout。

编辑: 更新自@Alnitak 指出超时有最大值,请参阅setTimeout fires immediately if the delay more than 2147483648 milliseconds

function scheduleMessage() {
    var today=new Date()

    //compute the date you wish to show the message
    var christmas=new Date(today.getFullYear(), 11, 25)
    if (today.getMonth()==11 && today.getDate()>25)
        christmas.setFullYear(christmas.getFullYear()+1)

    var timeout = christmas.getTime()-today.getTime();
    if( timeout > 2147483647 ){
        window.setTimeout( scheduleMessage(), 2147483647 )
    } else {
        window.setTimeout(function() {alert('Ho Ho Ho!'); scheduleMessage()}, timeout)
    }
}

【讨论】:

    【解决方案2】:

    在要检查的页面上添加此项

    setInterval(function () {
        var date = new Date();
        if (date.getDate() === 12 && date.getHours() === 10 && date.getMinutes === 0) {
            alert("Surprise!!")
        }
    }, 1000)
    

    FIDDLE


    更新 - 添加 date.getSeconds == 0 以限制它在 10:00:00 仅触发一次。感谢下面的cmets

    【讨论】:

    • 这段代码有bug,一个可见,一个不可见。无形的错误是它会一遍又一遍地重复显示警报,直到时间到达 10:01。
    • @Alnitak,再次,您的评论是基于我只想运行该函数一次的假设,而且完全由用户来编写代码,这是相当明显和简单的间隔结束后清除。
    • @ShannonHochkins 如果你清除它不会触发 next 个月的时间间隔(假设页面没有在两次之间重新加载)。
    • 我认为这样你可能会很不走运并且错过你正在等待的确切时间,调度不是那么精确。可能是第一个安排在 11:59:59.999,下一个安排在 12:00:01.000
    【解决方案3】:

    你可以使用这样的东西

    var runned = false;
    var d = new Date();
    if(d.getDate() == 12 && d.getHours() == 10 && !runned){
        //Do some magic
        runned = true;
    }
    

    如果你想要一些分钟(而不是整个小时,你可以添加 d.getMinutes()

    【讨论】:

    • for == '12' - .getDate() 的输出是一个数字
    • 哎呀,那里跑得有点快,现在修好了:)
    【解决方案4】:

    也许在元刷新和锻炼内容服务器端使用和iframe

    <meta http-equiv="refresh" content="{CHANGE_THIS_TO_WHAT_YOU_CALCULATED_AT_SERVER}">
    

    或使用javascripts setInterval

    var interval = 300000; // run in 5 minutes
    window.setInterval("reloadRefresh();", interval);
    
    function reloadRefresh() {
     // do whatever
    }
    

    【讨论】:

      【解决方案5】:

      不建议使用setInterval,因为它具有不确定的行为 - 可能会错过事件,或者一次触发所有事件。时间也会不同步。

      下面的代码使用setTimeout一分钟 周期,其中计时器每分钟重新同步,以尽可能接近 hh:mm:00.000s 点。

      function surprise(cb) {
          (function loop() {
              var now = new Date();
              if (now.getDate() === 12 && now.getHours() === 12 && now.getMinutes() === 0) {
                  cb();
              }
              now = new Date();                  // allow for time passing
              var delay = 60000 - (now % 60000); // exact ms to next minute interval
              setTimeout(loop, delay);
          })();
      }
      

      【讨论】:

      • 这很有趣!所以我假设你传递给惊喜函数的 cb 也是一个函数?这意味着您像这样运行:surprise(otherFunctionName);。你介意我问你为什么这样做吗?
      • 是的,没错——“为什么”被称为“关注点分离”——将“何时”你希望某事发生与“什么”分开。
      • 您使用 Modula 来计算毫秒的余数,您是否同意将分钟值(以毫秒为单位)作为变量更有用?我猜它读起来也会更好一些,但我确实喜欢你的解决方案,它应该会很好。
      • @ShannonHochkins 回复:60 年代 - 我会根据您的判断说。我个人读了 60000 并且转换是瞬时的。请注意,即使这种方法也不是没有风险 - 如果在此代码下调整系统时钟,则计时器可能会在时间还不是(还)10:00:xx 时触发。不过,实际上很难缓解!
      • 酷,不用担心@Alnitak,谢谢你的帖子,不过只是一个简单的问题,如果我要做这个服务器端而不是客户端,有没有办法仍然有一个用户界面网页“选择”时间,并且仍然正确启动计时器而无需不断打开页面?可能不对..
      猜你喜欢
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多