事件的周期性2

时间:2012-02-26 04:13:23

标签: c#

我之前的问题有很多缺点。我将再次尝试使用代码以及为什么它不起作用。

例如,我们的活动每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)的检查)。对不起,谢谢。

3 个答案:

答案 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月的例子。

  • 2010年12月没问题,因为差异为零:0 % 5 == 0
  • 2011年5月没问题,因为五月到十二月之间的差异是五个月:5 % 5 == 0
  • 2011年10月没问题,因为十月到十二月之间的差异是十个月:10 % 5 == 0
  • 2012年3月没关系。 3月到12月之间的差异是三个月,而不是实际发生的十五个月: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);
}