【问题标题】:Min/Max of dates in an array?数组中日期的最小值/最大值?
【发布时间】:2011-10-31 21:15:43
【问题描述】:

如何从日期数组中找出最小和最大日期?目前,我正在创建一个这样的数组:

var dates = [];
dates.push(new Date("2011/06/25"))
dates.push(new Date("2011/06/26"))
dates.push(new Date("2011/06/27"))
dates.push(new Date("2011/06/28"))

是否有内置函数可以执行此操作,还是我自己编写?

【问题讨论】:

    标签: javascript date max min


    【解决方案1】:

    代码用 IE,FF,Chrome 测试并正常运行:

    var dates=[];
    dates.push(new Date("2011/06/25"))
    dates.push(new Date("2011/06/26"))
    dates.push(new Date("2011/06/27"))
    dates.push(new Date("2011/06/28"))
    var maxDate=new Date(Math.max.apply(null,dates));
    var minDate=new Date(Math.min.apply(null,dates));
    

    【讨论】:

    • 转数字转换不适用于字符串 '2011/06/25',但适用于 new Date('2011/06/25')。数字(新日期('2011/06/25'))===1308949200000。代码在Chrome、IE、FF中测试
    • @RobG - “字符串日期”是什么意思?
    • 例如dates.push('2011/06/05')。使用字符串可以简单地对数组进行排序,并在必要时返回第一个和最后一个成员值并转换为日期。
    • @RobG - 在上面的问题中,数组包含 Date 对象,而不是“日期字符串” - 响应也适用于 Date 对象。在某些情况下,使用“日期字符串”是一种非常糟糕的做法。比较接下来的两个日期字符串:“2011/06/05”和“2011/06/05 00:00:00”。 1) 作为字符串: ("2011/06/05"==="2011/06/05 00:00:00") :结果为假; 2)作为日期对象(转换为数字): Number(new Date("2011/06/05"))===Number(new Date("2011/06/05 00:00:00")) :结果是真的 - 是正确的结果!
    • @AndrewD。如果 dateStrings 是一致的,比如说YYYY/MM/DD HH:MM:SS 并且涉及到很多字符串,你会推荐字符串比较还是Number(new Date(dateString)) 比较?
    【解决方案2】:

    类似:

    var min = dates.reduce(function (a, b) { return a < b ? a : b; }); 
    var max = dates.reduce(function (a, b) { return a > b ? a : b; });
    

    在 Chrome 15.0.854.0 开发版上测试

    【讨论】:

    • Array.reduce() 在 IE9 之前的 IE 中不可用。不过想法很酷。
    • Array.reduce() 可以用javascript等效函数实现
    • 没错,在Eloquent Javascript:function foreach(func, array) { for(var i = 0; i != array.length; ++i) { func(array[i]); } } function reduce(combine, base, array) { foreach(function(element) { base = combine(base, element); }, array); return base; }阅读它
    • IE
    • reduce 解决方案适用于字符串和日期对象。
    【解决方案3】:

    _.min_.max 处理日期数组;如果您正在使用 Lodash 或 Underscore,请使用它们,如果您还没有,请考虑使用 Lodash(它提供了许多类似的实用功能)。

    例如,

    _.min([
        new Date('2015-05-08T00:07:19Z'),
        new Date('2015-04-08T00:07:19Z'),
        new Date('2015-06-08T00:07:19Z')
    ])
    

    将返回数组中的第二个日期(因为它是最早的)。

    【讨论】:

    • 不直接回答 OP 的问题。 OP 询问 JavaScript 中是否有内置方法。因此,虽然 _.min 和 _.max 可用于查找最小或最大日期,但这不是 OP 正在寻找的。此外,对实用程序库的考虑是一个固执己见的话题。
    • 我非常不同意并认为这是一个有用的答案,@detj - OP 的问题目前的措辞假定要么有一个内置函数,要么他必须编写自己的函数,但这不是不是真的。在我看来,指出实用程序库作为 OP 提出的任何一种解决方案的替代方案似乎是合理的。但你的推理是站得住脚的,你的投票是你自己的。
    • 短小精悍,非常适合 TypeScript,并且支持 Date 类型。
    【解决方案4】:

    与 apply 相同,现在使用 spread

    const maxDate = new Date(Math.max(...dates));
    

    (可能是对最佳答案的评论)

    【讨论】:

      【解决方案5】:

      由于日期被转换为 UNIX 纪元(数字),您可以使用 Math.max/min 来查找:

      var maxDate = Math.max.apply(null, dates)
      // convert back to date object
      maxDate = new Date(maxDate)
      

      (仅在 chrome 中测试,但应该适用于大多数浏览器)

      【讨论】:

        【解决方案6】:

        **使用展开运算符| ES6 **

        let datesVar = [ 2017-10-26T03:37:10.876Z,
          2017-10-27T03:37:10.876Z,
          2017-10-23T03:37:10.876Z,
          2015-10-23T03:37:10.876Z ]
        
        Math.min(...datesVar);
        

        这将给出数组中的最小日期。

        它的简写 Math.min.apply(null, ArrayOfdates);

        【讨论】:

        • 如果您不赞成,请发表评论。为什么这是一个糟糕的选择?我喜欢这种语法,对于小型数组,性能损失可以忽略不计。
        • 我被否决了。 Rudresh 的回答是我上面的重复。不知道为什么人们不喜欢这个。它是单行代码而不是多行代码。
        • 这将返回一个数字而不是日期,因此您必须将其转换回日期。但否则它非常优雅。
        【解决方案7】:

        ONELINER

        var min= dates.sort((a,b)=>a-b)[0], max= dates.slice(-1)[0];
        

        导致变量minmax,复杂度O(nlogn),可编辑示例here。如果您的数组没有日期值(如null),请先通过dates=dates.filter(d=&gt; d instanceof Date); 清理它。

        var dates = [];
        dates.push(new Date("2011-06-25")); // I change "/" to "-" in "2011/06/25"
        dates.push(new Date("2011-06-26")); // because conosle log write dates 
        dates.push(new Date("2011-06-27")); // using "-".
        dates.push(new Date("2011-06-28"));
        
        var min= dates.sort((a,b)=>a-b)[0], max= dates.slice(-1)[0];
        
        console.log({min,max});

        【讨论】:

          【解决方案8】:
          var max_date = dates.sort(function(d1, d2){
              return d2-d1;
          })[0];
          

          【讨论】:

            【解决方案9】:

            上面的答案不处理空白/未定义的值来解决这个问题我使用了下面的代码并用 NA 替换了空白:

            function getMax(dateArray, filler) {
                  filler= filler?filler:"";
                  if (!dateArray.length) {
                    return filler;
                  }
                  var max = "";
                  dateArray.forEach(function(date) {
                    if (date) {
                      var d = new Date(date);
                      if (max && d.valueOf()>max.valueOf()) {
                        max = d;
                      } else if (!max) {
                        max = d;
                      }
                    }
                  });
                  return max;
                };
            console.log(getMax([],"NA"));
            console.log(getMax(datesArray,"NA"));
            console.log(getMax(datesArray));
            
            function getMin(dateArray, filler) {
             filler = filler ? filler : "";
              if (!dateArray.length) {
                return filler;
              }
              var min = "";
              dateArray.forEach(function(date) {
                if (date) {
                  var d = new Date(date);
                  if (min && d.valueOf() < min.valueOf()) {
                    min = d;
                  } else if (!min) {
                    min = d;
                  }
                }
              });
              return min;
            }
            
            console.log(getMin([], "NA"));
            console.log(getMin(datesArray, "NA"));
            console.log(getMin(datesArray));
            

            我添加了一个普通的 javascript demo here 并在this codepen中将其用作AngularJS的过滤器

            【讨论】:

              【解决方案10】:

              如果你从数组的字符串日期中得到字符串类型的最大或最小日期,你可以试试这个:

              const dates = ["2021-02-05", "2021-05-20", "2021-01-02"]
              const min = dates.reduce((acc,date)=>{return acc&&new Date(acc)<new Date(date)?acc:date},'')
              const max = dates.reduce((acc,date)=>{return acc&&new Date(acc)>new Date(date)?acc:date},'')
              

              【讨论】:

                【解决方案11】:

                这是一种特别好的方法(您可以使用其中一个对象属性获取对象数组的最大值):Math.max.apply(Math,array.map(function(o){return o.y;}))

                这是此页面的公认答案: Finding the max value of an attribute in an array of objects

                【讨论】:

                  【解决方案12】:

                  使用MomentUnderscorejQuery 来迭代日期数组。

                  示例 JSON:

                  "workerList": [{        
                          "shift_start_dttm": "13/06/2017 20:21",
                          "shift_end_dttm": "13/06/2017 23:59"
                      }, {
                          "shift_start_dttm": "03/04/2018 00:00",
                          "shift_end_dttm": "03/05/2018 00:00"        
                      }]
                  

                  Javascript:

                  function getMinStartDttm(workerList) {  
                      if(!_.isEmpty(workerList)) {
                          var startDtArr = [];
                          $.each(d.workerList, function(index,value) {                
                              startDtArr.push(moment(value.shift_start_dttm.trim(), 'DD/MM/YYYY HH:mm')); 
                           });            
                           var startDt = _.min(startDtArr);           
                           return start.format('DD/MM/YYYY HH:mm');
                      } else {
                          return '';
                      }   
                  }
                  

                  希望对你有帮助。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2019-12-16
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-09-10
                    • 1970-01-01
                    • 2022-11-10
                    • 2021-12-15
                    • 1970-01-01
                    相关资源
                    最近更新 更多