【问题标题】:How to calculate long periods of time in JavaScript?如何在 JavaScript 中计算长时间?
【发布时间】:2015-08-24 08:44:00
【问题描述】:

我一直在查看从特定日期开始运行的倒计时计时器,但是我使用的代码似乎只显示了过去 15 年的时间长度,而没有更早的时间?这是一个非常简单的概念,我只是无法开始工作,诸如 2001 年 1 月 12 日之类的日期很好,但任何低于 1999 年的日期似乎都没有效果,而且天数限制在 5440 左右...

window.onload=function() {
  // Month,Day,Year,Hour,Minute,Second
  upTime('oct,01,0000,00:00:00'); // ****** Change this line!
}

function upTime(countTo) {
  now = new Date();
  countTo = new Date(countTo);
  difference = (now-countTo);

  days=Math.floor(difference/(60*60*1000*24)*1);
  hours=Math.floor((difference%(60*60*1000*24))/(60*60*1000)*1);
  mins=Math.floor(((difference%(60*60*1000*24))%(60*60*1000))/(60*1000)*1);
  secs=Math.floor((((difference%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1);

  document.getElementById('days').firstChild.nodeValue = days;
  document.getElementById('hours').firstChild.nodeValue = hours;
  document.getElementById('minutes').firstChild.nodeValue = mins;
  document.getElementById('seconds').firstChild.nodeValue = secs;

  clearTimeout(upTime.to);
  upTime.to=setTimeout(function(){ upTime(countTo); },1000);
}
#countup p {
  display: inline-block;
  padding: 5px;
  background: #FFA500;
  margin: 0 0 20px;
}
<div id="countup">
  It's been
  <p id="days">00</p>
  <p class="timeRefDays">days</p>
  <p id="hours">00</p>
  <p class="timeRefHours">hours</p>
  <p id="minutes">00</p>
  <p class="timeRefMinutes">minutes</p>
  <p id="seconds">00</p>
  <p class="timeRefSeconds">second</p>
</div>

【问题讨论】:

  • 可能是因为秒数超过整数限制,溢出
  • oct,01,0000,00:00:00 是一种奇怪的格式,它的工作原理简直是个奇迹;您需要使用像 yyyy-mm-dd hh:mm:ss 这样的标准格式。
  • 此外,如果您将差异转换回日期,则不必使用 Math.floor hacks 来获取日期设置。
  • 我没有看到问题here。能不能再查一下。我用 1901 设定年份
  • 为什么不用new Date(year, month, day, hours, minutes, seconds, milliseconds?否则,使用new Date("October 13, 2014 11:13:00"); 或 ISO 日期"2015-12-24T12:00:00" 之类的日期字符串作为w3schools.com/js/js_date_formats.asp 中的示例。此外,您不需要一次又一次地除以60*60*1000*24(和其他常量)。在每一步之后保存临时结果并将其用于下一步。更清晰更快捷

标签: javascript


【解决方案1】:

编辑:

我改进了 sn-p 并包含了额外的信息和链接。


问题在于您如何设置Date() 对象。去here查看不同的有效选项。

在你的情况下,你想做的是:

var countTo = new Date(year, month, day, hours, minutes, seconds);

但是您只传递了一个参数,在这种情况下,它应该是 UCT 中指定日期和 1970 年 1 月 1 日午夜之间的毫秒数。

另外,您可以先创建Date() 对象,然后单独设置不同的时间单位。这样做时,您必须使用setFullYear。我在答案的第一版中使用了setYear,这显然是错误的:它不仅已过时,而且还会导致 0-99 范围内的意外结果(正如 OP 在对此答案的评论中指出的那样) .

我已经清理了我的 sn-p 以使其对其他人也有用:

//we get a reference to the input elements
var i_year = document.getElementById('i_year');
var i_month = document.getElementById('i_month');
var i_day = document.getElementById('i_day');
var i_hours = document.getElementById('i_hours');
var i_minutes = document.getElementById('i_minutes');
var i_seconds = document.getElementById('i_seconds');
var button = document.getElementById('start_counting');

//we declare a new date, it will be the default value
var start_time = new Date();

//counting starts!
setInterval(function() {
  upTime();
}, 1000);

function upTime() {
  //if the inputs have any value, we update start_time
  if (i_year.value) start_time.setFullYear(i_year.value);
  //Months go from 0 to 11, so we substract 1
  if (i_month.value) start_time.setMonth(i_month.value - 1);
  if (i_day.value) start_time.setDate(i_day.value);
  if (i_hours.value) start_time.setHours(i_hours.value);
  if (i_minutes.value) start_time.setMinutes(i_minutes.value);
  if (i_seconds.value) start_time.setSeconds(i_seconds.value);

  //difference between both dates in ms
  var difference = (new Date() - start_time);

  var msSecond = 1000;
  var msMinute = 60 * msSecond;
  var msHour = 60 * msMinute;
  var msDay = 24 * msHour;

  var days = Math.floor(difference / msDay);
  difference -= days * msDay;

  var hours = Math.floor(difference / msHour);
  difference -= hours * msHour;

  var minutes = Math.floor(difference / msMinute);
  difference -= minutes * msMinute;

  var seconds = Math.floor(difference / msSecond);

  //updating the counter with the new values
  document.getElementById('days').firstChild.nodeValue = days;
  document.getElementById('hours').firstChild.nodeValue = hours;
  document.getElementById('minutes').firstChild.nodeValue = minutes;
  document.getElementById('seconds').firstChild.nodeValue = seconds;

}
#countup p {
  display: inline-block;
  padding: 5px;
  background: #FFA500;
  margin: 0 0 20px;
}

#target_date input {
  display: inline-block;
  width: 50px;
  margin-bottom: 10px;
}
<div id="target_date">
  <input type="text" id="i_year" placeholder="Year">
  <input type="text" id="i_month" placeholder="Month">
  <input type="text" id="i_day" placeholder="Day">
  <input type="text" id="i_hours" placeholder="Hours">
  <input type="text" id="i_minutes" placeholder="Minutes">
  <input type="text" id="i_seconds" placeholder="Seconds">
</div>
<hr>

<div id="countup">
  It's been
  <p id="days">0</p>
  <p>days</p>
  <p id="hours">0</p>
  <p>hours</p>
  <p id="minutes">0</p>
  <p>minutes</p>
  <p id="seconds">0</p>
  <p>second</p>
</div>

日期对象支持的年份范围大约是 1970 年之前和之后的 285,616 年。这是由于 ECMAScript 日期对象支持的实际时间范围所致。阅读herehere 了解它。

最后一件事。如果您深入研究该主题,您会发现批评 javascript 处理计算日期之间差异的方式。并非所有都是正确的(例如,您可以在 sn-p javacript does 中检查闰年)。但是,如果您需要完全准确的结果,那么将时间追溯到数千年前将是有问题的。不仅因为技术方面,还因为 人类 方面(历史、时区、夏令时等的日历变化)。

有用于这种计算的特定于 javascript 的库。我认为Moment.js 是最受欢迎的之一。

希望对你有帮助!

【讨论】:

  • 这很棒,并且可以使用多年,直到 1000,但是当我尝试 0001 并且以 0 开头的年份不起作用并且 js 假定 0100 为 1915,对此有任何帮助
  • 我无法重现这种行为。如果我将年份设置为setYear(1),它会进行正确的计算。玩fiddle 并告诉我们。
  • jsfiddle.net/w7LLLz83 尝试这个,将年份设置为 1 不会产生正确答案,这显示过去 114 年,而不是应该是 2014 年
  • @L.Smith:我的错,我更新了sn-p,我们必须使用setFullYear()
猜你喜欢
  • 1970-01-01
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-20
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
相关资源
最近更新 更多