对字符串日期数组进行排序

Posted

技术标签:

【中文标题】对字符串日期数组进行排序【英文标题】:Sort a string date array 【发布时间】:2015-08-21 20:27:24 【问题描述】:

我想按升序对数组进行排序。日期为字符串格式

["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015"] 

甚至需要一个函数来检查这些日期是否为连续形式:

eg - Valid   - ["09/06/2015", "10/06/2015", "11/06/2015"] 
     Invalid - ["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015"] 

示例代码:

function sequentialDates(dates)
        var temp_date_array = [];

        $.each(dates, function( index, date ) 
            //var date_flag = Date.parse(date);
            temp_date_array.push(date);
        );

        console.log(temp_date_array);

        var last;
        for (var i = 0, l = temp_date_array.length; i < l; i++) 

          var cur = new Date();
          cur.setTime(temp_date_array[i]);
          last = last || cur;
          //console.log(last+' '+cur);

          if (isNewSequence(cur, last)) 
            console.log("Not Sequence");
          
        

        //return dates;
    

     function isNewSequence(a, b) 
          if (a - b > (24 * 60 * 60 * 1000))
              return true;
          return false;
      

【问题讨论】:

你已经有一些代码了吗? 在将 Date 存储为 String 时使用 ISO 8601,这样可以省去你的麻烦 【参考方案1】:

简单的解决方案

无需将字符串转换为日期或使用正则表达式。

简单的解决方案是使用 Array.sort() 方法。 sort 函数将日期格式设置为 YYYYMMDD,然后比较字符串值。假设日期输入格式为 DD/MM/YYYY。

data.sort(function(a,b) 
  a = a.split('/').reverse().join('');
  b = b.split('/').reverse().join('');
  return a > b ? 1 : a < b ? -1 : 0;
  // return a.localeCompare(b);         // <-- alternative 
);

更新:

建议使用localeCompare() 来简化排序功能的有用评论。上面的代码 sn-p 中显示了这个替代方案。

运行片段进行测试

<!doctype html>
<html>
<body style="font-family: monospace">
<ol id="stdout"></ol>
<script>
  var data = ["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015"];

data.sort(function(a,b) 
  a = a.split('/').reverse().join('');
  b = b.split('/').reverse().join('');
  return a > b ? 1 : a < b ? -1 : 0;
  
  // return a.localeCompare(b);         // <-- alternative 
  
);

for(var i=0; i<data.length; i++) 
  stdout.innerHTML += '<li>' + data[i];
</script>
</body>
</html>

【讨论】:

@RobG - 谢谢,这是一个很好的建议,我已经在答案中注明了替代方案。 @ritesh - 如果您的数据包含相同的日期,那么您可能需要添加其他排序标准。看到这个问题:***.com/questions/2784230【参考方案2】:

如果您想对它们进行排序,您需要将字符串转换为日期,并比较这些日期。您可以利用sort 方法接受的参数来实现:

var dateStrings = ["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015"];
var sortedStrings = dateStrings.sort(function(a,b) 
    var aComps = a.split("/");
    var bComps = b.split("/");
    var aDate = new Date(aComps[2], aComps[1], aComps[0]);
    var bDate = new Date(bComps[2], bComps[1], bComps[0]);
    return aDate.getTime() - bDate.getTime();
);

为了减少代码冗余并处理不同的日期格式,您可以添加一个额外的函数来创建sort 方法所需的比较器:

function createSorter(dateParser) 
    return function(a, b) 
        var aDate = dateParser(a);
        var bDate = dateParser(b);
        return aDate.getTime() - bDate.getTime();
    ;


dateStrings.sort(createSorter(function(dateString) 
    var comps = dateString.split("/");
    return new Date(comps[2], comps[1], comps[0]);
));

然后,您可以通过将不同的函数传递给 createSorter 调用来使用不同的日期格式化程序。

至于您的第二个问题,您可以从字符串中创建一个(排序的)日期数组,并在该数组上执行您的逻辑:

function myDateParser(dateString) 
    var comps = dateString.split("/");
    return new Date(comps[2], comps[1], comps[0]);


var sortedDates = dateStrings.map(myDateParser).sort();

您可以遍历sortedDates 数组,如果您发现两个不连续的日期,那么您的日期之间有间隔。

【讨论】:

【参考方案3】:

要对日期字符串进行升序排序而不改变其值,试试这个:

var T = ["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015"];

var sortedT = T.sort(s1,s2)
    var sdate1 = s1.split('/');
    var sdate2 = s2.split('/');
    var date1 = s1[1]+'/'+s1[0]+'/'+s1[2];
    var date2 = s2[1]+'/'+s2[0]+'/'+s2[2];
    if (Date.parse(date1) > Date.parse(date2)) return 1;
    else if (Date.parse(date1) < Date.parse(date2) return -1;
    else return 0;

结果数组sortedT 应该是日期字符串的排序数组。

注意:

您的日期格式存储在dd/mm/yyyy,但javascript 的标准日期格式是mm/dd/yyyy。因此,为了在不使用外部日期格式库的情况下将此字符串解析为日期,因此需要在排序期间转换日期字符串以实现兼容性。

【讨论】:

【参考方案4】:
var dateRE = /^(\d2)[\/\- ](\d2)[\/\- ](\d4)/;
function dmyOrdA(a, b)
a = a.replace(dateRE,"$3$2$1");
b = b.replace(dateRE,"$3$2$1");
if (a>b) return 1;
if (a <b) return -1;
return 0; 
function dmyOrdD(a, b)
a = a.replace(dateRE,"$3$2$1");
b = b.replace(dateRE,"$3$2$1");
if (a>b) return -1;
if (a <b) return 1;
return 0; 
function mdyOrdA(a, b)
a = a.replace(dateRE,"$3$1$2");
b = b.replace(dateRE,"$3$1$2");
if (a>b) return 1;
if (a <b) return -1;
return 0; 
function mdyOrdD(a, b)
a = a.replace(dateRE,"$3$1$2");
b = b.replace(dateRE,"$3$1$2");
if (a>b) return -1;
if (a <b) return 1;
return 0;  

dateArray = new Array("09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015");
var c = dateArray.sort( dmyOrdA );

console.log(c);

【讨论】:

它将返回 ["18/05/2015", "09/06/2015", "22/06/2015", "25/06/2015", "25/07/2015" "]

以上是关于对字符串日期数组进行排序的主要内容,如果未能解决你的问题,请参考以下文章

使用日期 Swift 3 对字典数组进行排序

如何对日期对象的 NSMutableArray 进行排序

如何按日期对字典数组进行排序?

如何根据 array[0] 元素对数组的 ArrayList 进行排序,该元素是以 dd/mm/yyyy 格式给出的日期?

如何对工作日的 NSArray 进行排序?

如何根据日期对“MMM YYYY”日期字符串进行排序? [复制]