日期范围之间的JavaScript循环


135

给定两个Date()对象,其中一个小于另一个,如何在日期之间每天循环?

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

}

这种循环会起作用吗?但是,如何向循环计数器添加一天?

谢谢!

Answers:


201

这是一种通过使用添加一天来使日期在必要时滚动到下个月的方式来实现此目的的方法,而不会花费毫秒。夏令时也不是问题。

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

1
请注意夏令时。当d.getDate()= GMT N并且d.getDate()+ 1 = GMT N-d.getDate()+1时-d.getDate()+1返回每月同一天两次。
拉斐尔·丰特斯2013年

1
为什么要Date.now()定义nownew Date() 默认返回当前日期作为对象Date没有new构造函数的调用只会给您一个Date字符串,然后将其转换为Date对象?
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 Ku​​bica


9

如果startDate和endDate确实是日期对象,则可以将它们转换为自1970年1月1日午夜以来的毫秒数,如下所示:

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

然后您可以从一个循环循环到另一个循环循环时间86400000(1000 * 60 * 60 * 24)-一天中的毫秒数:

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

1
+1,给了我足够的工作机会,我在我的问题中包括了有效的解决方案
Tom Gullen 2010年

5
当绕过夏时制更改时(在有问题的区域中),此功能不起作用。否则,很好的解决方案。
chadgh 2011年

3
您不能假设86400000一天中有几秒钟。对于夏令时更改和其他边缘条件,此循环非常脆弱。
杰里米·J·斯塔彻

2
除了DST,另一个边缘条件是“ Leap Second”。一秒的差异确实很重要-转换为毫秒的日期对应于给定日期的第一秒。一秒钟的错误,您就在前一天着陆。
Wojtek Kruszewski

9

如果您允许自己使用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

这里简单的工作代码,为我工作

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

根据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获取了开始日期和结束日期,并将其存储在控制器的scope变量中。

然后声明一个数组,该数组将在每次函数调用时重置,以便在下一次函数调用时可以存储新数据。

var dayLabel = [];

请记住使用新的Date(您的起始变量),因为如果您不使用新的日期并将其直接分配给变量,则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);
}

对此的一种评论是,小于!比小于=更受青睐,因为当出于某些原因循环多个月时,!=比较永远不会触发。
汤姆·古伦

1
除了DST,另一个边缘条件是“ Leap Second”。一秒的差异确实很重要-转换为毫秒的日期对应于给定日期的第一秒。一秒钟的错误,您就在前一天着陆。
Wojtek Kruszewski
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.