JavaScript'te tarih farkı nasıl hesaplanır?


181

Gün, saat, dakika, saniye, milisaniye, nanosaniye cinsinden tarih farkını hesaplamak istiyorum. Nasıl yapabilirim?



1
İlgili iki tarih farklı saat dilimlerinde ise aşağıdaki çözümler kırılacaktır. Daha doğru bir çözüm için şu soruya bakın stackoverflow.com/questions/3224834/… ?
Shyam Habarakada

Yanıtlar:


219

İki Datenesneniz olduğu varsayılarak , milisaniye cinsinden farkı elde etmek için bunları çıkarabilirsiniz:

var difference = date2 - date1;

Oradan, diğer değerleri türetmek için basit aritmetik kullanabilirsiniz.


38
Bu doğru cevap. Örneğin: gün Math.floor((date2 - date1) / (1000*60*60*24))cinsinden fark almak için - başka bir birimdeki fark için paydayı ayarlayın (taban değeri ms cinsinden).
trisweb

33
Milisaniyeyi yıllara çevirmek için "basit" bir aritmetik yoktur. Bisekstil yılı, saat dilimi ve bazı günlerde 23 veya 25 saatin farkında olmalısınız. Bazı yılların 365,25 günü var, bu yüzden burada basit bir aritmetik yok (hala doğru bir çözüm arıyor).
Alexandre Salomé

6
@Alexandre: Soru yıllarca sorulmadı. Gerçekten de, yıl farklılıklarını hesaplamak önemsizdir. Bununla birlikte, günler için, tarihlerin aynı saat diliminde (makul olmayan bir varsayım) olduğunu varsayalım. Bildiğim kadarıyla, bir gün 24 saat olarak tanımlanır ve Yaz Saati Uygulamasından kaynaklanan herhangi bir 'varyasyon' aslında zaman dilimlerinin bir anahtarıdır. Zaten zaman dilimleri arasında ayrım yapmazsanız, bir zaman farkı bulmaya çalışmak, sadece bir DST geçişi 'tekrar' zamanından dolayı değil, bir acı dünyasına sokacaktır. Yine de bir saat diliminde kalın ve hepsi işe yarıyor.
icktoofay

12
@ trisweb - günlerde fark yaratmak kadar basit bir şey bile yorumunuzdan daha karmaşıktır. Çarşamba 22:00 ile 09:00 Çarşamba arasında kaç gün var? Algoritmanız 0 diyor. Diğerleri 1'i düşünebilir.
RobG

@RobG relativistleri 1'den fazla veya 0'dan az düşünebilirler. Her şey gözlemciye bağlıdır.
Masum Bystander

78
var DateDiff = {

    inDays: function(d1, d2) {
        var t2 = d2.getTime();
        var t1 = d1.getTime();

        return parseInt((t2-t1)/(24*3600*1000));
    },

    inWeeks: function(d1, d2) {
        var t2 = d2.getTime();
        var t1 = d1.getTime();

        return parseInt((t2-t1)/(24*3600*1000*7));
    },

    inMonths: function(d1, d2) {
        var d1Y = d1.getFullYear();
        var d2Y = d2.getFullYear();
        var d1M = d1.getMonth();
        var d2M = d2.getMonth();

        return (d2M+12*d2Y)-(d1M+12*d1Y);
    },

    inYears: function(d1, d2) {
        return d2.getFullYear()-d1.getFullYear();
    }
}

var dString = "May, 20, 1984";

var d1 = new Date(dString);
var d2 = new Date();

document.write("<br />Number of <b>days</b> since "+dString+": "+DateDiff.inDays(d1, d2));
document.write("<br />Number of <b>weeks</b> since "+dString+": "+DateDiff.inWeeks(d1, d2));
document.write("<br />Number of <b>months</b> since "+dString+": "+DateDiff.inMonths(d1, d2));
document.write("<br />Number of <b>years</b> since "+dString+": "+DateDiff.inYears(d1, d2));

Kod örneği buradan alınmıştır .


Bu, yalnızca tek bir sayaç olarak kullanıldığında verilen formattaki tarih farkını döndürür. Örneğin, 3 ay 4 gün 5 saat istiyorsanız bu sonuçları üretmez. Daha fazla 3 ay 96 gün ve çok fazla saat.
Joris Kroos

30

