it-swarm.dev

الفرق بين تاريخين في السنوات والأشهر والأيام في JavaScript

لقد كنت أبحث عن 4 ساعات حتى الآن ، ولم أجد حلاً لإيجاد الفارق بين تاريخين في السنوات والأشهر والأيام في JavaScript ، مثل: كان 10 أبريل 2010 منذ 3 سنوات و x شهرًا وأيام ص.

هناك الكثير من الحلول ، لكنها لا تقدم إلا الفرق في تنسيق أي من الأيام OR months OR سنوات ، أو أنها غير صحيحة (بمعنى عدم أخذ رعاية العدد الفعلي للأيام خلال شهر أو سنوات كبيسة ، وما إلى ذلك. هل من الصعب جدًا القيام بذلك؟

لقد ألقيت نظرة على:

في php يكون الأمر سهلاً ، لكن لسوء الحظ لا يمكنني استخدام البرنامج النصي من جانب العميل إلا في هذا المشروع. وأي مكتبة أو إطار عمل يمكنه القيام بذلك سيكون جيدًا أيضًا.

فيما يلي قائمة بالنواتج المتوقعة لفوارق التاريخ:

//Expected output should be: "1 year, 5 months".
diffDate(new Date('2014-05-10'), new Date('2015-10-10'));

//Expected output should be: "1 year, 4 months, 29 days".
diffDate(new Date('2014-05-10'), new Date('2015-10-09'));

//Expected output should be: "1 year, 3 months, 30 days".
diffDate(new Date('2014-05-10'), new Date('2015-09-09'));

//Expected output should be: "9 months, 27 days".
diffDate(new Date('2014-05-10'), new Date('2015-03-09'));

//Expected output should be: "1 year, 9 months, 28 days".
diffDate(new Date('2014-05-10'), new Date('2016-03-09'));

//Expected output should be: "1 year, 10 months, 1 days".
diffDate(new Date('2014-05-10'), new Date('2016-03-11'));
39
Chris

ما مدى الدقة التي تحتاجها لتكون؟ إذا كنت بحاجة إلى أن تأخذ في الاعتبار السنوات الشائعة وسنوات القفز ، والفرق الدقيق في الأيام بين الأشهر ، فسوف تضطر إلى كتابة شيء أكثر تقدماً ولكن من أجل حساب أساسي وخشن ، يجب أن تفعل هذا الخدعة:

today = new Date()
past = new Date(2010,05,01) // remember this is equivalent to 06 01 2010
//dates in js are counted from 0, so 05 is june

function calcDate(date1,date2) {
    var diff = Math.floor(date1.getTime() - date2.getTime());
    var day = 1000 * 60 * 60 * 24;

    var days = Math.floor(diff/day);
    var months = Math.floor(days/31);
    var years = Math.floor(months/12);

    var message = date2.toDateString();
    message += " was "
    message += days + " days " 
    message += months + " months "
    message += years + " years ago \n"

    return message
    }


a = calcDate(today,past)
console.log(a) // returns Tue Jun 01 2010 was 1143 days 36 months 3 years ago

ضع في اعتبارك أن هذا غير دقيق ، من أجل حساب التاريخ بدقة تامة ، يجب أن يكون لديك تقويم ومعرفة ما إذا كانت سنة ما سنة كبيسة أم لا ، كما أن الطريقة التي أحسب بها عدد الشهور تقريبية فقط .

ولكن يمكنك تحسينه بسهولة.

29
Pawel Miech

في الواقع ، هناك حل مع البرنامج المساعد moment.js وهو سهل للغاية.

يمكنك استخدام moment.js

لا تعيد اختراع العجلة مرة أخرى.

مجرد سد Moment.js تاريخ النطاق المساعد .


مثال:

var starts = moment('2014-02-03 12:53:12');
var ends   = moment();

var duration = moment.duration(ends.diff(starts));

// with ###moment precise date range plugin###
// it will tell you the difference in human terms

var diff = moment.preciseDiff(starts, ends, true); 
// example: { "years": 2, "months": 7, "days": 0, "hours": 6, "minutes": 29, "seconds": 17, "firstDateWasLater":  false }


// or as string:
var diffHuman = moment.preciseDiff(starts, ends);
// example: 2 years 7 months 6 hours 29 minutes 17 seconds

document.getElementById('output1').innerHTML = JSON.stringify(diff)
document.getElementById('output2').innerHTML = diffHuman
<html>
<head>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>

  <script src="https://raw.githubusercontent.com/codebox/moment-precise-range/master/moment-precise-range.js"></script>

</head>
<body>
  
  <h2>Difference between "NOW and 2014-02-03 12:53:12"</h2>
  <span id="output1"></span>
  <br />
  <span id="output2"></span>
  
</body>
</html>
15
Inanc Gumus

لقد استخدمت هذا الرمز البسيط للحصول على الفرق في السنوات والأشهر والأيام مع التاريخ الحالي.

var sdt = new Date('1972-11-30');
var difdt = new Date(new Date() - sdt);
alert((difdt.toISOString().slice(0, 4) - 1970) + "Y " + (difdt.getMonth()+1) + "M " + difdt.getDate() + "D");
12
Rajeev P Nadig

للاستخدام السريع والسهل كتبت هذه الوظيفة منذ بعض الوقت. تقوم بإرجاع الفرق بين تاريخين بتنسيق Nice. لا تتردد في استخدامه (تم اختباره على webkit).

/**
 * Function to print date diffs.
 * 
 * @param {Date} fromDate: The valid start date
 * @param {Date} toDate: The end date. Can be null (if so the function uses "now").
 * @param {Number} levels: The number of details you want to get out (1="in 2 Months",2="in 2 Months, 20 Days",...)
 * @param {Boolean} prefix: adds "in" or "ago" to the return string
 * @return {String} Diffrence between the two dates.
 */
function getNiceTime(fromDate, toDate, levels, prefix){
    var lang = {
            "date.past": "{0} ago",
            "date.future": "in {0}",
            "date.now": "now",
            "date.year": "{0} year",
            "date.years": "{0} years",
            "date.years.prefixed": "{0} years",
            "date.month": "{0} month",
            "date.months": "{0} months",
            "date.months.prefixed": "{0} months",
            "date.day": "{0} day",
            "date.days": "{0} days",
            "date.days.prefixed": "{0} days",
            "date.hour": "{0} hour",
            "date.hours": "{0} hours",
            "date.hours.prefixed": "{0} hours",
            "date.minute": "{0} minute",
            "date.minutes": "{0} minutes",
            "date.minutes.prefixed": "{0} minutes",
            "date.second": "{0} second",
            "date.seconds": "{0} seconds",
            "date.seconds.prefixed": "{0} seconds",
        },
        langFn = function(id,params){
            var returnValue = lang[id] || "";
            if(params){
                for(var i=0;i<params.length;i++){
                    returnValue = returnValue.replace("{"+i+"}",params[i]);
                }
            }
            return returnValue;
        },
        toDate = toDate ? toDate : new Date(),
        diff = fromDate - toDate,
        past = diff < 0 ? true : false,
        diff = diff < 0 ? diff * -1 : diff,
        date = new Date(new Date(1970,0,1,0).getTime()+diff),
        returnString = '',
        count = 0,
        years = (date.getFullYear() - 1970);
    if(years > 0){
        var langSingle = "date.year" + (prefix ? "" : ""),
            langMultiple = "date.years" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (years > 1 ? langFn(langMultiple,[years]) : langFn(langSingle,[years]));
        count ++;
    }
    var months = date.getMonth();
    if(count < levels && months > 0){
        var langSingle = "date.month" + (prefix ? "" : ""),
            langMultiple = "date.months" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (months > 1 ? langFn(langMultiple,[months]) : langFn(langSingle,[months]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    var days = date.getDate() - 1;
    if(count < levels && days > 0){
        var langSingle = "date.day" + (prefix ? "" : ""),
            langMultiple = "date.days" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (days > 1 ? langFn(langMultiple,[days]) : langFn(langSingle,[days]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    var hours = date.getHours();
    if(count < levels && hours > 0){
        var langSingle = "date.hour" + (prefix ? "" : ""),
            langMultiple = "date.hours" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (hours > 1 ? langFn(langMultiple,[hours]) : langFn(langSingle,[hours]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    var minutes = date.getMinutes();
    if(count < levels && minutes > 0){
        var langSingle = "date.minute" + (prefix ? "" : ""),
            langMultiple = "date.minutes" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (minutes > 1 ? langFn(langMultiple,[minutes]) : langFn(langSingle,[minutes]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    var seconds = date.getSeconds();
    if(count < levels && seconds > 0){
        var langSingle = "date.second" + (prefix ? "" : ""),
            langMultiple = "date.seconds" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (seconds > 1 ? langFn(langMultiple,[seconds]) : langFn(langSingle,[seconds]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    if(prefix){
        if(returnString == ""){
            returnString = langFn("date.now");
        } else if(past)
            returnString = langFn("date.past",[returnString]);
        else
            returnString = langFn("date.future",[returnString]);
    }
    return returnString;
}
5
Chris

أعتقد أنك تبحث عن نفس الشيء الذي أردت. حاولت القيام بذلك باستخدام الاختلاف في المللي ثانية التي توفرها جافا سكريبت ، لكن تلك النتائج لا تعمل في العالم الحقيقي للتواريخ. إذا كنت تريد الفرق بين 1 فبراير 2016 و 31 يناير 2017 ، فإن النتيجة التي أريدها هي سنة واحدة و 0 شهرًا و 0 يومًا. سنة واحدة بالضبط (على افتراض أنك تعد اليوم الأخير يومًا كاملاً ، كما هو الحال في عقد الإيجار لشقة). ومع ذلك ، يمنحك نهج مللي ثانية 1 سنة 0 أشهر ويوم واحد ، حيث يتضمن نطاق التاريخ سنة كبيسة. إذن ، إليك الكود الذي استخدمته في javascript لنموذج Adobe الخاص بي (يمكنك تسمية الحقول): (تم التعديل ، حدث خطأ قمت بتصحيحه)

var f1 = this.getField("LeaseExpiration");
var g1 = this.getField("LeaseStart");


var end = f1.value
var begin = g1.value
var e = new Date(end);
var b = new Date(begin);
var bMonth = b.getMonth();
var bYear = b.getFullYear();
var eYear = e.getFullYear();
var eMonth = e.getMonth();
var bDay = b.getDate();
var eDay = e.getDate() + 1;

if ((eMonth == 0)||(eMonth == 2)||(eMonth == 4)|| (eMonth == 6) || (eMonth == 7) ||(eMonth == 9)||(eMonth == 11))

{
var eDays =  31;
}

if ((eMonth == 3)||(eMonth == 5)||(eMonth == 8)|| (eMonth == 10))

{
var eDays = 30;
}

if (eMonth == 1&&((eYear % 4 == 0) && (eYear % 100 != 0)) || (eYear % 400 == 0))
{
var eDays = 29;
}

if (eMonth == 1&&((eYear % 4 != 0) || (eYear % 100 == 0)))
{
var eDays = 28;
}


if ((bMonth == 0)||(bMonth == 2)||(bMonth == 4)|| (bMonth == 6) || (bMonth == 7) ||(bMonth == 9)||(bMonth == 11))

{
var bDays =  31;
}

if ((bMonth == 3)||(bMonth == 5)||(bMonth == 8)|| (bMonth == 10))

{
var bDays = 30;
}

if (bMonth == 1&&((bYear % 4 == 0) && (bYear % 100 != 0)) || (bYear % 400 == 0))
{
var bDays = 29;
}

if (bMonth == 1&&((bYear % 4 != 0) || (bYear % 100 == 0)))
{
var bDays = 28;
}


var FirstMonthDiff = bDays - bDay + 1;


if (eDay - bDay < 0)
{

eMonth = eMonth - 1;
eDay = eDay + eDays;

}

var daysDiff = eDay - bDay;

if(eMonth - bMonth < 0)
{
eYear = eYear - 1;
eMonth = eMonth + 12;
}

var monthDiff = eMonth - bMonth;

var yearDiff = eYear - bYear;

if (daysDiff == eDays)
{
daysDiff = 0;
monthDiff = monthDiff + 1;

if (monthDiff == 12)
{
monthDiff = 0;
yearDiff = yearDiff + 1;
}

}

if ((FirstMonthDiff != bDays)&&(eDay - 1 == eDays))

{
daysDiff = FirstMonthDiff;

}
event.value = yearDiff + " Year(s)" + " " + monthDiff + " month(s) " + daysDiff + " days(s)"
4
Murray

تعديل هذا ليكون أكثر دقة بكثير. سيتم تحويل التواريخ إلى تنسيق "YYYY-MM-DD" ، متجاهلاً HH: MM: SS ، ويأخذ تاريخًا نهائيًا اختياريًا أو يستخدم التاريخ الحالي ، ولا يهتم بترتيب القيم.

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';
}

ثم يمكنك استخدامه مثل هذا:

// 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

إصدار أقدم أقل دقة ولكن أبسط

كانت إجابة RajeevPNadig @ هي ما كنت أبحث عنه ، لكن رمزه يعرض قيمًا غير صحيحة كما هو مكتوب. هذا ليس دقيقًا جدًا لأنه يفترض أن تسلسل التواريخ من 1 يناير 1970 هو نفس تسلسل التواريخ في نفس عدد الأيام. مثلا يقوم بحساب الفرق من 1 يوليو إلى 1 سبتمبر (62 يومًا) كـ 0Y 2M 3D وليس 0Y 2M 0D لأن 1 يناير 1970 زائد 62 يومًا هو 3 مارس.

// 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");
}

ثم يمكنك استخدامه مثل هذا:

// 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"

إذا كانت حالة الاستخدام عبارة عن سلاسل زمنية فقط ، فهذا يعمل بشكل جيد إذا كنت تريد فقط بطانة سريعة وقذرة 4.

3
Mordred

بعض الرياضيات في النظام.

يمكنك طرح كائن Date واحد من آخر في Javascript ، وستحصل على الفرق بينهما في المللي ثانية. من هذه النتيجة ، يمكنك استخراج الأجزاء الأخرى التي تريدها (الأيام والشهور وما إلى ذلك)

فمثلا:

var a = new Date(2010, 10, 1);
var b = new Date(2010, 9, 1);

var c = a - b; // c equals 2674800000,
               // the amount of milisseconds between September 1, 2010
               // and August 1, 2010.

الآن يمكنك الحصول على أي جزء تريده. على سبيل المثال ، عدد الأيام التي انقضت بين التاريخين:

var days = (a - b) / (60 * 60 * 24 * 1000);
// 60 * 60 * 24 * 1000 is the amount of milisseconds in a day.
// the variable days now equals 30.958333333333332.

هذا ما يقرب من 31 يوما. يمكنك التقريب لأسفل لمدة 30 يومًا ، واستخدام ما تبقى للحصول على ساعات ، دقائق ، إلخ.

2
Renan

لقد قمتُ بإنشاء وظيفة أخرى لهذا الغرض:

function dateDiff(date) {
    date = date.split('-');
    var today = new Date();
    var year = today.getFullYear();
    var month = today.getMonth() + 1;
    var day = today.getDate();
    var yy = parseInt(date[0]);
    var mm = parseInt(date[1]);
    var dd = parseInt(date[2]);
    var years, months, days;
    // months
    months = month - mm;
    if (day < dd) {
        months = months - 1;
    }
    // years
    years = year - yy;
    if (month * 100 + day < mm * 100 + dd) {
        years = years - 1;
        months = months + 12;
    }
    // days
    days = Math.floor((today.getTime() - (new Date(yy + years, mm + months - 1, dd)).getTime()) / (24 * 60 * 60 * 1000));
    //
    return {years: years, months: months, days: days};
}

لا يتطلب أي مكتبات طرف ثالث. يأخذ وسيطة واحدة - التاريخ في تنسيق YYYY-MM-DD.

https://Gist.github.com/lemmon/d27c2d4a783b1cf72d1d1cc243458d56

2
Jakub Pelák
   let startDate = moment(new Date('2017-05-12')); // yyyy-MM-dd
   let endDate = moment(new Date('2018-09-14')); // yyyy-MM-dd

   let Years = newDate.diff(date, 'years');
   let months = newDate.diff(date, 'months');
   let days = newDate.diff(date, 'days');

console.log("Year: " + Years, ", Month: " months-(Years*12), ", Days: " days-(Years*365.25)-((365.25*(days- (Years*12)))/12));

ستتم طباعة المقتطف أعلاه: السنة: 1 ، الشهر: 4 ، الأيام: 2

2
Nilesh Patel

بعد حل آخر ، استنادا إلى بعض PHP. وظيفة strtotime ، استنادا أيضا إلى PHP ، ويمكن الاطلاع هنا: http://phpjs.org/functions/strtotime/ .

Date.dateDiff = function(d1, d2) {
    d1 /= 1000;
    d2 /= 1000;
    if (d1 > d2) d2 = [d1, d1 = d2][0];

    var diffs = {
        year: 0,
        month: 0,
        day: 0,
        hour: 0,
        minute: 0,
        second: 0
    }

    $.each(diffs, function(interval) {
        while (d2 >= (d3 = Date.strtotime('+1 '+interval, d1))) {
            d1 = d3;
            ++diffs[interval];
        }
    });

    return diffs;
};

الاستعمال:

> d1 = new Date(2000, 0, 1)
Sat Jan 01 2000 00:00:00 GMT+0100 (CET)

> d2 = new Date(2013, 9, 6)
Sun Oct 06 2013 00:00:00 GMT+0200 (CEST)

> Date.dateDiff(d1, d2)
Object {
  day: 5
  hour: 0
  minute: 0
  month: 9
  second: 0
  year: 13
}
2
webtweakers

يحتوي هذا الرابط على أفضل إجابة http://forums.asp.net/t/1610039.aspx؟How+to+calculate+difference+between+two+dates+in+years

ما عليك سوى إضافة التحقق من الصحة للأيام ، مثل:

if (firstDate.getDate () <= now.getDate ())

1
myself

الخيط القديم جدًا ، وأنا أعلم ، ولكن إليكم إسهامي ، حيث لم يتم حل الخيط بعد.

يستغرق الأمر سنوات كبيسة في الاعتبار ولا يستهلك أي عدد محدد من الأيام في الشهر أو السنة.

قد تكون معيبة في الحالات الحدودية حيث أنني لم أختبرها بشكل كامل ، لكنها تعمل لجميع التواريخ الواردة في السؤال الأصلي ، وبالتالي أنا واثق.

function calculate() {
  var fromDate = document.getElementById('fromDate').value;
  var toDate = document.getElementById('toDate').value;

  try {
    document.getElementById('result').innerHTML = '';

    var result = getDateDifference(new Date(fromDate), new Date(toDate));

    if (result && !isNaN(result.years)) {
      document.getElementById('result').innerHTML =
        result.years + ' year' + (result.years == 1 ? ' ' : 's ') +
        result.months + ' month' + (result.months == 1 ? ' ' : 's ') + 'and ' +
        result.days + ' day' + (result.days == 1 ? '' : 's');
    }
  } catch (e) {
    console.error(e);
  }
}

function getDateDifference(startDate, endDate) {
  if (startDate > endDate) {
    console.error('Start date must be before end date');
    return null;
  }
  var startYear = startDate.getFullYear();
  var startMonth = startDate.getMonth();
  var startDay = startDate.getDate();

  var endYear = endDate.getFullYear();
  var endMonth = endDate.getMonth();
  var endDay = endDate.getDate();

  // We calculate February based on end year as it might be a leep year which might influence the number of days.
  var february = (endYear % 4 == 0 && endYear % 100 != 0) || endYear % 400 == 0 ? 29 : 28;
  var daysOfMonth = [31, february, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

  var startDateNotPassedInEndYear = (endMonth < startMonth) || endMonth == startMonth && endDay < startDay;
  var years = endYear - startYear - (startDateNotPassedInEndYear ? 1 : 0);

  var months = (12 + endMonth - startMonth - (endDay < startDay ? 1 : 0)) % 12;

  // (12 + ...) % 12 makes sure index is always between 0 and 11
  var days = startDay <= endDay ? endDay - startDay : daysOfMonth[(12 + endMonth - 1) % 12] - startDay + endDay;

  return {
    years: years,
    months: months,
    days: days
  };
}
<p><input type="text" name="fromDate" id="fromDate" placeholder="yyyy-mm-dd" value="1999-02-28" /></p>
<p><input type="text" name="toDate" id="toDate" placeholder="yyyy-mm-dd" value="2000-03-01" /></p>
<p><input type="button" name="calculate" value="Calculate" onclick="javascript:calculate();" /></p>
<p />
<p id="result"></p>
1
David SN

فيما يلي خوارزمية تعطي تصحيحًا صحيحًا ولكنه غير دقيق تمامًا لأنه لا يأخذ في الاعتبار سنة كبيسة. يفترض أيضًا 30 يومًا في الشهر. الاستخدام الجيد على سبيل المثال هو إذا كان شخص ما يعيش في عنوان من 12/11/2010 إلى 11/10/2011 ، يمكن أن يخبر بسرعة أن الشخص يعيش هناك لمدة 10 أشهر و 29 يومًا. من 12/11/2010 إلى 11/12/2011 11 أشهر ويوم واحد. لأنواع معينة من التطبيقات ، هذا النوع من الدقة يكفي. هذا لأنواع التطبيقات لأنه يهدف إلى البساطة:

var datediff = function(start, end) {
  var diff = { years: 0, months: 0, days: 0 };
  var timeDiff = end - start;

  if (timeDiff > 0) {
    diff.years = end.getFullYear() - start.getFullYear();
    diff.months = end.getMonth() - start.getMonth();
    diff.days = end.getDate() - start.getDate();

    if (diff.months < 0) {
      diff.years--;
      diff.months += 12;
    }

    if (diff.days < 0) {
      diff.months = Math.max(0, diff.months - 1);
      diff.days += 30;
    }
  }

  return diff;
};

اختبارات الوحدة

0
Kevin Le - Khnle

أعلم أنه خيط قديم ، ولكن أود أن أضع سنتي بناءً على إجابةPawel Miech.

صحيح أنك تحتاج إلى تحويل الفرق إلى مللي ثانية ، ثم تحتاج إلى إجراء بعض الرياضيات. لكن لاحظ أنه يلزمك إجراء الرياضيات بطريقة متخلفة ، أي أنك تحتاج إلى حساب السنوات والأشهر والأيام والساعات ثم الدقائق.

اعتدت أن أفعل شيئا من هذا القبيل:

    var mins;
    var hours;
    var days;
    var months;
    var years;

    var diff = new Date() - new Date(yourOldDate);  
// yourOldDate may be is coming from DB, for example, but it should be in the correct format ("MM/dd/yyyy hh:mm:ss:fff tt")

    years = Math.floor((diff) / (1000 * 60 * 60 * 24 * 365));
    diff = Math.floor((diff) % (1000 * 60 * 60 * 24 * 365));
    months = Math.floor((diff) / (1000 * 60 * 60 * 24 * 30));
    diff = Math.floor((diff) % (1000 * 60 * 60 * 24 * 30));
    days = Math.floor((diff) / (1000 * 60 * 60 * 24));
    diff = Math.floor((diff) % (1000 * 60 * 60 * 24));
    hours = Math.floor((diff) / (1000 * 60 * 60));
    diff = Math.floor((diff) % (1000 * 60 * 60));
    mins = Math.floor((diff) / (1000 * 60));

لكن ، بالطبع ، هذا ليس دقيقًا لأنه يفترض أن جميع السنوات لها 365 يومًا وأن كل الشهور 30 ​​يومًا ، وهذا غير صحيح في جميع الحالات.

0
Dr. MAF

أود شخصيا استخدام http://www.datejs.com/ ، مفيد حقا. على وجه التحديد ، انظر إلى ملف time.js: http://code.google.com/p/datejs/source/browse/trunk/src/time.js

0
Joe Minichino

لحساب الفرق بين تاريخين في السنوات والأشهر والأيام والدقائق والثواني والميلي ثانية باستخدام TypeScript/JavaScript

dateDifference(actualDate) {
            // Calculate time between two dates:
            const date1 = actualDate; // the date you already commented/ posted
            const date2: any = new Date(); // today

            let r = {}; // object for clarity
            let message: string;

            const diffInSeconds = Math.abs(date2 - date1) / 1000;
            const days = Math.floor(diffInSeconds / 60 / 60 / 24);
            const hours = Math.floor(diffInSeconds / 60 / 60 % 24);
            const minutes = Math.floor(diffInSeconds / 60 % 60);
            const seconds = Math.floor(diffInSeconds % 60);
            const milliseconds = 
           Math.round((diffInSeconds - Math.floor(diffInSeconds)) * 1000);

            const months = Math.floor(days / 31);
            const years = Math.floor(months / 12);

            // the below object is just optional 
            // if you want to return an object instead of a message
            r = {
                years: years,
                months: months,
                days: days,
                hours: hours,
                minutes: minutes,
                seconds: seconds,
                milliseconds: milliseconds
            };

            // check if difference is in years or months
            if (years === 0 && months === 0) {
                // show in days if no years / months
                if (days > 0) {
                    if (days === 1) {
                        message = days + ' day';
                    } else { message = days + ' days'; }
                }  else if (hours > 0) {
                    if (hours === 1) {
                        message = hours + ' hour';
                    } else {
                        message = hours + ' hours';
                    }
                } else {
                    // show in minutes if no years / months / days
                    if (minutes === 1) {
                        message = minutes + ' minute';
                    } else {message = minutes + ' minutes';}  
                }
            } else if (years === 0 && months > 0) {
                // show in months if no years
                if (months === 1) {
                    message = months + ' month';
                } else {message = months + ' months';}
            } else if (years > 0) {
                // show in years if years exist
                if (years === 1) {
                    message = years + ' year';
                } else {message = years + ' years';}
            }

            return 'Posted ' + message + ' ago'; 
     // this is the message a user see in the view
        }

ومع ذلك ، يمكنك تحديث المنطق أعلاه للرسالة لإظهار الثواني والميلي ثانية أيضًا أو استخدام الكائن 'r' لتنسيق الرسالة بالطريقة التي تريدها.

إذا كنت ترغب في نسخ الكود مباشرةً ، يمكنك مشاهدة Gist الخاص بي بالشفرة أعلاه هنا

0
Sai Nikhil

المدة الزمنية بالأيام الكاملة ، الساعات ، الدقائق ، الثواني ، مللي ثانية:

// Extension for Date
Date.difference = function (dateFrom, dateTo) {
  var diff = { TotalMs: dateTo - dateFrom };
  diff.Days = Math.floor(diff.TotalMs / 86400000);

  var remHrs = diff.TotalMs % 86400000;
  var remMin = remHrs % 3600000;
  var remS   = remMin % 60000;

  diff.Hours        = Math.floor(remHrs / 3600000);
  diff.Minutes      = Math.floor(remMin / 60000);
  diff.Seconds      = Math.floor(remS   / 1000);
  diff.Milliseconds = Math.floor(remS % 1000);
  return diff;
};

// Usage
var a = new Date(2014, 05, 12, 00, 5, 45, 30); //a: Thu Jun 12 2014 00:05:45 GMT+0400 
var b = new Date(2014, 02, 12, 00, 0, 25, 0);  //b: Wed Mar 12 2014 00:00:25 GMT+0400
var diff = Date.difference(b, a);
/* diff: {
  Days: 92
  Hours: 0
  Minutes: 5
  Seconds: 20
  Milliseconds: 30
  TotalMs: 7949120030
} */
0
Oleg

لا يعمل أي من الرموز بالنسبة لي ، لذلك استخدم هذا بدلاً من ذلك لعدة أشهر وأيام:

function monthDiff(d2, d1) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth() + 1;
    months += d2.getMonth() + 1;
    return months <= 0 ? 0 : months;
}

function daysInMonth(date) {
    return new Date(date.getYear(), date.getMonth() + 1, 0).getDate();
}    

function diffDate(date1, date2) {
    if (date2 && date2.getTime() && !isNaN(date2.getTime())) {
        var months = monthDiff(date1, date2);
        var days = 0;

        if (date1.getUTCDate() >= date2.getUTCDate()) {
            days = date1.getUTCDate() - date2.getUTCDate();
        }
        else {
            months--;
            days = date1.getUTCDate() - date2.getUTCDate() + daysInMonth(date2);
        }

        // Use the variables months and days how you need them.
    }
}
0
Filgaia