AliRıza Adıyahşi
AliRıza Adıyahşi

Reputation: 15866

Linq Group by specific day interval?

I have following line to group my collection:

group c by new { date = GetGroupingDateKey(DateRangeType, c.ReadDate), name = c.Name } into g

and I use following function to get grouping date key:

private static DateTime GetGroupingDateKey(MeterReadingsTimeIntervals DateRangeType, DateTime Date)
{
    DateTime date = new DateTime();
    switch (DateRangeType)
    {
        case MeterReadingsTimeIntervals.Hourly:
            date = new DateTime(Date.Year, Date.Month, Date.Day, Date.Hour, 0, 0);
            break;
       case MeterReadingsTimeIntervals.Daily:
            date = new DateTime(Date.Year, Date.Month, Date.Day, 0, 0, 0);
            break;
        case MeterReadingsTimeIntervals.Weekly:

            // ???

            break;
        case MeterReadingsTimeIntervals.Monthly:
            date = new DateTime(Date.Year, Date.Month, 1, 0, 0, 0);
            break;
        case MeterReadingsTimeIntervals.Yearly:
            date = new DateTime(Date.Year, 1, 1, 0, 0, 0);
            break;
    }

    return date;
}

But I dont know about weekly grouping(it may be specific day intervals, 10 days,15 days, etc.). How can I group weekly? Should I use another way to group data?

Thanks in advice.

Upvotes: 0

Views: 860

Answers (3)

Nikola Davidovic
Nikola Davidovic

Reputation: 8656

Maybe like this:

date = Date.AddDays(-((Date.DayOfWeek - DayOfWeek.Monday +7)%7));
date = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0);

If you consider Monday start of the week.

You can try it using this code: EDIT Code edited after @Rawling suggestion, check the comments

DateTime dt = DateTime.Now;
dt = dt.AddDays(-((dt.DayOfWeek - DayOfWeek.Monday + 7)%7));
dt = new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0);//today is Friday and it will show Monday at the end.

Upvotes: 2

Rawling
Rawling

Reputation: 50104

With the helper function

int DaysFromLast(DateTime date, DayOfWeek dow)
{
    return (7 + date.DayOfWeek - dow) % 7;
}

you can use

var date = Date.Date;
date = date.AddDays(-DaysFromLast(date, DayOfWeek.Monday));

for a week starting on a Monday, and so on.

For arbitrary intervals, you'll need a constant start date (preferably back in the past); then

var date = Date.Date;
date = date.AddDays(-((date - startDate).Days % numberOfDaysInInterval));

Upvotes: 1

Davio
Davio

Reputation: 4737

The week is dependent on the kind of calendar that you're using and its rules. Some have the first week of the year start on the first Monday of the year, some on Sunday, etc, there are differences.

You can use GregorianCalendar for instance and its method GetWeekOfYear(DateTime).

case MeterReadingsTimeIntervals.Weekly:
  var gc = new GregorianCalendar();
  return gc.GetWeekOfYear(Date);

Now for this to work you have to make the return type of your method object or force the weekinfo into the same DateTime (set it to Monday of the found week),

Upvotes: 1

Related Questions