2013-06-05 81 views
7

我试图在客户在未来7天内有生日时收到提醒。比较DateTime without year

我这个代码试了一下:

public bool IsBirthdayImminent 
{ 
    get { return DateOfBirth != null && DateOfBirth.Value.Date >= DateTime.Today.Date.AddDays(-7); } 
} 

当然,这是不行的,因为日期存储其一年(比如1980年5月21日),同时也比较了一年。所以这个查询永远不会是true - 好吧,如果你在未来七天内出生的话,那么这个问题不会发生。

如何修改此查询以忽略年份?

编辑:

好吧,查询本身是没有问题的。我的主要观点是在12月< - > 1月左右处理闰年和情况。

+0

尝试:DateOfBirth.Value.Date> = DateTime.Today.Date.AddYears(DateOfBirth.Value.Date.Year - DateTime.Today.Date.Year).AddDays(-7) – NeverHopeless

+0

规范化两个日期:复制的DOB值,并将年份设置为与当年相同。现在你会比较苹果和苹果。 – Icarus

+0

@Idle_Mind可能没有闰年问题?例如,如果其中一个日期是1996年2月29日,并且您尝试将其设置为2013年2月29日,则可能无法获得理想的结果。多年来日期之间的其他差异也是如此。 – Servy

回答

8

我会建议使用下面的代码。这包括12月 - 1月和2月29日左右的情况。虽然您可能想要看一下并在2月28日正确的排除或排除给定的days

BirthdayImminent(new DateTime(1980, 1, 1), new DateTime(2012, 1, 2), 7); // false 
    BirthdayImminent(new DateTime(1980, 1, 1), new DateTime(2012, 12, 28), 7); // true 
    BirthdayImminent(new DateTime(1980, 2, 28), new DateTime(2012, 2, 21), 7); // true 

    private static bool BirthdayImminent(DateTime birthDate, DateTime referenceDate, int days) 
    { 
     DateTime birthdayThisYear = birthDate.AddYears(referenceDate.Year - birthDate.Year); 

     if (birthdayThisYear < referenceDate) 
      birthdayThisYear = birthdayThisYear.AddYears(1); 

     bool birthdayImminent = (birthdayThisYear - referenceDate).TotalDays <= days; 

     return birthdayImminent; 
    } 

同时保留边缘案例记在Guvante张贴在下面的评论。

+0

+1代替'AddYears'而不是试图破解一个构造函数。技术上来说,对于'日> = 60',您对闰日生日的处理是关闭的。使'AddYears'函数关闭'birthDate'将修复该边缘条件('2/29/2012.AddYears(3).AddYears(1)== 2/28/2016')。然而,鉴于要求,我会说你的方法是最好的,因为更正增加了非明显的合理冗余。 – Guvante

+1

@Guvante不适用于所有日子> = 60,只是闰年,当前日期也是闰年但在28日之前。尽管如此,它在这些条件下已经过去了一天。这就是为什么我很少回答DateTime问题的原因。他们超级混乱。 – Servy

+0

@Servy:你认为更正'birthdayThisYear'(上次作业之后)和'birthDate'之间的闰日数量就足够了吗? – Caramiriel

0

将birtdate年明确设置为DateTime.Today.Year,它会比较得很好。

+1

尽管如此,请注意12月至1月左右的情况。 – Caramiriel

1

事情是这样的:

DateTime birthDate = new DateTime(2012, 12, 2); 

DateTime birthdayThisYear; 
if (birthDate.Month == 2 && birthDate.Day == 29 && DateTime.IsLeapYear(DateTime.Now.Year)) 
    birthdayThisYear = new DateTime(DateTime.Now.Year, 2, 28); 
else 
    birthdayThisYear = new DateTime(DateTime.Now.Year, birthDate.Month, birthDate.Day); 

bool birthdayImminent = birthdayThisYear > DateTime.Now && (birthdayThisYear - DateTime.Now).TotalDays <= 7; 

是获取:

public bool IsBirthdayImminent 
{ 
    get 
    { 
     if (DateOfBirth == null) 
      return false; 
     else 
     { 
      DateTime birthdayThisYear; 
      if (birthDate.Month == 2 && birthDate.Day == 29 && DateTime.IsLeapYear(DateTime.Now.Year)) 
       birthdayThisYear = new DateTime(DateTime.Now.Year, 2, 28); 
      else 
       birthdayThisYear = new DateTime(DateTime.Now.Year, birthDate.Month, birthDate.Day); 

      return birthdayThisYear > DateTime.Now && (birthdayThisYear - DateTime.Now).TotalDays <= 7; 
     } 
    } 
} 
+2

-1如果某人在2月29日出生,这会在你称之为多数年的时候抛出异常。 – Servy

+0

@SeToY - 看起来不错。这也值得添加一个检查,以确保bithdate在未来,即'&& birthdayThisYear> DateTime.Now' – MarcF

+0

@Servy - 好点,它需要检查生日,月份是'2月'和日是' 29日“,OP需要决定如何处理-1天。 – MarcF

-1

试试这个:

public bool IsBirthdayImminent 
{ 
    get { return DateOfBirth != null && DateOfBirth.Value.Date.AddYear(DateTime.Now.Year -DateOfBirth.Value.Year) >= DateTime.Today.Date.AddDays(-7); } 
} 
+0

如果生日是在过去7天或是从现在到年底之间的任何时间,这将返回true。 – yoozer8

+0

这不是很优雅,而有更好的解决方案!我同意@Jim – Mehran

0

你可以使用 “DAYOFYEAR”:

public bool IsBirthdayImminent 
{ 
    get { return DateOfBirth != null && Math.Abs(DateOfBirth.Value.Date.DayOfYear - DateTime.Today.DayOfYear) <= 7; } 
} 
+3

这是如何处理闰年的?如果你的生日是闰年,而二十九日二月以后,一年的日子比非闰年多一天,不是吗? – Servy

+0

恩,好点。 DayOfYear只返回1到366之间的整数值,所以你是对的;这会混淆你的结果。 – bbar

+0

@Servy如果在DateofBirth.Value.Date和DateTime.Today之间有2月29日,那么这个减法的值将比它应该小1。如果有两个或更多,它仍然会关闭1天。 –