Bagaimana cara menghitung perbedaan tanggal dalam JavaScript?


181

Saya ingin menghitung perbedaan tanggal dalam hari, jam, menit, detik, milidetik, nanodetik. Bagaimana saya bisa melakukannya?



1
Solusi di bawah ini akan rusak jika dua tanggal yang terlibat berada di zona waktu yang berbeda. Lihat pertanyaannya di untuk solusi stackoverflow.com/questions/3224834/… yang lebih akurat ?
Shyam Habarakada

Jawaban:


219

Dengan asumsi Anda memiliki dua Dateobjek , Anda bisa menguranginya untuk mendapatkan perbedaan dalam milidetik:

var difference = date2 - date1;

Dari sana, Anda dapat menggunakan aritmatika sederhana untuk mendapatkan nilai-nilai lainnya.


38
Inilah jawaban yang tepat. Misalnya: untuk mendapatkan selisih hari Math.floor((date2 - date1) / (1000*60*60*24))- untuk selisih pada unit lain, sesuaikan penyebutnya (nilai dasarnya adalah dalam ms).
trisweb

33
Tidak ada aritmatika "sederhana" untuk mengkonversi milidetik ke tahun. Anda harus mengetahui tahun bissextile, zona waktu, dan beberapa hari memiliki 23 atau 25 jam. Beberapa tahun memiliki 365,25 hari, jadi tidak ada aritmatika sederhana di sini (masih mencari solusi yang akurat).
Alexandre Salomé

6
@Alexandre: Pertanyaannya tidak pernah ditanyakan selama bertahun-tahun. Memang, menghitung perbedaan tahun adalah nontrivial. Namun, selama berhari-hari, itu benar, seandainya tanggalnya berada di zona waktu yang sama (asumsi yang tidak masuk akal). Sejauh yang saya tahu, satu hari didefinisikan sebagai 24 jam, dan setiap 'variasi' dalam hal itu karena Daylight Savings Time sebenarnya adalah pergantian zona waktu. Jika Anda belum membedakan zona waktu, mencoba mencari tahu perbedaan waktu akan menempatkan Anda di dunia yang terluka, paling tidak karena pergantian waktu 'pengulangan' DST. Tetap di satu zona waktu, dan semuanya bekerja.
icktoofay

12
@ trisweb — bahkan sesuatu yang sederhana seperti mendapatkan perbedaan dalam beberapa hari lebih kompleks daripada komentar Anda. Berapa hari antara jam 10 malam hari Selasa dan jam 9 pagi hari Rabu? Algoritme Anda mengatakan 0. Orang lain mungkin berpikir 1.
RobG

@RGG relativis bahkan mungkin berpikir lebih dari 1 atau kurang dari 0. Itu semua tergantung pada pengamat.
Innocent 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));

Sampel kode diambil dari sini .


Ini hanya mengembalikan perbedaan tanggal dalam format yang diberikan jika digunakan sebagai penghitung tunggal. Misalnya jika Anda ingin 3 bulan 4 hari dan 5 jam itu TIDAK akan menghasilkan hasil tersebut. Lebih dalam garis 3 bulan 96 hari dan banyak jam.
Joris Kroos

30

Solusi lain adalah mengonversi perbedaan ke objek Tanggal baru dan mendapatkan tahun tanggal itu (beda dari 1970), bulan, hari dll.

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

Jadi perbedaannya seperti "3 tahun 6 bulan dan 4 hari". Jika Anda ingin mengambil perbedaan dalam gaya yang dapat dibaca manusia, itu dapat membantu Anda.


Bukan itu artinya! Kami menginginkan perbedaan SELURUH! Dalam contoh ini, perbedaan dalam hari adalah 1281, bukan 4!
chaim.dev

3
@ chaim.dev "Jika Anda ingin mengambil perbedaan dalam gaya yang dapat dibaca manusia, itu dapat membantu Anda."
Murat Çorlu

7
Ini tidak bisa diandalkan. Gagal memperhitungkan panjang bulan yang bervariasi, atau tahun kabisat dan anomali lainnya.
Marc Durdin

2
Terima kasih Murat, solusi ini telah menyelesaikan masalah saya. Apa yang saya benar-benar inginkan Itu harus bekerja dengan cara yang sama seperti php.
Ritesh Patadiya

27

Ekspresi seperti "perbedaan hari" tidak pernah sesederhana kelihatannya. Jika Anda memiliki tanggal berikut:

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

perbedaan waktu adalah 2 menit, haruskah "perbedaan hari" menjadi 1 atau 0? Masalah serupa muncul untuk setiap ekspresi perbedaan dalam bulan, tahun, atau apa pun karena tahun, bulan, dan hari memiliki panjang dan waktu yang berbeda (misalnya hari mulai penghematan siang hari adalah 1 jam lebih pendek dari biasanya dan dua jam lebih pendek dari hari yang Ini berakhir).

Berikut adalah fungsi untuk perbedaan hari yang mengabaikan waktu, yaitu untuk tanggal di atas ia mengembalikan 1.

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

Ini bisa lebih ringkas:

