【问题标题】:Percentage of time left with two given timestamps Javascript两个给定时间戳Javascript剩余的时间百分比
【发布时间】:2019-01-23 22:10:11
【问题描述】:

我有两个 Date() 时间,我试图使用它们之间的差异来设置进度条的宽度,当时间之间没有更多差异时,它会从 100% 缩小到 0%,但我得到了非常奇怪的结果。

这就是我目前正在尝试的方式(它在 React 中被拆分为几个不同的函数,所以我只包含相关的代码):

首先,我设置了目标日期时间,将endDate 设置为接下来 24 小时内(例如晚上 10 点)的最开始...

this.endDate = new Date();

if (this.props.data.end_hr === 0) {
    this.endDate.setHours(24, 0, 0, 0);
} else {
    this.endDate.setHours(this.props.data.end_hr);
}
this.endDate.setMinutes(0);
this.endDate.setSeconds(0);

this.countdown = setInterval(this.timeRemaining, 1000);

然后在每秒触发的timeRemaining 函数中,我获取当前日期时间并计算它们之间的差异。最后,我正在尝试计算发送到进度条 CSS 宽度属性的百分比...

let now = new Date().getTime();
let diff = this.endDate - now;

let percent =
  Math.round(((diff / this.endDate) * 100000000 * 2) / 100) + '%';

this.countdownProgress.style.width = percent;

diff 100% 正确,但百分比错误。

我已经尝试了各种不同的方法来计算我能想到的百分比,但没有任何效果,上面的方法是我能得到的最接近的方法。

谁能告诉我哪里出错了?

编辑:@Danziger 的回答以我想使用的方式实现。这将开始时间设置为晚上 10 点,结束时间设置为午夜。

事实证明它确实可以正常工作,所以我的代码中肯定有其他东西导致了这个问题。再次感谢 Danziger 让我看到光明!

const progressBar = document.getElementById('progressBar');
const progressText = document.getElementById('progressText');

const startDate = new Date();
startDate.setHours(22);
startDate.setMinutes(0);
startDate.setSeconds(0);

const endDate = new Date();
endDate.setHours(24,0,0,0);
endDate.setMinutes(0);
endDate.setSeconds(0);

const range = endDate - startDate;

function updateCountdown() {
  const diff = Math.max(0, endDate - new Date());
  
  progressBar.style.width = `${ 100 * diff / range }%`;
  progressText.innerText = `${ `000${ Math.ceil(diff / 1000) }`.slice(-4) } seconds`
  
  if (diff >= 0) {
    requestAnimationFrame(updateCountdown);
  }  
}

updateCountdown();
body {
  font-family: monospace;
}

.progressBar__base {
  position: relative;
  height: 32px;
  border: 3px solid black;
  margin: 0 0 8px;
}

.progressBar__progress {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: blue;
}
<div class="progressBar__base">
  <div class="progressBar__progress" id="progressBar"></div>
</div>

<div id="progressText"></div>

【问题讨论】:

  • 当您要计算 diff / (endDate - startDate) 时,您正在计算 diff / endDate - 即 diffstartDateendDate 之间总时间的百分比。此外,使用您当前对diff 的定义将为您提供一个递减 进度条。如果您想要增加,请改用diff = now - startDate
  • 刚刚尝试过 - Math.round(diff / (this.endDate - now)) 并且我收到了 1 回复?有问题的 endDate 目前设置为英国午夜,目前是 22:29。
  • 啊,所以我需要提供开始日期?我不这样做。只有 endDate 和当前时间
  • 如果没有开始日期,就无法知道已经取得了多少进展。这就像在问“鉴于您已经旅行了 200 英里,您到多伦多的旅程已经完成了多少?
  • 我们都去过那里:p

标签: javascript percentage


【解决方案1】:

您需要将diff 除以某个范围,在这种情况下,是您最初的时间差(这是它的最大值),而不是endDate

