如何计算到达某一天的剩余时间(以天、小时、分钟和秒为单位)?

How to calculate the time left in days, hours, minutes, and seconds left to reach certain day?

我正在使用 Moment.js 检索下一个星期五 (moment().day(5).format();),它成功运行并向控制台打印 2020-06-26T13:19:01+04:00

现在我想显示一个倒数计时器,显示距离到达特定日期还剩多长时间,倒数包括以天、小时、分钟和秒为单位的剩余时间:

如何以天、小时、分钟和秒为单位计算到达特定日期还剩多少时间?

您可以使用 moment.duration 获取持续时间对象,它可以为您提供以天、小时、分钟和秒为单位的值。只需获取天数并从持续时间中减去它们,然后获取小时数并减去它们等等。

function getRemaining (ts) {
  const now = moment();
  const then = moment(ts);
  const diff = then.diff(now);
  const dur = moment.duration(diff);

  let parts = [];
  for (const part of ['days', 'hours', 'minutes', 'seconds']) {
    const d = dur[part]();
    dur.subtract(moment.duration(d, part));
    parts.push(d);
  }
  return parts;
}

const ts = '2020-06-25 16:20';
const rem = getRemaining(ts);

console.log (rem)

setInterval(() => {
    const rem = getRemaining(ts);
    updateDom(rem)
}, 100)
.w {
  background: #5EC098;
  width: 64px;
  height: 64px;
  float: left;
  border-radius: 4px;
  margin: 4px;
}

