C# - 从列表中计算最小日期/最大日期

时间:2022-09-28 11:08:09

I have a List which contains Dates :

我有一个包含日期的列表:

List<string> StringDates;

    [0]: "04.03.2010"
    [1]: "09.03.2010"
    [2]: "11.03.2010"
    [3]: "12.03.2010"
    [4]: "16.03.2010"
    [5]: "18.03.2010"
    [6]: "19.03.2010"
    [7]: "23.03.2010"
    [8]: "25.03.2010"
    [9]: "26.03.2010"

Using C# what is the best/shortest way to find out min date / max date from this list ?

使用C#从这个列表中找出最小/最短日期的最佳/最短方法是什么?

6 个解决方案

#1


17  

I like the simple solution.

我喜欢简单的解决方案。

DateTime minDate = DateTime.MaxValue;
DateTime maxDate = DateTime.MinValue;
foreach (string dateString in StringDates)
{
    DateTime date = DateTime.Parse(dateString);
    if (date < minDate)
        minDate = date;
    if (date > maxDate)
        maxDate = date;
}

#2


24  

Convert them to DateTime using ParseExact (or TryParseExact) and then use Linq to get the Min and Max:

使用ParseExact(或TryParseExact)将它们转换为DateTime,然后使用Linq获取Min和Max:

List<DateTime> dates = StringDates
   .Select(x => DateTime.ParseExact(x, "dd.MM.yyyy", null))
   .ToList();
DateTime minDate = dates.Min();
DateTime maxDate = dates.Max();

Note that in your example the list was already sorted in ascending order. If you can guarantee that this will always be the case and you want better performance, you could just take the first and last element which would be O(1) instead of O(n). But the above is safer so even if your listed probably will always be sorted, you probably shouldn't make this optimization unless you actually need it, just in case one day the list doesn't come in sorted order.

请注意,在您的示例中,列表已按升序排序。如果你可以保证总是这样,并且你想要更好的性能,你可以采用第一个和最后一个元素,即O(1)而不是O(n)。但是上面的内容更安全,所以即使你列出的内容可能总是被排序,你可能不应该进行这种优化,除非你真的需要它,以防有一天列表没有排序。

#3


17  

use linq!:

使用linq!:

    var list = new List<DateTime>();
    list.Add(new DateTime(2010, 1, 1));
    list.Add(new DateTime(2008, 1, 1));
    list.Add(new DateTime(2009, 1, 1));
    Console.WriteLine(list.Max(date => date));
    Console.WriteLine(list.Min(date => date));

#4


2  

Via Linq, you can do:

通过Linq,您可以:

from row in StringDates
group row by true into r 
select new { 
    min = r.Min(z => z), 
    max = r.Max(z => z) 
}

#5


0  

This is similar to @Jeffrey's answer, but instead of parsing each date, it first finds the min and max dates comparing its string values, and then it parses the values at the end.

这类似于@Jeffrey的答案,但它不是解析每个日期,而是首先找到比较其字符串值的最小和最大日期,然后在最后解析值。

// This method handles the date comparisons
private int WeirdComparer(string strDate1, string strDate2)
{
    int res = string.Compare(strDate1, 6, strDate2, 6, 4);
    if (res == 0)
        res = string.Compare(strDate1, 3, strDate2, 3, 2);
    if (res == 0)
        res = string.Compare(strDate1, 0, strDate2, 0, 2);
    return res;
}

public void FindMinAndMaxDates(IList<string> strDates, out DateTime minDate, out DateTime maxDate)
{
    string min = "99.99.9999";
    string max = "00.00.0000";
    foreach (string strDate in strDates)
    {
        if (WeirdComparer(strDate, min) < 0)
            min = strDate;
        if (WeirdComparer(strDate, max) > 0)
            max = strDate;
    }
    minDate = DateTime.ParseExact(min, "dd.MM.yyyy", null);
    maxDate = DateTime.ParseExact(max, "dd.MM.yyyy", null);
}

#6


0  

I know this isn't a direct answer to your question, but could help others if they come here looking for something similar.

我知道这不是你问题的直接答案,但如果他们来这里寻找类似的东西,可以帮助别人。

I ran across this issue today while trying to find just the max date from a list of objects. Sometimes there won't be a value in the date for the objects so I had to figure out how to use a try parse with my linq.

我今天遇到了这个问题,试图从对象列表中找到最大日期。有时在对象的日期中没有值,所以我必须弄清楚如何使用我的linq进行try解析。

From a combination of what Mark used here I came up with this to solve my problem

