Difference between two dates in years, months, days in JavaScript

前端 未结 26 2840
执念已碎
执念已碎 2020-11-22 07:18

I\'ve been searching for 4 hours now, and have not found a solution to get the difference between two dates in years, months, and days in JavaScript, like: 10th of April 201

26条回答
  •  轮回少年
    2020-11-22 07:58

    Modified this to be a lot more accurate. It will convert dates to a 'YYYY-MM-DD' format, ignoring HH:MM:SS, and takes an optional endDate or uses the current date, and doesn't care about the order of the values.

    function dateDiff(startingDate, endingDate) {
        var startDate = new Date(new Date(startingDate).toISOString().substr(0, 10));
        if (!endingDate) {
            endingDate = new Date().toISOString().substr(0, 10);    // need date in YYYY-MM-DD format
        }
        var endDate = new Date(endingDate);
        if (startDate > endDate) {
            var swap = startDate;
            startDate = endDate;
            endDate = swap;
        }
        var startYear = startDate.getFullYear();
        var february = (startYear % 4 === 0 && startYear % 100 !== 0) || startYear % 400 === 0 ? 29 : 28;
        var daysInMonth = [31, february, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    
        var yearDiff = endDate.getFullYear() - startYear;
        var monthDiff = endDate.getMonth() - startDate.getMonth();
        if (monthDiff < 0) {
            yearDiff--;
            monthDiff += 12;
        }
        var dayDiff = endDate.getDate() - startDate.getDate();
        if (dayDiff < 0) {
            if (monthDiff > 0) {
                monthDiff--;
            } else {
                yearDiff--;
                monthDiff = 11;
            }
            dayDiff += daysInMonth[startDate.getMonth()];
        }
    
        return yearDiff + 'Y ' + monthDiff + 'M ' + dayDiff + 'D';
    }
    

    Then you can use it like this:

    // based on a current date of 2019-05-10
    dateDiff('2019-05-10'); // 0Y 0M 0D
    dateDiff('2019-05-09'); // 0Y 0M 1D
    dateDiff('2018-05-09'); // 1Y 0M 1D
    dateDiff('2018-05-18'); // 0Y 11M 23D
    dateDiff('2019-01-09'); // 0Y 4M 1D
    dateDiff('2019-02-10'); // 0Y 3M 0D
    dateDiff('2019-02-11'); // 0Y 2M 27D
    dateDiff('2016-02-11'); // 3Y 2M 28D - leap year
    dateDiff('1972-11-30'); // 46Y 5M 10D
    dateDiff('2016-02-11', '2017-02-11'); // 1Y 0M 0D
    dateDiff('2016-02-11', '2016-03-10'); // 0Y 0M 28D - leap year
    dateDiff('2100-02-11', '2100-03-10'); // 0Y 0M 27D - not a leap year
    dateDiff('2017-02-11', '2016-02-11'); // 1Y 0M 0D - swapped dates to return correct result
    dateDiff(new Date() - 1000 * 60 * 60 * 24); // 0Y 0M 1D
    

    Older less accurate but simpler version

    @RajeevPNadig's answer was what I was looking for, but his code returns incorrect values as written. This is not very accurate because it assumes that the sequence of dates from 1 January 1970 is the same as any other sequence of the same number of days. E.g. it calculates the difference from 1 July to 1 September (62 days) as 0Y 2M 3D and not 0Y 2M 0D because 1 Jan 1970 plus 62 days is 3 March.

    // startDate must be a date string
    function dateAgo(date) {
        var startDate = new Date(date);
        var diffDate = new Date(new Date() - startDate);
        return ((diffDate.toISOString().slice(0, 4) - 1970) + "Y " +
            diffDate.getMonth() + "M " + (diffDate.getDate()-1) + "D");
    }
    

    Then you can use it like this:

    // based on a current date of 2018-03-09
    dateAgo('1972-11-30'); // "45Y 3M 9D"
    dateAgo('2017-03-09'); // "1Y 0M 0D"
    dateAgo('2018-01-09'); // "0Y 2M 0D"
    dateAgo('2018-02-09'); // "0Y 0M 28D" -- a little odd, but not wrong
    dateAgo('2018-02-01'); // "0Y 1M 5D" -- definitely "feels" wrong
    dateAgo('2018-03-09'); // "0Y 0M 0D"
    

    If your use case is just date strings, then this works okay if you just want a quick and dirty 4 liner.

提交回复
热议问题