使用Javascript计算两个日期之间的持续时间

时间:2012-10-29 12:18:00

标签: javascript

我基本上想要两个日期,即:

 var startDate = new Date("01/01/2001 01:00:00");
 var currentDate = new Date();

然后我希望通过从startDate中减去currentDate来获得持续时间,并以以下形式显示: a b year(s)c day(s)d hour(s) )e秒(s)

到目前为止,我的问题是如果你采用捷径,即:

var duration = currentDate.getTime() - startDate.getTime();
var seconds = duration / 1000;
var minutes = duration / 1000 / 60;

等...

然后你会得到一个错误的持续时间,因为,例如,几个月并不总是30天,年份并不总是365天(闰年),等等。更不用说当我这样做的时候它大概是关闭的一年。

我已经浏览了网络并通过StackOverflow上的各种帖子,但我找不到一个JavaScript方法的工作示例,它准确地从另一个日期中减去一个日期并允许您获取详细信息(年,月,日,从结果日期开始的小时,分​​钟,秒。

有一个网站已经可以完全按照我的意愿执行此操作:http://www.timeanddate.com

6 个答案:

答案 0 :(得分:2)

如果你想要一个“正确”的结果,因为几个月有不同的天数,没有明显的简单解决方案。

但与此同时,人类大脑在大日期范围内变得越来越邋..所以“1年11个月”几乎与“近两年”一样好。因此,在开始使用100%正确的解决方案之前,请先假设自己假装结果是否足够好,并且只需使用30天。

如果真的不是一个选择:摆脱小时和分钟;他们只会让人困惑。创建两个从午夜开始的日期(即HH:MM:SS是00:00:00)。

现在的问题是他们之间有多少天,几个月和几年?那要看。 6月1日和8月31日之间的时间差不多是两个月,但两个日期之间没有一个月。它是61 days, 0 months。还是1 month, 30 days?哪个是“正确的”?

数学正确的解决方案将为您提供长达61天的差异结果,用户会感到恼火。

人类解决方案在数学上并不正确,因此您最终必须编写假想人类时间感的启发式算法。

这就是为什么如此多的网站说“超过一个月”,如果某些日期相差超过30天并继续“半年”,“一年”(330至380天之间的任何事情)和“更多”他们使用邋human的人类大脑而不是试图提出一个“确切”的结果(a)也没有真正有用,并且b)没有人真正同意“确切”是什么应该是的意思)。

答案 1 :(得分:1)

我几天来一直在努力解决这个问题。最后做了一些我觉得有用的东西它现在看起来像垃圾,邋comments的评论和愚蠢的var名称,而Ill明天会做清理。但我想如果你需要它我会发布它。

编辑:我清理了代码并对其进行了精简。请在此处查看:https://gist.github.com/4705863

EDIT2:该死的,发现了一个错误。我在上面。 修正了错误,现在运行正常!

    // Time difference function
function timeDiff(start, end) {
    //today, now!
    //Get the diff
    var diff = end - start;
    //Create numbers for dividing to get hour, minute and second diff
    var units = [
    1000 * 60 * 60 *24,
    1000 * 60 * 60,
    1000 * 60,
    1000
    ];

    var rv = []; // h, m, s array
    //loop through d, h, m, s. we are not gonna use days, its just there to subtract it from the time
    for (var i = 0; i < units.length; ++i) {
        rv.push(Math.floor(diff / units[i]));
        diff = diff % units[i];
    }

    //Get the year of this year
    var thisFullYear = end.getFullYear();
    //Check how many days there where in last month
    var daysInLastMonth = new Date(thisFullYear, end.getMonth(), 0).getDate();
    //Get this month
    var thisMonth = end.getMonth(); 
    //Subtract to get differense between years
    thisFullYear = thisFullYear - start.getFullYear();
    //Subtract to get differense between months
    thisMonth = thisMonth - start.getMonth();
    //If month is less than 0 it means that we are some moths before the start date in the year.
    // So we subtract one year, and add the negative number (month) to 12. (12 + -1 = 11)
    subAddDays = daysInLastMonth - start.getDate();
    thisDay = end.getDate();
    thisMonth = thisMonth - 1;
    if(thisMonth < 0){
        thisFullYear = thisFullYear - 1;
        thisMonth = 12 + thisMonth;
        //Get ends day of the month
    }
    //Subtract the start date from the number of days in the last month, add add the result to todays day of the month
    subAddDays = daysInLastMonth - start.getDate();
    subAddDays = thisDay + subAddDays;


    if(subAddDays >= daysInLastMonth){
        subAddDays = subAddDays - daysInLastMonth;
        thisMonth++;
        if (thisMonth > 11){
            thisFullYear++;
            thisMonth = 0;
        }
    }
    return {
        years: thisFullYear,
        months: thisMonth,
        days: subAddDays,
        hours: rv[1],
        minutes: rv[2],
        seconds: rv[3]
    };
}
//The start date/From date. Here i add one hour to offset it. 
//var start = new Date(1814, 3, 20, 1);
//The end date. today, now!
//var end = new Date();
//Get the difference
//var d = timeDiff(start, end);
// Log that bitch
//console.log('years: '+ d.years + '. months: '+ d.months + '. days: ' + d.days + '. hours:' +d.hours+ '. minutes:' + d.minutes + '. seconds: ' + d.seconds);

