2013-06-05 4 views
7

J'essaie d'être informé lorsqu'un client aura son anniversaire dans les 7 prochains jours.Comparer DateHeure sans année

Je l'ai essayé avec ce code:

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

Bien sûr, cela ne fonctionne pas, la date est enregistrée avec son année (disons 21/05/1980) et il compare également l'année . Donc, cette requête ne sera jamais true - eh bien, pas si vous êtes né dans les sept prochains jours si.

Comment puis-je modifier cette requête pour ignorer l'année?

Edit:

D'accord, la requête elle-même est pas un problème du tout. Mon principal point est le traitement des années bissextiles et des situations autour de Décembre < -> Janvier.

+0

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

+0

Normaliser les deux dates: effectuer une copie de la valeur DOB et définissez l'année comme étant la même que l'année en cours. Maintenant, vous allez comparer des pommes aux pommes. – Icarus

+0

@Idle_Mind Pourriez-vous ne pas avoir de problèmes avec les années bissextiles? Si, par exemple, l'une des dates est le 29 février 1996 et que vous essayez de la définir au 29 février 2013, vous risquez de ne pas obtenir le résultat souhaité. Idem pour d'autres différences entre les dates au fil des ans. – Servy

Répondre

8

Je suggère d'utiliser le code suivant. Cela comprend les cas de décembre à janvier et le 29 février. Bien que vous pourriez vouloir jeter un oeil et corriger le 28 février pour être inclus ou exclus dans le days donné.

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

garder également le cas de bord à l'esprit Guvante posté dans les commentaires ci-dessous.

+0

+1 pour 'AddYears' au lieu d'essayer de bidouiller un constructeur. Techniquement pour 'days> = 60', votre gestion des anniversaires binaires est désactivée par un. Faire la fonction 'AddYears' de la' date de naissance 'fixerait cette condition de bord ('2/29/2012.AddYears (3) .AddYears (1) == 2/28/2016'). Cependant, étant donné les exigences, je dirais que votre méthode est la meilleure, puisque la correction ajoute une redondance non clairement raisonnée. – Guvante

+1

@Guvante Cela ne s'applique pas à tous les jours> = 60, seulement les années bissextiles où la date actuelle est aussi une année bissextile mais avant le 28. Il est éteint par un jour dans ces conditions cependant. C'est pourquoi je réponds si rarement aux questions DateTime. Ils sont super malpropres. – Servy

+0

@Servy: Pensez-vous que corriger la quantité de jours intercalaires entre 'birthdayThisYear' (après la dernière affectation) et' birthDate' sera suffisant? – Caramiriel

0

Définissez l'année de birtdate explicitement à DateTime.Today.Year, et il se comparera très bien.

+1

Soyez au courant des cas autour de Décembre-Janvier cependant. – Caramiriel

1

Quelque chose comme ceci:

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; 

En tant que 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 Si quelqu'un est né le 29 février, une exception sera générée la plupart des années. – Servy

+0

@SeToY - Ça a l'air bien. Il vaut également la peine d'ajouter une vérification pour s'assurer que la date est dans le futur, par exemple '&& birthdayThisYear> DateTime.Now' – MarcF

+0

@Servy - Bon endroit, il faudrait un chèque pour les anniversaires où le mois est 'fév' et le jour est ' 29 ', où le PO doit décider comment gérer le -1 jour. – MarcF

-1

Essayez ceci:

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

Cela retournera vrai si l'anniversaire a été soit dans les 7 derniers jours ou est n'importe quel moment entre maintenant et la fin de l'année. – yoozer8

+0

ce n'est pas très élégant, alors qu'il existe de meilleures solutions! et je suis d'accord avec @Jim – Mehran

0

Vous pouvez utiliser "DayOfYear":

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

Comment cela gère-t-il les années bissextiles? Si votre anniversaire est sur une année bissextile, et après le 29 février, le jour de l'année est un de plus que cette date sur une année non bissextile, non? – Servy

+0

Hm, bon point. DayOfYear renvoie juste une valeur entière entre 1 et 366, donc vous avez raison; ça gâcherait vos résultats. – bbar

+0

@Servy S'il y a un 29 février entre 'DateofBirth.Value.Date' et' DateTime.Today', alors la valeur de cette soustraction sera 1 inférieure à ce qu'elle devrait être. S'il y en a deux ou plus, il sera toujours éteint d'un jour. –