4

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

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

然后我想通过减去并以以下形式显示持续时间startDatecurrentDatea years b month(s) c day(s) d hours(s) e second(s)

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

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

ETC...

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

我浏览了网络并浏览了 StackOverflow 上的各种帖子,但我找不到一个 JavaScript 方法的工作示例,该方法可以准确地从另一个日期减去一个日期并允许您获取详细信息(年、月、日、小时、分钟, 第二) 从结果日期开始。

有一个网站已经可以完全按照我的意愿做到这一点:http ://www.timeanddate.com

4

6 回答 6

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 天之间)和“超过一年”,那么许多网站会说“超过一个月”的原因“等等。他们利用草率的人脑来发挥自己的优势,而不是试图提出一个“精确”的结果(这a)也没有真正的帮助,b)没有人真正同意“精确”应该是什么意思)。

于 2012-10-29T12:33:09.620 回答
1

几天来,我一直在努力解决这个确切的问题。终于做了一些我认为有用的东西。现在看起来像废话,草率的评论和愚蠢的 var 名称,明天我会进行清理。但我想无论如何我都会发布它以防万一你需要它。

编辑:我清理了代码并做了一个要点。在这里查看:https ://gist.github.com/4705863

EDIT2:该死的,发现了一个错误。我在上面。修复了BUG,现在可以正常使用了!

    // 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);
于 2013-02-04T01:57:52.090 回答
1

留给自己未来的答案

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

并使用

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

有用

于 2017-03-22T18:17:40.860 回答
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。

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

于 2012-10-29T12:23:06.840 回答
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(三月)+ 4(六月)= 33。

Days = 33

但是 33 天似乎很奇怪,因为它可以转换为 1 个月 + 某些天。如果发生这种情况,就会出现选择哪个月份的问题 - 3 月(31 天)、6 月(30 天)或只是减少 30 天来增加一个月。我认为在考虑巨大差异的同时,这无关紧要。如果我们考虑三月,那么差异将是

4 Years 15 Months 2 Days或者干脆5 Years 3 Months 2 Days

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

已编辑

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");
于 2012-10-29T12:41:30.947 回答
-1
var years = currentDate.getYear() - startDate.getYear();
var months = currentDate.getMonth() - startDate.getMonth();
...
于 2012-10-29T12:28:17.190 回答