以下是我要做的事情:
给定日期,星期几和整数n
,确定日期是否为该月的n
天。
例如:
1/1/2009,Monday,2
的输入
将是假的,因为1/1/2009
不是第二个星期一
输入
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));
}
答案 0 :(得分:12)
您可以更改一周的检查,以便函数显示:
private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n){
int d = date.Day;
return date.DayOfWeek == dow && (d-1)/7 == (n-1);
}
除此之外,它看起来非常好而且效率很高。
答案 1 :(得分:8)
答案来自this website。复制/粘贴此处以防网站丢失。
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;
}
答案 2 :(得分:1)
Here是MSDN必须说的。它的VB,但很容易翻译。
答案 3 :(得分:1)
看起来该语言为给定日期提供日期/日期方法。如果有人感兴趣,您可以阅读Zeller's congruence。
我不认为这是他们想要你做的,但你可以找到一个月的第一天的那一天。现在,我想到了你可以找到给定日期的一周中的某一天N
并获得模7。
哦,等等,这是一周中某天(如星期日)的第N次出现,或者像本月的第N次工作日!好的,我看到了这些例子。
如果您可以构建一个日期,例如一个月的第一天,那么它可能会有所作为。
鉴于它是星期一的第N次出现,并且您无法摆弄任何日期时间数据类型,并且您可以同时访问每周的获取日和获取日期月份功能周日会是零?
1)首先,星期几必须与给定的星期几相匹配 2)N必须至少为1且最多为4 3)月份的日期在n * 7 * dayOfWeek + 1和n * 7 * dayOfWeek + 6之间,相同的n。 - 让我考虑一下。如果星期天是第一个.. 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#中做过伪代码。短路&amp;&amp;就像我的..
星期天开始的几个月内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日是周日或周六一样 [编辑:本来应该检查周末案例。遗憾!] 强>
答案 4 :(得分:1)
您可以找到一个函数,该函数返回任何月份特定工作日第n次出现的日期。
请参阅http://chiragrdarji.wordpress.com/2010/08/23/find-second-saturday-and-fourth-saturday-of-month/
答案 5 :(得分:0)
在this answer中,需要翻转以下代码:
// 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”);
}
答案 6 :(得分:0)
上面的大多数答案都是部分准确或不必要的复杂。 您可以尝试这个更简单的功能,它还会检查给定日期是否是该月的最后一天而是第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;
}
答案 7 :(得分:0)
如果你想要一个月的Nth DayOfWeek的一段时间(不仅仅是一个)的日期列表,你可以使用它:
next()
...并以这种方式称呼它:
internal static List<DateTime> GetDatesForNthDOWOfMonth(int weekNum, DayOfWeek DOW, DateTime beginDate, DateTime endDate)
{
List<DateTime> datesForNthDOWOfMonth = new List<DateTime>();
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<DateTime> 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()));
}
...等