Ulangi rentang tanggal dengan JavaScript

141

Diberikan dua Date()objek, di mana satu lebih kecil dari yang lain, bagaimana cara saya mengulang setiap hari di antara tanggal?

for(loopDate = startDate; loopDate < endDate; loopDate += 1)
{

}

Apakah pengulangan semacam ini akan berhasil? Tapi bagaimana saya bisa menambahkan satu hari ke penghitung loop?

Terima kasih!

Tom Gullen
sumber

Jawaban:

212

Berikut cara melakukannya dengan memanfaatkan cara menambahkan satu hari menyebabkan tanggal bergulir ke bulan berikutnya jika perlu, dan tanpa dipusingkan dengan milidetik. Tabungan siang hari juga tidak menjadi masalah.

var now = new Date();
var daysOfYear = [];
for (var d = new Date(2012, 0, 1); d <= now; d.setDate(d.getDate() + 1)) {
    daysOfYear.push(new Date(d));
}

Perhatikan bahwa jika Anda ingin menyimpan tanggal, Anda harus membuat yang baru (seperti di atas dengan new Date(d)), atau Anda akan berakhir dengan setiap tanggal yang disimpan menjadi nilai akhir ddalam pengulangan.

David Johnstone
sumber
Jauh lebih mudah dibaca daripada semua jawaban lainnya. Menambahkan 86400000 milidetik setiap loop sangat tidak terbaca.
Owen
3
Berhati-hatilah dengan waktu musim panas. d.getDate () + 1 ketika d.getDate () = GMT N dan d.getDate () + 1 = GMT N - 1 d.getDate () + 1 mengembalikan hari yang sama dalam sebulan dua kali.
Rafael Fontes
1
Mengapa Date.now()saat mendefinisikan now? new Date() mengembalikan tanggal saat ini sebagai objek secara default . Memanggil Datetanpa newkonstruktor hanya memberi Anda string Tanggal yang kemudian Anda ubah menjadi objek Tanggal?
tatlar
Bagi saya new Date(2012, 0, 1);mengambil hari yang salah (sehari sebelumnya), new Date(Date.UTC(2012, 0, 1))bekerja dengan baik.
Tk421
Saya telah mencoba beberapa solusi di internet. Anehnya, terkadang ia melewatkan beberapa hari. Seperti 1.12, 2.12, 3.12, 5.12 ... (perhatikan bahwa 4.12 dilewati) saya tidak tahu mengapa itu terjadi ... Ada yang punya masalah ini dan menemukan solusinya?
Erik Kubica
76

Berdasarkan jawaban Tom Gullen.

var start = new Date("02/05/2013");
var end = new Date("02/10/2013");


var loop = new Date(start);
while(loop <= end){
   alert(loop);           

   var newDate = loop.setDate(loop.getDate() + 1);
   loop = new Date(newDate);
}
Tabares
sumber
Apa yang harus Anda impor untuk menggunakan ini?
DevAllanPer
3
@DevAllanPer bukan apa-apa, Dateadalah pengembang
global.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
12

Saya rasa saya menemukan jawaban yang lebih sederhana, jika Anda membiarkan diri Anda menggunakan Moment.js :

// cycle through last five days, today included
// you could also cycle through any dates you want, mostly for
// making this snippet not time aware
const currentMoment = moment().subtract(4, 'days');
const endMoment = moment().add(1, 'days');
while (currentMoment.isBefore(endMoment, 'day')) {
  console.log(`Loop at ${currentMoment.format('YYYY-MM-DD')}`);
  currentMoment.add(1, 'days');
}
<script src="https://cdn.jsdelivr.net/npm/moment@2/moment.min.js"></script>

vvo
sumber
9

Jika startDate dan endDate memang objek tanggal, Anda dapat mengonversinya ke dalam milidetik sejak tengah malam 1 Jan 1970, seperti ini:

var startTime = startDate.getTime(), endTime = endDate.getTime();

Kemudian Anda dapat melakukan loop dari satu ke yang lain dengan menambahkan loopTime sebanyak 86400000 (1000 * 60 * 60 * 24) - jumlah milidetik dalam satu hari:

