在年,月,日中得到2个日期的差,但是答案总是要过几天/月

时间:2019-03-16 10:45:55

标签: javascript date math

所以我试图做一个简单的计数器。我本质上是想找出Jun 5, 2011 00:00:00日期与现在之间的差异。然后以Years Months Days Hours Minutes Seconds的格式显示此日期。

我去timeanddate.com来计算差异。该网站非常可靠,它告诉我区别是7 years, 9 months, 11 days, 20 hours, 38 minutes, 4 seconds。但是我的代码告诉我它的7 years, 9 months, 13 days。我在做什么错,我该如何解决?现在有可以为我计算所有这些的函数吗?

<html>
<body>

<p id="demo"></p>

<script>
// Date to start on
var startDate = new Date("Jun 5, 2011 00:00:00").getTime();

// Update the count down every 1 second
var x = setInterval(function() {

  // Get todays date and time
  var now = new Date().getTime();
    
  // Find how long its been since the start date and now
  var distance = (now - startDate);
    
  // Time calculations
  var years = Math.floor(distance / 31536000000);
  var months = Math.floor((distance % 31536000000)/2628000000);
  var days = Math.floor(((distance % 31536000000) % 2628000000)/86400000);
    
  // Output the result in an element with id="demo"
  document.getElementById("demo").innerHTML = years + " years, " + months + " months, " + days + " days ";
    
}, 1000);
</script>

</body>
</html>

2 个答案:

答案 0 :(得分:1)

一年并不总是有365天。与您引用的网站相比,还有另一个区别:

通常,当人们说“今天恰好是1个月前”时,他们的意思是同一天。因此,3月14日恰好是2月14日之后的1个月,而4月14日恰好是3月14日之后的1个月。这意味着“月”的长度取决于您的参考点。在此示例中,第一个差异是28天(在非ap年),而第二个差异是31天。

可以通过以下代码实现与您在网站上获得的结果非常接近的解决方案:

function dateDiff(a, b) {
    // Some utility functions:
    const getSecs = dt => (dt.getHours() * 24 + dt.getMinutes()) * 60 + dt.getSeconds();
    const getMonths = dt => dt.getFullYear() * 12 + dt.getMonth();

    // 0. Convert to new date objects to avoid side effects
    a = new Date(a);
    b = new Date(b);
    if (a > b) [a, b] = [b, a]; // Swap into order 
    
    // 1. Get difference in number of seconds during the day:
    let diff = getSecs(b) - getSecs(a);
    if (diff < 0) {
        b.setDate(b.getDate()-1); // go back one day
        diff += 24*60*60; // compensate with the equivalent of one day
    }
    // 2. Get difference in number of days of the month
    let days = b.getDate() - a.getDate();
    if (days < 0) {
        b.setDate(0); // go back to (last day of) previous month
        days += b.getDate(); // compensate with the equivalent of one month
    }
    // 3. Get difference in number of months
    const months = getMonths(b) - getMonths(a); 
    return {
        years: Math.floor(months/12),
        months: months % 12,
        days, 
        hours: Math.floor(diff/3600),
        minutes: Math.floor(diff/60) % 24,
        seconds: diff % 60
    };
}

// Date to start on
var startDate = new Date("Jun 5, 2011 00:00:00");

// Update the count every 1 second
setInterval(function() {
    const diff = dateDiff(startDate, new Date);
    const str = Object.entries(diff).map(([name, value]) =>
        value > 1 ? value + " " + name : value ? value + " " + name.slice(0, name.length-1) : ""
    ).filter(Boolean).join(", ") || "0 seconds";  
    document.getElementById("demo").textContent = str;
}, 1000); 
<div id="demo"></div>

一些想法

当您一次增加一天的开始日期而不是结束日期时,此可变的月概念可能会导致意外结果:2019年2月28日到2019年4月1日之间的距离报告为1个月,4天。但是,当您在第一个日期添加1天时,差异将精确地报告为1个月。那三天去哪儿了? ,-)

因此,此解决方案(以及所引用的网站上的解决方案)在更改结束日期时效果很好。对于您希望通过输出中的“逻辑”步骤更改开始日期的情况,您将需要略有不同的算法。但是,当您更改结束日期时,您会得到这样的“跳跃”。

例如:2019年2月28日至2019年4月1日。差额是1个月+ 1天还是1个月+ 4天?如果您认为自己有答案,那么将其中一个日期的一天移到另一天的位置上……就没有办法获得一致的输出,每次一个日期移动1天时,输出也会跳1天。

答案 1 :(得分:0)

您的逻辑是错误的。 您的逻辑仅对没有a年的年份有效,因为leap年多了一天。 在您的问题中发生了两个leap年。所以两者会发生差异