Linq Group by specific day interval? - c#

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.

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.

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));

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),

Related

Check if any dates within a range fall within a specified month

I am at a bit of a loss as to the best approach. Let's say I have the following:
//Get the first and last day of the month -- ex February
int month = DateTime.ParseExact("February", "MMMM", new CultureInfo("en-US")).Month;
var now = DateTime.Now;
var firstOfMonth = new DateTime(now.Year, month, 1);
var lastOfMonth = new DateTime(now.Year, month, DateTime.DaysInMonth(now.Year, month));
var coverageStartDate = new DateTime(now.Year, 1, 1);
var coverageEndDate = new DateTime(now.Year, 2, 15);
I am trying to create a check to see if the date range of coverageStartDate and coverageEndDate falls in the month of February. Keep in mind that the values could also look like:
var coverageStartDate = new DateTime(now.Year, 2, 3);
var coverageEndDate = new DateTime(now.Year, 2, 10);
As long as there is a single date in the coverage start / end date range falls in the month of February, I would want to return true.
With DateTime you can use >=, <=, etc.
Adopting your code, I would do something like this:
var firstOfMonth = new DateTime(now.Year, month, 1, 0, 0, 0);
var lastOfMonth = new DateTime(now.Year, month, DateTime.DaysInMonth(now.Year, month), 23, 59, 59);
var coverageStartDate = new DateTime(now.Year, 1, 1);
var coverageEndDate = new DateTime(now.Year, 2, 15);
if(coverageStartDate <= lastOfMonth && coverageEndDate >= firstOfMonth)
{
// Do something
}
This code does not requires that years have to be the same, so the coverage time can span multiple years.

How to get the first Sunday of next month for a given date?

I am looking for some logic to get the date get the first Sunday of next month for a given date using c#.
How to get the first Sunday of next month for a given date using c#?
You didn't show any effort but let's we code what Jon says step by step;
How to get the first Sunday of next month for a given date
We call dt as a DateTime for a given date in your question. All months starts with 1 as a day number. That's why we can create a DateTime called firstDayOfNextMonth
DateTime firstDayOfNextMonth = new DateTime(dt.Year, dt.Month + 1, 1);
Now what? Sure we need to check the day name and it is Sunday or not. Until when? Until we found a day as Sunday. That's why we need to iterate this day (1 day per) until we found it. We can use DayOfWeek enumeration for that which gives as it's day name.
Let's define a DateTime as firstSundayOfNextMonth in our code;
DateTime firstSundayOfNextMonth;
And now iterate your first day of next week until we found a Sunday;
while (firstDayOfNextMonth.DayOfWeek != DayOfWeek.Sunday)
{
firstDayOfNextMonth = firstDayOfNextMonth.AddDays(1);
}
When this while statement stop working? Yes, when we found the first Sunday. That's why we need to assign this value to firstSundayOfNextMonth variable outside of this loop.
while (firstDayOfNextMonth.DayOfWeek != DayOfWeek.Sunday)
{
firstDayOfNextMonth = firstDayOfNextMonth.AddDays(1);
}
firstSundayOfNextMonth = firstDayOfNextMonth;
And we found it. firstSundayOfNextMonth is the first Sunday of the next month for a given DateTime (which is dt in our case).
public static DateTime GetFirstSundayOfNextMonth(DateTime givenDate)
{
DateTime firstDayNextMonth = givenDate.AddDays(-givenDate.Day + 1).AddMonths(1);
int diff = 7 - (int)firstDayNextMonth.DayOfWeek;
return firstDayNextMonth.AddDays(diff);
}
Try this :
DateTime dt1 = new DateTime(2015, 03, 13);
DateTime dm = dt1.AddMonths(1);
DateTime addm = new DateTime(dm.Year,dm.Month,1);
var nextSunday = addm.AddDays(7 - (int)addm.DayOfWeek);
You can put any date in place of 2015, 03, 13 like year,month,day.
To get the next week day after a certain date, I found a simple way.
public static DateTime FirstDayOfWeekOnOrAfter(this DateTime date, DayOfWeek dayOfWeek)
{
return date.AddDays(Math.Abs(dayOfWeek - date.DayOfWeek));
}
public static DateTime FirstDayOfWeekOnOrBefore(this DateTime date, DayOfWeek dayOfWeek)
{
return date.AddDays(-Math.Abs(dayOfWeek - date.DayOfWeek));
}
DateTime nextMonthfirstSunday;
DayOfWeek firstDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month+1, 1).DayOfWeek;
switch (firstDay)
{
case DayOfWeek.Sunday:
nextMonthfirstSunday = new DateTime(DateTime.Now.Year, DateTime.Now.Month+1, 1);
break;
case DayOfWeek.Monday:
nextMonthfirstSunday = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 7);
break;
case DayOfWeek.Tuesday:
nextMonthfirstSunday = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 6);
break;
case DayOfWeek.Wednesday:
nextMonthfirstSunday = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 5);
break;
case DayOfWeek.Thursday:
nextMonthfirstSunday = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 4);
break;
case DayOfWeek.Friday:
nextMonthfirstSunday = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 3);
break;
default://Saturday
nextMonthfirstSunday = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 2);
break;
}
public static DateTime GetFirstSundayOfNextMonth(DateTime dt)
{
dt = dt.AddMonths(1); // In case of December using new DateTime(dt.Year, dt.Month + 1, 1) could throw and error. So first use .AddMonths(1).
dt = new DateTime(dt.Year, dt.Month, 1); // Get first date of month
return dt.AddDays((7 - dt.DayOfWeek.GetHashCode() + DayOfWeek.Sunday.GetHashCode()) % 7); // get first sunday.
}