从马克在这里使用的组合我想出了解决我的问题

        List<string> stringDates = new List<string>();
        stringDates.Add("Not a date");
        stringDates.Add("2015-01-01");
        stringDates.Add("2015-10-10");
        stringDates.Add("2015-9-10");
        stringDates.Add("123");

        DateTime sapInvoiceDate;
        DateTime tempDate = DateTime.MinValue;
        sapInvoiceDate = stringDates.Select(x => DateTime.TryParse(x, out tempDate)).Select(x => tempDate).Max();  

#1


17  

I like the simple solution.

我喜欢简单的解决方案。

DateTime minDate = DateTime.MaxValue;
DateTime maxDate = DateTime.MinValue;
foreach (string dateString in StringDates)
{
    DateTime date = DateTime.Parse(dateString);
    if (date < minDate)
        minDate = date;
    if (date > maxDate)
        maxDate = date;
}

#2


24  

Convert them to DateTime using ParseExact (or TryParseExact) and then use Linq to get the Min and Max:

使用ParseExact(或TryParseExact)将它们转换为DateTime,然后使用Linq获取Min和Max:

List<DateTime> dates = StringDates
   .Select(x => DateTime.ParseExact(x, "dd.MM.yyyy", null))
   .ToList();
DateTime minDate = dates.Min();
DateTime maxDate = dates.Max();

Note that in your example the list was already sorted in ascending order. If you can guarantee that this will always be the case and you want better performance, you could just take the first and last element which would be O(1) instead of O(n). But the above is safer so even if your listed probably will always be sorted, you probably shouldn't make this optimization unless you actually need it, just in case one day the list doesn't come in sorted order.

请注意,在您的示例中,列表已按升序排序。如果你可以保证总是这样,并且你想要更好的性能,你可以采用第一个和最后一个元素,即O(1)而不是O(n)。但是上面的内容更安全,所以即使你列出的内容可能总是被排序,你可能不应该进行这种优化,除非你真的需要它,以防有一天列表没有排序。

#3


17  

use linq!:

使用linq!:

    var list = new List<DateTime>();
    list.Add(new DateTime(2010, 1, 1));
    list.Add(new DateTime(2008, 1, 1));
    list.Add(new DateTime(2009, 1, 1));
    Console.WriteLine(list.Max(date => date));
    Console.WriteLine(list.Min(date => date));

#4


2  

Via Linq, you can do:

通过Linq,您可以:

from row in StringDates
group row by true into r 
select new { 
    min = r.Min(z => z), 
    max = r.Max(z => z) 
}

#5


0  

This is similar to @Jeffrey's answer, but instead of parsing each date, it first finds the min and max dates comparing its string values, and then it parses the values at the end.

这类似于@Jeffrey的答案,但它不是解析每个日期,而是首先找到比较其字符串值的最小和最大日期,然后在最后解析值。

// This method handles the date comparisons
private int WeirdComparer(string strDate1, string strDate2)
{
    int res = string.Compare(strDate1, 6, strDate2, 6, 4);
    if (res == 0)
        res = string.Compare(strDate1, 3, strDate2, 3, 2);
    if (res == 0)
        res = string.Compare(strDate1, 0, strDate2, 0, 2);
    return res;
}

public void FindMinAndMaxDates(IList<string> strDates, out DateTime minDate, out DateTime maxDate)
{
    string min = "99.99.9999";
    string max = "00.00.0000";
    foreach (string strDate in strDates)
    {
        if (WeirdComparer(strDate, min) < 0)
            min = strDate;
        if (WeirdComparer(strDate, max) > 0)
            max = strDate;
    }
    minDate = DateTime.ParseExact(min, "dd.MM.yyyy", null);
    maxDate = DateTime.ParseExact(max, "dd.MM.yyyy", null);
}

#6


0  

I know this isn't a direct answer to your question, but could help others if they come here looking for something similar.

我知道这不是你问题的直接答案,但如果他们来这里寻找类似的东西,可以帮助别人。

I ran across this issue today while trying to find just the max date from a list of objects. Sometimes there won't be a value in the date for the objects so I had to figure out how to use a try parse with my linq.

我今天遇到了这个问题,试图从对象列表中找到最大日期。有时在对象的日期中没有值,所以我必须弄清楚如何使用我的linq进行try解析。

From a combination of what Mark used here I came up with this to solve my problem

从马克在这里使用的组合我想出了解决我的问题

        List<string> stringDates = new List<string>();
        stringDates.Add("Not a date");
        stringDates.Add("2015-01-01");
        stringDates.Add("2015-10-10");
        stringDates.Add("2015-9-10");
        stringDates.Add("123");

        DateTime sapInvoiceDate;
        DateTime tempDate = DateTime.MinValue;
        sapInvoiceDate = stringDates.Select(x => DateTime.TryParse(x, out tempDate)).Select(x => tempDate).Max();