Как сгруппировать период времени в годовые периоды?(разбить временной интервал на годовые периоды) - PullRequest
2 голосов
/ 28 марта 2012

У меня есть диапазон двух дат:

DateTime start = new DateTime(2012,4,1);
DateTime end = new DateTime(2016,7,1);

И я хочу, чтобы все периоды группировались по году между этими периодами.Это означает, что выходные данные должны быть:

2012-04-01 - 2012-12-31
2013-01-01 - 2013-12-31
2014-01-01 - 2014-12-31
2015-01-01 - 2015-12-31
2016-01-01 - 2016-07-01

Предпочтительно, чтобы выходные данные были в списке IList<Tuple<DateTime,DateTime>>.

Как бы вы это сделали?Можно ли как-нибудь сделать это с LINQ?

Да, и переход на летнее время не является абсолютно критичным, но, безусловно, бонусом.

Спасибо!

Ответы [ 4 ]

3 голосов
/ 28 марта 2012
DateTime start = new DateTime(2012,4,1); 
DateTime end = new DateTime(2016,7,1); 

var dates = from year in Enumerable.Range(start.Year,end.Year-start.Year+1)
        let yearStart=new DateTime(year,1,1)
        let yearEnd=new DateTime(year,12,31)
        select Tuple.Create(start>yearStart ? start : yearStart, end<yearEnd ? end : yearEnd); 

IList<Tuple<DateTime,DateTime>> result = dates.ToList();
3 голосов
/ 28 марта 2012
    static IList<Tuple<DateTime, DateTime>> GetDateRangesByYear(DateTime start, DateTime end)
    {
        List<Tuple<DateTime, DateTime>> ranges = new List<Tuple<DateTime,DateTime>>();

        for (int year = start.Year; year <= end.Year; ++year)
        {
            DateTime yearBegin = year == start.Year ? start : new DateTime(year, 1, 1);
            DateTime yearEnd = year == end.Year ? end : new DateTime(year, 12, 31);

            ranges.Add(Tuple.Create(yearBegin, yearEnd));
        }

        return ranges;
    }
1 голос
/ 28 марта 2012

А как же:

static public List<Tuple<DateTime, DateTime>> GroupByYear(DateTime start, DateTime end)
{
    List<Tuple<DateTime, DateTime>> datetimes = Enumerable.Range(start.Year + 1, end.Year - 1 - start.Year)
                                                          .Select(x => new Tuple<DateTime, DateTime>(new DateTime(x, 1, 1), new DateTime(x, 12, 31)))
                                                          .ToList();
    datetimes.Add(new Tuple<DateTime, DateTime>(start, new DateTime(start.Year, 12, 31)));
    datetimes.Add(new Tuple<DateTime, DateTime>(new DateTime(end.Year, 1, 1), end));

    return datetimes.OrderBy(x => x.Item1.Year).ToList();
}
0 голосов
/ 28 марта 2012

Я не проверял все крайние случаи, но в основном это нужно делать

IList<Tuple<DateTime, DateTime>> GetYearPeriods(DateTime start, DateTime end)
{   
    var years = end.Year - start.Year - 1;
    var startDates = Enumerable.Range(start.Year+1, years)
                               .Select(year => new DateTime(year, 1, 1));
    var endDates = Enumerable.Range(start.Year+1, years)
                             .Select(year => new DateTime(year, 12, 31));

    var firstPeriod = Tuple.Create(start, new DateTime(start.Year, 12, 31));
    var middlePeriods = startDates.Zip(endDates, (s,e) => Tuple.Create(s, e));
    var lastPeriod = Tuple.Create(new DateTime(end.Year, 1, 1), end);

    return 
      (new[] {firstPeriod}).Union(middlePeriods).Union(new[] {lastPeriod}).ToList();
}
...