【问题标题】:Loop through a date range with JavaScript使用 JavaScript 循环遍历日期范围
【发布时间】:2011-05-19 16:55:37
【问题描述】:

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

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

}

这种循环行得通吗?但是我怎样才能在循环计数器中增加一天呢?

谢谢!

【问题讨论】:

    标签: javascript loops date iteration date-range


    【解决方案1】:

    这是一种方法,它利用添加一天的方式使日期在必要时滚动到下个月,而不会弄乱毫秒。夏令时也不是问题。

    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 毫秒不是很可读。
    • 注意夏令时。 d.getDate() + 1 当 d.getDate() = GMT N 和 d.getDate() + 1 = GMT N - 1 d.getDate() + 1 返回一个月的同一天两次。
    • 在定义now时为什么要Date.now()new Date()returns the current date as an object by default。在没有 new 构造函数的情况下调用 Date 只会给您一个 Date 字符串,然后您将其转换为 Date 对象?
    • 对我来说 new Date(2012, 0, 1); 选择了错误的一天(前一天),new Date(Date.UTC(2012, 0, 1)) 工作正常。
    • ``` d = new Date('2019-03-31') d.setDate(d.getDate() + 1) d.toISOString().slice(0, 10) // 2019-03-31 ``` ^^ 失败。
    【解决方案2】:

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

    【讨论】:

    【解决方案3】:

    如果您允许自己使用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');
    }
    &lt;script src="https://cdn.jsdelivr.net/npm/moment@2/moment.min.js"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案4】:

      如果 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,给了我足够的工作,我在我的问题中包含了可行的解决方案
      • 这在循环过去夏令时更改时不起作用(在有问题的区域)。否则很好的解决方案。
      • 你不能假设一天有86400000秒。这个循环很容易受到夏令时变化和其他边缘条件的影响。
      • 除了夏令时,另一个边缘条件是“闰秒”。一秒的差异确实很重要 - 转换为毫秒的日期对应于给定日期的第一秒。一秒钟的错误,你在前一天登陆。
      【解决方案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
      
      }

      【讨论】:

        【解决方案6】:
        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
        }
        

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

            如果你想要一个毫秒级的高效方法:

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

            【讨论】:

              【解决方案9】:

              假设您从 UI 中获取了开始日期和结束日期,并将其存储在控制器的范围变量中。

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

              var dayLabel = [];

              记得使用new Date(你的起始变量),因为如果你不使用新的日期直接赋值给变量,setDate函数会在每次迭代中改变原来的变量值`

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

              【讨论】:

                【解决方案10】:

                根据 Jayarjo 的回答:

                var loopDate = new Date();
                loopDate.setTime(datFrom.valueOf());
                
                while (loopDate.valueOf() < datTo.valueOf() + 86400000) {
                
                    alert(loopDay);
                
                    loopDate.setTime(loopDate.valueOf() + 86400000);
                }
                

                【讨论】:

                • 对此的一个评论是,小于比较比 != 更受欢迎,因为由于某种原因循环多个月时,!= 比较永远不会触发。
                • 除了夏令时,另一个边缘条件是“闰秒”。一秒的差异确实很重要 - 转换为毫秒的日期对应于给定日期的第一秒。一秒钟的错误,你在前一天登陆。
                猜你喜欢
                • 1970-01-01
                • 2010-12-23
                • 1970-01-01
                • 2011-02-19
                • 2020-03-06
                • 1970-01-01
                • 2023-02-17
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多