.n {
  position: absolute;
  margin: 8px;
  background: rgba(0, 0, 0, .5);
  width: 48px;
  height: 48px;
  line-height: 48px;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.2.1/moment.min.js"></script>
<div class="w">
  <div class="n" id="days">
  </div>
</div>
<div class="w">
  <div class="n" id="hours">
    
  </div>
</div>
<div class="w">
  <div class="n" id="minutes">
    
  </div>
</div>
<div class="w">
  <div class="n" id="seconds">
    
  </div>
</div>

<script>
function updateDom(vals) {
    let i=0;
    for (const part of ['days', 'hours', 'minutes', 'seconds']) {
    const ele = document.getElementById(part);
    ele.innerText = vals[i++];
  }
}
</script>

设置有效的结束日期 首先,您需要设置一个有效的结束日期。这应该是 JavaScript 的 Date.parse() 方法可以理解的任何格式的字符串。例如:

const deadline = '2015-12-31';

短格式:

const deadline = '31/12/2015';

或者,长格式:

const deadline = 'December 31 2015';

这些格式中的每一种都允许您指定确切的时间和时区(或者在 ISO 日期的情况下与 UTC 的偏移量)。例如:

const deadline = 'December 31 2015 23:59:59 GMT+0200';

计算剩余时间 下一步是计算剩余时间。我们需要编写一个函数,它接受一个表示给定结束时间的字符串(如上所述)。然后我们计算那个时间和当前时间之间的差异。这是它的样子:

 function getTimeRemaining(endtime){
  const total = Date.parse(endtime) - Date.parse(new Date());
  const seconds = Math.floor( (total/1000) % 60 );
  const minutes = Math.floor( (total/1000/60) % 60 );
  const hours = Math.floor( (total/(1000*60*60)) % 24 );
  const days = Math.floor( total/(1000*60*60*24) );

  return {
    total,
    days,
    hours,
    minutes,
    seconds
  };
}

首先,我们要创建一个变量总计,以保存截止日期前的剩余时间。 Date.parse() 函数将时间字符串转换为以毫秒为单位的值。这使我们能够相互减去两次并得到两者之间的时间量。

const total = Date.parse(endtime) - Date.parse(new Date());

将时间转换为可用格式 现在我们要将毫秒转换为天、小时、分钟和秒。以秒为例:

const seconds = Math.floor( (t/1000) % 60 );

让我们来分解一下这里发生的事情。

  1. 将毫秒除以 1000 以转换为秒:(t/1000)
  2. 将总秒数除以 60 并获取余数。您不需要所有的秒数,只需要计算分钟后剩余的秒数:(t/1000) % 60
  3. 四舍五入到最接近的整数。这是因为你想要完整的秒数,而不是几分之一秒:Math.floor( (t/1000) % 60 )

重复此逻辑将毫秒转换为分钟、小时和天。

将时钟数据作为可重用对象输出

准备好天数、小时数、分钟数和秒数后,我们现在准备好 return 将数据作为可重用对象:

return {
  total,
  days,
  hours,
  minutes,
  seconds
};

此对象允许您调用您的函数并获取任何计算值。这是您如何获得剩余分钟数的示例:

getTimeRemaining(deadline).minutes

方便吧?

.. 显示时钟并在它到达零时停止

现在我们有一个函数可以显示剩余的天数、小时数、分钟数和秒数,我们可以构建我们的时钟了。首先,我们将创建以下 HTML 元素来保存我们的时钟:

<div id="clockdiv"></div>

然后我们将编写一个函数,在我们的新 div:

中输出时钟数据
function initializeClock(id, endtime) {
  const clock = document.getElementById(id);
  const timeinterval = setInterval(() => {
    const t = getTimeRemaining(endtime);
    clock.innerHTML = 'days: ' + t.days + '<br>' +
                      'hours: '+ t.hours + '<br>' +
                      'minutes: ' + t.minutes + '<br>' +
                      'seconds: ' + t.seconds;
    if (t.total <= 0) {
      clearInterval(timeinterval);
    }
  },1000);
}

这个函数有两个参数。这些是包含我们时钟的元素的 ID,以及倒计时的结束时间。在函数内部,我们将声明一个时钟变量并使用它来存储对我们的时钟容器 div 的引用。这意味着我们不必继续查询 DOM。 接下来,我们将使用 setInterval 每秒执行一个匿名函数。此函数将执行以下操作:

计算剩余时间。 将剩余时间输出到我们的div。 如果剩余时间为零,则停止计时。

此时,唯一剩下的步骤是 运行 时钟,如下所示:

initializeClock('clockdiv', deadline);

恭喜!您现在只需 JavaScript.

的 18 行就拥有了一个基本时钟

准备显示时钟 在设计时钟样式之前,我们需要稍微改进一下。

删除初始延迟,以便您的时钟立即显示。 使时钟脚本更有效率,这样它就不会不断地重建整个时钟。 根据需要添加前导零。

移除初始延迟 在时钟中,我们使用 setInterval 每秒更新一次显示。这在大多数情况下都很好,除了在开始时会有一秒钟的延迟。要消除此延迟,我们必须在间隔开始前更新一次时钟。

让我们将传递给 setInterval 的匿名函数移动到它自己的单独函数中。我们可以将此函数命名为 updateClock。在 setInterval 之外调用一次 updateClock 函数,然后在 setInterval 内部再次调用它。这样,时钟就不会延迟显示了。

在你的 JavaScript 中,替换为:

const timeinterval = setInterval(() => { ... },1000);

有了这个:

function updateClock(){
  const t = getTimeRemaining(endtime);
  clock.innerHTML = 'days: ' + t.days + '<br>' +
                    'hours: '+ t.hours + '<br>' +
                    'minutes: ' + t.minutes + '<br>' +
                    'seconds: ' + t.seconds;
  if (t.total <= 0) {
    clearInterval(timeinterval);
  }
}

updateClock(); // run function once at first to avoid delay
var timeinterval = setInterval(updateClock,1000);

避免不断重建时钟 我们需要使时钟脚本更有效率。我们只想更新时钟中的数字,而不是每秒重建整个时钟。实现这一点的一种方法是将每个数字放在一个 span 标签中,并且只更新这些 span 的内容。

这是 HTML:

<div id="clockdiv">
    Days: <span class="days"></span><br>
    Hours: <span class="hours"></span><br>
    Minutes: <span class="minutes"></span><br>
    Seconds: <span class="seconds"></span>
</div>

现在让我们获取对这些元素的引用。在定义时钟变量后立即添加以下代码

const daysSpan = clock.querySelector('.days');
const hoursSpan = clock.querySelector('.hours');
const minutesSpan = clock.querySelector('.minutes');
const secondsSpan = clock.querySelector('.seconds');

接下来,我们需要更改 updateClock 函数以仅更新数字。新代码将如下所示:

function updateClock(){
    const t = getTimeRemaining(endtime);

    daysSpan.innerHTML = t.days;
    hoursSpan.innerHTML = t.hours;
    minutesSpan.innerHTML = t.minutes;
    secondsSpan.innerHTML = t.seconds;

    ...
}

添加前导零 现在时钟不再每秒重建,我们还有一件事要做:添加前导零。例如,不是让时钟显示 7 秒,而是显示 07 秒。一种简单的方法是在数字的开头添加一串“0”,然后切掉最后两位数字。

例如,要将前导零添加到“秒”值,您可以更改为:

secondsSpan.innerHTML = t.seconds;

对此:

secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);

如果愿意,您也可以在分钟和小时前添加前导零。如果你已经走到这一步,恭喜你!您的时钟现在可以显示了。

注意:您可能需要在 CodePen 中单击“Re运行”才能开始倒计时。