在C#中按日期对字符串列表进行排序

17

我有一个日期的List<string>
我的列表如下:

{"01/01/2013","10/01/2013","20/01/2013"}

我想要将列表按照以下方式排序:

{"20/01/2013","10/01/2013","01/01/2013"}

我该如何制作这个?

6个回答

50

使用LINQ:

var list = new List<string> {"01/01/2013", "10/01/2013", "20/01/2013"};
var orderedList = list.OrderByDescending(x => DateTime.Parse(x)).ToList();

更新(根据评论中的问题):

您可以像这样处理无效日期(无效日期被视为 default(DateTime)):

var list = new List<string> { "01/01/2013", "10/01/2013", "N/A" , "20/01/2013"  };
var orderedList2 = list.OrderByDescending(x =>
            {
                DateTime dt;
                DateTime.TryParse(x, out dt);
                return dt;
            });

或者,如果你想要将无效的日期时间作为列表中的第一项:

var orderedList3 = list.OrderByDescending(x =>
            {
                DateTime dt;
                if (!DateTime.TryParse(x, out dt)) return DateTime.MaxValue;
                return dt;
            }); 

您还可以过滤掉无效日期:

var filteredList = list.Where(x =>
            {
                DateTime dt;
                return DateTime.TryParse(x, out dt);
            }).Select(DateTime.Parse).OrderByDescending(x => x);

或者更好的方法:

var filteredList = list.Select(x =>
        {
            DateTime dt;
            return new {valid = DateTime.TryParse(x, out dt), date = dt};
        }).Where(x => x.valid).Select(x => x.date).OrderByDescending(x => x);

1
如果有一个无效的日期时间字符串怎么办?是否有任何方法可以将该无效的日期时间更改为特定的字符串? - Yusril Maulidan Raji
如果还有字符串呢?比如缺失的数据?你该如何排序? - Demodave

4

在面向对象的世界中,不应该使用数据的字符串表示形式 :)

最好的方法是将这些字符串转换为实际的 DateTime 对象,并通过 linq 按相反顺序进行排序:

var dates = Array.ConvertAll(dateStrings, x => DateTime.Parse(x));
return dates.OrderByDesc(x => x);

另一种方法是实现自定义排序函数,参见此链接。然后您只需在排序函数中使用它:
DateAsStringComparer myComparer = new DateAsStringComparer();
dateStrings.Sort(myComparer);

+1 因为你没有像我一样烦恼字符串比较 :) - Simon Whitehead
实际上,您不需要使用lambda表达式,可以像这样完成 - Array.ConvertAll(dateStrings,DateTime.Parse)。 - himanshupareek66

4

试试这个:

List<string> s = new List<string>() { "01/01/2013", "10/01/2013", "20/01/2013" };
var d = s.OrderByDescending(i => DateTime.ParseExact(i, "dd/MM/yyyy", null));

1
为什么要使用 List<string> 而不是 List<DateTime>
List<DateTime> dates = ...

dates.OrderByDescending(c => c).ToList();

我相信他有他的理由。例如,我也需要它。 - Martin K

0

由于日期格式为英式或澳式(日/月/年),您可以使用OrderByDescending对它们进行排序:

List<string> dates = new List<string>() { "01/01/2013", "10/01/2013", "20/10/2013" };

foreach (var date in dates.OrderByDescending(x => x))
    Console.WriteLine(date);

个人而言,我会先将它们转换为DateTime对象。


0

将自定义格式的 DateTime 字符串转换为统一格式的 string,您可以采用以下简单且安全的代码片段。

    string formatStr = "yyyyMMddHHmmss";
    string result = Convert.ToDateTime(inputStr).ToString(formatStr);

在代码中,formatStr 可以是 DateTime 类可以接受的任何可能形式,您可以将其设置为所需的格式,在这里,您可以使用与目标格式字符串(如“20/01/2013”)匹配的 dd/MM/yyyy

因此,对于您的情况,代码可以简单地如下所示:

    List<string> list = new List<string> { "01/01/2013", "10/01/2013", "20/01/2013" };
    var listAfterSorting = list.OrderByDescending(t => 
        Convert.ToDateTime(t).ToString("dd/MM/yyyy")
            .ToList());

在某些情况下,使用ParseExact解析日期时间字符串时,可能会抛出错误/异常String was not recognized as a valid DateTime。在这种情况下,如果您转而使用TryParseExact,结果可能是default(DateTime)= 1/1/0001 12:00:00 AM,因为解析失败。因此,我不建议使用ParseExactTryParseExact


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接