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

2024-03-07

我在用Moment.js https://momentjs.com/docs/#/displaying/fromnow/检索下周五 (moment().day(5).format();)成功运行并打印2020-06-26T13:19:01+04:00到控制台

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

如何计算到达特定日期所需的时间(以天、小时、分钟和秒为单位)?


设置有效的结束日期 首先,您需要设置一个有效的结束日期。这应该是 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 {
  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。 接下来,我们将使用设置时间间隔每秒执行一个匿名函数。该函数将执行以下操作:

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

此时,唯一剩下的步骤是像这样运行时钟:

initializeClock('clockdiv', deadline);

恭喜!现在,您只需 18 行 JavaScript 就拥有了一个基本时钟。

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

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

消除初始延迟在时钟中,我们使用 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;

to this:

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何计算到达某一天的剩余时间(天、小时、分钟、秒)? 的相关文章

随机推荐

  • 简单文件复制的正确 Java 配置是什么

    我对 Spring 非常陌生 对 Spring Integration 更陌生 所以如果这是一个非常基本的问题 我深表歉意 我想构建一个非常基本的日志文件处理器来学习诀窍 与此非常相似 example http forum spring i
  • Python:用于从各种格式加载音频元数据的功能最丰富的库是什么?

    我正在寻找一个功能丰富的优秀库 用于从各种音频格式 MP3 FLAC OGG WAV 等 读取元数据 我已经看过 Mutagen 但文档几乎不存在 而且它似乎无法加载基本信息 例如艺术家和音频标题 艺术家和音频标题编码是否正确 它无法满足哪
  • AppCode 工作区和 TFS 命令行客户端工具

    我可以使用 AppCode 创建一个工作区 并成功签入和签出 TFS 这一切都很好 但是当我使用TFS 的跨平台命令行客户端 http msdn microsoft com en us library gg413282 28v vs 100
  • perl 如何将 perl 脚本的列表形式系统调用的 STDOUT 附加到文件

    My bosswrap pl将生成元素中包含空格的任意数组 它通过系统调用重复发送数组wrapped pl 它根据数组创建 STDOUT 随后 bosswrap pl必须附加 STDOUTwrapped pl到一个文件bosswrap pl
  • Android - 拍摄照片并通过 Intent 使用自定义名称将其保存到自定义目的地

    我有一个程序可以通过 Intent 打开相机来拍照 这么多部分已经可以正常工作了 但是 我希望它将它保存到具有特定文件名的特定文件夹中 文件名是可选的 但它确实很有帮助 这就是我到目前为止所拥有的 这是打开相机的代码行 TODO camer
  • Alfresco:定义新的控制参数

    我正在开发一个自定义表单控件 需要定义一个名为字符串类型的新控制参数helptext 我了解如何在我的 share config custom 中调用它 如何在我的自定义表单控件中使用它 但不知道如何最初声明它 我看到其他控制参数使用以下格
  • 如何在blazor web assembly中获取id_token

    我有一个带有 oidc 身份验证的 Blazor WebAssembly 最新 3 2 0 应用程序 asp net 身份验证提供了一种获取 accessToken 的方法 但看不到任何访问我的场景所需的 id token jwt 的方法
  • 生成带前导 0 的整数

    我有一个项目 我必须生成从 00000 到 99999 的随机数 随机化并不是让我陷入困境的地方 但事实上它总是需要 5 个字符 所以当它生成数字 14 时 我希望它是 00014 实现这一目标的最佳方法是什么 sprintf http d
  • 如何仅删除 a:before 中的下划线?

    我有一组样式链接 使用 before应用箭头 它在所有浏览器中看起来都不错 但是当我将下划线应用于链接时 我不想在链接上有下划线 before部分 箭头 请参阅 jsfiddle 例如 http jsfiddle net r42e5 1 h
  • Matlab 的 slice() 函数无法按预期工作

    我想在 13 处绘制离散的 2D 图像z地点位于 4 4 52 使用以下代码行 a 100 mesh x mesh y mesh z meshgrid 1 1 100 1 1 100 4 4 52 a unifdist 0 b unifdi
  • 将 DropDownListFor 助手绑定到字典

    我正在创建并填充字典 并希望通过使用将其绑定到下拉列表下拉列表的 http msdn microsoft com en us library ee703573 aspx辅助方法 我如何映射该词典的key and value到下拉菜单 看起来
  • 如何确定拨打的电话是本地电话还是 STD 或 ISD

    我正在开发一个应用程序 需要跟踪用户发出的拨出呼叫 我可以通过使用广播接收器来跟踪 我还想检测呼叫是本地呼叫还是 STD 或 ISD 但我无法检测到 假设 你知道哪个State 电信界 正在拨出电话 然后你只需要检查你的地方州 电信界 与去
  • Elastic Beanstalk .ebextensions 在 WAR 中被忽略

    我正在尝试改变client max body size我的 Elastic Beanstalk NGINX 反向代理的属性 以便允许上传更大的 JPEG 文件 因此 我将文件夹 ebextensions 添加到 WAR 文件的根目录中 WA
  • 如何在Android模拟器上模拟速度?

    有没有办法在Android模拟器上模拟速度 edit 这样做的目的是测试 getSpeed 方法 Example 我想将设备设置为每小时 20 英里 是的 你可以这么做 如果您使用 Eclipse 开发应用程序 则必须进入 DDMS 视角
  • Titan 警告:查询需要迭代所有顶点

    下面我补充一下cdate索引和一些数据 baseGraph makeKey cdate dataType Long class indexed Vertex class make for int i 0 i lt 20 i Vertex p
  • C++11 std::to_string(double) - 没有尾随零

    今天尝试了C 11 STL的一些新功能 遇到了std to string 可爱的 可爱的一组功能 创建一个 stringstream 对象来进行一次双精度到字符串的转换对我来说总是显得有些过分 所以我很高兴我们现在可以做这样的事情 std
  • 无法在 Google 云端硬盘文件夹中创建虚拟环境

    我正在使用 Google Drive 保留我的代码项目的副本 以防我的计算机死机 我也在使用 GitHub 但不在某些私人项目上 但是 当我尝试使用创建虚拟环境时virtualenv 我收到以下错误 PS C users fchatter
  • 如何保护 phpMyAdmin

    我注意到我的网站有一些奇怪的请求试图找到 phpmyadmin 例如 phpmyadmin pma etc 现在我已经通过 apt 在 Ubuntu 上安装了 PMA 并且想通过不同于 phpmyadmin 的网址访问它 我可以做什么来改变
  • Jenkins 中的条件构建后步骤(理想情况下没有插件)

    如果我理解正确的话 我可以使用这个插件来设置构建步骤的条件 https wiki jenkins ci org display JENKINS Conditional BuildStep Plugin https wiki jenkins
  • 如何计算到达某一天的剩余时间(天、小时、分钟、秒)?

    我在用Moment js https momentjs com docs displaying fromnow 检索下周五 moment day 5 format 成功运行并打印2020 06 26T13 19 01 04 00到控制台 现