for(loopTime = startTime; loopTime < endTime; loopTime += 86400000)
{
    var loopDay=new Date(loopTime)
    //use loopDay as you wish
}
jayarjo
sumber
1
+1, memberi saya cukup banyak untuk dikerjakan, saya menyertakan solusi yang berfungsi dalam pertanyaan saya
Tom Gullen
5
ini tidak berfungsi saat mengulang melewati perubahan waktu musim panas (di area di mana itu menjadi masalah). Solusi bagus sebaliknya.
chadgh
3
Anda tidak dapat berasumsi bahwa ada 86400000detik dalam sehari. Loop ini rentan terhadap perubahan penghematan siang hari dan kondisi edge lainnya.
Jeremy J Starcher
2
Selain DST, kondisi edge lainnya adalah "Leap Second". Sebuah satu perbedaan kedua tidak peduli - Tanggal dikonversi ke milidetik sesuai dengan detik pertama hari tertentu. Kesalahan satu detik dan Anda mendarat di hari sebelumnya.
Wojtek Kruszewski
5

Di sini kode kerja sederhana, bekerja untuk saya

var from = new Date(2012,0,1);
var to = new Date(2012,1,20);
    
// loop for every day
for (var day = from; day <= to; day.setDate(day.getDate() + 1)) {
      
   // your day is here

}

Amr Ibrahim
sumber
2
var start = new Date("2014-05-01"); //yyyy-mm-dd
var end = new Date("2014-05-05"); //yyyy-mm-dd

while(start <= end){

    var mm = ((start.getMonth()+1)>=10)?(start.getMonth()+1):'0'+(start.getMonth()+1);
    var dd = ((start.getDate())>=10)? (start.getDate()) : '0' + (start.getDate());
    var yyyy = start.getFullYear();
    var date = dd+"/"+mm+"/"+yyyy; //yyyy-mm-dd

    alert(date); 

    start = new Date(start.setDate(start.getDate() + 1)); //date increase by 1
}
MaxEcho
sumber
1

Berdasarkan Jawaban Tabare, saya harus menambahkan satu hari lagi di akhir, karena siklus terputus sebelumnya

var start = new Date("02/05/2013");
var end = new Date("02/10/2013");
var newend = end.setDate(end.getDate()+1);
var end = new Date(newend);
while(start < end){
   alert(start);           

   var newDate = start.setDate(start.getDate() + 1);
   start = new Date(newDate);
}
Carlos Vizcaya Savchenco
sumber
0

Jika Anda menginginkan cara yang efisien dengan milidetik:

var daysOfYear = [];
for (var d = begin; d <= end; d = d + 86400000) {
    daysOfYear.push(new Date(d));
}
Guilherme Simão Couto
sumber
0

Mari kita asumsikan Anda mendapatkan tanggal mulai dan tanggal akhir dari UI dan menyimpannya dalam variabel cakupan di pengontrol.

Kemudian mendeklarasikan sebuah array yang akan direset pada setiap pemanggilan fungsi sehingga pada pemanggilan fungsi berikutnya data baru dapat disimpan.

var dayLabel = [];

Ingatlah untuk menggunakan Tanggal baru (variabel awal Anda) karena jika Anda tidak menggunakan tanggal baru dan langsung menetapkannya ke variabel, fungsi setDate akan mengubah nilai variabel asal di setiap iterasi`

for (var d = new Date($scope.startDate); d <= $scope.endDate; d.setDate(d.getDate() + 1)) {
                dayLabel.push(new Date(d));
            }
Utkarsh Joshi
sumber
-2

Berdasarkan jawaban Jayarjo:

var loopDate = new Date();
loopDate.setTime(datFrom.valueOf());

while (loopDate.valueOf() < datTo.valueOf() + 86400000) {

    alert(loopDay);

    loopDate.setTime(loopDate.valueOf() + 86400000);
}
Tom Gullen
sumber
Satu komentar untuk ini adalah bahwa perbandingan kurang dari lebih disukai daripada! =, Seperti ketika loop selama beberapa bulan karena alasan tertentu! = Perbandingan tidak pernah aktif.
Tom Gullen
1
Selain DST, kondisi edge lainnya adalah "Leap Second". Sebuah satu perbedaan kedua tidak peduli - Tanggal dikonversi ke milidetik sesuai dengan detik pertama hari tertentu. Kesalahan satu detik dan Anda mendarat di hari sebelumnya.
Wojtek Kruszewski