Wie berechnet man die Differenz in Monaten zwischen zwei Daten in C #?
Gibt es ein Äquivalent zur VB- DateDiff()
Methode in C #? Ich muss einen Unterschied in Monaten zwischen zwei Daten feststellen, die Jahre voneinander entfernt sind. Die Dokumentation sagt, dass ich TimeSpan
wie folgt verwenden kann :
TimeSpan ts = date1 - date2;
aber das gibt mir Daten in Tagen. Ich möchte diese Zahl nicht durch 30 teilen, da nicht jeder Monat 30 Tage beträgt und da die beiden Operandenwerte ziemlich weit voneinander entfernt sind, befürchte ich, dass das Teilen durch 30 einen falschen Wert ergibt.
Irgendwelche Vorschläge?
DateDiff
Implantation: referencesource.microsoft.com/#Microsoft.VisualBasic/… .Antworten:
Angenommen, der Tag des Monats ist irrelevant (dh der Unterschied zwischen 2011.1.1 und 2010.12.31 ist 1), wobei Datum1> Datum2 einen positiven Wert und Datum2> Datum1 einen negativen Wert ergibt
Angenommen, Sie möchten eine ungefähre Anzahl von "durchschnittlichen Monaten" zwischen den beiden Daten, sollte das Folgende für alle außer sehr großen Datumsunterschieden funktionieren.
Wenn Sie die letztere Lösung verwenden, sollten Ihre Komponententests den breitesten Datumsbereich angeben, mit dem Ihre Anwendung arbeiten soll, und die Ergebnisse der Berechnung entsprechend validieren.
Update (danke an Gary )
Bei Verwendung der Methode "Durchschnittliche Monate" beträgt die etwas genauere Zahl für die "durchschnittliche Anzahl der Tage pro Jahr" 365,2425 .
quelle
(date1.Year - date2.Year) * 12 + date1.Month - date2.Month + (date1.Day >= date2.Day ? 0 : -1)
Hier ist eine umfassende Lösung, um a zurückzugeben
DateTimeSpan
, ähnlich wie aTimeSpan
, mit der Ausnahme, dass alle Datumskomponenten zusätzlich zu den Zeitkomponenten enthalten sind.Verwendungszweck:
Ausgänge:
Der Einfachheit halber habe ich die Logik in die
DateTimeSpan
Struktur integriert, aber Sie können die Methode verschieben,CompareDates
wo immer Sie es für richtig halten. Beachten Sie auch, dass es keine Rolle spielt, welches Datum vor dem anderen liegt.quelle
34
Tage für diesen Zeitunterschied zurück? Es ist35
timeanddate.com/date/…31
Monate mit weniger Tagen "durchläuft". Ich habe die Logik umgekehrt (so dass sie von früh nach später als umgekehrt geht) und akkumuliere jetzt die Monate, ohne das aktuelle Datum zu ändern (und somit Zwischenmonate mit weniger Tagen zu durchlaufen). Ich bin mir immer noch nicht ganz sicher, was das ideale Ergebnis ist sollte beim Vergleich10/31/2012
mit sein11/30/2012
. Im Moment ist das Ergebnis1
Monat.2020-02-29
es2021-06-29
- es gibt "1y 4m 1d" zurück, aber der Wert sollte "1y 4m 0d" sein, richtig?Du könntest es tun
quelle
if ( date1.AddMonths(x).Month == date2.Month )
Dann verwenden Sie einfach x + 1 alsWenn Sie die genaue Anzahl der vollen Monate wünschen, immer positiv (2000-01-15, 2000-02-14 gibt 0 zurück), wenn Sie berücksichtigen, dass ein voller Monat der gleiche Tag im nächsten Monat ist (so etwas wie die Altersberechnung)
Grund bearbeiten: Der alte Code war in einigen Fällen nicht korrekt wie:
quelle
new { From = new DateTime(2015, 12, 31), To = new DateTime(2015, 6, 30), Result = 6 }
Der Testnew { From = new DateTime(2015, 12, 31), To = new DateTime(2016, 06, 30), Result = 6 }
. Der "Fehler" liegt imto.Day < from.Day
Code, der nicht berücksichtigt, dass Monate an einem anderen "Tag des Monats" enden können. In diesem Fall sind vom 31. Dezember 2015 bis zum 30. Juni 2016 6 vollständige Monate vergangen (da der Juni 30 Tage hat), aber Ihr Code würde 5 zurückgeben.Ich habe die Verwendung dieser Methode in VB.NET über MSDN überprüft und es scheint, dass sie viele Verwendungen hat. In C # gibt es keine solche integrierte Methode. (Auch wenn es keine gute Idee ist) Sie können VBs in C # aufrufen.
Microsoft.VisualBasic.dll
Ihrem Projekt als Referenz hinzuMicrosoft.VisualBasic.DateAndTime.DateDiff
in Ihrem Codequelle
Microsoft.VisualBasic.dll
Modul geladen werden muss, aber die dafür erforderliche Zeit ist vernachlässigbar. Es gibt keinen Grund, sich um gründlich getestete und nützliche Funktionen zu betrügen, nur weil Sie sich entschieden haben, Ihr Programm in C # zu schreiben. (Dies gilt auch für Dinge wieMy.Application.SplashScreen
.)using
Aussage tun können , aber ich bezweifle, dass es ernsthaften Schaden geben wird.DateAndTime.Year()
gibt, zu existieren, da diesDateTime
eineYear
Eigenschaft hat. Es existiert nur, um VB.NET eher wie VB6 erscheinen zu lassen. Als ehemaliger VB6-Programmierer kann ich das schätzen ;-)Um einen Unterschied in Monaten zu erhalten (sowohl Anfang als auch Ende), unabhängig von den Daten:
quelle
start
undend
sind identisch. Dann erhalten Sie ein Ergebnis von 1. Wie ist das richtig? Warum addieren Sie 1 zum Ergebnis? Wer stimmt dieser Antwort zu: - /?Verwenden Noda Zeit :
(Beispielquelle)
quelle
Ich brauchte nur etwas Einfaches, um z. B. Beschäftigungsdaten zu berücksichtigen, bei denen nur der Monat / das Jahr eingegeben wurde, und wollte daher unterschiedliche Jahre und Monate, in denen gearbeitet wurde. Dies ist das, was ich hier nur aus Gründen der Nützlichkeit verwende
.NET Geige
quelle
Sie können die DateDiff- Klasse der Time Period Library für .NET verwenden :
quelle
Hier ist mein Beitrag, um einen Unterschied in Monaten zu erzielen, den ich für richtig befunden habe:
Verwendungszweck:
Sie können eine andere Methode namens DiffYears erstellen und genau dieselbe Logik wie oben und AddYears anstelle von AddMonths in der while-Schleife anwenden.
quelle
Dies funktionierte für das, wofür ich es brauchte. Der Tag des Monats spielte in meinem Fall keine Rolle, da es immer der letzte Tag des Monats ist.
quelle
Der genaueste Weg ist der, der die Differenz in Monaten nach Bruchteilen zurückgibt:
quelle
Hier ist eine einfache Lösung, die zumindest für mich funktioniert. Es ist wahrscheinlich nicht das schnellste, da es die AddMonth-Funktion von cool DateTime in einer Schleife verwendet:
quelle
quelle
Dies ist aus meiner eigenen Bibliothek, wird die Differenz der Monate zwischen zwei Daten zurückgeben.
quelle
Jan-31-2014
undDec-31-2013
Sie können eine Funktion wie diese haben.
Zum Beispiel wird von 2012/12/27 bis 2012/12/29 3 Tage. Ebenso wird von 2012/12/15 bis 2013/01/15 2 Monate, weil es bis 2013/01/14 1 Monat ist. Ab dem 15. beginnt der 2. Monat.
Sie können das "=" in der zweiten if-Bedingung entfernen, wenn Sie nicht beide Tage in die Berechnung einbeziehen möchten. Das heißt, von 2012/12/15 bis 2013/01/15 beträgt 1 Monat.
quelle
Sie können die folgende Erweiterung verwenden: Code
Implementierung !
quelle
Hier ist eine viel präzisere Lösung, bei der VB.Net DateDiff nur für Jahr, Monat und Tag verwendet wird. Sie können die DateDiff-Bibliothek auch in C # laden.
Datum1 muss <= Datum2 sein
VB.NET
C #
quelle
Dies ist eine Antwort auf die Antwort von Kirk Woll. Ich habe noch nicht genügend Reputationspunkte, um auf einen Kommentar zu antworten ...
Ich mochte Kirks Lösung und wollte sie schamlos abreißen und in meinem Code verwenden, aber als ich sie durchgesehen habe, wurde mir klar, dass sie viel zu kompliziert ist. Unnötiges Umschalten und Schleifen sowie ein öffentlicher Konstruktor, dessen Verwendung sinnlos ist.
Hier ist mein Umschreiben:
Verwendung1, so ziemlich das Gleiche:
Verwendung2, ähnlich:
quelle
In meinem Fall ist es erforderlich, den gesamten Monat vom Startdatum bis zum Tag vor diesem Tag im nächsten Monat oder vom Anfang bis zum Monatsende zu berechnen.
Beispiel: vom 01.01.2008 bis zum 31.01.2008 ist ein vollständiger Monat
Beispiel2: vom 01.05.2008 bis zum 02.04.2008 ist ein vollständiger Monat
Auf dieser Grundlage ist hier meine Lösung:
Verwendungszweck:
Hinweis: In meinem Fall war es erforderlich, die verbleibenden Tage nach den vollständigen Monaten zu berechnen. Wenn dies nicht der Fall ist, können Sie das Ergebnis der Tage ignorieren oder sogar die Methodenrückgabe von Tupel in Ganzzahl ändern.
quelle
Diese Lösung ist für die Berechnung von Vermietungen / Abonnements vorgesehen, bei denen Differenz nicht Subtraktion bedeutet, sondern die Zeitspanne innerhalb dieser beiden Daten.
quelle
Es gibt 3 Fälle: dasselbe Jahr, vorheriges Jahr und andere Jahre.
Wenn der Tag des Monats keine Rolle spielt ...
quelle
Ich habe eine Funktion geschrieben, um dies zu erreichen, weil die anderen Wege für mich nicht funktionierten.
quelle
Mein Verständnis der gesamten Monatsdifferenz zwischen zwei Daten hat einen integralen und einen gebrochenen Teil (das Datum ist wichtig).
Der integrale Bestandteil ist die volle Monatsdifferenz.
Der Bruchteil ist für mich die Differenz des Prozentsatzes des Tages (zu den vollen Tagen des Monats) zwischen dem Start- und dem Endmonat.
Mit dieser Erweiterung sind dies die Ergebnisse:
quelle
Es gibt nicht viele klare Antworten darauf, weil Sie immer Dinge annehmen.
Diese Lösung berechnet zwischen zwei Daten die Monate zwischen der Annahme, dass Sie den Tag des Monats zum Vergleich speichern möchten (dh, der Tag des Monats wird bei der Berechnung berücksichtigt).
Wenn Sie beispielsweise ein Datum vom 30. Januar 2012 haben, ist der 29. Februar 2012 kein Monat, sondern der 1. März 2013.
Es wurde ziemlich gründlich getestet, wird es wahrscheinlich später bereinigen, wenn wir es verwenden, aber hier:
quelle
Basierend auf der hervorragenden DateTimeSpan-Arbeit, die oben ausgeführt wurde, habe ich den Code ein wenig normalisiert. das scheint ziemlich gut zu funktionieren:
quelle
CompareDates(x, y)
demx={01/02/2019 00:00:00}
undy={01/05/2020 00:00:00}
dannMonths
gibt mir2
Diese einfache statische Funktion berechnet den Bruchteil von Monaten zwischen zwei Datumszeiten, z
Die Funktion geht davon aus, dass das erste Datum kleiner als das zweite Datum ist. Um mit negativen Zeitintervallen umzugehen, kann man die Funktion leicht ändern, indem man am Anfang ein Vorzeichen und einen Variablentausch einführt.
quelle
Die Differenz zwischen zwei Daten in Monaten berechnen zu können, ist völlig logisch und wird in vielen Geschäftsanwendungen benötigt. Die verschiedenen Programmierer hier, die Kommentare abgegeben haben wie - Was ist der Unterschied in den Monaten zwischen "Mai 1.2010" und "Juni 16.2010, Was ist der Unterschied in den Monaten zwischen dem 31. Dezember 2010 und dem 1. Januar 2011?" - haben es nicht verstanden die Grundlagen von Geschäftsanwendungen.
Hier ist die Antwort auf die obigen 2 Kommentare: Die Anzahl der Monate zwischen dem 1. Mai 2010 und dem 16. Juni 2010 beträgt 1 Monat, die Anzahl der Monate zwischen dem 31. Dezember 2010 und dem 1. Januar 2011 beträgt 0. Es Es wäre sehr dumm, sie als 1,5 Monate und 1 Sekunde zu berechnen, wie die obigen Codierer vorgeschlagen haben.
Personen, die an Kreditkarten-, Hypotheken-, Steuer-, Miet-, monatlichen Zinsberechnungen und einer Vielzahl anderer Geschäftslösungen gearbeitet haben, würden dem zustimmen.
Das Problem ist, dass eine solche Funktion in C # oder VB.NET nicht enthalten ist. Datediff berücksichtigt nur Jahre oder die Monatskomponente und ist daher eigentlich nutzlos.
Hier sind einige Beispiele aus der Praxis, wo Sie Monate benötigen und korrekt berechnen können:
Sie lebten in einer Kurzzeitmiete vom 18. Februar bis 23. August. Wie viele Monate bist du dort geblieben? Die Antwort ist einfach - 6 Monate
Sie haben ein Bankkonto, auf dem die Zinsen am Ende eines jeden Monats berechnet und gezahlt werden. Sie zahlen am 10. Juni Geld ein und nehmen es am 29. Oktober (im selben Jahr) heraus. Für wie viele Monate bekommen Sie Interesse? Sehr einfache Antwort - 4 Monate (wieder spielen die zusätzlichen Tage keine Rolle)
In Geschäftsanwendungen liegt die meiste Zeit, wenn Sie Monate berechnen müssen, daran, dass Sie "volle" Monate basierend auf der Berechnung der Zeit durch Menschen kennen müssen. nicht basierend auf einigen abstrakten / irrelevanten Gedanken.
quelle
Erweiterte Kirks-Struktur mit ToString (Format) und Duration (lange ms)
quelle
quelle