【问题标题】:Countdown timer using Moment js使用 Moment js 的倒数计时器
【发布时间】:2013-04-14 07:05:09
【问题描述】:

我正在为活动页面制作倒计时,我为此使用了 moment js。

这里是fiddle

我正在计算事件日期和当前日期(时间戳)之间的日期差异,然后使用时刻 js 的“持续时间”方法。但是剩下的时间并没有像预期的那样到来。
预期 - 00:30m:00s
实际 - 5h:59m:00s

代码:

<script>
  $(document).ready(function(){

    var eventTime = '1366549200';
    var currentTime = '1366547400';
    var time = eventTime - currentTime;
    var duration = moment.duration(time*1000, 'milliseconds');
    var interval = 1000;

    setInterval(function(){
      duration = moment.duration(duration.asMilliseconds() - interval, 'milliseconds');
      $('.countdown').text(moment(duration.asMilliseconds()).format('H[h]:mm[m]:ss[s]'));
    }, interval);
  });
  </script>

我阅读了 momentjs 文档以找出问题所在,但没有运气。

感谢您的宝贵时间。

更新:

我最终会这样做:

<script>
  $(document).ready(function(){

    var eventTime = '1366549200';
    var currentTime = '1366547400';
    var leftTime = eventTime - currentTime;//Now i am passing the left time from controller itself which handles timezone stuff (UTC), just to simply question i used harcoded values.
    var duration = moment.duration(leftTime, 'seconds');
    var interval = 1000;

    setInterval(function(){
      // Time Out check
      if (duration.asSeconds() <= 0) {
        clearInterval(intervalId);
        window.location.reload(true); #skip the cache and reload the page from the server
      }

      //Otherwise
      duration = moment.duration(duration.asSeconds() - 1, 'seconds');
      $('.countdown').text(duration.days() + 'd:' + duration.hours()+ 'h:' + duration.minutes()+ 'm:' + duration.seconds() + 's');
    }, interval);
  });
  </script>

JS Fiddle.

【问题讨论】:

  • 什么是“预期”?我们无法读懂您的想法以了解的实际期望。
  • @zerkms - 我相信相差30分钟,从1小时30分开始倒计时
  • @zerkms - 更新问题。
  • momentjs 不格式化时间跨度,而是格式化日期。如果您输出日期(除了时间),您会看到它是 unix 纪元的第一天,您的时区偏移
  • github.com/icambron/moment-countdown moment-countdown 是一个与 Countdown.js 集成的小 moment.js 插件

标签: javascript jquery countdown unix-timestamp momentjs


【解决方案1】:

这对我来说是上述答案的混合体。

const moment = require('moment');
require("moment-countdown");
let timeRemaining = 2330;
console.log('moment', moment(moment().add(timeRemaining, 'seconds')).countdown().toString());