/*  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
@ kasarovskizebear — diuji di IE, Firefox dan Safari, berfungsi dengan baik. Ini menggunakan ECMAScript dasar yang saya harapkan dapat berfungsi di browser apa pun, apa yang tidak bekerja untuk Anda?
RobG

Saya meletakkannya di halaman pengujian, dan itu bekerja dengan baik di chrome, tetapi saya tetap mendapatkan null kembali di IE9 dan FF terbaru
mnsr

@ RafiB. — Saya tidak tahu bagaimana menurut Anda satu lebih akurat daripada yang lain, mereka pada dasarnya melakukan hal yang sama yaitu menghitung perbedaan dalam seluruh hari menggunakan nilai waktu UTC. Ambiguitas dalam pertanyaan itu tidak diklarifikasi. Jika ya, itu dapat mengarah ke solusi yang berbeda.
RobG

@RobG Harap edit contoh di komentar solusi yang lebih ringkas. Bulan seharusnya '12' bukan '22'
S.aad

1
@ IgorKudryashov — maaf, saya tidak mengerti. 2000 adalah tahun kabisat, jadi 28 Feb 2000 hingga 28 Feb 2001 adalah 366 hari. Dalam tahun non-kabisat, 365 hari. Saya telah menambahkan beberapa contoh lagi.
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>

Tidak membantu saya. Tidak dapat memperpanjang ini hingga berbulan-bulan atau bertahun-tahun dalam pendekatan yang sama.
tomazahlin

9

gunakan Moment.js untuk semua perhitungan tanggal-waktu terkait JavaScript Anda

Jawaban untuk pertanyaan Anda adalah:

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

Detail lengkap dapat ditemukan di sini


4
Dan merangkul 400+ Kb ekstra untuk perbedaan tanggal belaka.
Romeo Mihalcea

@RomeoMihalcea Current minified moment.js 2.22.2 dengan satu lokal adalah 53 KB, 17 KB di-gzip. Saya mengerti keprihatinan Anda. Ini adalah perpustakaan yang sangat besar untuk digunakan untuk satu fungsi sederhana, tetapi menangani begitu banyak kebiasaan terkait tanggal / waktu sehingga sering sepadan.
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      
}

Terima kasih atas solusinya :)
bhagirathi

Sebagian besar solusi yang saya temukan tidak berfungsi atau terlalu panjang lebar. Solusi Anda sejauh ini adalah yang paling sederhana dan bekerja persis seperti yang dimaksudkan! Cheers :)
Bruce

bagaimana jika saya ingin tahu perbedaan dengan lebih tepat dari satu jam? dalam pertanyaan posting ada jam dan detik, untuk apa semua pengaturan angka ini?
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

Maaf tetapi perhitungan milidetik datar tidak dapat diandalkan Terima kasih atas semua tanggapan, tetapi beberapa fungsi yang saya coba gagal pada 1. Tanggal dekat tanggal hari ini 2. Tanggal di tahun 1970 atau 3. Tanggal di tahun kabisat.

Pendekatan yang paling berhasil bagi saya dan mencakup semua skenario misalnya tahun kabisat, hampir tanggal pada tahun 1970, feb 29 dll.

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

Jika Anda menggunakan moment.js maka cukup mudah untuk menemukan perbedaan tanggal.

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

Saya pikir ini harus dilakukan.

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

Ini adalah bagaimana Anda dapat mengimplementasikan perbedaan antara tanggal tanpa kerangka kerja.

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


Kode ini memberikan hasil yang akurat tentang hari, waktu, dan bahkan menit
Maximus Su

Semoga kalian menggunakannya
Maximus Su

0

Oke, ada banyak cara untuk melakukannya. Ya, Anda dapat menggunakan JS tua biasa. Coba saja:

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

Mari kita meniru bagian menggunakan Date.prototype.setMinutes dan pastikan kita berada dalam jangkauan.

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

Atau Anda dapat menggunakan beberapa perpustakaan seperti js-joda , di mana Anda dapat dengan mudah melakukan hal-hal seperti ini (langsung dari dokumen):

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

Ada lebih banyak perpustakaan ofc, tetapi js-joda memiliki bonus tambahan yang tersedia juga di Jawa, di mana ia telah diuji secara luas. Semua tes tersebut telah dimigrasikan ke js-joda, itu juga tidak berubah.


-1

ini akan berfungsi dengan baik jika Anda hanya perlu menunjukkan waktu yang tersisa, karena JavaScript menggunakan bingkai untuk waktunya Anda akan mendapatkan Waktu Akhir Anda - Waktu RN setelah itu kami dapat membaginya dengan 1000 karena ternyata 1000 frame = 1 detik, setelah itu Anda dapat menggunakan matematika dasar waktu, tetapi masih ada masalah dengan kode ini, karena perhitungannya statis, itu tidak dapat mengkompensasi total hari yang berbeda dalam setahun (360/365/366), kumpulan dari JIKA setelah perhitungan adalah menjadikannya nol jika waktunya lebih rendah dari 0, harap ini membantu walaupun itu bukan yang Anda minta :)

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;
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.