Başka bir çözüm, farkı yeni bir Date nesnesine dönüştürmek ve o tarihin yılını (1970'ten fark), ay, gün vb.

var date1 = new Date(2010, 6, 17);
var date2 = new Date(2013, 12, 18);
var diff = new Date(date2.getTime() - date1.getTime());
// diff is: Thu Jul 05 1973 04:00:00 GMT+0300 (EEST)

console.log(diff.getUTCFullYear() - 1970); // Gives difference as year
// 3

console.log(diff.getUTCMonth()); // Gives month count of difference
// 6

console.log(diff.getUTCDate() - 1); // Gives day count of difference
// 4

Yani fark "3 yıl 6 ay 4 gün" gibidir. İnsan tarafından okunabilir bir tarzda fark almak istiyorsanız, bu size yardımcı olabilir.


Anlamı değil! BÜTÜN farkı istiyoruz! Bu örnekte, günlerdeki fark 4 değil 1281'dir!
chaim.dev

3
@ chaim.dev "Eğer insan tarafından okunabilir bir tarzda fark almak istiyorsanız, bu size yardımcı olabilir."
Murat Çorlu

7
Bu güvenilir değil. Değişen ay uzunluklarını veya artık yılları ve diğer anomalileri dikkate almaz.
Marc Durdin

2
Teşekkürler Murat, Bu çözüm sorunumu çözdü. Ne gerçekten istiyorum php yaptığı gibi çalışması gerekir.
Ritesh Patadiya

27

"Günlerdeki fark" gibi ifadeler hiçbir zaman göründükleri kadar basit değildir. Aşağıdaki tarihlere sahipseniz:

d1: 2011-10-15 23:59:00
d1: 2011-10-16 00:01:00

zaman farkı 2 dakikadır, "gün farkı" 1 veya 0 olmalı mı? Aylar, yıllar veya yıllar, aylar ve günler farklı uzunluklarda ve farklı saatlerde olduğu için herhangi bir aydaki farkın herhangi bir ifadesi için benzer sorunlar ortaya çıkar (örneğin, gün ışığından yararlanma saatinin başladığı gün normalden 1 saat daha kısa ve güne göre iki saat daha kısa) biter).

İşte günleri göz ardı eden günlerdeki farkın bir işlevi, yani yukarıdaki tarihler için 1 döndürür.

/*
   Get the number of days between two dates - not inclusive.

   "between" does not include the start date, so days
   between Thursday and Friday is one, Thursday to Saturday
   is two, and so on. Between Friday and the following Friday is 7.

   e.g. getDaysBetweenDates( 22-Jul-2011, 29-jul-2011) => 7.

   If want inclusive dates (e.g. leave from 1/1/2011 to 30/1/2011),
   use date prior to start date (i.e. 31/12/2010 to 30/1/2011).

   Only calculates whole days.

   Assumes d0 <= d1
*/
function getDaysBetweenDates(d0, d1) {

  var msPerDay = 8.64e7;

  // Copy dates so don't mess them up
  var x0 = new Date(d0);
  var x1 = new Date(d1);

  // Set to noon - avoid DST errors
  x0.setHours(12,0,0);
  x1.setHours(12,0,0);

  // Round to remove daylight saving errors
  return Math.round( (x1 - x0) / msPerDay );
}

Bu daha kısa olabilir:

/*  Return number of days between d0 and d1.
**  Returns positive if d0 < d1, otherwise negative.
**
**  e.g. between 2000-02-28 and 2001-02-28 there are 366 days
**       between 2015-12-28 and 2015-12-29 there is 1 day
**       between 2015-12-28 23:59:59 and 2015-12-29 00:00:01 there is 1 day
**       between 2015-12-28 00:00:01 and 2015-12-28 23:59:59 there are 0 days
**        
**  @param {Date} d0  - start date
**  @param {Date} d1  - end date
**  @returns {number} - whole number of days between d0 and d1
**
*/
function daysDifference(d0, d1) {
  var diff = new Date(+d1).setHours(12) - new Date(+d0).setHours(12);
  return Math.round(diff/8.64e7);
}

// Simple formatter
function formatDate(date){
  return [date.getFullYear(),('0'+(date.getMonth()+1)).slice(-2),('0'+date.getDate()).slice(-2)].join('-');
}

// Examples
[[new Date(2000,1,28), new Date(2001,1,28)],  // Leap year
 [new Date(2001,1,28), new Date(2002,1,28)],  // Not leap year
 [new Date(2017,0,1),  new Date(2017,1,1)] 
].forEach(function(dates) {
  document.write('From ' + formatDate(dates[0]) + ' to ' + formatDate(dates[1]) +
                 ' is ' + daysDifference(dates[0],dates[1]) + ' days<br>');
});