【讨论】:

    【解决方案2】:

    这里有一些其他的解决方案。 无需使用额外的插件。

    下面的片段使用.subtract API 并且需要时刻 2.1.0+

    片段也可以在这里https://jsfiddle.net/traBolic/ku5cyrev/

    使用.format API 格式化:

    const duration = moment.duration(9, 's');
    
    const intervalId = setInterval(() => {
      duration.subtract(1, "s");
    
      const inMilliseconds = duration.asMilliseconds();
    
      // "mm:ss:SS" will include milliseconds
      console.log(moment.utc(inMilliseconds).format("HH[h]:mm[m]:ss[s]"));
    
      if (inMilliseconds !== 0) return;
    
      clearInterval(intervalId);
      console.warn("Times up!");
    }, 1000);
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"&gt;&lt;/script&gt;

    通过.hours.minutes.seconds API 在模板字符串中进行手动格式化

    const duration = moment.duration(9, 's');
    
    const intervalId = setInterval(() => {
      duration.subtract(1, "s");
    
      console.log(`${duration.hours()}h:${duration.minutes()}m:${duration.seconds()}s`);
      // `:${duration.milliseconds()}` to add milliseconds
    
      if (duration.asMilliseconds() !== 0) return;
    
      clearInterval(intervalId);
      console.warn("Times up!");
    }, 1000);
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案3】:

      您没有使用本机反应或反应,所以请原谅我这不是您的解决方案。 - 因为这是一篇已有 7 年历史的帖子,我很确定你现在已经明白了;)

      但我一直在寻找类似的 react-native 东西,这让我想到了这个 SO 问题。万一其他人走上我以为我会分享的同一条路 use-moment-countdown 用于反应或反应本机的钩子:https://github.com/BrooklinJazz/use-moment-countdown

      例如,您可以像这样制作一个 10 分钟的计时器:

      import React from 'react'
      
      import  { useCountdown } from 'use-moment-countdown'
      
      const App = () => {
        const {start, time} = useCountdown({m: 10})
        return (
          <div onClick={start}>
            {time.format("hh:mm:ss")}
          </div>
        )
      }
      
      export default App
      

      【讨论】:

        【解决方案4】:

        这是我的 5 分钟计时器:

        var start = moment("5:00", "m:ss");
        var seconds = start.minutes() * 60;
        this.interval = setInterval(() => {
            this.timerDisplay = start.subtract(1, "second").format("m:ss");
            seconds--;
            if (seconds === 0) clearInterval(this.interval);
        }, 1000);
        

        【讨论】:

          【解决方案5】:

          我想我也会把它扔出去(没有插件)。它倒计时 10 秒到未来。

              var countDownDate = moment().add(10, 'seconds');
          
                var x = setInterval(function() {
                  diff = countDownDate.diff(moment());
              
                  if (diff <= 0) {
                    clearInterval(x);
                     // If the count down is finished, write some text 
                    $('.countdown').text("EXPIRED");
                  } else
                    $('.countdown').text(moment.utc(diff).format("HH:mm:ss"));
          
                }, 1000);
          <script src="https://momentjs.com/downloads/moment.min.js"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
          <div class="countdown"></div>

          【讨论】:

          【解决方案6】:

          看看这个插件:

          moment-countdown

          moment-countdown 是一个很小的moment.js 插件,它集成了 Countdown.js。文件是here

          它是如何工作的?

          //from then until now
          moment("1982-5-25").countdown().toString(); //=> '30 years, 10 months, 14 days, 1 hour, 8 minutes, and 14 seconds'
          
          //accepts a moment, JS Date, or anything parsable by the Date constructor
          moment("1955-8-21").countdown("1982-5-25").toString(); //=> '26 years, 9 months, and 4 days'
          
          //also works with the args flipped, like diff()
          moment("1982-5-25").countdown("1955-8-21").toString(); //=> '26 years, 9 months, and 4 days'
          
          //accepts all of countdown's options
          moment().countdown("1982-5-25", countdown.MONTHS|countdown.WEEKS, NaN, 2).toString(); //=> '370 months, and 2.01 weeks'
          

          【讨论】:

          【解决方案7】:

          以下还需要moment-duration-format plugin

          $.fn.countdown = function ( options ) {
              var $target = $(this);
              var defaults = {
                  seconds: 0,
                  format: 'hh:mm:ss',
                  stopAtZero: true
              };
              var settings = $.extend(defaults, options);
              var eventTime = Date.now() + ( settings.seconds * 1000 );
              var diffTime = eventTime - Date.now();
              var duration = moment.duration( diffTime, 'milliseconds' );
              var interval = 0;
              $target.text( duration.format( settings.format, { trim: false }) );
              var counter = setInterval(function () {
                  $target.text( moment.duration( duration.asSeconds() - ++interval, 'seconds' ).format( settings.format, { trim: false }) );
                  if( settings.stopAtZero && interval >= settings.seconds ) clearInterval( counter );
              }, 1000);
          };
          

          使用示例:

          $('#someDiv').countdown({
              seconds: 30*60,
              format: 'mm:ss'
          });
          

          【讨论】:

            【解决方案8】:

            虽然我确信这不会被接受为这个非常古老的问题的答案,但我来到这里是为了寻找一种方法来解决这个问题。

            我创建了一个演示 here at codepen.io

            HTML:

            <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js" type="text/javascript"></script>
            <script src="https://cdn.rawgit.com/mckamey/countdownjs/master/countdown.min.js" type="text/javascript"></script>
            <script src="https://code.jquery.com/jquery-3.0.0.min.js" type="text/javascript"></script>
            <div>
              The time is now: <span class="now"></span>, a timer will go off <span class="duration"></span> at <span class="then"></span>
            </div>
            <div class="difference">The timer is set to go off <span></span></div>
            <div class="countdown"></div>
            

            Javascript:

            var now = moment(); // new Date().getTime();
            var then = moment().add(60, 'seconds'); // new Date(now + 60 * 1000);
            
            $(".now").text(moment(now).format('h:mm:ss a'));
            $(".then").text(moment(then).format('h:mm:ss a'));
            $(".duration").text(moment(now).to(then));
            (function timerLoop() {
              $(".difference > span").text(moment().to(then));
              $(".countdown").text(countdown(then).toString());
              requestAnimationFrame(timerLoop);
            })();
            

            输出:

            The time is now: 5:29:35 pm, a timer will go off in a minute at 5:30:35 pm
            The timer is set to go off in a minute
            1 minute
            

            注意:上面的第 2 行根据momentjs 更新,上面的第 3 行根据countdownjs 更新,由于requestAnimationFrame(),所有这些都以大约 60 FPS 的速度进行动画处理


            代码片段:

            或者你可以只看这段代码sn-p:

            var now = moment(); // new Date().getTime();
            var then = moment().add(60, 'seconds'); // new Date(now + 60 * 1000);
            
            $(".now").text(moment(now).format('h:mm:ss a'));
            $(".then").text(moment(then).format('h:mm:ss a'));
            $(".duration").text(moment(now).to(then));
            (function timerLoop() {
              $(".difference > span").text(moment().to(then));
              $(".countdown").text(countdown(then).toString());
              requestAnimationFrame(timerLoop);
            })();
            
            // CountdownJS: http://countdownjs.org/
            // Rawgit: http://rawgit.com/
            // MomentJS: http://momentjs.com/
            // jQuery: https://jquery.com/
            // Light reading about the requestAnimationFrame pattern:
            // http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
            // https://css-tricks.com/using-requestanimationframe/
            <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js" type="text/javascript"></script>
            <script src="https://cdn.rawgit.com/mckamey/countdownjs/master/countdown.min.js" type="text/javascript"></script>
            <script src="https://code.jquery.com/jquery-3.0.0.min.js" type="text/javascript"></script>
            <div>
              The time is now: <span class="now"></span>,
            </div>
            <div>
              a timer will go off <span class="duration"></span> at <span class="then"></span>
            </div>
            <div class="difference">The timer is set to go off <span></span></div>
            <div class="countdown"></div>

            要求:

            可选要求:

            此外,这里还有一些关于requestAnimationFrame() 模式的简单读物:

            我发现requestAnimationFrame() 模式比setInterval() 模式更优雅。

            【讨论】:

              【解决方案9】:

              时区。如果您希望来自世界各地的访问者获得相同的时间,您必须使用getTimezoneOffset() 来处理它们。

              试试这个http://jsfiddle.net/cxyms/2/,它适用于我,但我不确定它是否适用于其他时区。

              var eventTimeStamp = '1366549200'; // Timestamp - Sun, 21 Apr 2013 13:00:00 GMT
              var currentTimeStamp = '1366547400'; // Timestamp - Sun, 21 Apr 2013 12:30:00 GMT
              
              var eventTime = new Date();
              eventTime.setTime(366549200);
              
              var Offset = new Date(eventTime.getTimezoneOffset()*60000)
              
              var Diff = eventTimeStamp - currentTimeStamp + (Offset.getTime() / 2);
              var duration = moment.duration(Diff, 'milliseconds');
              var interval = 1000;
              
              setInterval(function(){
                duration = moment.duration(duration.asMilliseconds() - interval, 'milliseconds');
                $('.countdown').text(moment(duration.asMilliseconds()).format('H[h]:mm[m]:ss[s]'));
              }, interval);
              

              【讨论】:

                【解决方案10】:

                在最后一条语句中,您将持续时间转换为同时考虑时区的时间。我假设你的时区是 +530,所以 5 小时 30 分钟被添加到 30 分钟。您可以按照下面给出的方式进行操作。

                var eventTime= 1366549200; // Timestamp - Sun, 21 Apr 2013 13:00:00 GMT
                var currentTime = 1366547400; // Timestamp - Sun, 21 Apr 2013 12:30:00 GMT
                var diffTime = eventTime - currentTime;
                var duration = moment.duration(diffTime*1000, 'milliseconds');
                var interval = 1000;
                
                setInterval(function(){
                  duration = moment.duration(duration - interval, 'milliseconds');
                    $('.countdown').text(duration.hours() + ":" + duration.minutes() + ":" + duration.seconds())
                }, interval);
                

                【讨论】:

                • diffTime 已经是毫秒了,为什么在设置时长时要乘以 1000?
                • 不,它以秒为单位,因为 '1366549200000' 和 '1366547400' 以秒为单位。
                • new Date('Sun, 21 Apr 2013 13:00:00 GMT').getTime(); // = 1366549200000 in milliseconds
                • 如果有人发现上述 cmets 令人困惑(就像我一样),您不需要需要将 diffTime 乘以 1000,因为 .getTime 返回自 1970 年以来的毫秒数/ 01/01.
                • 非常感谢您指出这一点!让我更正一下,diffTime 以秒为单位,因为根据问题中给出的日期,“1366549200”和“1366547400”以秒为单位。
                猜你喜欢
                • 1970-01-01
                • 2021-08-25
                • 1970-01-01
                • 2020-11-27
                • 2014-12-13
                • 1970-01-01
                • 2022-11-11
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多