Vòng lặp JavaScript giữa các phạm vi ngày


135

Cho hai Date()đối tượng, trong đó một đối tượng nhỏ hơn đối tượng kia, làm thế nào để tôi lặp lại mỗi ngày giữa các ngày?

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

}

Loại vòng lặp này sẽ làm việc? Nhưng làm thế nào tôi có thể thêm một ngày vào bộ đếm vòng lặp?

Cảm ơn!

Câu trả lời:


200

Đây là một cách để làm điều đó bằng cách sử dụng cách thêm một ngày làm cho ngày chuyển sang tháng tiếp theo nếu cần thiết và không bị rối tung với mili giây. Tiết kiệm ánh sáng ban ngày cũng không phải là một vấn đề.

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

Lưu ý rằng nếu bạn muốn lưu trữ ngày, bạn sẽ cần tạo một ngày mới (như trên với new Date(d)), nếu không, bạn sẽ kết thúc với mỗi ngày được lưu trữ là giá trị cuối cùng của dvòng lặp.


Vì vậy, dễ đọc hơn nhiều so với tất cả các câu trả lời khác. Thêm 86400000 giây mỗi vòng không thể đọc được.
Owen

1
Hãy cẩn thận với thời gian tiết kiệm ánh sáng ban ngày. d.getDate () + 1 khi d.getDate () = GMT N và d.getDate () + 1 = GMT N - 1 d.getDate () + 1 trả về cùng một ngày hai tháng.
Phông chữ Rafael

1
Tại sao phải làm Date.now()khi xác định now? new Date() trả về ngày hiện tại dưới dạng một đối tượng theo mặc định . Gọi Datemà không có hàm newtạo chỉ cung cấp cho bạn chuỗi Ngày mà sau đó bạn chuyển đổi thành đối tượng Ngày?
tatlar

Đối với tôi new Date(2012, 0, 1);là chọn ngày không chính xác (một ngày trước), new Date(Date.UTC(2012, 0, 1))làm việc tốt.
Tk421

Tôi đã thử nhiều giải pháp trên internet. Điều kỳ lạ là đôi khi nó bỏ qua một số ngày. Giống như 1.12, 2.12, 3.12, 5.12 ... (lưu ý rằng 4.12 bị bỏ qua) tôi không biết tại sao nó lại xảy ra ... Bất cứ ai cũng có vấn đề này và tìm ra giải pháp?
Erik Kubica


9

Nếu startDate và endDate thực sự là các đối tượng ngày, bạn có thể chuyển đổi chúng thành số mili giây kể từ nửa đêm ngày 1 tháng 1 năm 1970, như thế này:

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

Sau đó, bạn có thể lặp từ vòng này sang vòng lặp tăng dần khác bằng 86400000 (1000 * 60 * 60 * 24) - số mili giây trong một ngày:

for(loopTime = startTime; loopTime < endTime; loopTime += 86400000)
{
    var loopDay=new Date(loopTime)
    //use loopDay as you wish
}

1
+1, đã cho tôi đủ để làm việc, tôi đã bao gồm giải pháp làm việc trong câu hỏi của tôi
Tom Gullen

5
điều này không hoạt động khi lặp qua thay đổi thời gian tiết kiệm ánh sáng ban ngày (ở những khu vực có vấn đề). Giải pháp tốt khác.
chadgh

3
Bạn không thể cho rằng có 86400000vài giây trong một ngày. Vòng lặp này rất dễ bị thay đổi khi tiết kiệm ánh sáng ban ngày và các điều kiện cạnh khác.
Jeremy J Starcher

2
Ngoài DST, một điều kiện cạnh khác là "Bước nhảy vọt thứ hai". Sự khác biệt một giây không thành vấn đề - Ngày được chuyển đổi thành mili giây tương ứng với giây đầu tiên của một ngày nhất định. Một lỗi thứ hai và bạn hạ cánh vào ngày hôm trước.
Wojtek Kruszewski

9

Tôi nghĩ rằng tôi đã tìm thấy một câu trả lời thậm chí đơn giản hơn, nếu bạn cho phép mình sử dụng 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>


5

Đây là mã làm việc đơn giản, làm việc cho tôi

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

}


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
}

1

Dựa trên câu trả lời của Tabare, tôi đã phải thêm một ngày nữa vào cuối, vì chu kỳ đã bị cắt trước

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

0

Nếu bạn muốn một cách hiệu quả với mili giây:

var daysOfYear = [];
for (var d = begin; d <= end; d = d + 86400000) {
    daysOfYear.push(new Date(d));
}

0

Giả sử bạn đã nhận được ngày bắt đầu và ngày kết thúc từ UI và lưu nó trong biến phạm vi trong bộ điều khiển.

Sau đó khai báo một mảng sẽ được thiết lập lại trên mỗi lệnh gọi hàm để trong lần gọi tiếp theo cho hàm, dữ liệu mới có thể được lưu trữ.

var dayLabel = [];

Hãy nhớ sử dụng Ngày mới (biến bắt đầu của bạn) bởi vì nếu bạn không sử dụng ngày mới và trực tiếp gán nó cho biến thì hàm setDate sẽ thay đổi giá trị biến gốc trong mỗi lần lặp`

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

-2

Dựa trên câu trả lời của Jayarjo:

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

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

    alert(loopDay);

    loopDate.setTime(loopDate.valueOf() + 86400000);
}

Một nhận xét cho điều này là một so sánh ít hơn so với được ưa thích hơn! =, Vì khi vòng lặp trong nhiều tháng vì một số lý do, so sánh không bao giờ kích hoạt.
Tom Gullen

1
Ngoài DST, một điều kiện cạnh khác là "Bước nhảy vọt thứ hai". Sự khác biệt một giây không thành vấn đề - Ngày được chuyển đổi thành mili giây tương ứng với giây đầu tiên của một ngày nhất định. Một lỗi thứ hai và bạn hạ cánh vào ngày hôm trước.
Wojtek Kruszewski
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.