Given a date (of type DateTime
), how do I find the 3rd Friday in the month of that date?
Old post, but I found remarkably few decent answers online for this surely quite common problem! Mark Ransom's answer should be the last word on this algorithm-wise, but here is a C# helper class (in this case I think clearer than extensions) for anyone who wants a quick answer to the common problems of "first day of week in month", "xth day of week in month" and "last day of week in month".
I modified it to return DateTime.MinValue
if the Xth day of the week falls outside the provided month rather than wrapping to the next month, because that to me seems more useful.
I've thrown in a LINQPad-runnable example program too.
void Main()
{
DayOfWeek dow = DayOfWeek.Friday;
int y = 2014;
int m = 2;
String.Format("First {0}: {1}", new object[] { dow, DateHelper.FirstDayOfWeekInMonth(y, m, dow) }).Dump();
"".Dump();
String.Format("Last {0}: {1}", new object[] { dow, DateHelper.LastDayOfWeekInMonth(y, m, dow) }).Dump();
"".Dump();
for(int i = 1; i <= 6; i++)
String.Format("{0} #{1}: {2}", new object[] { dow, i, DateHelper.XthDayOfWeekInMonth(y, m, dow, i) }).Dump();
}
public class DateHelper
{
public static DateTime FirstDayOfWeekInMonth(int year, int month, DayOfWeek day)
{
DateTime res = new DateTime(year, month, 1);
int offset = -(res.DayOfWeek - day);
if (offset < 0)
offset += 7;
res = res.AddDays(offset);
return res;
}
public static DateTime LastDayOfWeekInMonth(int year, int month, DayOfWeek day)
{
DateTime dt = new DateTime(year, month, 1).AddMonths(1);
DateTime res = FirstDayOfWeekInMonth(dt.Year, dt.Month, day);
res = res.AddDays(-7);
return res;
}
public static DateTime XthDayOfWeekInMonth(int year, int month, DayOfWeek day, int x)
{
DateTime res = DateTime.MinValue;
if (x > 0)
{
res = FirstDayOfWeekInMonth(year, month, day);
if (x > 1)
res = res.AddDays((x - 1) * 7);
res = res.Year == year && res.Month == month ? res : DateTime.MinValue;
}
return res;
}
}
Prints:
First Friday: 07/02/2014 00:00:00
Last Friday: 28/02/2014 00:00:00
Friday #1: 07/02/2014 00:00:00
Friday #2: 14/02/2014 00:00:00
Friday #3: 21/02/2014 00:00:00
Friday #4: 28/02/2014 00:00:00
Friday #5: 01/01/0001 00:00:00
Friday #6: 01/01/0001 00:00:00