1
@ rudeovskizebear — IE, Firefox ve Safari'de test edildi, iyi çalışıyor. Herhangi bir tarayıcıda çalışmayı beklediğim temel ECMAScript'i kullanıyor, sizin için işe yaramayan nedir?
RobG

Bir test sayfasına koydum ve
kromda

@ RafiB. — Birinin diğerinden nasıl daha doğru olduğunu düşündüğünüzü bilmiyorum, aslında aynı şeyi yapıyorlar, yani bir UTC zaman değeri kullanarak tüm günlerdeki farkı hesaplıyorlar. Sorudaki belirsizlik netlik kazanmadı. Eğer öyleyse, farklı bir çözüme yol açabilir.
RobG

@RobG Lütfen daha kısa çözümlerin yorumlarındaki örnekleri düzenleyin. Ay '22' değil '12' olmalıdır
S.aad

1
@ IgorKudryashov — üzgünüm, anlayamıyorum. 2000 artık bir yıl, yani 28 Şubat 2000 ila 28 Şubat 2001 366 gündür. Artık olmayan bir yılda 365 gün. Birkaç örnek daha ekledim.
RobG

18
<html lang="en">
<head>
<script>
function getDateDiff(time1, time2) {
  var str1= time1.split('/');
  var str2= time2.split('/');

  //                yyyy   , mm       , dd
  var t1 = new Date(str1[2], str1[0]-1, str1[1]);
  var t2 = new Date(str2[2], str2[0]-1, str2[1]);

  var diffMS = t1 - t2;    
  console.log(diffMS + ' ms');

  var diffS = diffMS / 1000;    
  console.log(diffS + ' ');

  var diffM = diffS / 60;
  console.log(diffM + ' minutes');

  var diffH = diffM / 60;
  console.log(diffH + ' hours');

  var diffD = diffH / 24;
  console.log(diffD + ' days');
  alert(diffD);
}

//alert(getDateDiff('10/18/2013','10/14/2013'));
</script>
</head>
<body>
  <input type="button" 
       onclick="getDateDiff('10/18/2013','10/14/2013')" 
       value="clickHere()" />

</body>
</html>

Bana yardım etmiyor. Bunu aynı yaklaşımla aylara veya yıllara uzatamazsınız.
tomazahlin

9

Moment.js kullanınJavaScript ile ilgili tüm tarih-saat hesaplamanız için

Sorunuzun cevabı:

var a = moment([2007, 0, 29]);   
var b = moment([2007, 0, 28]);    
a.diff(b) // 86400000  

Tüm ayrıntıları burada bulabilirsiniz


4
Ve sadece bir tarih farkı için fazladan 400+ Kb'yi kucaklayın.
Romeo Mihalcea

@RomeoMihalcea Şu anki küçültülmüş moment.js 2.22.2 bir yerel ayar ile 53 KB, 17 KB sıkıştırılmış. Endişenizi anlıyorum. Tek bir basit işlev için kullanmak için büyük bir kütüphane, ancak tarih / zamanla ilgili birçok tuhaflıkla ilgileniyor ve genellikle buna değer.
HeikoS

8
function DateDiff(date1, date2) {
    date1.setHours(0);
    date1.setMinutes(0, 0, 0);
    date2.setHours(0);
    date2.setMinutes(0, 0, 0);
    var datediff = Math.abs(date1.getTime() - date2.getTime()); // difference 
    return parseInt(datediff / (24 * 60 * 60 * 1000), 10); //Convert values days and return value      
}

Çözümler için teşekkürler :)
bhagirathi

Bulduğum çoğu çözüm ya çalışmıyor ya da çok uzun soluklu. Çözümünüz şu ana kadar en basit olanıdır ve tam olarak tasarlandığı gibi çalışır! Şerefe :)
Bruce

farkı bir saatten daha kesin bir şekilde bilmek istersem ne olur? sonrası soru saat ve saniye var, tüm bu sıfırlama için ne?
2oppin


6
var d1=new Date(2011,0,1); // jan,1 2011
var d2=new Date(); // now

var diff=d2-d1,sign=diff<0?-1:1,milliseconds,seconds,minutes,hours,days;
diff/=sign; // or diff=Math.abs(diff);
diff=(diff-(milliseconds=diff%1000))/1000;
diff=(diff-(seconds=diff%60))/60;
diff=(diff-(minutes=diff%60))/60;
days=(diff-(hours=diff%24))/24;

console.info(sign===1?"Elapsed: ":"Remains: ",
             days+" days, ",
             hours+" hours, ",
             minutes+" minutes, ",
             seconds+" seconds, ",
             milliseconds+" milliseconds.");

4

