如何确定给定日期是否是该月的第N个工作日?

这是我想要做的:给定日期,星期几和整数n ,确定日期是否是该月的第n天。

例如:

  • 输入1/1/2009,Monday,2将是假的,因为1/1/2009不是第二个星期一

  • 11/13/2008 11/13/2008,Thursday,2将返回true,因为它是第二个星期四

如何改进此实施?

 private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n) { int d = date.Day; return date.DayOfWeek == dow && (d/ 7 == n || (d/ 7 == (n - 1) && d % 7 > 0)); } 

您可以更改一周的检查,以便函数读取:

 private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n){ int d = date.Day; return date.DayOfWeek == dow && (d-1)/7 == (n-1); } 

除此之外,它看起来非常好,效率很高。

答案来自这个网站 。 复制/粘贴此处以防网站丢失。

 public static DateTime FindTheNthSpecificWeekday(int year, int month,int nth, System.DayOfWeek day_of_the_week) { // validate month value if(month < 1 || month > 12) { throw new ArgumentOutOfRangeException("Invalid month value."); } // validate the nth value if(nth < 0 || nth > 5) { throw new ArgumentOutOfRangeException("Invalid nth value."); } // start from the first day of the month DateTime dt = new DateTime(year, month, 1); // loop until we find our first match day of the week while(dt.DayOfWeek != day_of_the_week) { dt = dt.AddDays(1); } if(dt.Month != month) { // we skip to the next month, we throw an exception throw new ArgumentOutOfRangeException(string.Format("The given month has less than {0} {1}s", nth, day_of_the_week)); } // Complete the gap to the nth week dt = dt.AddDays((nth - 1) * 7); return dt; } 

以下是MSDN所说的内容。 它的VB,但它很容易翻译。

看起来该语言为给定日期提供日期/日期方法。 如果有人感兴趣,你可以阅读泽勒的同意 。

我不认为这是他们想要你做的,但你可以找到一个月的第一天的那一天。 现在我想到了你可以找到给定日期的星期几作为N并获得模7。

哦,等等,这是一周中某天(如星期日)的第N次出现,或者像本月的第N个工作日 ! 好的,我看到了这些例子。

如果你可以构建一个月份的第一个日期,也许会有所作为。

鉴于它是一周中某天的第N次出现 ,并且您无法摆弄任何日期时间数据类型,并且您可以同时访问一周中的获取日期并获取一天中的某些日期函数。 周日会不会是零?

1)首先,星期几必须与给定的星期几相匹配。
2)N必须至少为1,最多为4。
3)对于相同的n,该月的日期将在n * 7 * dayOfWeek + 1和n * 7 * dayOfWeek + 6之间。
– 让我考虑一下。 如果星期天是第一个.. 0 * 7 * 0 + 1 = 1,星期六6号将是0 * 7 * 0 + 6。

认为上面的1和3是足够的,因为获取日期函数不应违反2。

 (* first try, this code sucks *) function isNthGivenDayInMonth(date : dateTime; dow : dayOfWeek; N : integer) : boolean; var B, A : integer (* on or before and after day of month *) var Day : integer (* day of month *) begin B := (N-1)*7 + 1; A := (N-1)*7 + 6; D := getDayOfMonth(date); if (dow <> getDayOfWeek(date) then return(false) else return( (B <= Day) and (A >= Day) ); end; (* function *) 

希望那个哈哈没有错误!
[编辑:周六将是第7,上限(N-1)*7 + 7 ]
您的解决方案看起来会匹配2个不同的周? 星期天看起来总是会回零吗? 应该在C#中做过伪代码。短路&&就像我的..如果星期天开始的几个月内N = 1的第一场比赛不应该是周日吗?

  d/ 7 == n 

这会导致(either 0 or 1)/7 == 1 ,这是不对的! 你的|| 罗伯特也有这个(n-1) 。 和Robert Wagner一起回答吧! 它只有2行,短是好! 拥有(Day-1) mod 7
[编辑: (Day-1) div 7 ]消除了我不必要的变量和2行设置。

为了记录,应该检查边界情况等等,就像8月31日是周日或周六一样。
[编辑:本来应该检查周末案例。 抱歉!]

您可以找到一个函数,该函数返回任何月份特定工作日第n次出现的日期。

见http://chiragrdarji.wordpress.com/2010/08/23/find-second-saturday-and-fourth-saturday-of-month/

在这个答案中 ,需要翻转以下代码:

 // Complete the gap to the nth week dt = dt.AddDays((nth - 1) * 7); if(dt.Month != month) { // we skip to the next month, we throw an exception throw new ArgumentOutOfRangeException(”The given month has less than ” nth.ToString() ” ” day_of_the_week.ToString() “s”); } 

上面的大多数答案都是部分准确或不必要的复杂。 您可以尝试这个更简单的function,该function还会检查给定日期是否是该月的最后一天而是第N天。

  public static bool IsNthDayofMonth(this DateTime date, DayOfWeek weekday, int N) { if (N > 0) { var first = new DateTime(date.Year, date.Month, 1); return (date.Day - first.Day)/ 7 == N - 1 && date.DayOfWeek == weekday; } else { var last = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1); return (last.Day - date.Day) / 7 == (Math.Abs(N) - 1) && date.DayOfWeek == weekday; } 

如果你想要一个月的Nth DayOfWeek的一段时间(不仅仅是一个)的日期列表,你可以使用:

 internal static List GetDatesForNthDOWOfMonth(int weekNum, DayOfWeek DOW, DateTime beginDate, DateTime endDate) { List datesForNthDOWOfMonth = new List(); int earliestDayOfMonth = 1; int latestDayOfMonth = 7; DateTime currentDate = beginDate; switch (weekNum) { case 1: earliestDayOfMonth = 1; latestDayOfMonth = 7; break; case 2: earliestDayOfMonth = 8; latestDayOfMonth = 14; break; case 3: earliestDayOfMonth = 15; latestDayOfMonth = 21; break; case 4: earliestDayOfMonth = 22; latestDayOfMonth = 28; break; } while (currentDate < endDate) { DateTime dateToInc = currentDate; DateTime endOfMonth = new DateTime(dateToInc.Year, dateToInc.Month, DateTime.DaysInMonth(dateToInc.Year, dateToInc.Month)); bool dateFound = false; while (!dateFound) { dateFound = dateToInc.DayOfWeek.Equals(DOW); if (dateFound) { if ((dateToInc.Day >= earliestDayOfMonth) && (dateToInc.Day <= latestDayOfMonth)) { datesForNthDOWOfMonth.Add(dateToInc); } } if (dateToInc.Date.Equals(endOfMonth.Date)) continue; dateToInc = dateToInc.AddDays(1); } currentDate = new DateTime(currentDate.Year, currentDate.Month, 1); currentDate = currentDate.AddMonths(1); } return datesForNthDOWOfMonth; } 

......并以这种方式称呼它:

 // This is to get the 1st Monday in each month from today through one year from today DateTime beg = DateTime.Now; DateTime end = DateTime.Now.AddYears(1); List dates = GetDatesForNthDOWOfMonth(1, DayOfWeek.Monday, beg, end); // To see the list of dateTimes, for verification foreach (DateTime d in dates) { MessageBox.Show(string.Format("Found {0}", d.ToString())); } 

你可以这样得到每个月的第二个星期五:

 List dates = GetDatesForNthDOWOfMonth(2, DayOfWeek.Friday, beg, end); 

...等等。