我之前的问题有很多缺点。我将再次尝试使用代码以及为什么它不起作用。
例如,我们的活动每3个月举行一次。事件有DateStart,DataEnd和Periodicity 例如,我们有一条记录:
start = 02/23/2012 22:00:00;
end = 12/31/2012 23:30:00;
periodicity = 3;
当前月份= 2月,5月,8月,11月时,方法必须返回true。
代码:
public bool MonthPeriodicityChecker (DateTime start, DateTime end, DateTime dateToCheck, int periodicity)
{
var monthDiff = dateToCheck.Month - startDate.Month;
return (monthDiff-1) % periodicity == 0;
}
如果dateToCheck中的月份等于4月,7月,10月,则此代码返回true
。它是在第一个月跳过。
更新
该死的,对不起。在更远的地方,我有循环,总结日期。此循环从1开始,并将此1添加到start
。下一次约会是2月24日。因此,在我的程序中,2月份不打印(也有月份数(23)的检查)。对不起,谢谢。
答案 0 :(得分:2)
如果你想在二月,五月,八月和十一月触发,你不应该从差异中减去一个。只需使用:
return (monthDiff % periodicity) == 0;
当月份相等(二月)时,0 % 3 == 0
。如果您是三个月的倍数(例如八月),6 % 3 == 0
。
而且我不确定C#,但是当采用负数模数时,某些语言不能像你期望的那样,所以我会用双重安全:
public bool MonthPeriodicityChecker (DateTime start, DateTime end,
DateTime dateToCheck, int periodicity)
{
var monthDiff = dateToCheck.Month - startDate.Month + 12; // make positive
return (monthDiff % periodicity) == 0;
}
然而,请记住,因为您在计算中只使用了一年中的某个月,如果您运行超过12个月并且您的周期不是分为12个,那么这可能无法按预期工作干净。
每五个月开始使用2010年12月的例子。
0 % 5 == 0
。5 % 5 == 0
。 10 % 5 == 0
。3 % 5 == 3
。结果就是你每年五月,十月和十二月都会开火。
您可以通过确保考虑年限来解决这个小问题(如果 对您来说是个问题),例如:
public bool MonthPeriodicityChecker (DateTime start, DateTime end,
DateTime dateToCheck, int periodicity)
{
// assuming Month returns 1-12 here which is the case for C# I think.
var monthDiff = (dateToCheck.Year * 12 + dateToCheck.Month - 1)
- (startDate.Year * 12 + startDate.Month - 1);
return (monthDiff % periodicity) == 0;
}
这也消除了增加12以获得正数的需要,因为推进年份将确保(从12月到1月的跳跃现在将给你1而不是-11),假设dateToCheck.Month
将始终大于或等于startDate.Month
。
如果dateToCheck
可能更少 startDate
,您可能需要首先检查并返回false作为上述函数的第一步。
答案 1 :(得分:0)
你的月减法不好。如果从12月改为1月会发生什么?
这种方法怎么样:
public bool monthPeriodicityChecker(DateTime start, DateTime end, dateToCheck, periodicity)
{
if ((dateToCheck < start) || (dateToCheck > start))
return false;
int monthDiff = 0;
while (startDate.AddMonths(1) < dateToCheck)
{
monthDiff++
// i'm sure there is a speedier way to calculate the month difference, but this should do for the purpose of this example
}
return (monthDiff) % periodicity == 0;
};
答案 2 :(得分:0)
您可以通过生成范围内的所有日期来执行此操作,然后查看其中是否有任何日期与dateToCheck
相同。首先,得到几个月:
private IEnumerable<DateTime> GetDatesInRange(DateTime start, DateTime end, int periodicity)
{
var current = start;
do
{
yield return current;
current += TimeSpan.FromMonths(periodicity);
}
while(current <= end)
}
然后,看看是否有同一个月:
public bool MonthPeriodicityChecker(DateTime start, DateTime end, DateTime dateToCheck, int periodicity)
{
return GetDatesInRange(start, end, periodicity).Any(date => date.Month == dateToCheck.Month);
}