2013-06-05 16 views
7

Ich versuche eine Benachrichtigung zu erhalten, wenn ein Kunde innerhalb der nächsten 7 Tage Geburtstag hat.Vergleichen DateTime ohne Jahr

Ich habe es mit diesem Code versucht:

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

Natürlich funktioniert das nicht, da das Datum mit Jahr (etwa 1980.05.21) gespeichert ist, und vergleicht auch das Jahr, . Also diese Abfrage wird nie true sein - na ja, nicht wenn du innerhalb der nächsten sieben Tage geboren bist.

Wie kann ich diese Abfrage ändern, um das Jahr zu ignorieren?

Edit:

Ordnung, die Abfrage selbst ist kein Problem. Mein primärer Punkt ist der Umgang mit Schaltjahren und Situationen um Dezember < -> Januar.

+0

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

+0

Normalisieren beide Daten: eine Kopie des DOB-Wertes und legen Sie fest, dass das Jahr dem aktuellen Jahr entspricht. Jetzt vergleichen Sie Äpfel mit Äpfeln. – Icarus

+0

@Idle_Mind Könnte das keine Probleme mit Schaltjahren haben? Wenn beispielsweise eines der Daten der 29. Februar 1996 ist und Sie versuchen, es auf den 29. Februar 2013 zu setzen, erhalten Sie möglicherweise nicht das gewünschte Ergebnis. Gleiches gilt für alle anderen Unterschiede zwischen Daten im Laufe der Jahre. – Servy

Antwort

8

Ich würde vorschlagen, den folgenden Code zu verwenden. Dies schließt Fälle um Dezember - Januar und Februar, 29. ein. Obwohl Sie vielleicht einen Blick darauf werfen und den 28. Februar korrigieren möchten, um innerhalb der gegebenen days aufgenommen oder ausgeschlossen zu werden.

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; 
    } 

Halten Sie auch den Rand Fall im Auge Guvante unten in den Kommentaren gepostet.

+0

+1 für 'AddYears' anstatt zu versuchen, einen Konstruktor zusammen zu hacken. Technisch für 'Tage> = 60' ist die Bearbeitung von Schaltjahren um eins verkürzt. Wenn beide 'AddYears' -Funktionen vom' birthDate' entfernt würden, würde diese Kantenbedingung behoben ('2/29/2012.AddYears (3) .AddYears (1) == 2/28/2016'). Angesichts der Anforderungen würde ich jedoch sagen, dass Ihre Methode am besten ist, da die Korrektur nicht offensichtlich begründete Redundanz hinzufügt. – Guvante

+1

@Guvante Das gilt nicht für alle Tage> = 60, nur Schaltjahre, wenn das aktuelle Datum auch ein Schaltjahr ist, aber vor dem 28.. Es ist jedoch unter diesen Bedingungen um einen Tag frei. Deshalb beantworte ich DateTime-Fragen selten. Sie sind super chaotisch. – Servy

+0

@Servy: Denkst du, die Anzahl der Schalttage zwischen 'birthdayThisYear' (nach letzter Zuweisung) und' birthDate' zu ​​korrigieren? – Caramiriel

0

Setzen Sie das Jahr des Birtdate explizit auf DateTime.Today.Year, und es wird gut vergleichen.

+1

Beachten Sie Fälle von Dezember bis Januar. – Caramiriel

1

Etwas wie folgt aus:

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; 

Als Getter:

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 Wenn jemand am 29. Februar geboren wird, wird dies eine Ausnahme auslösen die meisten Jahre, die Sie es nennen. – Servy

+0

@SeToY - Sieht gut aus. Es lohnt sich auch, einen Scheck hinzuzufügen, um sicherzustellen, dass das Bithdate in der Zukunft ist, zB '&& birthdayThisYear> DateTime.Now' – MarcF

+0

@Servy - Guter Ort, es würde einen Scheck für Geburtstage erfordern, wo der Monat 'Feb' und Tag 'ist 29., wo das OP entscheiden muss, wie mit dem -1 Tag umzugehen ist. – MarcF

-1

Try this:

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

Dies wird als wahr zurückgegeben, wenn der Geburtstag entweder in den letzten 7 Tagen war oder bis zum Ende des Jahres. – yoozer8

+0

das ist nicht sehr elegant, während es bessere Lösungen gibt! und ich stimme @Jim – Mehran

0

Sie könnten "DayOfYear" verwenden:

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

Wie funktioniert das Schaltjahr? Wenn dein Geburtstag in einem Schaltjahr ist, und nach dem 29. Februar, ist der Tag des Jahres ein Jahr mehr als dieses Datum in einem Nicht-Schaltjahr, nein? – Servy

+0

Hm, guter Punkt. DayOfYear gibt nur einen ganzzahligen Wert zwischen 1 und 366 zurück, also hast du recht; das würde deine Ergebnisse durcheinander bringen. – bbar

+0

@Servy Wenn zwischen dem "DateofBirth.Value.Date" und dem "DateTime.Today" ein Feb. 29. liegt, dann ist der Wert dieser Subtraktion 1 kleiner als es sein sollte. Wenn es zwei oder mehr gibt, ist es immer noch um 1 Tag ausgeschaltet. –