วนรอบช่วงวันที่ด้วย JavaScript


141

เมื่อพิจารณาจากDate()วัตถุสองชิ้นโดยที่วัตถุหนึ่งน้อยกว่าอีกชิ้นหนึ่งฉันจะวนรอบทุกวันระหว่างวันที่ได้อย่างไร

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

}

การวนซ้ำแบบนี้จะใช้ได้หรือไม่? แต่ฉันจะเพิ่มหนึ่งวันในตัวนับลูปได้อย่างไร?

ขอบคุณ!

คำตอบ:


212

ต่อไปนี้เป็นวิธีที่ทำได้โดยใช้วิธีการเพิ่มหนึ่งวันทำให้วันที่นั้นเลื่อนไปยังเดือนถัดไปหากจำเป็นและไม่ต้องวุ่นวายกับมิลลิวินาที การประหยัดเวลากลางวันก็ไม่ใช่ปัญหาเช่นกัน

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

โปรดทราบว่าหากคุณต้องการจัดเก็บวันที่คุณจะต้องสร้างวันที่ใหม่ (ตามที่ระบุไว้ด้านบนnew Date(d)) มิฉะนั้นคุณจะลงเอยด้วยวันที่ที่จัดเก็บไว้ทั้งหมดเป็นค่าสุดท้ายของdการวนซ้ำ


อ่านได้ง่ายกว่าคำตอบอื่น ๆ ทั้งหมด การเพิ่ม 86400000 มิลลิวินาทีแต่ละลูปนั้นไม่สามารถอ่านได้มากนัก
Owen

3
ระมัดระวังเวลาออมแสง d.getDate () + 1 เมื่อ d.getDate () = GMT N และ d.getDate () + 1 = GMT N - 1 d.getDate () + 1 ส่งคืนวันเดียวกันของเดือนสองครั้ง
Rafael Fontes

1
ทำไมDate.now()เมื่อกำหนดnow? ส่งกลับวันที่ปัจจุบันเป็นวัตถุโดยค่าเริ่มต้นnew Date() การโทรDateโดยไม่มีตัวnewสร้างจะให้สตริงวันที่ซึ่งคุณจะแปลงเป็นวัตถุวันที่หรือไม่?
tatlar

สำหรับฉันnew Date(2012, 0, 1);คือรับวันที่ไม่ถูกต้อง (หนึ่งวันก่อนหน้านี้) new Date(Date.UTC(2012, 0, 1))ทำงานได้ดี
Tk421

ฉันได้ลองใช้วิธีแก้ปัญหาหลายอย่างบนอินเทอร์เน็ต แปลกคือบางครั้งบางวันก็ข้ามไป เช่น 1.12, 2.12, 3.12, 5.12 ... (สังเกตว่า 4.12 ถูกข้ามไป) ฉันไม่รู้ว่าทำไมมันถึงเกิดขึ้น ... ใครมีปัญหานี้และพบวิธีแก้ไข?
Erik Kubica

76

จากคำตอบของ 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);
}

คุณต้องนำเข้าอะไรจึงจะใช้สิ่งนี้ได้?
DevAllanPer

3
@DevAllanPer nothing Dateเป็นผู้พัฒนา
Dmitri Pisarev

12

ฉันคิดว่าฉันพบคำตอบที่ง่ายกว่านี้หากคุณอนุญาตให้ตัวเองใช้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>


9

หาก startDate และ endDate เป็นอ็อบเจ็กต์วันที่คุณสามารถแปลงเป็นจำนวนมิลลิวินาทีได้ตั้งแต่เที่ยงคืน 1 ม.ค. 1970 เช่นนี้

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

จากนั้นคุณสามารถวนซ้ำจากที่หนึ่งไปยังอีกที่เพิ่มขึ้น loopTime โดย 86400000 (1,000 * 60 * 60 * 24) - จำนวนมิลลิวินาทีในหนึ่งวัน:

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

1
+1 ให้ฉันมากพอที่จะทำงานได้ ive รวมวิธีการแก้ปัญหาในคำถามของฉัน
Tom Gullen

5
สิ่งนี้ใช้ไม่ได้เมื่อวนลูปผ่านการเปลี่ยนแปลงเวลาออมแสง (ในพื้นที่ที่เป็นปัญหา) ทางออกที่ดีเป็นอย่างอื่น
chadgh

3
คุณไม่สามารถสมมติว่ามี86400000วินาทีในหนึ่งวัน วงนี้เปราะบางต่อการเปลี่ยนแปลงการออมแสงและเงื่อนไขขอบอื่น ๆ
Jeremy J Starcher

2
นอกจาก DST แล้วเงื่อนไขขอบอีกประการหนึ่งคือ "Leap Second" ความแตกต่างที่สองไม่ว่า - วันที่แปลงเป็นมิลลิวินาทีตรงตามลักษณะที่สองครั้งแรกในวันที่กำหนด เกิดข้อผิดพลาดหนึ่งวินาทีและคุณมาถึงในวันก่อนหน้า
Wojtek Kruszewski


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

จากคำตอบของ Tabare ฉันต้องเพิ่มอีกหนึ่งวันในตอนท้ายเนื่องจากวงจรจะถูกตัดก่อน

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

หากคุณต้องการวิธีที่มีประสิทธิภาพในระดับมิลลิวินาที:

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

0

สมมติว่าคุณได้รับวันที่เริ่มต้นและวันที่สิ้นสุดจาก UI และเก็บไว้ในตัวแปรขอบเขตในตัวควบคุม

จากนั้นประกาศอาร์เรย์ซึ่งจะได้รับการรีเซ็ตทุกการเรียกใช้ฟังก์ชันเพื่อให้สามารถจัดเก็บข้อมูลใหม่ในการเรียกใช้ฟังก์ชันในครั้งถัดไป

var dayLabel = [];

อย่าลืมใช้วันที่ใหม่ (ตัวแปรเริ่มต้นของคุณ)เพราะถ้าคุณไม่ใช้วันที่ใหม่และกำหนดให้กับตัวแปรโดยตรงฟังก์ชัน setDate จะเปลี่ยนค่าตัวแปรต้นกำเนิดในการวนซ้ำแต่ละครั้ง '

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

-2

จากคำตอบของ Jayarjo:

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

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

    alert(loopDay);

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

ความคิดเห็นหนึ่งสำหรับเรื่องนี้คือการเปรียบเทียบที่น้อยกว่านั้นต้องการมากกว่า! = เนื่องจากเมื่อวนซ้ำหลายเดือนด้วยเหตุผลบางประการการเปรียบเทียบ! = จะไม่เริ่มทำงาน
Tom Gullen

1
นอกจาก DST แล้วเงื่อนไขขอบอีกประการหนึ่งคือ "Leap Second" ความแตกต่างที่สองไม่ว่า - วันที่แปลงเป็นมิลลิวินาทีตรงตามลักษณะที่สองครั้งแรกในวันที่กำหนด เกิดข้อผิดพลาดหนึ่งวินาทีและคุณมาถึงในวันก่อนหน้า
Wojtek Kruszewski
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.