Here are methods to find the first/last specified day of week in a given month:
public DateTime GetFirstDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek)
{
DateTime dt = new DateTime(year, month, 1);
int first = (int)dt.DayOfWeek;
int wanted = (int)dayOfWeek;
if (wanted < first)
wanted += 7;
return dt.AddDays(wanted - first);
}
public DateTime GetLastDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek)
{
int daysInMonth = CultureInfo.CurrentCulture.Calendar.GetDaysInMonth(year, month);
DateTime dt = new DateTime(year, month, daysInMonth);
int last = (int)dt.DayOfWeek;
int wanted = (int)dayOfWeek;
if (wanted > last)
last += 7;
return dt.AddDays(wanted - last);
}
From those, you can easily find the answers to the other questions... just add 7 days to find the next occurence of the day you're looking for
EDIT: thinking more about it, it would be pretty handy to have that in the form of extension methods, such as :
Console.WriteLine("Next monday : {0}", DateTime.Today.Next(DayOfWeek.Monday));
Console.WriteLine("Last saturday : {0}", DateTime.Today.Previous(DayOfWeek.Saturday));
Here is the implementation :
public static class DateExtensions
{
public static DateTime Next(this DateTime from, DayOfWeek dayOfWeek)
{
int start = (int)from.DayOfWeek;
int wanted = (int)dayOfWeek;
if (wanted < start)
wanted += 7;
return from.AddDays(wanted - start);
}
public static DateTime Previous(this DateTime from, DayOfWeek dayOfWeek)
{
int end = (int)from.DayOfWeek;
int wanted = (int)dayOfWeek;
if (wanted > end)
end += 7;
return from.AddDays(wanted - end);
}
}
It's probably more flexible than the first methods I suggested... With that, you can easily do things like that :
// Print all Sundays between 2009/01/01 and 2009/03/31
DateTime from = new DateTime(2009, 1, 1);
DateTime to = new DateTime(2009, 3, 31);
DateTime sunday = from.Next(DayOfWeek.Sunday);
while(sunday <= to)
{
Console.WriteLine(sunday);
sunday = sunday.AddDays(7);
}