Getting first and last day of the current month

I have here 2 datepicker for start date and end date.
how can I get the first day and last day of the current month
rdpStartDate.SelectedDate = DateTime.Now;
rdpEndDate.SelectedDate = DateTime.Now;
DateTime now = DateTime.Now;
var startDate = new DateTime(now.Year, now.Month, 1);
var endDate = startDate.AddMonths(1).AddDays(-1);
var now = DateTime.Now;
var first = new DateTime(now.Year, now.Month, 1);
var last = first.AddMonths(1).AddDays(-1);
You could also use DateTime.DaysInMonth method:
var last = new DateTime(now.Year, now.Month, DateTime.DaysInMonth(now.Year, now.Month));
var myDate = DateTime.Now;
var startOfMonth = new DateTime(myDate.Year, myDate.Month, 1);
var endOfMonth = startOfMonth.AddMonths(1).AddDays(-1);
That should give you what you need.
Try this code it is already built in c#
int lastDay = DateTime.DaysInMonth (2014, 2);
and the first day is always 1.
Good Luck!
An alternative way is to use DateTime.DaysInMonth to get the number of days in the current month as suggested by #Jade
Since we know the first day of the month will always 1 we can use it as default for the first day with the current Month & year as current.year,current.Month,1.
var now = DateTime.Now; // get the current DateTime
//Get the number of days in the current month
int daysInMonth = DateTime.DaysInMonth (now.Year, now.Month);
//First day of the month is always 1
var firstDay = new DateTime(now.Year,now.Month,1);
//Last day will be similar to the number of days calculated above
var lastDay = new DateTime(now.Year,now.Month,daysInMonth);
//So
rdpStartDate.SelectedDate = firstDay;
rdpEndDate.SelectedDate = lastDay;
string firstdayofyear = new DateTime(DateTime.Now.Year, 1, 1).ToString("MM-dd-yyyy");
string lastdayofyear = new DateTime(DateTime.Now.Year, 12, 31).ToString("MM-dd-yyyy");
string firstdayofmonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).ToString("MM-dd-yyyy");
string lastdayofmonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(1).AddDays(-1).ToString("MM-dd-yyyy");

linq weekly grouping?

Linq
from c in customerReadings
group c by new { date = GetGroupingDateKey(DateRangeType, c.ReadDate), name = c.Name } into g
select new MeterReadingsForChart
{
ReadDate = g.Key.date,
Name = g.Key.name,
Value = g.Sum(y => y.Value),
TimeInterval = DateRangeType
};
GetGroupingDateKey()
private static DateTime GetGroupingDateKey(MeterReadingsTimeIntervals DateRangeType, DateTime Date)
{
DateTime date = new DateTime();
switch (DateRangeType)
{
case MeterReadingsTimeIntervals.Hourly:
//For Example data is betweet 10:05 - 11:05
//DateTime offSet = Date.AddMinutes(-5);
//date = new DateTime(offSet.Year, offSet.Month, offSet.Day, offSet.Hour, 5, 0);
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:
date = Date.AddDays(-((7 + Date.DayOfWeek - DayOfWeek.Monday) % 7));
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;
}
Records time : 10/10/2012 - between 09:15 and 10:15
Hourly groupped data count : 2 (expected)
Daily groupped data count : 1 (expected)
Weekly groupped data count : 5 (group count (not expected))
Monthly groupped data count : 1 (expected)
Yearly groupped data count : 1 (expexted)
How can I group records by week. What is the wrong about my weekly grouping?
Thanks in advance.
I would imagine your Date has a time part - you need to zero it out, e.g.
date = Date.Date.AddDays(-((7 + Date.DayOfWeek - DayOfWeek.Monday) % 7));

How to get the current time in Jerusalem with C#?

I need to know Jerusalem Current time.
That code taking server time but I need Jerusalem time:
DateTime currentTime = DateTime.Now;
dayName = currentTime.DayOfWeek;
Edit:
with help of Vinoth answer(I took only the AddHours(2) part) it should be like that (not works):
DateTime currentTime = DateTime.Now;
currentTime=currentTime.AddHours(2);//Jerusalem Time
dayName = currentTime.DayOfWeek;
Edit2:my improvement (ToUniversalTime())
DateTime currentTime = DateTime.Now;
currentTime=currentTime.ToUniversalTime().AddHours(2);//Jerusalem Time
dayName = currentTime.DayOfWeek;
This will help you. I have used this is one of my app. Jus pasting the code
public static DateTime GetIsraelTime(DateTime d) {
d = d.AddHours(2); // Israel is at GMT+2
// April 2nd, 2:00 AM
DateTime DSTStart = new DateTime(d.Year, 4, 2, 2, 0 ,0);
while (DSTStart.DayOfWeek != DayOfWeek.Friday)
DSTStart = DSTStart.AddDays(-1);
CultureInfo jewishCulture = CultureInfo.CreateSpecificCulture("he-IL");
System.Globalization.HebrewCalendar cal =
new System.Globalization.HebrewCalendar();
jewishCulture.DateTimeFormat.Calendar = cal;
// Yom HaKipurim, at the start of the next Jewish year, 2:00 AM
DateTime DSTFinish =
new DateTime(cal.GetYear(DSTStart)+1, 1, 10, 2, 0 ,0, cal);
while (DSTFinish.DayOfWeek != DayOfWeek.Sunday)
DSTFinish= DSTFinish.AddDays(-1);
if (d>DSTStart && d<DSTFinish)
d = d.AddHours(1);
return (d);
}
var israelTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, "Israel Standard Time")
Complete time zones ids list can be found here.

Categories

Resources