在过去的某个日期计算周年纪念的最简单方法是什么?

时间:2014-07-25 10:52:47

标签: c# datetime timespan

我需要一个函数来计算在过去和今天的当前日期给出开始日期的人是否有即将到来的周年纪念日。我在下面找到了这段代码,但是看下面的代码,我觉得有一个更简单的方法来计算这个,而不需要这个for循环:

private const int ANNIVERSARY_ALERT = 10;

public virtual string UpcomingMilestone
{
    get
    {
        var years = Years() + 2;
        for (int year = 0; year < years; year++)
        {
            int days = year * 365;
            int dayDiff = days - NumberOfDays;
            if (dayDiff == 0)
            {
                return year + " year milestone";
            }
            if (dayDiff < ANNIVERSARY_ALERT && dayDiff > 0)
            {
                return year + " year milestone in " + dayDiff + " days";
            }
        }
        return string.Empty;
    }
}

public virtual int NumberOfDays
{
    get
    {
        TimeSpan ts = DateTime.Today - StartDate.Value;
        return (int)ts.TotalDays;
    }
}

public virtual int Years()
{
    TimeSpan span = DateTime.Now.Subtract(StartDate.Value);
    return (int)(span.Days / 365.25); // leap years included
}

任何人都可以建议一种方法来计算上述内容而无需进行此循环吗?对于代码可维护性而言,这更多是针对任何性能考虑因素。

4 个答案:

答案 0 :(得分:2)

使用startdate的相关部分组成一个新的DateTime:

//My birthday, feel free to put this date in your calendars!
var startDate = new DateTime(1976, 2, 29);

//Get the anniversary date for this year
DateTime nextAnniversary;

try
{
    nextAnniversary = new DateTime(DateTime.Today.Year, startDate.Month, startDate.Day);
}
catch(ArgumentOutOfRangeException)
{
    //DateTime conversion failed, try next day in the year
    nextAnniversary = new DateTime(DateTime.Today.Year, startDate.AddDays(1).Month, startDate.AddDays(1).Day);
}

//Check if this year's anniversary has already happened
if(nextAnniversary < DateTime.Today) nextAnniversary = nextAnniversary.AddYears(1);

答案 1 :(得分:0)

这应该这样做。您需要提供可以是一天或一周的TimeSpan range,以及与您相匹配的日期。

    public bool Upcomming(DateTime date, TimeSpan range){
        var newdate = new Date(DateTime.Now.Year, date.Month, date.Day);
        return newdate - DateTime.Now < range;
    }

答案 2 :(得分:0)

int anniversaryYear = DateTime.Now.Year - StartDate.Year + 1;    

DateTime nextAnniversary = StartDate.AddYears(anniversaryYear);    

if (nextAnniversary == DateTime.Now)
{
    return anniverasryYear + " year milestone";
}

if (DateTime.Now > nextAnniverasry)
{
    anniverasryYear++;
    nextAnniversary = StartDate.AddYears(anniversaryYear);    
}

var daysTillNext = Math.Abs( (nextAnniversary - DateTime.Now).TotalDays );     
return string.Format("{0} milestone in {1}", anniversaryYear, daysTillNext); 

答案 3 :(得分:0)

这些方法应该足以满足您的目的。

public DateTime GetNextAnniversaryDate(DateTime anniversary)
{
    var today = DateTime.Today;
    var year = anniversary.Month < today.Month || 
              (anniversary.Month == today.Month && anniversary.Day < today.Day)
        ? today.Year + 1 : today.Year;

    return anniversary.Month == 2 && anniversary.Day == 29 &&
           !DateTime.IsLeapYear(year)
        ? new DateTime(year, 2, 28)
        : new DateTime(year, anniversary.Month, anniversary.Day);
}

public int GetDaysUntilNextAnniversary(DateTime anniversary)
{
    var nextDate = GetNextAnniversaryDate(anniversary);
    return (int)(nextDate - DateTime.Today).TotalDays;
}

请注意,我们特别选择在2月28日庆祝闰日纪念日,因为周年纪念日不是闰年。如果需要,您可以将其更改为3月1日。

另请注意,此问题假定相关人员的日期与计算机的本地时钟相同。此可能不正确,例如,如果本地计算机位于用户时区之前的时区,则可能是休息一天。如果您想考虑这一点,那么您可以使用TimeZoneInfoDateTime.UtcNow。或者您可以使用Noda TimeMore about this on my blog