Min / Max tanggal dalam larik?

106

Bagaimana saya bisa mengetahui tanggal minimum dan maksimum dari serangkaian tanggal? Saat ini, saya membuat array seperti ini:

var dates = [];
dates.push(new Date("2011/06/25"))
dates.push(new Date("2011/06/26"))
dates.push(new Date("2011/06/27"))
dates.push(new Date("2011/06/28"))

Apakah ada fungsi bawaan untuk melakukan ini atau saya akan menulis sendiri?

Legenda
sumber

Jawaban:

137

Kode diuji dengan IE, FF, Chrome dan berfungsi dengan baik:

var dates=[];
dates.push(new Date("2011/06/25"))
dates.push(new Date("2011/06/26"))
dates.push(new Date("2011/06/27"))
dates.push(new Date("2011/06/28"))
var maxDate=new Date(Math.max.apply(null,dates));
var minDate=new Date(Math.min.apply(null,dates));
Andrew D.
sumber
1
Konversi ke nomor tidak diterapkan untuk string '2011/06/25', tetapi untuk Tanggal baru ('2011/06/25'). Nomor (Tanggal baru ('2011/06/25')) === 1308949200000. Kode diuji di Chrome, IE, FF
Andrew D.
@RobG - Apa yang Anda maksud dengan "tanggal string"?
Andrew D.
mis dates.push('2011/06/05'). Dengan menggunakan string, array dapat dengan mudah diurutkan dan nilai anggota pertama dan terakhir dikembalikan dan dikonversi ke tanggal jika perlu.
RobG
10
@RobG - dalam pertanyaan di atas, array berisi objek Tanggal, bukan "string tanggal" - respons juga untuk objek Tanggal. Menggunakan "string tanggal" adalah praktik yang sangat buruk dalam beberapa kasus. Bandingkan dua string tanggal berikutnya: "2011/06/05" dan "2011/06/05 00:00:00". 1) sebagai string: ("2011/06/05" === "2011/06/05 00:00:00"): hasilnya salah; 2) sebagai objek Tanggal (dengan konversi ke angka): Number (new Date ("2011/06/05")) === Number (new Date ("2011/06/05 00:00:00")): hasil benar - adalah hasil yang benar!
Andrew D.
@Distroartonline. Jika dateString konsisten, katakanlah YYYY/MM/DD HH:MM:SSdan ada banyak string yang terlibat, apakah Anda akan merekomendasikan perbandingan atau perbandingan string Number(new Date(dateString))?
BlackPanther
83

Sesuatu seperti:

var min = dates.reduce(function (a, b) { return a < b ? a : b; }); 
var max = dates.reduce(function (a, b) { return a > b ? a : b; });

Diuji di Chrome 15.0.854.0 dev


sumber
Array.reduce()tidak tersedia di IE sebelum IE9. Ide yang bagus.
jfriend00
1
Array.reduce () dapat diimplementasikan dengan fungsi setara javascript
Andrew D.
Tepatnya, baca tentang itu di Eloquent Javascript :function foreach(func, array) { for(var i = 0; i != array.length; ++i) { func(array[i]); } } function reduce(combine, base, array) { foreach(function(element) { base = combine(base, element); }, array); return base; }
blaze
1
IE <9 bisa mati, dan memang, sekarang hanya menyumbang 9,3% dari penggunaan browser global per April 2013.
wprl
3
Solusi pengurangan berfungsi untuk string dan untuk objek Tanggal.
Benoit
33

_.mindan _.maxbekerja pada susunan tanggal; gunakan jika Anda menggunakan Lodash atau Underscore, dan pertimbangkan untuk menggunakan Lodash (yang menyediakan banyak fungsi utilitas seperti ini) jika Anda belum melakukannya.

Sebagai contoh,

_.min([
    new Date('2015-05-08T00:07:19Z'),
    new Date('2015-04-08T00:07:19Z'),
    new Date('2015-06-08T00:07:19Z')
])

akan mengembalikan tanggal kedua dalam larik (karena ini adalah yang paling awal).

Mark Amery
sumber
3
Tidak langsung menjawab pertanyaan OP. OP menanyakan apakah metode built-in tersedia di JavaScript. Jadi, meskipun _.min & _.max dapat digunakan untuk mencari tanggal min atau maks, tetapi bukan itu yang dicari OP. Juga, pertimbangan perpustakaan utilitas adalah topik yang memiliki pendapat.
detj
13
Saya dengan hormat tidak setuju dan berpikir ini adalah jawaban yang berguna, @detj - pertanyaan OP seperti yang saat ini digembar-gemborkan menganggap bahwa ada fungsi bawaan atau dia harus menulis sendiri, tetapi ini tidak benar. Tampaknya masuk akal bagi saya untuk menunjukkan pustaka utilitas sebagai alternatif untuk salah satu solusi yang diusulkan OP. Tetapi alasan Anda dapat dipertahankan, dan suara Anda adalah milik Anda sendiri.
Mark Amery
16

