2013-06-05 117 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天。 –