Comment calculer la différence en mois entre deux dates en C #?
Y a-t-il l'équivalent de la DateDiff()
méthode de VB en C #. J'ai besoin de trouver une différence de mois entre deux dates séparées par des années. La documentation dit que je peux utiliser TimeSpan
comme:
TimeSpan ts = date1 - date2;
mais cela me donne des données en jours. Je ne veux pas diviser ce nombre par 30 car tous les mois ne sont pas 30 jours et comme les deux valeurs d'opérande sont assez éloignées l'une de l'autre, je crains que la division par 30 ne me donne une mauvaise valeur.
Aucune suggestion?
DateDiff
implantation: referencesource.microsoft.com/#Microsoft.VisualBasic/… .Réponses:
En supposant que le jour du mois n'est pas pertinent (c'est-à-dire que le diff entre 2011.1.1 et 2010.12.31 est 1), avec date1> date2 donnant une valeur positive et date2> date1 une valeur négative
Ou, en supposant que vous souhaitiez un nombre approximatif de «mois moyens» entre les deux dates, les éléments suivants devraient fonctionner pour toutes les différences de dates, sauf les énormes.
Notez que si vous utilisiez cette dernière solution, vos tests unitaires devraient indiquer la plage de dates la plus large avec laquelle votre application est conçue pour fonctionner et valider les résultats du calcul en conséquence.
Mise à jour (avec merci à Gary )
Si vous utilisez la méthode du «mois moyen», un nombre légèrement plus précis à utiliser pour le «nombre moyen de jours par an» est 365,2425 .
la source
(date1.Year - date2.Year) * 12 + date1.Month - date2.Month + (date1.Day >= date2.Day ? 0 : -1)
Voici une solution complète pour renvoyer un
DateTimeSpan
, similaire à unTimeSpan
, sauf qu'il inclut tous les composants de date en plus des composants d'heure.Usage:
Les sorties:
Pour plus de commodité, j'ai regroupé la logique dans la
DateTimeSpan
structure, mais vous pouvez déplacer la méthodeCompareDates
où bon vous semble. Notez également, peu importe la date qui précède l'autre.la source
34
jours pour cette différence de date et d'heure, c'est en fait35
timeanddate.com/date/…31
et la date "passe à travers" des mois avec moins de jours. J'ai inversé la logique (pour qu'elle passe du début à plus tard que l'inverse) et accumule maintenant les mois sans modifier la date actuelle (et donc passer par des mois intermédiaires avec moins de jours) Je ne sais toujours pas exactement quel est le résultat idéal devrait être lors de la comparaison10/31/2012
avec11/30/2012
. En ce moment, le résultat est le1
mois.2020-02-29
de2021-06-29
- il renvoie "1y 4m 1d", mais la valeur doit être "1y 4m 0d", non?Vous pourriez faire
la source
if ( date1.AddMonths(x).Month == date2.Month )
alors vous utilisez simplement x + 1 comme nombre de moisSi vous voulez le nombre exact de mois complets, toujours positif (2000-01-15, 2000-02-14 renvoie 0), considérant qu'un mois complet est lorsque vous atteignez le même jour le mois suivant (quelque chose comme le calcul de l'âge)
Modifier la raison: l'ancien code n'était pas correct dans certains cas comme:
la source
new { From = new DateTime(2015, 12, 31), To = new DateTime(2015, 6, 30), Result = 6 }
le test échouera car le résultat est 5.new { From = new DateTime(2015, 12, 31), To = new DateTime(2016, 06, 30), Result = 6 }
. Le "bug" réside dans leto.Day < from.Day
code qui ne tient pas compte du fait que les mois peuvent se terminer par un "jour du mois" différent. Dans ce cas du 31 décembre 2015 au 30 juin 2016, 6 mois complets se seront écoulés (depuis juin a 30 jours) mais votre code en retournerait 5.J'ai vérifié l'utilisation de cette méthode dans VB.NET via MSDN et il semble qu'elle ait beaucoup d'utilisations. Il n'y a pas une telle méthode intégrée en C #. (Même ce n'est pas une bonne idée), vous pouvez appeler les VB en C #.
Microsoft.VisualBasic.dll
à votre projet comme référenceMicrosoft.VisualBasic.DateAndTime.DateDiff
dans votre codela source
Microsoft.VisualBasic.dll
module doit être chargé, mais le temps qu'il faut pour le faire est négligeable. Il n'y a aucune raison de vous empêcher d'utiliser des fonctionnalités testées et utiles uniquement parce que vous avez choisi d'écrire votre programme en C #. (Cela vaut aussi pour des choses comme çaMy.Application.SplashScreen
.)using
déclaration, mais je doute qu'il y ait de graves dommages.DateAndTime.Year()
d'exister, étant donné qu'ellesDateTime
ont uneYear
propriété. Il n'existe que pour que VB.NET ressemble davantage à VB6. En tant qu'ancien programmeur VB6, je peux l'apprécier ;-)Pour obtenir la différence en mois (début et fin inclus), indépendamment des dates:
la source
start
etend
sont identiques. Ensuite, vous obtenez un résultat de 1. Comment est-ce vrai? Pourquoi ajoutez-vous 1 au résultat? Qui vote pour cette réponse: - /?Utilisez Noda Time :
(exemple de source)
la source
J'avais juste besoin de quelque chose de simple pour répondre, par exemple, à des dates d'emploi où seul le mois / l'année est entré, donc je voulais des années et des mois distincts travaillés.
.NET Fiddle
la source
Vous pouvez utiliser la classe DateDiff de la bibliothèque de périodes pour .NET :
la source
Voici ma contribution pour obtenir la différence en mois que j'ai trouvée exacte:
Usage:
Vous pouvez créer une autre méthode appelée DiffYears et appliquer exactement la même logique que ci-dessus et AddYears au lieu d'AddMonths dans la boucle while.
la source
Cela a fonctionné pour ce dont j'avais besoin. Le jour du mois n'a pas d'importance dans mon cas car il se trouve que c'est toujours le dernier jour du mois.
la source
La façon la plus précise est celle qui renvoie la différence en mois par fraction:
la source
Voici une solution simple qui fonctionne au moins pour moi. Ce n'est probablement pas le plus rapide car il utilise la fonctionnalité AddMonth de DateTime dans une boucle:
la source
la source
Ceci est de ma propre bibliothèque, retournera la différence de mois entre deux dates.
la source
Jan-31-2014
etDec-31-2013
Vous pouvez avoir une fonction quelque chose comme ça.
Par exemple, du 2012/12/27 au 2012/12/29 devient 3 jours. De même, du 2012/12/15 au 2013/01/15 devient 2 mois, car jusqu'au 2013/01/14 c'est 1 mois. à partir du 15, c'est le 2e mois qui a commencé.
Vous pouvez supprimer le "=" dans la seconde condition if, si vous ne souhaitez pas inclure les deux jours dans le calcul. soit du 2012/12/15 au 2013/01/15 soit 1 mois.
la source
vous pouvez utiliser l'extension suivante: Code
La mise en oeuvre !
la source
Voici une solution beaucoup plus concise utilisant VB.Net DateDiff pour l'année, le mois et le jour uniquement. Vous pouvez également charger la bibliothèque DateDiff en C #.
date1 doit être <= date2
VB.NET
C #
la source
C'est en réponse à la réponse de Kirk Woll. Je n'ai pas encore assez de points de réputation pour répondre à un commentaire ...
J'aimais la solution de Kirk et j'allais l'arracher sans vergogne et l'utiliser dans mon code, mais quand je l'ai regardée, j'ai réalisé que c'était beaucoup trop compliqué. Commutation et boucle inutiles, et un constructeur public inutile à utiliser.
Voici ma réécriture:
Usage1, à peu près la même:
Usage2, similaire:
la source
Dans mon cas, il est nécessaire de calculer le mois complet de la date de début à la veille de ce jour du mois suivant ou du début à la fin du mois.
Ex: du 1/1/2018 au 31/1/2018 est un mois complet
Ex2: du 01/05/2018 au 4/2/2018 est un mois complet
sur cette base, voici ma solution:
Usage:
Remarque: dans mon cas, il était nécessaire de calculer les jours restants après les mois complets, donc si ce n'est pas votre cas, vous pouvez ignorer le résultat des jours ou même changer la méthode de retour de tuple à entier.
la source
Cette solution est pour le calcul de location / abonnement, où la différence ne signifie pas être une soustraction, elle est censée être la durée dans ces deux dates.
la source
Il y a 3 cas: la même année, l'année précédente et les autres années.
Si le jour du mois n'a pas d'importance ...
la source
J'ai écrit une fonction pour accomplir cela, car les autres méthodes ne fonctionnaient pas pour moi.
la source
Ma compréhension de la différence totale des mois entre 2 dates a une partie intégrale et une partie fractionnaire (la date compte).
La partie intégrante est la différence des mois complets.
La partie fractionnaire, pour moi, est la différence du% de la journée (aux jours entiers du mois) entre les mois de début et de fin.
Avec cette extension, voici les résultats:
la source
Il n'y a pas beaucoup de réponses claires à ce sujet parce que vous supposez toujours des choses.
Cette solution calcule entre deux dates les mois entre l'hypothèse que vous souhaitez enregistrer le jour du mois pour comparaison, (ce qui signifie que le jour du mois est pris en compte dans le calcul)
Exemple, si vous avez une date du 30 janvier 2012, le 29 février 2012 ne sera pas un mois mais le 1er mars 2013 le sera.
Il a été testé assez soigneusement, le nettoiera probablement plus tard au fur et à mesure que nous l'utilisons, mais ici:
la source
Sur la base de l'excellent travail DateTimeSpan effectué ci-dessus, j'ai normalisé un peu le code; cela semble assez bien fonctionner:
la source
CompareDates(x, y)
oùx={01/02/2019 00:00:00}
ety={01/05/2020 00:00:00}
puisMonths
me donne2
Cette fonction statique simple calcule la fraction de mois entre deux Datetimes, par exemple
La fonction suppose que la première date est inférieure à la deuxième date. Pour gérer les intervalles de temps négatifs, on peut facilement modifier la fonction en introduisant un signe et un échange de variable au début.
la source
Pouvoir calculer la différence entre 2 dates en mois est une chose parfaitement logique à faire et est nécessaire dans de nombreuses applications commerciales. Les nombreux codeurs ici qui ont fourni des commentaires tels que - quelle est la différence de mois entre "1er mai 2010" et "16 juin 2010, quelle est la différence de mois entre le 31 décembre 2010 et le 1er janvier 2011? - n'ont pas compris les bases des applications métier.
Voici la réponse aux 2 commentaires ci-dessus - Le nombre de mois entre le 1er mai 2010 et le 16 juin 2010 est de 1 mois, le nombre de mois entre le 31 décembre 2010 et le 1er janvier 2011 est de 0. Il serait très stupide de les calculer comme 1,5 mois et 1 seconde, comme les codeurs ci-dessus l'ont suggéré.
Les gens qui ont travaillé sur les cartes de crédit, le traitement des hypothèques, le traitement des impôts, le traitement des loyers, le calcul des intérêts mensuels et une grande variété d'autres solutions commerciales seraient d'accord.
Le problème est qu'une telle fonction n'est pas incluse dans C # ou VB.NET d'ailleurs. Datediff ne prend en compte que les années ou la composante mois, donc est en fait inutile.
Voici quelques exemples concrets où vous devez calculer correctement les mois:
Vous avez vécu dans une location à court terme du 18 février au 23 août. Combien de mois y êtes-vous resté? La réponse est simple - 6 mois
Vous avez un compte bancaire où les intérêts sont calculés et payés à la fin de chaque mois. Vous déposez de l'argent le 10 juin et le retirez le 29 octobre (même année). Pour combien de mois recevez-vous de l'intérêt? Réponse très simple - 4 mois (encore une fois, les jours supplémentaires n'ont pas d'importance)
Dans les applications commerciales, la plupart du temps, lorsque vous devez calculer des mois, c'est parce que vous devez connaître des mois «complets» en fonction de la façon dont les humains calculent le temps; ne repose pas sur des pensées abstraites / non pertinentes.
la source
Structure Kirks étendue avec ToString (format) et durée (long ms)
la source
la source