Given a DateTime and a DayOfWeek should return the date of the last DayOfWeek of that month.
E.g. 1st-March-2009 and Sunday would return 29th-March-2009
Given a DateTime and a DayOfWeek should return the date of the last DayOfWeek of that month.
E.g. 1st-March-2009 and Sunday would return 29th-March-2009
Get the first day in the next month, then find the first mathing weekday in that month. Go back seven days and you are at that weekday in the last week of the corrent month:
DateTime date = new DateTime(2009, 3, 12);
DayOfWeek day = DayOfWeek.Sunday;
DateTime nextMonth = new DateTime(date.Year, date.Month, 1).AddMonths(1);
while (nextMonth.DayOfWeek != day) {
nextMonth = nextMonth.AddDays(1);
}
DateTime lastInMonth = nextMonth.AddDays(-7);
(You could replace the loop with some arithmetic that calculates the number of days to add based on the numeric values of the DayOfWeek values, but this is more straight forward.)
Edit:
You could of course also get the last day in the current month, then loop backwards until you find the correct weekday.
http://datetimeextensions.codeplex.com/ has a Last(dayOfWeek) extension method that will do this for you
Test included :-)
Can't find a handy one-liner but this one works:
static DateTime LastDayOfWeekInMonth(DateTime day, DayOfWeek dow)
{
DateTime lastDay = new DateTime(day.Year, day.Month, 1).AddMonths(1).AddDays(-1);
DayOfWeek lastDow = lastDay.DayOfWeek;
int diff = dow - lastDow;
if (diff > 0) diff -= 7;
System.Diagnostics.Debug.Assert(diff <= 0);
return lastDay.AddDays(diff);
}
Try this: start at the last day and count back until you hit the day you're looking for
static DateTime LastOccurenceOfDay(DateTime dt, DayOfWeek dow)
{
DateTime looperDate = new DateTime(dt.Year, dt.Month, 1)
.AddMonths(1).AddDays(-1);
while (looperDate.DayOfWeek!=dow)
looperDate =looperDate.AddDays(-1);
return looperDate;
Edit: Recovered the old version Dangph is refering to in the comments.
static DateTime LastOccurenceOfDay(DateTime dt, DayOfWeek dow)
{
//set start of loop
DateTime looperDate = new DateTime(dt.Year, dt.Month, 1);
//initialze return value
DateTime returnDate = dt;
//loop until the month is over
while (looperDate.Month == dt.Month)
{
//if the current DayOfWeek is the date you're looking for
if (looperDate.DayOfWeek == dow)
//remember it.
returnDate = looperDate;
//increase day
looperDate=looperDate.AddDays(1);
}
return returnDate;
}
static DateTime LastDateOfWeekForMonth(DayOfWeek weekday, int month, int year)
{
DateTime d = new DateTime(year, month, 1).AddMonths(1);
while (!(d.DayOfWeek == weekday && d.Month == month))
{
d = d.AddDays(-1);
}
return d;
}
public DateTime GetLastDayOfMonth(int year, int month, DayOfWeek dayOfWeek)
{
var daysInMonth = DateTime.DaysInMonth(year, month);
var lastDay = new DateTime(year, month, daysInMonth);
while (lastDay.DayOfWeek != dayOfWeek)
{
lastDay = lastDay.AddDays(-1);
}
return lastDay;
}
static DateTime GetDayOfWeekInMonthFromWeekIndex(this DateTime date, DayOfWeek dow, int weekIndex)
{
if (weekIndex > 4)
return LastDayOfWeekInMonth(date, dow);
DateTime newDate = new DateTime(date.Year, date.Month, 1);
DayOfWeek newDow = newDate.DayOfWeek;
int diff = dow - newDow;
diff += ((weekIndex - 1) * 7);
return newDate.AddDays(diff);
}