如何从按周,月,季度或年份分组的随机日期列表中提取最大日期?

时间:2018-05-05 16:18:51

标签: c# linq date calendar

给定一个随机日期列表,是否有一个优雅的C#方式(LINQ或其他)来提取列表中的最后日期,按周,月,季度或年份分组?

我希望这是明确的,但如果没有,请使用此示例日期集:

  • Mon 01/01/2018
  • 星期二02/01/2018
  • 星期四04/01/2018
  • 星期二09/01/2018
  • Thu 11/01/2018
  • 星期五12/01/2018
  • 星期一22/01/2018
  • 星期二23/01/2018
  • Wed 24/01/2018
  • Wed 31/01/2018
  • Thu 01/02/2018
  • 星期二27/02/2018

按周提取最大值将产生

  • 星期四04/01/2018 =样本第一周的最后一个日期
  • Fri 12/01/2018 =样本第二周的最后一个日期
  • Wed 24/01/2018 = etc。
  • Thu 01/02/2018
  • 星期二27/02/2018

按月提取最大值将产生

  • Wed 31/01/2018 =样本中1月份的最后一个日期
  • 星期二27/02/2018 =样本中二月份的最后一次日期

我需要能够按周数,日历月,日历季和日历年进行提取。

我甚至不确定如何开始这个。所以目前我没有代码要分享。

非常欢迎任何想法。

澄清:此处包含工作日名称,以造福我们人类。我的实际日期是正确的DateTime类型。因此代码不需要将字符串解析为DateTimes。

此外,如果没有LINQ,我可以轻松地编写类似的内容。但我希望的是使用LINQ或其他一些聪明技巧的优雅解决方案。

2 个答案:

答案 0 :(得分:1)

使用LINQ非常简单。这是按分组的示例:

var grouped = dates.OrderBy(x => x.Ticks).GroupBy(x => x.Month)
                   .Select(x => new {Month = x.Key, Max = x.Max()});

这给出了你的例子:

  

{Month = 1,Max = 1/31/2018 12:00:00 AM}

     

{Month = 2,Max = 2/27/2018 12:00:00 AM}

要为执行此操作,请将此lambda用于GroupBy

x => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(
         x, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday
     )

输出:

  

{Week = 1,Max = 1/4/2018 12:00:00 AM}

     

{Week = 2,Max = 1/12/2018 12:00:00 AM}

     

{Week = 4,Max = 1/24/2018 12:00:00 AM}

     

{Week = 5,Max = 2/1/2018 12:00:00 AM}

     

{Week = 9,Max = 2/27/2018 12:00:00 AM}

季度

x => (x.Month + 2)/3

输出:

  

{Quarter = 1,Max = 2/27/2018 12:00:00 AM}

x => x.Year

输出

  

{Year = 2018,Max = 2/27/2018 12:00:00 AM}

答案 1 :(得分:0)

我在C#中确定了这一点,可以适应任何其他所需的分组

    public static Dictionary<Tuple<int, int>, DateTime> MaxByYearMonth(this List<DateTime> sourceDateTimes)
    {
        IEnumerable<DateTime>                             ordered = sourceDateTimes.OrderBy(x => x.Ticks);
        IEnumerable<IGrouping<Tuple<int, int>, DateTime>> grouped = ordered.GroupBy(x => new Tuple<int, int>(x.Year, x.Month));
        Dictionary<Tuple<int, int>, DateTime>             maxed   = grouped.ToDictionary(x => x.Key, x => x.Max());
        return maxed;
    }