【问题标题】:Calculating timespan in years, months and days in JavaScript在 JavaScript 中计算年、月和日的时间跨度
【发布时间】:2014-10-01 08:23:06
【问题描述】:

我想计算两个日期之间的时间跨度(注意:输入格式为 dd.MM.yyyy,请参见下面的代码)。特别的是,不想每个月用 30 天,一年用 360 天。我更想要“人类格式”的差异(不知道如何称呼它)。

假设,我想计算从 2014 年 10 月 1 日到 2015 年 3 月 17 日的差值(包括最后一天)。从 10 月到 2 月,这需要 5 个月。然后剩下的就是 18 天(从第 1 天到第 17 天,包括第 17 天)。所以结果应该是:

0 年 5 个月 18 天

这种计算当然忽略了某些月份有 31、30、28 或 29 天(日期计算除外,当日期采用这种形式时:开始日期:2014 年 10 月 17 日;结束日期:1 月 12 日, 2015)。

不幸的是,我没有找到任何已经实现这种计算的 JS 库。 Moments.js,似乎没有任何方法。

所以我开始创建自己的代码,但我仍然总是偏离预期结果几天(2-3 天)。老实说,如果我查看我的代码,我会觉得它很烂,必须有一种更智能、更优雅的方法来计算它(在我的示例中,我将它输出到一个跨度):

function getTimeDifferenceContract(startDateStr, endDateStr) {
    var returnObject = { "years": null, "months": null, "days": null };
    var startDateArray = startDateStr.split('.');
    var endDateArray = endDateStr.split('.');
    var startMonthIx = startDateArray[1]-1;
    var endMonthIx = endDateArray[1]-1;
    var startDate = new Date(startDateArray[2], startMonthIx, startDateArray[0]);
    var endDate = new Date(endDateArray[2], endMonthIx, endDateArray[0]);

    var endDateFixed = new Date(endDate.getTime()+(1*24*60*60*1000));

    if (endDate > startDate) {
        var years = 0;
        var months = 0;
        var days = 0;
        var dateDiff = endDateFixed.getTime() - startDate.getTime();

        var sD = startDate.getDate();
        var sM = startDate.getMonth()+1;
        var sY = startDate.getFullYear();

        var eD = endDateFixed.getDate();
        var eM = endDateFixed.getMonth()+1;
        var eY = endDateFixed.getFullYear();

        if (sY == eY && sM == eM) {         
            days = Math.floor(dateDiff / (1000 * 60 * 60 * 24));
        }
        else if (sY == eY) {
            if (sD > eD) {
                months = eM - sM - 1;
                var startMonthRestDays = getMonthdays(sM, sY) - sD;
                days = startMonthRestDays + eD;
            }
            else {
                months = eM - sM;
                days = eD - sD;
            }
        }
        else {
            years = eY - sY - 1;
            var monthForYears = 0;
            if (years > 0) {
                monthForYears = (years - 1) * 12;
            } else {
                monthForYears = years * 12;
            }
            months = (12 - sM) + (eM - 1) + (monthForYears)
            var startMonthRestDays = getMonthdays(sM, sY) - sD;
            days = startMonthRestDays + eD - 0;
        }

        var lastMonth = eM - 1;
        var yearForEndMonthDays = eY;
        if (lastMonth < 1) {
            lastMonth = 12;
            yearForEndMonthDays = eY - 1;
        }       
        var endMonthDays = getMonthdays(lastMonth, yearForEndMonthDays);
        if (days >= endMonthDays) {          
            months = months + 1;
            days = days - endMonthDays - 1;
        }
        if (months >= 12) {
            years = years + 1;
            months = months - 12;
        }

        returnObject.years = years;
        returnObject.months = months;
        returnObject.days = days;
    }
    return returnObject;
}

function main() {   
    var difference = getTimeDifferenceContract("30.09.2014", "01.10.2015");
    var years = difference.years;
    var months = difference.months;
    var days = difference.days;

    jQuery('#myText').text(years + " years, " + months + " months, " + days + " days");
}

main();

小提琴:http://jsfiddle.net/4ddL27gx/2/

有解决这个问题的想法吗?

【问题讨论】:

标签: javascript date timespan date-arithmetic


【解决方案1】:

我希望这会有所帮助:

Obtain difference between two dates in years, months, days in JavaScript

我有同样的必要性,但没有答案,所以我写了一个似乎可以工作的函数......

【讨论】:

    【解决方案2】:

    我已经用时刻来达到你需要的结果

    var moment1 = new moment(new Date("30/Sep/2014"));
    var moment2 = new moment(new Date("01/Oct/2015"));
    
    var diffInMilliSeconds = moment2.diff(moment1);
    
    var duration = moment.duration(diffInMilliSeconds);
    
    var years = duration.years();
    var months = duration.months();
    var days = duration.days();
    
    $('.div1').text(moment1.format());
    $('.div2').text(moment2.format());
    $('.div3').text(years + " years, " + months + " months, " + days + " days");
    

    jsfiddle http://jsfiddle.net/mfarouk/qLqm3uuh/1/

    【讨论】:

    • 这看起来很有希望,但是当我输入 01/Jan/2015 作为开始日期和 01/03/2015 作为结束日期时,它会计算 1 个月和 29 天。当我使用 2015 年 3 月 1 日至 2015 年 5 月 1 日这样的日期时,它正确计算了 2 个月,为什么 2 月的情况不计算 2 个月? jsfiddle:jsfiddle.net/Lfxttzd3/1
    • 因为这是一个持续时间,一个月被认为是 30 天,一年是 356,所以它首先以天为单位计算持续时间,这是表示二月份情况下持续时间的最准确方式,如果你说它是2 个月要明确表示天数,您应该说 2 个月,一个 31 天,另一个是 28 天,或者您可以只说 1 个月和 29 天,这样更具可读性
    • 另外你在你的持续时间内有一个闰年,你可能需要说 2 年是闰年,或者只说 2 年零一天
    • @Shihan 如果您找到更好的解决方案,请告诉我
    • 遗憾的是还没有找到满足所有要求的单一解决方案。
    猜你喜欢
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多