Maalesef milisaniye sabit hesaplama güvenilir değil Tüm yanıtlar için teşekkürler, ancak denediğim fonksiyonlardan birkaçı ya 1'de başarısız oluyor. Bugünün tarihine yakın bir tarih 2. 1970 ya da bir artık yılda bir tarih.

Benim için en iyi yaklaşan ve artık yıl, 1970'teki yakın tarih, 29 şubat vb. Tüm senaryoları kapsayan yaklaşım.

var someday = new Date("8/1/1985");
var today = new Date();
var years = today.getFullYear() - someday.getFullYear();

// Reset someday to the current year.
someday.setFullYear(today.getFullYear());

// Depending on when that day falls for this year, subtract 1.
if (today < someday)
{
    years--;
}
document.write("Its been " + years + " full years.");

3

Moment.js kullanıyorsanız, tarih farkını bulmak oldukça basittir.

var now  = "04/09/2013 15:00:00";
var then = "04/09/2013 14:20:30";

moment.utc(moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"))).format("HH:mm:ss")

3
function DateDiff(b, e)
{
    let
        endYear = e.getFullYear(),
        endMonth = e.getMonth(),
        years = endYear - b.getFullYear(),
        months = endMonth - b.getMonth(),
        days = e.getDate() - b.getDate();
    if (months < 0)
    {
        years--;
        months += 12;
    }
    if (days < 0)
    {
        months--;
        days += new Date(endYear, endMonth, 0).getDate();
    }
    return [years, months, days];
}

[years, months, days] = DateDiff(
    new Date("October 21, 1980"),
    new Date("July 11, 2017")); // 36 8 20

3

Bence bunu yapmalı.

let today = new Date();
let form_date=new Date('2019-10-23')
let difference=form_date>today ? form_date-today : today-form_date
let diff_days=Math.floor(difference/(1000*3600*24))

2

Tarihler arasındaki farkı çerçevesiz bu şekilde uygulayabilirsiniz.

function getDateDiff(dateOne, dateTwo) {
        if(dateOne.charAt(2)=='-' & dateTwo.charAt(2)=='-'){
            dateOne = new Date(formatDate(dateOne));
            dateTwo = new Date(formatDate(dateTwo));
        }
        else{
            dateOne = new Date(dateOne);
            dateTwo = new Date(dateTwo);            
        }
        let timeDiff = Math.abs(dateOne.getTime() - dateTwo.getTime());
        let diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
        let diffMonths = Math.ceil(diffDays/31);
        let diffYears = Math.ceil(diffMonths/12);

        let message = "Difference in Days: " + diffDays + " " +
                      "Difference in Months: " + diffMonths+ " " + 
                      "Difference in Years: " + diffYears;
        return message;
     }

    function formatDate(date) {
         return date.split('-').reverse().join('-');
    }

    console.log(getDateDiff("23-04-2017", "23-04-2018"));

1

function daysInMonth (month, year) {
    return new Date(year, month, 0).getDate();
}
function getduration(){

let A= document.getElementById("date1_id").value
let B= document.getElementById("date2_id").value

let C=Number(A.substring(3,5))
let D=Number(B.substring(3,5))
let dif=D-C
let arr=[];
let sum=0;
for (let i=0;i<dif+1;i++){
  sum+=Number(daysInMonth(i+C,2019))
}
let sum_alter=0;
for (let i=0;i<dif;i++){
  sum_alter+=Number(daysInMonth(i+C,2019))
}
let no_of_month=(Number(B.substring(3,5)) - Number(A.substring(3,5)))
let days=[];
if ((Number(B.substring(3,5)) - Number(A.substring(3,5)))>0||Number(B.substring(0,2)) - Number(A.substring(0,2))<0){
days=Number(B.substring(0,2)) - Number(A.substring(0,2)) + sum_alter
}

if ((Number(B.substring(3,5)) == Number(A.substring(3,5)))){
console.log(Number(B.substring(0,2)) - Number(A.substring(0,2)) + sum_alter)
}

time_1=[]; time_2=[]; let hour=[];
 time_1=document.getElementById("time1_id").value
 time_2=document.getElementById("time2_id").value
  if (time_1.substring(0,2)=="12"){
     time_1="00:00:00 PM"
  }
if (time_1.substring(9,11)==time_2.substring(9,11)){
hour=Math.abs(Number(time_2.substring(0,2)) - Number(time_1.substring(0,2)))
}
if (time_1.substring(9,11)!=time_2.substring(9,11)){
hour=Math.abs(Number(time_2.substring(0,2)) - Number(time_1.substring(0,2)))+12
}
let min=Math.abs(Number(time_1.substring(3,5))-Number(time_2.substring(3,5)))
document.getElementById("duration_id").value=days +" days "+ hour+"  hour " + min+"  min " 
}
<input type="text" id="date1_id" placeholder="28/05/2019">
<input type="text" id="date2_id" placeholder="29/06/2019">
<br><br>
<input type="text" id="time1_id" placeholder="08:01:00 AM">
<input type="text" id="time2_id" placeholder="00:00:00 PM">
<br><br>
<button class="text" onClick="getduration()">Submit </button>
<br><br>
<input type="text" id="duration_id" placeholder="days hour min">


Bu kod, gün, saat ve dakika sayısı hakkında doğru sonuçlar verir
Maximus Su

Umarım onu ​​kullanırsınız
Maximus Su

0

Tamam, bunu yapmanın bir çok yolu var. Evet, düz eski JS kullanabilirsiniz. Sadece dene:

let dt1 = new Date()
let dt2 = new Date()

Date.prototype.setMinutes kullanarak geçişi taklit edelim ve menzil içinde olduğumuzdan emin olalım.

dt1.setMinutes(7)
dt2.setMinutes(42)
console.log('Elapsed seconds:',(dt2-dt1)/1000)

Alternatif olarak , js-joda gibi bazı kütüphaneleri kullanabilirsiniz , burada böyle şeyler (doğrudan dokümanlardan) kolayca yapabilirsiniz:

var dt1 = LocalDateTime.parse("2016-02-26T23:55:42.123");
var dt2 = dt1
  .plusYears(6)
  .plusMonths(12)
  .plusHours(2)
  .plusMinutes(42)
  .plusSeconds(12);

// obtain the duration between the two dates
dt1.until(dt2, ChronoUnit.YEARS); // 7
dt1.until(dt2, ChronoUnit.MONTHS); // 84
dt1.until(dt2, ChronoUnit.WEEKS); // 356
dt1.until(dt2, ChronoUnit.DAYS); // 2557
dt1.until(dt2, ChronoUnit.HOURS); // 61370
dt1.until(dt2, ChronoUnit.MINUTES); // 3682242
dt1.until(dt2, ChronoUnit.SECONDS); // 220934532

Çok daha fazla ofc kütüphanesi var, ancak js-joda'nın Java'da da kapsamlı bir şekilde test edildiği ek bir bonus var. Tüm bu testler js-joda'ya taşındı, aynı zamanda değişmez.


-1

JavaScript yalnızca zaman için çerçeveler kullandığından, Bitiş Zamanı - Zaman RN'nizi alacağınızdan, görünüşe göre 1000 kare = 1 saniye olduğu için 1000'e bölebileceğimiz için bu iyi çalışmalıdır. Bundan sonra temel zaman matematiğini kullanabilirsiniz, ancak bu kodda hala bir sorun vardır, çünkü hesaplama statik olduğundan, bir yıldaki farklı gün toplamını (360/365/366) telafi edemez, Hesaplamadan sonra zaman 0'dan düşükse null yapmaksa, tam olarak sorduğunuz şey olmasa da bu yardımcı olur :)

var now = new Date();
var end = new Date("End Time");
var total = (end - now) ;
var totalD =  Math.abs(Math.floor(total/1000));

var years = Math.floor(totalD / (365*60*60*24));
var months = Math.floor((totalD - years*365*60*60*24) / (30*60*60*24));
var days = Math.floor((totalD - years*365*60*60*24 - months*30*60*60*24)/ (60*60*24));
var hours = Math.floor((totalD - years*365*60*60*24 - months*30*60*60*24 - days*60*60*24)/ (60*60));
var minutes = Math.floor((totalD - years*365*60*60*24 - months*30*60*60*24 - days*60*60*24 - hours*60*60)/ (60));
var seconds = Math.floor(totalD - years*365*60*60*24 - months*30*60*60*24 - days*60*60*24 - hours*60*60 - minutes*60);

var Y = years < 1 ? "" : years + " Years ";
var M = months < 1 ? "" : months + " Months ";
var D = days < 1 ? "" : days + " Days ";
var H = hours < 1 ? "" : hours + " Hours ";
var I = minutes < 1 ? "" : minutes + " Minutes ";
var S = seconds < 1 ? "" : seconds + " Seconds ";
var A = years == 0 && months == 0 && days == 0 && hours == 0 && minutes == 0 && seconds == 0 ? "Sending" : " Remaining";

document.getElementById('txt').innerHTML = Y + M + D + H + I + S + A;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.