Sama seperti apply, sekarang dengan spread :

const maxDate = new Date(Math.max(...dates));

(bisa menjadi komentar untuk jawaban terbaik)

lvd
sumber
12

Karena tanggal diubah menjadi periode UNIX (angka), Anda dapat menggunakan Math.max / menit untuk mencari:

var maxDate = Math.max.apply(null, dates)
// convert back to date object
maxDate = new Date(maxDate)

(diuji di chrome saja, tetapi seharusnya berfungsi di sebagian besar browser)

Ricardo Tomasi
sumber
8

** Gunakan Operator Spread | ES6 **

let datesVar = [ 2017-10-26T03:37:10.876Z,
  2017-10-27T03:37:10.876Z,
  2017-10-23T03:37:10.876Z,
  2015-10-23T03:37:10.876Z ]

Math.min(...datesVar);

Itu akan memberikan tanggal minimum dari array.

Singkatannya Math.min.apply (null, ArrayOfdates);

Rudresh Ajgaonkar
sumber
1
Jika Anda tidak menyukai, silakan beri komentar. Mengapa ini pilihan yang buruk? Saya suka sintaksnya dan untuk array kecil, penalti kinerja dapat diabaikan.
GijsjanB
1
Saya tidak disukai. Jawaban Rudresh adalah duplikat jawaban saya di atas. Tidak tahu mengapa orang tidak menyukai ini. Ini adalah satu baris kode versus banyak baris.
3
Ini mengembalikan angka bukan tanggal jadi Anda harus mengubahnya kembali menjadi tanggal. Tapi sebaliknya cukup elegan.
Tomáš Hübelbauer
6

ONELINER :

var min= dates.sort((a,b)=>a-b)[0], max= dates.slice(-1)[0];

menghasilkan variabel mindan max, kompleksitas O (nlogn) , contoh yang dapat diedit di sini . Jika array Anda memiliki nilai tanpa tanggal (like null), bersihkan dulu dengan dates=dates.filter(d=> d instanceof Date);.

Kamil Kiełczewski
sumber
2
var max_date = dates.sort(function(d1, d2){
    return d2-d1;
})[0];
wong2
sumber
1

Jawaban di atas tidak menangani nilai kosong / tidak ditentukan untuk memperbaikinya saya menggunakan kode di bawah ini dan mengganti kosong dengan NA:

function getMax(dateArray, filler) {
      filler= filler?filler:"";
      if (!dateArray.length) {
        return filler;
      }
      var max = "";
      dateArray.forEach(function(date) {
        if (date) {
          var d = new Date(date);
          if (max && d.valueOf()>max.valueOf()) {
            max = d;
          } else if (!max) {
            max = d;
          }
        }
      });
      return max;
    };
console.log(getMax([],"NA"));
console.log(getMax(datesArray,"NA"));
console.log(getMax(datesArray));

function getMin(dateArray, filler) {
 filler = filler ? filler : "";
  if (!dateArray.length) {
    return filler;
  }
  var min = "";
  dateArray.forEach(function(date) {
    if (date) {
      var d = new Date(date);
      if (min && d.valueOf() < min.valueOf()) {
        min = d;
      } else if (!min) {
        min = d;
      }
    }
  });
  return min;
}

console.log(getMin([], "NA"));
console.log(getMin(datesArray, "NA"));
console.log(getMin(datesArray));

Saya telah menambahkan demo javascript biasa di sini dan menggunakannya sebagai filter dengan AngularJS di codepen ini

Samdeesh
sumber
0

Ini adalah cara yang sangat bagus untuk melakukan ini (Anda bisa mendapatkan maksimum array objek menggunakan salah satu properti objek): Math.max.apply(Math,array.map(function(o){return o.y;}))

Ini adalah jawaban yang diterima untuk halaman ini: Menemukan nilai maksimal atribut dalam larik objek


sumber
-2

Menggunakan Moment , Underscore dan jQuery , untuk mengulang array tanggal.

Contoh JSON:

"workerList": [{        
        "shift_start_dttm": "13/06/2017 20:21",
        "shift_end_dttm": "13/06/2017 23:59"
    }, {
        "shift_start_dttm": "03/04/2018 00:00",
        "shift_end_dttm": "03/05/2018 00:00"        
    }]

Javascript:

function getMinStartDttm(workerList) {  
    if(!_.isEmpty(workerList)) {
        var startDtArr = [];
        $.each(d.workerList, function(index,value) {                
            startDtArr.push(moment(value.shift_start_dttm.trim(), 'DD/MM/YYYY HH:mm')); 
         });            
         var startDt = _.min(startDtArr);           
         return start.format('DD/MM/YYYY HH:mm');
    } else {
        return '';
    }   
}

Semoga membantu.

Siva Anand
sumber