const progressBarDescending = document.getElementById('progressBarDescending');
const progressBarAscending = document.getElementById('progressBarAscending');
const progressTextDescending = document.getElementById('progressTextDescending');
const progressTextAscending = document.getElementById('progressTextAscending');

const startDate = new Date();
const endDate = new Date(startDate.getTime() + 10000); // + 10 seconds
const range = endDate - startDate;

function updateCountdown() {
  const diff = Math.max(0, endDate - new Date());
  
  progressBarDescending.style.width = `${ 100 * diff / range }%`;
  progressBarAscending.style.width = `${ 100 - 100 * diff / range }%`;
  
  progressTextDescending.innerText = `${ `000${ Math.ceil(diff / 1000) }`.slice(-4) } seconds left`;
  progressTextAscending.innerText = `${ `000${ Math.floor((range - diff) / 1000) }`.slice(-4) } seconds elapsed`;
  
  if (diff >= 0) {
    requestAnimationFrame(updateCountdown);
  }  
}

updateCountdown();
body {
  font-family: monospace;
}

.progressBar__base {
  position: relative;
  height: 32px;
  border: 3px solid black;
  margin: 16px 0 8px;
}

.progressBar__progress {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: blue;
}
<div class="progressBar__base">
  <div class="progressBar__progress" id="progressBarDescending"></div>
</div>

<div id="progressTextDescending"></div>

<div class="progressBar__base">
  <div class="progressBar__progress" id="progressBarAscending"></div>
</div>

<div id="progressTextAscending"></div>

所以,假设您从startDate = 5endDate = 15 开始倒计时,那么您的range = 10

如果您想在5 秒后更新diff,那就是diff = endDate - now = endDate - 10 = 5。那么,progress = 100 * diff / range = 100 * 5 / 10不是 progress = 100 * diff / endDate = 100 * 5 / 15

【讨论】:

  • 非常感谢。在导入开始时间(这是必需的,因为这是一个预定的事件)并按照您的方法后,它现在似乎显示了正确的百分比,但它正在上升。即当我需要它输出 60% 时它显示 40%,因为我的条形图从右向左减小。知道我如何翻转结果吗?
  • 忽略最后一条评论,它正在倒计时,但它似乎没有显示正确的百分比。开始时间和结束时间之间的差异设置为实时相隔 2 小时(开始时间为晚上 10 点,结束时间为午夜)(英国)。但是现在晚上 11 点,它说只剩下 34%,而应该是 50% 左右。有什么想法吗?
  • 如果您进行了任何更改,能否将您问题中的代码更新为您目前拥有的代码?
  • 嘿兄弟,我刚刚编辑了您的代码以使用指定的开始和结束时间,并将其添加到我原来的问题中。它确实可以正常工作,所以我必须在我的代码中的某个地方发生其他事情,这会导致它失败。
【解决方案2】:

我认为您的问题是您没有定义的startTime 用作参考,而是使用now

如果你有startTime,你会这样做:

let now = new Date().getTime();
let totalTime = endTime - startTime;
let progress = now - startTime;
let percentage = (progress / totalTime) * 100;

我实际上不确定你自己的计算得到了什么价值。

【讨论】:

  • endDate 将始终是下一个 24 小时内的任何时间。因此,如果现在是 5:30,那么 endDate 可能是 7:00。 endDate 总是在未来。
  • 谢谢,所以我也需要提供开始时间吗?我以为我可以只使用 endDate 和当前时间来做到这一点,但我猜这不可能?
  • 如果你想一想,如果你只有当前时间和结束时间,你会占多少百分比?您当前的时间将代表什么范围内的进展?在达到 100% 之前,您是否总是处于 0% 的进度?
  • 您还可以在考试成绩之间进行类比。它们通常在 0 到某个分数之间。 5/10 的测试分数意味着您在 0 分和 10 分的范围内获得了 5 分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 2019-08-23
  • 2016-12-06
  • 2011-06-08
  • 1970-01-01
  • 2014-06-01
相关资源
最近更新 更多