简体   繁体   English

使用 JavaScript 遍历日期范围

[英]Loop through a date range with JavaScript

Given two Date() objects, where one is less than the other, how do I loop every day between the dates?给定两个Date()对象,其中一个小于另一个,我如何在日期之间每天循环?

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

}

Would this sort of loop work?这种循环会起作用吗? But how can I add one day to the loop counter?但是我怎样才能将一天添加到循环计数器中呢?

Thanks!谢谢!

Here's a way to do it by making use of the way adding one day causes the date to roll over to the next month if necessary, and without messing around with milliseconds.这是一种方法,通过使用添加一天的方式使日期在必要时滚动到下个月,并且不会弄乱毫秒。 Daylight savings aren't an issue either.夏令时也不是问题。

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

Note that if you want to store the date, you'll need to make a new one (as above with new Date(d) ), or else you'll end up with every stored date being the final value of d in the loop.请注意,如果您想存储日期,则需要创建一个新new Date(d)如上使用new Date(d) ),否则您将最终将每个存储的日期作为循环中d的最终值.

Based on Tom Gullen´s answer.基于汤姆古伦的回答。

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

I think I found an even simpler answer, if you allow yourself to use Moment.js :如果您允许自己使用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>

If startDate and endDate are indeed date objects you could convert them to number of milliseconds since midnight Jan 1, 1970, like this:如果 startDate 和 endDate 确实是日期对象,您可以将它们转换为自 1970 年 1 月 1 日午夜以来的毫秒数,如下所示:

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

Then you could loop from one to another incrementing loopTime by 86400000 (1000*60*60*24) - number of milliseconds in one day:然后你可以从一个循环到另一个循环时间增加 86400000 (1000*60*60*24) - 一天的毫秒数:

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

Here simple working code, worked for me这是简单的工作代码,对我有用

 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 }

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
}

As a function,作为 function,

 function getDatesFromDateRange(from, to) { const dates = []; for (let date = from; date <= to; date.setDate(date.getDate() + 1)) { const cloned = new Date(date.valueOf()); dates.push(cloned); } return dates; } const start = new Date(2019, 11, 31); const end = new Date(2020, 1, 1); const datesArray = getDatesFromDateRange(start, end); console.dir(datesArray);

Based on Tabare's Answer, I had to add one more day at the end, since the cycle is cut before根据 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);
}

Didn't want to store the result in an array, so maybe using yield?不想将结果存储在数组中,所以也许使用 yield?

 /** * @param {object} params * @param {Date} params.from * @param {Date} params.to * @param {number | undefined} params.incrementBy * @yields {Date} */ function* iterateDate(params) { const increaseBy = Math.abs(params.incrementBy?? 1); for(let current = params.from; current.getTime() <= params.to.getTime(); current.setDate(current.getDate() + increaseBy)) { yield new Date(current); } } for (const d of iterateDate({from: new Date(2021,0,1), to: new Date(2021,0,31), incrementBy: 1})) { console.log(d.toISOString()); }

If you want an efficient way with milliseconds:如果您想要一种以毫秒为单位的有效方法:

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

Let us assume you got the start date and end date from the UI and stored it in the scope variable in the controller.让我们假设您从 UI 获得开始日期和结束日期,并将其存储在控制器的作用域变量中。

Then declare an array which will get reset on every function call so that on the next call for the function the new data can be stored.然后声明一个数组,该数组将在每次函数调用时重置,以便在下次调用该函数时可以存储新数据。

var dayLabel = []; var dayLabel = [];

Remember to use new Date(your starting variable) because if you dont use the new date and directly assign it to variable the setDate function will change the origional variable value in each iteration`请记住使用新日期(您的起始变量),因为如果您不使用新日期并将其直接分配给变量,则 setDate 函数将在每次迭代中更改原始变量值`

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

Based on Jayarjo's answer:基于 Jayarjo 的回答:

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

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

    alert(loopDay);

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM