2009-06-11 8 views
14

Je me demandais simplement s'il y avait une solution élégante pour ce qui suit.Calculs de fin de mois

Si j'ai 30 Juin 2009 et ajouter un mois, je veux qu'il aille au 31 Juillet 2009, pas 30 Juillet 2009.

Cette logique est basée sur le fait que 30 Juin 2009 a été la fin du mois de juin et quand j'ajoute un mois je veux aller à la fin du mois prochain.

Mais si j'avons 29 Juin 2009 et ajouter un mois, il devrait aller au 29 Juillet 2009.

Notez que je dois être en mesure d'ajouter un certain nombre de mois et je dois prendre en années bissextiles.

Aussi je sais que la logique ici est discutable, mais c'est une exigence de l'entreprise qui fonctionne avec des contrats de fin de mois allant jusqu'à la fin du mois pour un mois dans le futur.

J'ai pensé à plusieurs solutions mais aucune qui soit très élégante. Par conséquent, je pensais que quelqu'un pourrait avoir un meilleur moyen.

Vive Anthony

+1

Vous vous contredisez. "Si j'ai le 30 juin 2009 et que j'ajoute un mois, je ne veux pas qu'il soit au 31 juillet 2009 ... quand j'ajoute un mois je veux aller à la fin du mois prochain.". Voulez-vous dire que vous voulez que ça se termine à la fin du mois? –

+0

ya que je viens de remarquer que moi-même ... :) –

+0

Quelles sont vos solutions inélégantes? –

Répondre

32

Pour vérifier si une date est la fin du mois, vous vérifiez si le lendemain est jour de quelques mois. votre algorithme devrait alors être "Si le jour n'est pas la fin du mois, ajouter 1 mois Si c'est la fin du mois, ajouter un jour, ajouter un mois, soustraire un jour."

bool IsEndOfMonth(DateTime date) { 
     return date.AddDays(1).Day == 1; 
    } 
    DateTime AddMonthSpecial(DateTime date) { 
     if (IsEndOfMonth(date)) 
      return date.AddDays(1).AddMonths(1).AddDays(-1); 
     else 
      return date.AddMonths(1); 
    } 
+0

Qu'en est-il le 31 Dec 2009 + 2 mois. Doit être 28 fév 2010 ... –

+0

désolé, j'ai fait une erreur dans l'explication "ajouter un jour, ajouter un mois, soustraire un mois" devrait être "ajouter un jour, ajouter un mois, soustraire jour." J'ai corrigé cette dernière phrase. – Jimmy

+1

votre exemple fonctionne toujours parce que vous ajoutez 2 mois au 1er janvier 2010, obtenant 1 mar 2010, puis en soustrayant le 1 jour pour obtenir "1 jour avant le mois suivant", ce qui est équivalent à "dernier jour du mois" – Jimmy

1

Pouvez-vous y arriver en commençant le premier jour du mois précédent et y retourner un jour?

0
  1. Vérifiez si l'ancienne date est "fin de mois".
    1. Ajoutez un jour à la date et vérifiez si le numéro du mois change.
  2. Ajouter un mois
  3. Si l'ancienne date était « fin de mois »
    1. Réglez le jour du mois à 1
    2. Ajouter un autre mois
    3. Soustraire un jour
+0

{get; } ms-help: //MS.VSCC.v90/MS.MSDNQTR.v90.en/fxref_mscorlib/html/899d9772-e792-052a-2c0b-8a28aea0d5b9.htm – sesame

0

Mon approche de ce problème commencerait par avoir une routine à détermine si un jour donné est le dernier jour du mois (en tenant compte de l'année bissextile bien sûr!)

Vous aurez également besoin d'une routine qui vous donne le dernier jour d'un mois, étant donné un jour dans ce mois.

Ensuite, si vous rencontrez un jour qui est un dernier jour, ajoutez un jour et utilisez la deuxième routine pour obtenir le dernier jour de ce mois. Utilisez une boucle pour plusieurs mois.

0

Vous pouvez implémenter un EndOfMonth() et isEndOfMonth().

de sorte que votre code serait, plus ou moins,

if isEndOfMonth(this.Date()) 
    endDate = (startmonth + addedMonths).EndOfMonth() 
else 
    endDate = startDate + addedMonths 

Un peu simpliste, mais vous voyez l'idée.

Il y a bien sûr beaucoup d'idées ici pour la logique de EndOFMonth et isEndOfMonth

2
DateTime exampleDate = DateTime.Parse("12/31/2009"); 
bool isLastDayOfMonth = (exampleDate.AddDays(1).Month != exampleDate.Month); 

if (isLastDayOfMonth) 
    Console.WriteLine(exampleDate.AddDays(1).AddMonths(1).AddDays(-1)); 
else 
    Console.WriteLine(new DateTime(exampleDate.Year, exampleDate.Month, 1).AddMonths(2).AddDays(-1)); 

EDIT: Je lis à nouveau votre question. Vous devrez mettre un chèque pour voir si son dernier jour du mois. Désolé, je voudrais avoir lu la question clairement de ce qui est nécessaire.
J'espère que c'est assez bon pour vous donner une idée de ce qui est nécessaire.

0

Voici une solution simple C# .NET qui compte pour les années bissextiles, etc:

static DateTime ContractDue(DateTime start, int months) 
{ 
    if (start.Month == start.AddDays(1).Month) 
    { // Same month, just add the months 
      return start.AddMonths(months); 
    } 
    // Last day of month... add a day, add the months, then go back one day 
    return start.AddDays(1).AddMonths(months).AddDays(-1); 
} 
-1

Si vous avez besoin que EndOfMonth ou AddNMonth simple, alors vous avez déjà votre réponse. Sinon, pour avoir une solution générique complète, vous aurez besoin d'une implémentation du modèle de récurrence comme vous pouvez le voir dans l'interface utilisateur du Outlook Meeting interface. Je ne vous suggère pas d'utiliser l'implémentation Outlook, mais il devrait y avoir quelques composants .NET que vous pouvez acheter. Ou implémentez-le vous-même, mais ne sous-estimez pas et ne testez pas tous les éléments - c'est un composant très délicat à mettre en œuvre.

0

Vous pouvez utiliser la méthode quelque chose comme DateTime.DaysInMonth():

DateTime workingMonth = new DateTime(2009, 06, 30).AddDays(1); 
int nextMonthDays = DateTime.DaysInMonth(workingMonth.Year, workingMonth.Month); 
DateTime newMonth = new DateTime(workingMonth.Year, workingMonth.Month, nextMonthDays); 
0

Serait-ce alors la fonction du complément de trouver si je suis sur le début d'un mois? DateTime.Now.AddDays(-1).Month == DateTime.Now.AddMonths(-1).Month

Questions connexes