答案 2 :(得分:0)

http://www.w3schools.com/jsref/jsref_obj_date.asp

myDate.UTC() // get the number of milliseconds since the Unix epoch

所以

delta_ms = laterDate.UTC() - earlierDate.UTC();
delta_days = Math.round(delta_ms / (1000 * 60 * 60 * 24));

如果你想要几个月和几年,你需要指定你是否想要日历差异(例如5月1日到6月1日是1个月,但是2月28日到3月30日是......?),或者是“标准”年份比如365天和30天等等。

即使看起来应该如此,这也不是直截了当的。例如,在金融领域,至少有5种方法可以计算两个日期之间的差距,使用标准月份与否,以及是否使用标准日期。在某个日期之后生成日期很容易(2月1日之后的1个日历月是3月1日),但后退不是,因为映射不是1:1。

另外,请注意,这是一个绝对值,不需要调整闰年,闰秒,夏令时,时区和所有其他时间格式的短暂时间。

答案 3 :(得分:0)

您也可以考虑这些案例。 考虑2个日期2nd Mar 20085th Jun 2013

             Mar
2008  ________###########################
2009  ###################################
2010  ###################################
2011  ###################################
2012  ####################################  (leap)
2013  ###############--------------------
                  Jun

您可以减去两者之间的年份(即2009年,2010年,2011年,2012年)。现在2012年是闰年,但无关紧要,因为它将计入而不是

Years = 4

现在,你还剩下这个

            2 
Mar 08  ____################################
Apr 08 ####################################
May 08 #####################################
Jun 08 ####################################
Jul 08 #####################################
Aug 08 #####################################
Sep 08 ####################################
Oct 08 #####################################
Nov 08 ####################################
Dec 08 #####################################
Jan 12 #####################################
Feb 12 ###################################
Mar 12 #####################################
Apr 12 ####################################
May 12 #####################################
Jun 12 #########----------------------------
                5

算上整整几个月。它们包含多少天并不重要。它们被计入而非

Months = 14

           2 
Mar 08  ____################################
Jun 12  #########----------------------------
                5

现在计算Mar2008和Jun2012的剩余天数(不包括结束日期)。这里的计数是29(3月)+ 4(6月)= 33。

Days = 33

但33天似乎很奇怪,因为它可以转换为1个月+几天。如果发生这种情况,问题出现在哪个月可以选择 - 3月(31天),6月(30天)或仅减少30天以增加一个月。我认为在考虑巨大差异时,这几乎不重要。如果我们考虑三月,那么差异将是

4 Years 15 Months 2 Days或只是5 Years 3 Months 2 Days

同样的方法可以持续一段时间。

<强> EDITED

Let `date1` be greater than `date2`
Let max(month) gives the total days in the month

years = date1.year - date2.year - 1;
months = date1.month - date2.month - 1;
days = (max(date2.month) - date1.day) + (date2.day - 1);
if(days >= 30)       //Here you can take totals days in date1 or date2
{
    month++;
    days-=30;
}
while(month >= 12)      //Here month can reach a value of 24 because it can be incremented above too
{
    years++;
    month-=12;
}
print("Difference is " + years + " years " + month + " months " + days + " days");

答案 4 :(得分:0)

将来为自己留下答案

只需使用时刻及其持续时间插件

并使用

moment.duration(moment('then').diff(moment('now'))).format('d [Days] hh:mm:ss')

它有效

答案 5 :(得分:-1)

var years = currentDate.getYear() - startDate.getYear();
var months = currentDate.getMonth() - startDate.getMonth();
...